[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