[PATCH] D105431: [LLD] Fix a padding bug in the old Mach-O backend in LLD.

Neil Henning via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 5 05:22:48 PDT 2021


sheredom created this revision.
sheredom added a reviewer: lhames.
sheredom added projects: lld, lld-macho.
Herald added a reviewer: lld-macho.
sheredom requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This commit fixes a bug with the old Mach-O backend, where it is
possible for a header to be written that does not contain enough
space for the UUID and codesign sections to be present.

To fix it, we simply add a padding to the header to ensure there is
always enough space.

Note: this bug is **not** present in the new Mach-O backend, but
we couldn't use that for other reasons.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D105431

Files:
  lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
  lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp


Index: lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
===================================================================
--- lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -193,6 +193,7 @@
   uint32_t              _startOfLoadCommands;
   uint32_t              _countOfLoadCommands;
   uint32_t              _endOfLoadCommands;
+  uint32_t              _endOfHeader;
   uint32_t              _startOfRelocations;
   uint32_t              _startOfFunctionStarts;
   uint32_t              _startOfDataInCode;
@@ -248,7 +249,7 @@
 
 
 size_t MachOFileLayout::headerAndLoadCommandsSize() const {
-  return _endOfLoadCommands;
+  return _endOfHeader;
 }
 
 MachOFileLayout::MachOFileLayout(const NormalizedFile &file,
@@ -281,8 +282,9 @@
       _endOfLoadCommands += sizeof(linkedit_data_command);
       _countOfLoadCommands++;
     }
+    _endOfHeader = _endOfLoadCommands;
     // Assign file offsets to each section.
-    _startOfSectionsContent = _endOfLoadCommands;
+    _startOfSectionsContent = _endOfHeader;
     unsigned relocCount = 0;
     uint64_t offset = _startOfSectionsContent;
     for (const Section &sect : file.sections) {
@@ -319,6 +321,7 @@
       << "  startOfLoadCommands=" << _startOfLoadCommands << "\n"
       << "  countOfLoadCommands=" << _countOfLoadCommands << "\n"
       << "  endOfLoadCommands=" << _endOfLoadCommands << "\n"
+      << "  endOfHeader=" << _endOfHeader << "\n"
       << "  startOfRelocations=" << _startOfRelocations << "\n"
       << "  startOfSymbols=" << _startOfSymbols << "\n"
       << "  startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
@@ -331,6 +334,8 @@
                           + loadCommandsSize(_countOfLoadCommands,
                                              alwaysIncludeFunctionStarts);
 
+    _endOfHeader = _endOfLoadCommands + _file.headerPad;
+
     // Assign section file offsets.
     buildFileOffsets();
     buildLinkEditInfo();
@@ -360,6 +365,7 @@
       << "  startOfLoadCommands=" << _startOfLoadCommands << "\n"
       << "  countOfLoadCommands=" << _countOfLoadCommands << "\n"
       << "  endOfLoadCommands=" << _endOfLoadCommands << "\n"
+      << "  endOfHeader=" << _endOfHeader << "\n"
       << "  startOfLinkEdit=" << _startOfLinkEdit << "\n"
       << "  startOfRebaseInfo=" << _startOfRebaseInfo << "\n"
       << "  endOfRebaseInfo=" << _endOfRebaseInfo << "\n"
@@ -628,7 +634,7 @@
   memset(seg->segname, 0, 16);
   seg->flags = 0;
   seg->vmaddr = 0;
-  seg->fileoff = _endOfLoadCommands;
+  seg->fileoff = _endOfHeader;
   seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
   seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
   seg->nsects = _file.sections.size();
@@ -1013,6 +1019,7 @@
       lc += sizeof(linkedit_data_command);
     }
   }
+
   assert(lc == &_buffer[_endOfLoadCommands]);
   return llvm::Error::success();
 }
@@ -1025,7 +1032,7 @@
     if (s.content.empty())
       continue;
     uint32_t offset = _sectInfo[&s].fileOffset;
-    assert(offset >= _endOfLoadCommands);
+    assert(offset >= _endOfHeader);
     uint8_t *p = &_buffer[offset];
     memcpy(p, &s.content[0], s.content.size());
     p += s.content.size();
Index: lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
===================================================================
--- lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
+++ lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
@@ -261,6 +261,8 @@
   std::vector<uint8_t>        functionStarts;
   std::vector<DataInCode>     dataInCode;
 
+  uint32_t                    headerPad = 16 + 24; // Space for UUID + CODESIGN
+
   // TODO:
   // code-signature
   // split-seg-info


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105431.356486.patch
Type: text/x-patch
Size: 3742 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210705/602d9a14/attachment.bin>


More information about the llvm-commits mailing list