mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 07:11:05 -06:00
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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user