summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>2024-09-20 13:54:23 (GMT)
committerAditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>2024-09-27 14:35:08 (GMT)
commitbd2c47ad11213b200cb1c9d320b00ba788e04685 (patch)
treee7f9933238b28f859c4149d87bbd71c1af62ca0f
parentb684ebf6ad0f62bbc656b34bd3067f33dc719578 (diff)
downloadCMake-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.cxx35
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;
}