[llvm] [Archive][COFF] Split hybrid COFF files when adding them to an archive (PR #205160)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 2 07:16:53 PDT 2026
================
@@ -1580,6 +1580,69 @@ std::optional<MemoryBufferRef> COFFObjectFile::findHybridObjectSection() const {
return std::nullopt;
}
+std::unique_ptr<MemoryBuffer> COFFObjectFile::stripHybridSection() const {
+ if (getDOSHeader() || getMachine() != COFF::IMAGE_FILE_MACHINE_ARM64)
+ return nullptr;
+
+ for (SectionRef S : sections()) {
+ Expected<StringRef> Name = S.getName();
+ if (errorToBool(Name.takeError()) || *Name != kArm64ECSectionName)
+ continue;
+
+ const coff_section *HybridSec = getCOFFSection(S);
+ if (!HybridSec->SizeOfRawData)
+ continue;
+
+ // Copy the original buffer, skipping the hybrid section content.
+ std::unique_ptr<WritableMemoryBuffer> NativeView =
+ WritableMemoryBuffer::getNewUninitMemBuffer(Data.getBufferSize() -
+ HybridSec->SizeOfRawData);
+ uint32_t HybridEnd = HybridSec->PointerToRawData + HybridSec->SizeOfRawData;
+ memcpy(NativeView->getBufferStart(), Data.getBufferStart(),
+ HybridSec->PointerToRawData);
+ memcpy(NativeView->getBufferStart() + HybridSec->PointerToRawData,
+ Data.getBufferStart() + HybridEnd, Data.getBufferSize() - HybridEnd);
+
+ auto getTargetPtr = [&](const void *Ptr) {
+ return NativeView->getBufferStart() +
+ (reinterpret_cast<const char *>(Ptr) - Data.getBufferStart());
+ };
+
+ // Adjust the COFF header, if necessary.
+ if (COFFHeader) {
+ auto Header =
+ reinterpret_cast<coff_file_header *>(getTargetPtr(COFFHeader));
+ if (Header->PointerToSymbolTable >= HybridEnd)
+ Header->PointerToSymbolTable -= HybridSec->SizeOfRawData;
+ } else {
+ auto Header = reinterpret_cast<coff_bigobj_file_header *>(
+ getTargetPtr(COFFBigObjHeader));
+ if (Header->PointerToSymbolTable >= HybridEnd)
+ Header->PointerToSymbolTable -= HybridSec->SizeOfRawData;
+ }
+
+ // Adjust section headers.
+ auto COFFSec = reinterpret_cast<coff_section *>(getTargetPtr(HybridSec));
+ COFFSec->PointerToRawData = 0;
+ COFFSec->SizeOfRawData = 0;
----------------
cjacek wrote:
I added zeroing of `VirtualSize` and extended the comment to clarify how the section is stripped. (Initially, I implemented a full removal, including the COFF headers, but later decided against it. That approach required additional fixups to symbols, making it more invasive for a questionable benefit.)
https://github.com/llvm/llvm-project/pull/205160
More information about the llvm-commits
mailing list