[llvm] dd2165e - [objcopy] Fix order of Mach-O LINKEDIT pieces during layout

Daniel Rodríguez Troitiño via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 11 12:06:55 PST 2022


Author: Daniel Rodríguez Troitiño
Date: 2022-11-11T12:05:57-08:00
New Revision: dd2165ef88927b835d21c3ce3fe26c3fb9f7fdb0

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

LOG: [objcopy] Fix order of Mach-O LINKEDIT pieces during layout

The exports trie and the chained fixups where in the opposite order, and
function starts happenned before them, instead of after them.

Restore the correct order and rewrite the code to make it easier to move
around in the future if needed by reusing the `Offset` variable and
keeping both the `StartOf...` and the size of each piece together.

This was found out while trying to use the system strip in a binary
already stripped by LLVM and receiving errors around chained fixups when
we enabled those in the linker.

Reviewed By: alexander-shaposhnikov

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

Added: 
    llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test
    llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
index 7edce6e42c0c7..30e25d05d76b5 100644
--- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
@@ -235,39 +235,38 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
          "Incorrect tail offset");
   Offset = std::max(Offset, HeaderSize + O.Header.SizeOfCmds);
 
-  // The order of LINKEDIT elements is as follows:
-  // rebase info, binding info, weak binding info, lazy binding info, export
-  // trie, data-in-code, symbol table, indirect symbol table, symbol table
-  // strings, dylib codesign drs, code signature.
   uint64_t NListSize = Is64Bit ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
   uint64_t StartOfLinkEdit = Offset;
-  uint64_t StartOfRebaseInfo = StartOfLinkEdit;
-  uint64_t StartOfBindingInfo = StartOfRebaseInfo + O.Rebases.Opcodes.size();
-  uint64_t StartOfWeakBindingInfo = StartOfBindingInfo + O.Binds.Opcodes.size();
-  uint64_t StartOfLazyBindingInfo =
-      StartOfWeakBindingInfo + O.WeakBinds.Opcodes.size();
-  uint64_t StartOfExportTrie =
-      StartOfLazyBindingInfo + O.LazyBinds.Opcodes.size();
-  uint64_t StartOfFunctionStarts = StartOfExportTrie + O.Exports.Trie.size();
-  uint64_t StartOfDyldExportsTrie =
-      StartOfFunctionStarts + O.FunctionStarts.Data.size();
-  uint64_t StartOfChainedFixups =
-      StartOfDyldExportsTrie + O.ExportsTrie.Data.size();
-  uint64_t StartOfDataInCode =
-      StartOfChainedFixups + O.ChainedFixups.Data.size();
+
+  // The order of LINKEDIT elements is as follows:
+  // rebase info, binding info, weak binding info, lazy binding info, export
+  // trie, chained fixups, dyld exports trie, function starts, data-in-code,
+  // symbol table, indirect symbol table, symbol table strings,
+  // dylib codesign drs, and code signature.
+  auto updateOffset = [&Offset](size_t Size) {
+    uint64_t PreviousOffset = Offset;
+    Offset += Size;
+    return PreviousOffset;
+  };
+
+  uint64_t StartOfRebaseInfo = updateOffset(O.Rebases.Opcodes.size());
+  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 StartOfChainedFixups = updateOffset(O.ChainedFixups.Data.size());
+  uint64_t StartOfDyldExportsTrie = updateOffset(O.ExportsTrie.Data.size());
+  uint64_t StartOfFunctionStarts = updateOffset(O.FunctionStarts.Data.size());
+  uint64_t StartOfDataInCode = updateOffset(O.DataInCode.Data.size());
   uint64_t StartOfLinkerOptimizationHint =
-      StartOfDataInCode + O.DataInCode.Data.size();
-  uint64_t StartOfSymbols =
-      StartOfLinkerOptimizationHint + O.LinkerOptimizationHint.Data.size();
+      updateOffset(O.LinkerOptimizationHint.Data.size());
+  uint64_t StartOfSymbols = updateOffset(NListSize * O.SymTable.Symbols.size());
   uint64_t StartOfIndirectSymbols =
-      StartOfSymbols + NListSize * O.SymTable.Symbols.size();
-  uint64_t StartOfSymbolStrings =
-      StartOfIndirectSymbols +
-      sizeof(uint32_t) * O.IndirectSymTable.Symbols.size();
-  uint64_t StartOfDylibCodeSignDRs =
-      StartOfSymbolStrings + StrTableBuilder.getSize();
-  uint64_t StartOfCodeSignature =
-      StartOfDylibCodeSignDRs + O.DylibCodeSignDRs.Data.size();
+      updateOffset(sizeof(uint32_t) * O.IndirectSymTable.Symbols.size());
+  uint64_t StartOfSymbolStrings = updateOffset(StrTableBuilder.getSize());
+  uint64_t StartOfDylibCodeSignDRs = updateOffset(O.DylibCodeSignDRs.Data.size());
+
+  uint64_t StartOfCodeSignature = Offset;
   uint32_t CodeSignatureSize = 0;
   if (O.CodeSignatureCommandIndex) {
     StartOfCodeSignature = alignTo(StartOfCodeSignature, 16);

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test
new file mode 100644
index 0000000000000..4915f344c1e7e
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-1.test
@@ -0,0 +1,496 @@
+## This test verifies that the linkedit segment is
+## laid out in the right order.
+
+# RUN: yaml2obj %s -o %t.original
+# RUN: llvm-objcopy %t.original %t.copy
+# RUN: obj2yaml %t.copy > %t.yaml
+## Print the results several times in order to capture the linkedit offsets
+## in the order they are needed, but still following the order of the load
+## commands where they appear.
+# RUN: cat %t.yaml %t.yaml %t.yaml | FileCheck %s
+
+# CHECK: cmd:             LC_SEGMENT_64
+# CHECK: segname:         __LINKEDIT
+# CHECK: fileoff:         [[#LINKEDIT_FILEOFF:]]
+# CHECK: filesize:        [[#LINKEDIT_FILESIZE:]]
+
+# CHECK: cmd:             LC_DYLD_INFO_ONLY
+# CHECK: rebase_off:      [[#REBASE_OFF: LINKEDIT_FILEOFF]]
+# CHECK: rebase_size:     [[#REBASE_SIZE:]]
+# CHECK: bind_off:        [[#BIND_OFF: REBASE_OFF + REBASE_SIZE]]
+# CHECK: bind_size:       [[#BIND_SIZE:]]
+# CHECK: weak_bind_off:   [[#WEAK_BIND_OFF: BIND_OFF + BIND_SIZE]]
+# CHECK: weak_bind_size:  [[#WEAK_BIND_SIZE:]]
+# CHECK: lazy_bind_off:   [[#LAZY_BIND_OFF: WEAK_BIND_OFF + WEAK_BIND_SIZE]]
+# CHECK: lazy_bind_size:  [[#LAZY_BIND_SIZE:]]
+# CHECK: export_off:      [[#EXPORTS_OFF:LAZY_BIND_OFF + LAZY_BIND_SIZE]]
+# CHECK: export_size:     [[#EXPORTS_SIZE:]]
+
+# CHECK: cmd:             LC_FUNCTION_STARTS
+# CHECK: dataoff:         [[#FUNCTION_STARTS_FILEOFF: EXPORTS_OFF + EXPORTS_SIZE]]
+# CHECK: datasize:        [[#FUNCTION_STARTS_FILESIZE:]]
+
+# CHECK: cmd:             LC_DATA_IN_CODE
+# CHECK: dataoff:         [[#DATA_IN_CODE_FILEOFF: FUNCTION_STARTS_FILEOFF + FUNCTION_STARTS_FILESIZE]]
+# CHECK: datasize:        [[#DATA_IN_CODE_FILESIZE:]]
+
+## Jump over LC_CODE_SIGNATURE, which needs to be checked last
+
+# CHECK: --- !mach-o
+
+# CHECK: cmd:             LC_SYMTAB
+# CHECK: symoff:          [[#SYMTAB_SYMOFF: DATA_IN_CODE_FILEOFF + DATA_IN_CODE_FILESIZE]]
+# CHECK: nsyms:           [[#SYMTAB_NSYMS:]]
+
+## Skip over the strings table offset/size (part of LC_SYMTAB) until next loop.
+
+# CHECK: cmd:             LC_DYSYMTAB
+# CHECK: indirectsymoff:  [[#DYSYMTAB_INDIRECTSYMOFF: SYMTAB_SYMOFF + mul(SYMTAB_NSYMS, 16)]]
+# CHECK: nindirectsyms:   [[#DYSYMTAB_NINDIRECTSYMS:]]
+
+# CHECK: --- !mach-o
+
+# CHECK: cmd:             LC_SYMTAB
+# CHECK: stroff:          [[#SYMTAB_STROFF: DYSYMTAB_INDIRECTSYMOFF + mul(DYSYMTAB_NINDIRECTSYMS, 4)]]
+# CHECK: strsize:         [[#SYMTAB_STRSIZE:]]
+
+# CHECK: cmd:             LC_CODE_SIGNATURE
+## LC_CODE_SIGNATURE needs to be aligned to 16 bytes boundaries.
+# CHECK: dataoff:         [[#CODE_SIGNATURE_FILEOFF: mul(div(SYMTAB_STROFF + SYMTAB_STRSIZE + 8, 16), 16)]]
+# CHECK: datasize:        [[#CODE_SIGNATURE_FILESIZE:LINKEDIT_FILEOFF + LINKEDIT_FILESIZE - CODE_SIGNATURE_FILEOFF]]
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x2
+  ncmds:           18
+  sizeofcmds:      1352
+  flags:           0x210085
+  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:         392
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          16384
+    fileoff:         0
+    filesize:        16384
+    maxprot:         5
+    initprot:        5
+    nsects:          4
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x100003F80
+        size:            16
+        offset:          0x3F80
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         E80B000000E80C000000C39000000000
+      - sectname:        __stubs
+        segname:         __TEXT
+        addr:            0x100003F90
+        size:            12
+        offset:          0x3F90
+        align:           1
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000408
+        reserved1:       0x0
+        reserved2:       0x6
+        reserved3:       0x0
+        content:         FF256A400000FF256C400000
+      - sectname:        __stub_helper
+        segname:         __TEXT
+        addr:            0x100003F9C
+        size:            26
+        offset:          0x3F9C
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         4C8D1D6D4000004153FF2555000000906800000000E9E6FFFFFF
+      - 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:         010000001C000000000000001C000000000000001C00000002000000803F00003400000034000000913F00000000000034000000030000000C000100100001000000000000000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         152
+    segname:         __DATA_CONST
+    vmaddr:          4294983680
+    vmsize:          16384
+    fileoff:         16384
+    filesize:        16384
+    maxprot:         3
+    initprot:        3
+    nsects:          1
+    flags:           16
+    Sections:
+      - sectname:        __got
+        segname:         __DATA_CONST
+        addr:            0x100004000
+        size:            8
+        offset:          0x4000
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x6
+        reserved1:       0x2
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '0000000000000000'
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __DATA
+    vmaddr:          4295000064
+    vmsize:          16384
+    fileoff:         32768
+    filesize:        16384
+    maxprot:         3
+    initprot:        3
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __la_symbol_ptr
+        segname:         __DATA
+        addr:            0x100008000
+        size:            16
+        offset:          0x8000
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x7
+        reserved1:       0x3
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         AC3F0000010000000000000000000000
+      - sectname:        __data
+        segname:         __DATA
+        addr:            0x100008010
+        size:            8
+        offset:          0x8010
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '0000000000000000'
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4295016448
+    vmsize:          16384
+    fileoff:         49152
+    filesize:        920
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_DYLD_INFO_ONLY
+    cmdsize:         48
+    rebase_off:      49152
+    rebase_size:     8
+    bind_off:        49160
+    bind_size:       56
+    weak_bind_off:   49216
+    weak_bind_size:  32
+    lazy_bind_off:   49248
+    lazy_bind_size:  16
+    export_off:      49264
+    export_size:     48
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          49328
+    nsyms:           6
+    stroff:          49448
+    strsize:         80
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       1
+    iextdefsym:      1
+    nextdefsym:      2
+    iundefsym:       3
+    nundefsym:       3
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  49424
+    nindirectsyms:   5
+    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:            D565F8BE-1140-391A-BD6E-9CED386430F2
+  - 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:        16256
+    stacksize:       0
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         48
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 0
+      compatibility_version: 0
+    Content:         libFoo-classic.dylib
+    ZeroPadBytes:    4
+  - 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:         49312
+    datasize:        8
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         49320
+    datasize:        8
+  - cmd:             LC_CODE_SIGNATURE
+    cmdsize:         16
+    dataoff:         49536
+    datasize:        536
+LinkEditData:
+  RebaseOpcodes:
+    - Opcode:          REBASE_OPCODE_SET_TYPE_IMM
+      Imm:             1
+    - Opcode:          REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+      Imm:             3
+      ExtraData:       [ 0x0 ]
+    - Opcode:          REBASE_OPCODE_DO_REBASE_IMM_TIMES
+      Imm:             1
+    - Opcode:          REBASE_OPCODE_DONE
+      Imm:             0
+  BindOpcodes:
+    - Opcode:          BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
+      Imm:             1
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+      Imm:             0
+      Symbol:          _weak_foo
+    - Opcode:          BIND_OPCODE_SET_TYPE_IMM
+      Imm:             1
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+      Imm:             3
+      ULEBExtraData:   [ 0x8 ]
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
+      Imm:             0
+      ULEBExtraData:   [ 0xFFFFFFFFFFFFFFF8 ]
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DO_BIND
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
+      Imm:             2
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+      Imm:             0
+      Symbol:          dyld_stub_binder
+    - Opcode:          BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+      Imm:             2
+      ULEBExtraData:   [ 0x0 ]
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DO_BIND
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+  WeakBindOpcodes:
+    - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+      Imm:             0
+      Symbol:          _weak_foo
+    - Opcode:          BIND_OPCODE_SET_TYPE_IMM
+      Imm:             1
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+      Imm:             3
+      ULEBExtraData:   [ 0x8 ]
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
+      Imm:             0
+      ULEBExtraData:   [ 0xFFFFFFFFFFFFFFF8 ]
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DO_BIND
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+  LazyBindOpcodes:
+    - Opcode:          BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+      Imm:             3
+      ULEBExtraData:   [ 0x0 ]
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
+      Imm:             1
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+      Imm:             0
+      Symbol:          _foo
+    - Opcode:          BIND_OPCODE_DO_BIND
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+    - Opcode:          BIND_OPCODE_DONE
+      Imm:             0
+      Symbol:          ''
+  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:         0x3F80
+            Other:           0x0
+            ImportName:      ''
+  NameList:
+    - n_strx:          60
+      n_type:          0xE
+      n_sect:          7
+      n_desc:          0
+      n_value:         4295000080
+    - 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:         4294983552
+    - n_strx:          28
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          256
+      n_value:         0
+    - n_strx:          33
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          384
+      n_value:         0
+    - n_strx:          43
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          512
+      n_value:         0
+  StringTable:
+    - ' '
+    - __mh_execute_header
+    - _main
+    - _foo
+    - _weak_foo
+    - dyld_stub_binder
+    - __dyld_private
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+  IndirectSymbols: [ 0x3, 0x4, 0x5, 0x3, 0x4 ]
+  FunctionStarts:  [ 0x3F80 ]
+  DataInCode:
+    - Offset:          0x3F8C
+      Length:          4
+      Kind:            0x4
+...

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test
new file mode 100644
index 0000000000000..0c5521ece0e44
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/linkedit-order-2.test
@@ -0,0 +1,339 @@
+## This test verifies that the linkedit segment is
+## laid out in the right order.
+
+# RUN: yaml2obj %s -o %t.original
+# RUN: llvm-objcopy %t.original %t.copy
+# RUN: obj2yaml %t.copy > %t.yaml
+## Print the results several times in order to capture the linkedit offsets
+## in the order they are needed, but still following the order of the load
+## commands where they appear.
+# RUN: cat %t.yaml %t.yaml %t.yaml | FileCheck %s
+
+# CHECK: cmd:             LC_SEGMENT_64
+# CHECK: segname:         __LINKEDIT
+# CHECK: fileoff:         [[#LINKEDIT_FILEOFF:]]
+# CHECK: filesize:        [[#LINKEDIT_FILESIZE:]]
+
+# CHECK: cmd:             LC_DYLD_CHAINED_FIXUPS
+# CHECK: dataoff:         [[#CHAINED_FIXUPS_FILEOFF: LINKEDIT_FILEOFF]]
+# CHECK: datasize:        [[#CHAINED_FIXUPS_FILESIZE:]]
+
+# CHECK: cmd:             LC_DYLD_EXPORTS_TRIE
+# CHECK: dataoff:         [[#DYLD_EXPORTS_TRIE_FILEOFF: CHAINED_FIXUPS_FILEOFF + CHAINED_FIXUPS_FILESIZE]]
+# CHECK: datasize:        [[#DYLD_EXPORTS_TRIE_FILESIZE:]]
+
+## Jump over LC_SYMTAB and LC_DYSYMTAB, which will be checked during
+## later.
+
+# CHECK: cmd:             LC_FUNCTION_STARTS
+# CHECK: dataoff:         [[#FUNCTION_STARTS_FILEOFF: DYLD_EXPORTS_TRIE_FILEOFF + DYLD_EXPORTS_TRIE_FILESIZE]]
+# CHECK: datasize:        [[#FUNCTION_STARTS_FILESIZE:]]
+
+# CHECK: cmd:             LC_DATA_IN_CODE
+# CHECK: dataoff:         [[#DATA_IN_CODE_FILEOFF: FUNCTION_STARTS_FILEOFF + FUNCTION_STARTS_FILESIZE]]
+# CHECK: datasize:        [[#DATA_IN_CODE_FILESIZE:]]
+
+## Jump over LC_CODE_SIGNATURE, which needs to be checked last
+
+# CHECK: --- !mach-o
+
+# CHECK: cmd:             LC_SYMTAB
+# CHECK: symoff:          [[#SYMTAB_SYMOFF: DATA_IN_CODE_FILEOFF + DATA_IN_CODE_FILESIZE]]
+# CHECK: nsyms:           [[#SYMTAB_NSYMS:]]
+
+## Skip over the strings table offset/size (part of LC_SYMTAB) until next loop.
+
+# CHECK: cmd:             LC_DYSYMTAB
+# CHECK: indirectsymoff:  [[#DYSYMTAB_INDIRECTSYMOFF: SYMTAB_SYMOFF + mul(SYMTAB_NSYMS, 16)]]
+# CHECK: nindirectsyms:   [[#DYSYMTAB_NINDIRECTSYMS:]]
+
+# CHECK: --- !mach-o
+
+# CHECK: cmd:             LC_SYMTAB
+# CHECK: stroff:          [[#SYMTAB_STROFF: DYSYMTAB_INDIRECTSYMOFF + mul(DYSYMTAB_NINDIRECTSYMS, 4)]]
+# CHECK: strsize:         [[#SYMTAB_STRSIZE:]]
+
+# CHECK: cmd:             LC_CODE_SIGNATURE
+## LC_CODE_SIGNATURE needs to be aligned to 16 bytes boundaries.
+# CHECK: dataoff:         [[#CODE_SIGNATURE_FILEOFF: mul(div(SYMTAB_STROFF + SYMTAB_STRSIZE + 8, 16), 16)]]
+# CHECK: datasize:        [[#CODE_SIGNATURE_FILESIZE:LINKEDIT_FILEOFF + LINKEDIT_FILESIZE - CODE_SIGNATURE_FILEOFF]]
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x2
+  ncmds:           18
+  sizeofcmds:      1032
+  flags:           0x210085
+  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:         312
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          16384
+    fileoff:         0
+    filesize:        16384
+    maxprot:         5
+    initprot:        5
+    nsects:          3
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x100003F9C
+        size:            16
+        offset:          0x3F9C
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         E80B000000E80C000000C39000000000
+      - sectname:        __stubs
+        segname:         __TEXT
+        addr:            0x100003FAC
+        size:            12
+        offset:          0x3FAC
+        align:           1
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000408
+        reserved1:       0x0
+        reserved2:       0x6
+        reserved3:       0x0
+        content:         FF254E000000FF2550000000
+      - 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:         010000001C000000000000001C000000000000001C000000020000009C3F00003400000034000000AD3F00000000000034000000030000000C000100100001000000000000000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         152
+    segname:         __DATA_CONST
+    vmaddr:          4294983680
+    vmsize:          16384
+    fileoff:         16384
+    filesize:        16384
+    maxprot:         3
+    initprot:        3
+    nsects:          1
+    flags:           16
+    Sections:
+      - sectname:        __got
+        segname:         __DATA_CONST
+        addr:            0x100004000
+        size:            16
+        offset:          0x4000
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x6
+        reserved1:       0x2
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '00000000000010800100000000000080'
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4295000064
+    vmsize:          16384
+    fileoff:         32768
+    filesize:        719
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_DYLD_CHAINED_FIXUPS
+    cmdsize:         16
+    dataoff:         32768
+    datasize:        104
+  - cmd:             LC_DYLD_EXPORTS_TRIE
+    cmdsize:         16
+    dataoff:         32872
+    datasize:        48
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          32936
+    nsyms:           4
+    stroff:          33016
+    strsize:         48
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      2
+    iundefsym:       2
+    nundefsym:       2
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  33000
+    nindirectsyms:   4
+    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:            F74FD957-51B1-3D8E-AE70-D8A248BB5D93
+  - 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:        16284
+    stacksize:       0
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         56
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 0
+      compatibility_version: 0
+    Content:         libFoo-chained-fixups.dylib
+    ZeroPadBytes:    5
+  - 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:         32920
+    datasize:        8
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         32928
+    datasize:        8
+  - cmd:             LC_CODE_SIGNATURE
+    cmdsize:         16
+    dataoff:         33072
+    datasize:        415
+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:         0x3F9C
+            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:         4294983580
+    - n_strx:          28
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          256
+      n_value:         0
+    - n_strx:          33
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          384
+      n_value:         0
+  StringTable:
+    - ' '
+    - __mh_execute_header
+    - _main
+    - _foo
+    - _weak_foo
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+  IndirectSymbols: [ 0x2, 0x3, 0x2, 0x3 ]
+  FunctionStarts:  [ 0x3F9C ]
+  ChainedFixups:   [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x50, 0x0,
+                     0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0,
+                     0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                     0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                     0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0,
+                     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0,
+                     0x0, 0x10, 0x6, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0,
+                     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
+                     0x1, 0x2, 0x0, 0x0, 0xFD, 0xC, 0x0, 0x0, 0x0, 0x5F,
+                     0x66, 0x6F, 0x6F, 0x0, 0x5F, 0x77, 0x65, 0x61, 0x6B,
+                     0x5F, 0x66, 0x6F, 0x6F, 0x0 ]
+  DataInCode:
+    - Offset:          0x3FA8
+      Length:          4
+      Kind:            0x4
+...


        


More information about the llvm-commits mailing list