[llvm] 652713e - [MachO][ObjCopy] Handle exports trie in LC_DYLD_INFO and LC_DYLD_EXPORTS_TRIE

Daniel Rodríguez Troitiño via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 22 18:51:44 PST 2022


Author: Daniel Rodríguez Troitiño
Date: 2022-11-22T18:50:06-08:00
New Revision: 652713e268d86a79c9a2935fb4ed7207bd0f0d1c

URL: https://github.com/llvm/llvm-project/commit/652713e268d86a79c9a2935fb4ed7207bd0f0d1c
DIFF: https://github.com/llvm/llvm-project/commit/652713e268d86a79c9a2935fb4ed7207bd0f0d1c.diff

LOG: [MachO][ObjCopy] Handle exports trie in LC_DYLD_INFO and LC_DYLD_EXPORTS_TRIE

The exports trie used to be pointed by the information in LC_DYLD_INFO,
but when chained fixups are present, the exports trie is pointed by
LC_DYLD_EXPORTS_TRIE instead.

Modify ObjCopy code to calculate the right offset and size needed
depending on the existence of LC_DYLD_INFO or LC_DYLD_EXPORTS_TRIE, read
the exports from either of those places, and write the export
information as pointed to either of those places.

Depends on D134571.

Reviewed By: alexander-shaposhnikov

Differential Revision: https://reviews.llvm.org/D137879

Added: 
    llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test

Modified: 
    llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
    llvm/lib/ObjCopy/MachO/MachOReader.cpp
    llvm/lib/ObjCopy/MachO/MachOWriter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
index 30e25d05d76b5..067ef39d90522 100644
--- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
@@ -235,6 +235,26 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
          "Incorrect tail offset");
   Offset = std::max(Offset, HeaderSize + O.Header.SizeOfCmds);
 
+  // The exports trie can be in either LC_DYLD_INFO or in
+  // LC_DYLD_EXPORTS_TRIE, but not both.
+  size_t DyldInfoExportsTrieSize = 0;
+  size_t DyldExportsTrieSize = 0;
+  for (const auto &LC : O.LoadCommands) {
+    switch (LC.MachOLoadCommand.load_command_data.cmd) {
+    case MachO::LC_DYLD_INFO:
+    case MachO::LC_DYLD_INFO_ONLY:
+      DyldInfoExportsTrieSize = O.Exports.Trie.size();
+      break;
+    case MachO::LC_DYLD_EXPORTS_TRIE:
+      DyldExportsTrieSize = O.Exports.Trie.size();
+      break;
+    default:
+      break;
+    }
+  }
+  assert((DyldInfoExportsTrieSize == 0 || DyldExportsTrieSize == 0) &&
+         "Export trie in both LCs");
+
   uint64_t NListSize = Is64Bit ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
   uint64_t StartOfLinkEdit = Offset;
 
@@ -253,9 +273,9 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
   uint64_t StartOfBindingInfo = updateOffset(O.Binds.Opcodes.size());
   uint64_t StartOfWeakBindingInfo = updateOffset(O.WeakBinds.Opcodes.size());
   uint64_t StartOfLazyBindingInfo = updateOffset(O.LazyBinds.Opcodes.size());
-  uint64_t StartOfExportTrie = updateOffset(O.Exports.Trie.size());
+  uint64_t StartOfExportTrie = updateOffset(DyldInfoExportsTrieSize);
   uint64_t StartOfChainedFixups = updateOffset(O.ChainedFixups.Data.size());
-  uint64_t StartOfDyldExportsTrie = updateOffset(O.ExportsTrie.Data.size());
+  uint64_t StartOfDyldExportsTrie = updateOffset(DyldExportsTrieSize);
   uint64_t StartOfFunctionStarts = updateOffset(O.FunctionStarts.Data.size());
   uint64_t StartOfDataInCode = updateOffset(O.DataInCode.Data.size());
   uint64_t StartOfLinkerOptimizationHint =
@@ -368,7 +388,7 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
       break;
     case MachO::LC_DYLD_EXPORTS_TRIE:
       MLC.linkedit_data_command_data.dataoff = StartOfDyldExportsTrie;
-      MLC.linkedit_data_command_data.datasize = O.ExportsTrie.Data.size();
+      MLC.linkedit_data_command_data.datasize = DyldExportsTrieSize;
       break;
     case MachO::LC_DYLD_INFO:
     case MachO::LC_DYLD_INFO_ONLY:
@@ -386,7 +406,7 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
       MLC.dyld_info_command_data.lazy_bind_size = O.LazyBinds.Opcodes.size();
       MLC.dyld_info_command_data.export_off =
           O.Exports.Trie.empty() ? 0 : StartOfExportTrie;
-      MLC.dyld_info_command_data.export_size = O.Exports.Trie.size();
+      MLC.dyld_info_command_data.export_size = DyldInfoExportsTrieSize;
       break;
     // Note that LC_ENCRYPTION_INFO.cryptoff despite its name and the comment in
     // <mach-o/loader.h> is not an offset in the binary file, instead, it is a

diff  --git a/llvm/lib/ObjCopy/MachO/MachOReader.cpp b/llvm/lib/ObjCopy/MachO/MachOReader.cpp
index b9bb02db23920..e0fdd1ce4cfa2 100644
--- a/llvm/lib/ObjCopy/MachO/MachOReader.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOReader.cpp
@@ -284,7 +284,11 @@ void MachOReader::readLazyBindInfo(Object &O) const {
 }
 
 void MachOReader::readExportInfo(Object &O) const {
-  O.Exports.Trie = MachOObj.getDyldInfoExportsTrie();
+  // This information can be in LC_DYLD_INFO or in LC_DYLD_EXPORTS_TRIE
+  ArrayRef<uint8_t> Trie = MachOObj.getDyldInfoExportsTrie();
+  if (Trie.empty())
+    Trie = MachOObj.getDyldExportsTrie();
+  O.Exports.Trie = Trie;
 }
 
 void MachOReader::readLinkData(Object &O, Optional<size_t> LCIndex,

diff  --git a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
index 80a8b29047099..d0a9dc9e9c15c 100644
--- a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
@@ -569,7 +569,15 @@ void MachOWriter::writeChainedFixupsData() {
 }
 
 void MachOWriter::writeExportsTrieData() {
-  return writeLinkData(O.ExportsTrieCommandIndex, O.ExportsTrie);
+  if (!O.ExportsTrieCommandIndex)
+    return;
+  const MachO::linkedit_data_command &ExportsTrieCmd =
+      O.LoadCommands[*O.ExportsTrieCommandIndex]
+          .MachOLoadCommand.linkedit_data_command_data;
+  char *Out = (char *)Buf->getBufferStart() + ExportsTrieCmd.dataoff;
+  assert((ExportsTrieCmd.datasize == O.Exports.Trie.size()) &&
+         "Incorrect export trie size");
+  memcpy(Out, O.Exports.Trie.data(), O.Exports.Trie.size());
 }
 
 void MachOWriter::writeTail() {

diff  --git a/llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test b/llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test
new file mode 100644
index 0000000000000..08ebaeebfaba4
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test
@@ -0,0 +1,205 @@
+# RUN: yaml2obj %s | llvm-objdump --macho --exports-trie - | FileCheck %s
+
+# CHECK:      Exports trie:
+# CHECK-NEXT: 0x100000000 __mh_execute_header
+# CHECK-NEXT: 0x100003F98 _main
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x2
+  ncmds:           15
+  sizeofcmds:      728
+  flags:           0x200085
+  reserved:        0x0
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __PAGEZERO
+    vmaddr:          0
+    vmsize:          4294967296
+    fileoff:         0
+    filesize:        0
+    maxprot:         0
+    initprot:        0
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          16384
+    fileoff:         0
+    filesize:        16384
+    maxprot:         5
+    initprot:        5
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x100003FB0
+        size:            8
+        offset:          0x3FB0
+        align:           4
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         C30F1F0000000000
+      - sectname:        __unwind_info
+        segname:         __TEXT
+        addr:            0x100003FB8
+        size:            72
+        offset:          0x3FB8
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4294983680
+    vmsize:          16384
+    fileoff:         16384
+    filesize:        176
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_DYLD_CHAINED_FIXUPS
+    cmdsize:         16
+    dataoff:         16384
+    datasize:        56
+  - cmd:             LC_DYLD_EXPORTS_TRIE
+    cmdsize:         16
+    dataoff:         16440
+    datasize:        48
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          16504
+    nsyms:           2
+    stroff:          16536
+    strsize:         32
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      2
+    iundefsym:       2
+    nundefsym:       0
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+  - cmd:             LC_LOAD_DYLINKER
+    cmdsize:         32
+    name:            12
+    Content:         '/usr/lib/dyld'
+    ZeroPadBytes:    7
+  - cmd:             LC_UUID
+    cmdsize:         24
+    uuid:            362D6303-E0AC-3074-B083-CF48B87DB35D
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         32
+    platform:        1
+    minos:           786432
+    sdk:             787200
+    ntools:          1
+    Tools:
+      - tool:            3
+        version:         50069504
+  - cmd:             LC_SOURCE_VERSION
+    cmdsize:         16
+    version:         0
+  - cmd:             LC_MAIN
+    cmdsize:         24
+    entryoff:        16304
+    stacksize:       0
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         56
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 85943299
+      compatibility_version: 65536
+    Content:         '/usr/lib/libSystem.B.dylib'
+    ZeroPadBytes:    6
+  - cmd:             LC_FUNCTION_STARTS
+    cmdsize:         16
+    dataoff:         16488
+    datasize:        8
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         0
+    datasize:        0
+LinkEditData:
+  ExportTrie:
+      TerminalSize:    0
+      NodeOffset:      0
+      Name:            ''
+      Flags:           0x0
+      Address:         0x0
+      Other:           0x0
+      ImportName:      ''
+      Children:
+        - TerminalSize:    0
+          NodeOffset:      5
+          Name:            _
+          Flags:           0x0
+          Address:         0x0
+          Other:           0x0
+          ImportName:      ''
+          Children:
+            - TerminalSize:    2
+              NodeOffset:      33
+              Name:            _mh_execute_header
+              Flags:           0x0
+              Address:         0x0
+              Other:           0x0
+              ImportName:      ''
+            - TerminalSize:    3
+              NodeOffset:      37
+              Name:            main
+              Flags:           0x0
+              Address:         0x3F98
+              Other:           0x0
+              ImportName:      ''
+  NameList:
+    - n_strx:          2
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          16
+      n_value:         4294967296
+    - n_strx:          22
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294983600
+  StringTable:
+    - ' '
+    - __mh_execute_header
+    - _main
+    - ''
+    - ''
+    - ''
+    - ''
+  FunctionStarts:  [ 0x3FB0 ]
+...


        


More information about the llvm-commits mailing list