[llvm] Fix getting section info in large mach-o files. (PR #165940)

Peter Rong via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 31 16:58:11 PDT 2025


================
@@ -1978,20 +1978,34 @@ uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const {
   return SectSize;
 }
 
-ArrayRef<uint8_t> MachOObjectFile::getSectionContents(uint32_t Offset,
+ArrayRef<uint8_t> MachOObjectFile::getSectionContents(uint64_t Offset,
                                                       uint64_t Size) const {
   return arrayRefFromStringRef(getData().substr(Offset, Size));
 }
 
 Expected<ArrayRef<uint8_t>>
 MachOObjectFile::getSectionContents(DataRefImpl Sec) const {
-  uint32_t Offset;
+  uint64_t Offset;
   uint64_t Size;
 
   if (is64Bit()) {
     MachO::section_64 Sect = getSection64(Sec);
     Offset = Sect.offset;
     Size = Sect.size;
+    // Check for large mach-o files where the section contents might exceed
+    // 4GB. MachO::section_64 objects only have 32 bit file offsets to the
+    // section contents and can overflow in dSYM files. We can track this and
+    // adjust the section offset to be 64 bit safe.
+    uint64_t SectOffsetAdjust = 0;
+    for (uint32_t SectIdx=0; SectIdx<Sec.d.a; ++SectIdx) {
+      MachO::section_64 CurrSect =
+          getStruct<MachO::section_64>(*this, Sections[SectIdx]);
+      const uint64_t EndSectFileOffset =
+          (uint64_t)CurrSect.offset + CurrSect.size;
+      if (EndSectFileOffset >= UINT32_MAX)
+        SectOffsetAdjust += EndSectFileOffset & 0xFFFFFFFF00000000ull;
+    }
----------------
DataCorrupted wrote:

We are building this adjustment on a strong assumption that section offsets are ordered, this might not be true for MachO (although most likely). 

Assert and bail out if sections are not ordered in case we run into any corner cases that are not dSYM.

```suggestion
    // adjust the section offset to be 64 bit safe.
    // Assumes the sections are ordered.
    uint64_t PrevTrueOffset = 0;
    uint64_t SectOffsetAdjust = 0;
    for (uint32_t SectIdx=0; SectIdx<Sec.d.a; ++SectIdx) {
      MachO::section_64 CurrSect =
          getStruct<MachO::section_64>(*this, Sections[SectIdx]);
      assert(SectOffsetAdjust && (PrevTrueOffset <= CurrSect.offset) && "Overflowing sections must be ordered for adjustment")
      const uint64_t EndSectFileOffset =
          (uint64_t)CurrSect.offset + CurrSect.size;
      if (EndSectFileOffset >= UINT32_MAX)
        SectOffsetAdjust += EndSectFileOffset & 0xFFFFFFFF00000000ull;
      PrevTrueOffset = (uint64_t) CurrSect.offset | SectOffsetAdjust;
    }
```

https://github.com/llvm/llvm-project/pull/165940


More information about the llvm-commits mailing list