diff options
author | Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com> | 2024-09-20 13:54:23 (GMT) |
---|---|---|
committer | Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com> | 2024-09-27 14:35:08 (GMT) |
commit | bd2c47ad11213b200cb1c9d320b00ba788e04685 (patch) | |
tree | e7f9933238b28f859c4149d87bbd71c1af62ca0f | |
parent | b684ebf6ad0f62bbc656b34bd3067f33dc719578 (diff) | |
download | CMake-bd2c47ad11213b200cb1c9d320b00ba788e04685.zip CMake-bd2c47ad11213b200cb1c9d320b00ba788e04685.tar.gz CMake-bd2c47ad11213b200cb1c9d320b00ba788e04685.tar.bz2 |
AIX: Fix support for editing XCOFF binary inside an archive
When AIX stores a `.so` inside a `.a` archive, the loader section is
aligned to maximum of the text and data alignment. In commit 98013ad1ca
(cmXCOFF: Add support for editing binary inside an archive, 2024-07-01)
we only accounted for the data alignment.
Issue: #26275
-rw-r--r-- | Source/cmXCOFF.cxx | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/Source/cmXCOFF.cxx b/Source/cmXCOFF.cxx index 923b6d9..6fd6fbf 100644 --- a/Source/cmXCOFF.cxx +++ b/Source/cmXCOFF.cxx @@ -209,7 +209,10 @@ Impl<XCOFF>::Impl(cmXCOFF* external, std::unique_ptr<std::iostream> fin, this->SetErrorMessage("XCOFF loader section missing."); return; } - this->bytes_to_align = this->AuxHeader.o_algndata; + this->bytes_to_align = + this->AuxHeader.o_algntext > this->AuxHeader.o_algndata + ? this->AuxHeader.o_algntext + : this->AuxHeader.o_algndata; if (!this->Stream->seekg((this->AuxHeader.o_snloader - 1) * sizeof(typename XCOFF::scnhdr), std::ios::cur)) { @@ -376,16 +379,6 @@ IsArchive check_if_big_archive(const char* fname) } } -size_t getLastWordLen(const std::string& path) -{ - std::size_t lastSlashPos = path.find_last_of("/\\"); - if (lastSlashPos == std::string::npos) { - return path.length(); - } - - return (path.length() - lastSlashPos - 1); -} - //============================================================================ // External class implementation. @@ -429,14 +422,22 @@ cmXCOFF::cmXCOFF(const char* fname, Mode mode) ar_hdr arHeader; f->read(reinterpret_cast<char*>(&arHeader), sizeof(ar_hdr)); - // We will sometimes get /opt/freeware/lib/libshared.a. So extract - // the last part only. - // Example: libshared.a [We need to length of "libshared.a" characters]. - archive_name_length = static_cast<int>(getLastWordLen(std::string(fname))); + { + errno = 0; + char* ar_namlen_endp; + unsigned long ar_namlen = + strtoul(arHeader.ar_namlen, &ar_namlen_endp, 10); + if ((ar_namlen_endp != arHeader.ar_namlen) && (errno == 0)) { + archive_name_length = static_cast<int>(ar_namlen); + } else { + this->ErrorMessage = "Error parsing archive name length."; + return; + } + } - // Move to the next even byte. + // Round off to even byte. if (archive_name_length % 2 == 0) { - nextEvenByte = archive_name_length + 2; + nextEvenByte = archive_name_length; } else { nextEvenByte = archive_name_length + 1; } |