[llvm] 940e178 - [llvm-objdump] Start on -chained_fixups for llvm-otool

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 15 07:59:01 PDT 2022


Author: Nico Weber
Date: 2022-08-15T10:58:52-04:00
New Revision: 940e178c0018b32af2f1478d331fc41a92a7dac7

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

LOG: [llvm-objdump] Start on -chained_fixups for llvm-otool

And --chained-fixups for llvm-objdump.

For now, this only prints the dyld_chained_fixups_header and adds
plumbing for the flag. This will be expanded in future commits.

When Apple's effort to upstream their chained fixups code continues,
we'll replace this code with the then-upstreamed code. But we need
something in the meantime for testing ld64.lld's chained fixups
code.

Update chained-fixups.yaml with a file that actually contains
the chained fixup data (`LinkEditData` doesn't encode it yet,
so use `__LINKEDIT` via `--raw-segment=data`).

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

Added: 
    

Modified: 
    llvm/docs/CommandGuide/llvm-objdump.rst
    llvm/docs/CommandGuide/llvm-otool.rst
    llvm/include/llvm/BinaryFormat/MachO.h
    llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml
    llvm/tools/llvm-objdump/MachODump.cpp
    llvm/tools/llvm-objdump/MachODump.h
    llvm/tools/llvm-objdump/ObjdumpOpts.td
    llvm/tools/llvm-objdump/OtoolOpts.td
    llvm/tools/llvm-objdump/llvm-objdump.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst
index a06e8aeee4ad5..19b33391a9493 100644
--- a/llvm/docs/CommandGuide/llvm-objdump.rst
+++ b/llvm/docs/CommandGuide/llvm-objdump.rst
@@ -312,6 +312,10 @@ MACH-O ONLY OPTIONS AND COMMANDS
 
   Disassemble just the specified symbol's instructions.
 
+.. option:: --chained-fixups
+
+  Print chained fixup information.
+
 .. option:: --dyld_info
 
   Print bind and rebase information used by dyld to resolve external

diff  --git a/llvm/docs/CommandGuide/llvm-otool.rst b/llvm/docs/CommandGuide/llvm-otool.rst
index c4673502d3246..f2ed563b6303d 100644
--- a/llvm/docs/CommandGuide/llvm-otool.rst
+++ b/llvm/docs/CommandGuide/llvm-otool.rst
@@ -23,6 +23,10 @@ OPTIONS
 
  Select slice of universal Mach-O file.
 
+.. option:: -chained_fixups
+
+ Print chained fixup information.
+
 .. option:: -C
 
  Print linker optimization hints.

diff  --git a/llvm/include/llvm/BinaryFormat/MachO.h b/llvm/include/llvm/BinaryFormat/MachO.h
index 389596538b643..ac1af5dafb9ee 100644
--- a/llvm/include/llvm/BinaryFormat/MachO.h
+++ b/llvm/include/llvm/BinaryFormat/MachO.h
@@ -1002,6 +1002,19 @@ struct nlist_64 {
   uint64_t n_value;
 };
 
+// Values for dyld_chained_fixups_header::imports_format.
+enum {
+  DYLD_CHAINED_IMPORT = 1,
+  DYLD_CHAINED_IMPORT_ADDEND = 2,
+  DYLD_CHAINED_IMPORT_ADDEND64 = 3,
+};
+
+// Values for dyld_chained_fixups_header::symbols_format.
+enum {
+  DYLD_CHAINED_SYMBOL_UNCOMPRESSED = 0,
+  DYLD_CHAINED_SYMBOL_ZLIB = 1,
+};
+
 /// Structs for dyld chained fixups.
 /// dyld_chained_fixups_header is the data pointed to by LC_DYLD_CHAINED_FIXUPS
 /// load command.

diff  --git a/llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml b/llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml
index 4072d8daef4f4..a35320988450e 100644
--- a/llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml
+++ b/llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml
@@ -1,102 +1,106 @@
 # RUN: yaml2obj %s -o %t
 # RUN: llvm-objdump -p %t | FileCheck %s
 # RUN: llvm-otool -l %t | FileCheck %s
-#
+
 # CHECK: LC_DYLD_CHAINED_FIXUPS
 # CHECK: LC_DYLD_EXPORTS_TRIE
 
+# RUN: llvm-objdump --macho --chained-fixups %t | \
+# RUN:     FileCheck --check-prefix=DETAILS -DNAME=%t %s
+# RUN: llvm-otool -chained_fixups %t | \
+# RUN:     FileCheck --check-prefix=DETAILS -DNAME=%t %s
+
+# DETAILS:      [[NAME]]:
+# DETAILS-NEXT: chained fixups header (LC_DYLD_CHAINED_FIXUPS)
+# DETAILS-NEXT:   fixups_version = 0
+# DETAILS-NEXT:   starts_offset  = 32
+# DETAILS-NEXT:   imports_offset = 44
+# DETAILS-NEXT:   symbols_offset = 44
+# DETAILS-NEXT:   imports_count  = 0
+# DETAILS-NEXT:   imports_format = 1 (DYLD_CHAINED_IMPORT)
+# DETAILS-NEXT:   symbols_format = 0
+
+## This yaml is from a dylib produced by ld64
+##   echo ".global _foo\n_foo" > dylib.s
+##   clang -target=x86_64-apple-macos12 -dynamiclib -isysroot Inputs/MacOSX.sdk dylib.s -o libdylib.dylib
+##   obj2yaml --raw-segment=data libdylib.dylib
 --- !mach-o
 FileHeader:
   magic:           0xFEEDFACF
-  cputype:         0x100000C
-  cpusubtype:      0x0
-  filetype:        0x2
-  ncmds:           16
-  sizeofcmds:      744
-  flags:           0x200085
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x6
+  ncmds:           13
+  sizeofcmds:      568
+  flags:           0x100085
   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
+    cmdsize:         152
     segname:         __TEXT
-    vmaddr:          4294967296
+    vmaddr:          0
     vmsize:          16384
     fileoff:         0
     filesize:        16384
     maxprot:         5
     initprot:        5
-    nsects:          2
+    nsects:          1
     flags:           0
     Sections:
       - sectname:        __text
         segname:         __TEXT
-        addr:            0x100003F98
-        size:            24
-        offset:          0x3F98
-        align:           2
+        addr:            0x4000
+        size:            0
+        offset:          0x4000
+        align:           0
         reloff:          0x0
         nreloc:          0
         flags:           0x80000400
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         C0035FD6FF4300D100008052FF0F00B9FF430091C0035FD6
-      - sectname:        __unwind_info
-        segname:         __TEXT
-        addr:            0x100003FB0
-        size:            80
-        offset:          0x3FB0
-        align:           2
-        reloff:          0x0
-        nreloc:          0
-        flags:           0x0
-        reserved1:       0x0
-        reserved2:       0x0
-        reserved3:       0x0
-        content:         010000001C000000000000001C000000000000001C00000002000000983F00003400000034000000B13F00000000000034000000030000000C0002001400020000000001040000000010000200000002
+        content:         ''
   - cmd:             LC_SEGMENT_64
     cmdsize:         72
     segname:         __LINKEDIT
-    vmaddr:          4294983680
+    vmaddr:          16384
     vmsize:          16384
     fileoff:         16384
-    filesize:        753
+    filesize:        96
     maxprot:         1
     initprot:        1
     nsects:          0
     flags:           0
+  - cmd:             LC_ID_DYLIB
+    cmdsize:         48
+    dylib:
+      name:            24
+      timestamp:       1
+      current_version: 0
+      compatibility_version: 0
+    Content:         libdylib.dylib
+    ZeroPadBytes:    3
   - cmd:             LC_DYLD_CHAINED_FIXUPS
     cmdsize:         16
     dataoff:         16384
-    datasize:        56
+    datasize:        48
   - cmd:             LC_DYLD_EXPORTS_TRIE
     cmdsize:         16
-    dataoff:         16440
-    datasize:        56
+    dataoff:         16432
+    datasize:        16
   - cmd:             LC_SYMTAB
     cmdsize:         24
-    symoff:          16504
-    nsyms:           15
-    stroff:          16744
-    strsize:         120
+    symoff:          16456
+    nsyms:           1
+    stroff:          16472
+    strsize:         8
   - cmd:             LC_DYSYMTAB
     cmdsize:         80
     ilocalsym:       0
-    nlocalsym:       12
-    iextdefsym:      12
-    nextdefsym:      3
-    iundefsym:       15
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      1
+    iundefsym:       1
     nundefsym:       0
     tocoff:          0
     ntoc:            0
@@ -110,136 +114,37 @@ LoadCommands:
     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:            F445529E-643C-3A38-8F59-AB64566BCAFF
+    uuid:            52409B91-DF59-346A-A63F-D4E6FFDC3E04
   - cmd:             LC_BUILD_VERSION
     cmdsize:         32
     platform:        1
     minos:           786432
-    sdk:             786432
+    sdk:             851968
     ntools:          1
     Tools:
       - tool:            3
-        version:         46596096
+        version:         53674242
   - 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: 85917696
+      current_version: 65793
       compatibility_version: 65536
-    Content:         '/usr/lib/libSystem.B.dylib'
-    ZeroPadBytes:    6
+    Content:         '/usr/lib/libSystem.dylib'
+    ZeroPadBytes:    8
   - cmd:             LC_FUNCTION_STARTS
     cmdsize:         16
-    dataoff:         16496
+    dataoff:         16448
     datasize:        8
   - cmd:             LC_DATA_IN_CODE
     cmdsize:         16
-    dataoff:         16504
+    dataoff:         16456
     datasize:        0
-  - cmd:             LC_CODE_SIGNATURE
-    cmdsize:         16
-    dataoff:         16864
-    datasize:        273
-LinkEditData:
-  NameList:
-    - n_strx:          33
-      n_type:          0x64
-      n_sect:          0
-      n_desc:          0
-      n_value:         0
-    - n_strx:          39
-      n_type:          0x64
-      n_sect:          0
-      n_desc:          0
-      n_value:         0
-    - n_strx:          46
-      n_type:          0x66
-      n_sect:          0
-      n_desc:          1
-      n_value:         1636754403
-    - n_strx:          1
-      n_type:          0x2E
-      n_sect:          1
-      n_desc:          0
-      n_value:         4294983576
-    - n_strx:          109
-      n_type:          0x24
-      n_sect:          1
-      n_desc:          0
-      n_value:         4294983576
-    - n_strx:          1
-      n_type:          0x24
-      n_sect:          0
-      n_desc:          0
-      n_value:         4
-    - n_strx:          1
-      n_type:          0x4E
-      n_sect:          1
-      n_desc:          0
-      n_value:         4
-    - n_strx:          1
-      n_type:          0x2E
-      n_sect:          1
-      n_desc:          0
-      n_value:         4294983580
-    - n_strx:          114
-      n_type:          0x24
-      n_sect:          1
-      n_desc:          0
-      n_value:         4294983580
-    - n_strx:          1
-      n_type:          0x24
-      n_sect:          0
-      n_desc:          0
-      n_value:         20
-    - n_strx:          1
-      n_type:          0x4E
-      n_sect:          1
-      n_desc:          0
-      n_value:         20
-    - n_strx:          1
-      n_type:          0x64
-      n_sect:          1
-      n_desc:          0
-      n_value:         0
-    - 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:         4294983576
-    - n_strx:          27
-      n_type:          0xF
-      n_sect:          1
-      n_desc:          0
-      n_value:         4294983580
-  StringTable:
-    - ' '
-    - __mh_execute_header
-    - _foo
-    - _main
-    - '/tmp/'
-    - main.c
-    - '/var/folders/gj/wf3swl0x215b2sq1qy84kzkm0000gn/T/main-e32fe7.o'
-    - _foo
-    - _main
+__LINKEDIT:      00000000200000002C0000002C000000000000000100000000000000000000000200000000000000000000000000000000015F666F6F000804008080010000000000000000000000020000000F010000004000000000000020005F666F6F0000
 ...

diff  --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index cdbecd5ec243c..a2593cffb4d87 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -81,6 +81,7 @@ bool objdump::DataInCode;
 bool objdump::FunctionStarts;
 bool objdump::LinkOptHints;
 bool objdump::InfoPlist;
+bool objdump::ChainedFixups;
 bool objdump::DyldInfo;
 bool objdump::DylibsUsed;
 bool objdump::DylibId;
@@ -112,6 +113,7 @@ void objdump::parseMachOOptions(const llvm::opt::InputArgList &InputArgs) {
   FunctionStarts = InputArgs.hasArg(OBJDUMP_function_starts);
   LinkOptHints = InputArgs.hasArg(OBJDUMP_link_opt_hints);
   InfoPlist = InputArgs.hasArg(OBJDUMP_info_plist);
+  ChainedFixups = InputArgs.hasArg(OBJDUMP_chained_fixups);
   DyldInfo = InputArgs.hasArg(OBJDUMP_dyld_info);
   DylibsUsed = InputArgs.hasArg(OBJDUMP_dylibs_used);
   DylibId = InputArgs.hasArg(OBJDUMP_dylib_id);
@@ -1193,6 +1195,48 @@ static void printMachOChainedFixups(object::MachOObjectFile *Obj) {
     reportError(std::move(Err), Obj->getFileName());
 }
 
+static void
+PrintChainedFixupsHeader(const MachO::dyld_chained_fixups_header &H) {
+  outs() << "chained fixups header (LC_DYLD_CHAINED_FIXUPS)\n";
+  outs() << "  fixups_version = " << H.fixups_version << '\n';
+  outs() << "  starts_offset  = " << H.starts_offset << '\n';
+  outs() << "  imports_offset = " << H.imports_offset << '\n';
+  outs() << "  symbols_offset = " << H.symbols_offset << '\n';
+  outs() << "  imports_count  = " << H.imports_count << '\n';
+
+  outs() << "  imports_format = " << H.imports_format;
+  switch (H.imports_format) {
+  case llvm::MachO::DYLD_CHAINED_IMPORT:
+    outs() << " (DYLD_CHAINED_IMPORT)";
+    break;
+  case llvm::MachO::DYLD_CHAINED_IMPORT_ADDEND:
+    outs() << " (DYLD_CHAINED_IMPORT_ADDEND)";
+    break;
+  case llvm::MachO::DYLD_CHAINED_IMPORT_ADDEND64:
+    outs() << " (DYLD_CHAINED_IMPORT_ADDEND64)";
+    break;
+  }
+  outs() << '\n';
+
+  outs() << "  symbols_format = " << H.symbols_format;
+  if (H.symbols_format == llvm::MachO::DYLD_CHAINED_SYMBOL_ZLIB)
+    outs() << " (zlib compressed)";
+  outs() << '\n';
+}
+
+static void PrintChainedFixups(MachOObjectFile *O) {
+  // MachOObjectFile::getChainedFixupsHeader() reads LC_DYLD_CHAINED_FIXUPS.
+  // FIXME: Support chained fixups in __TEXT,__chain_starts section too.
+  auto ChainedFixupHeader =
+      unwrapOrError(O->getChainedFixupsHeader(), O->getFileName());
+  if (!ChainedFixupHeader)
+    return;
+
+  PrintChainedFixupsHeader(*ChainedFixupHeader);
+
+  // FIXME: Print more things.
+}
+
 static void PrintDyldInfo(MachOObjectFile *O) {
   outs() << "dyld information:" << '\n';
   printMachOChainedFixups(O);
@@ -1916,8 +1960,9 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
   // UniversalHeaders or ArchiveHeaders.
   if (Disassemble || Relocations || PrivateHeaders || ExportsTrie || Rebase ||
       Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols ||
-      DataInCode || FunctionStarts || LinkOptHints || DyldInfo || DylibsUsed ||
-      DylibId || Rpaths || ObjcMetaData || (!FilterSections.empty())) {
+      DataInCode || FunctionStarts || LinkOptHints || ChainedFixups ||
+      DyldInfo || DylibsUsed || DylibId || Rpaths || ObjcMetaData ||
+      (!FilterSections.empty())) {
     if (LeadingHeaders) {
       outs() << Name;
       if (!ArchiveMemberName.empty())
@@ -1986,6 +2031,8 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
     DumpSectionContents(FileName, MachOOF, Verbose);
   if (InfoPlist)
     DumpInfoPlistSectionContents(FileName, MachOOF);
+  if (ChainedFixups)
+    PrintChainedFixups(MachOOF);
   if (DyldInfo)
     PrintDyldInfo(MachOOF);
   if (DylibsUsed)

diff  --git a/llvm/tools/llvm-objdump/MachODump.h b/llvm/tools/llvm-objdump/MachODump.h
index 12783e15b425c..32920425e80f3 100644
--- a/llvm/tools/llvm-objdump/MachODump.h
+++ b/llvm/tools/llvm-objdump/MachODump.h
@@ -36,6 +36,7 @@ void parseMachOOptions(const llvm::opt::InputArgList &InputArgs);
 extern bool Bind;
 extern bool DataInCode;
 extern std::string DisSymName;
+extern bool ChainedFixups;
 extern bool DyldInfo;
 extern bool DylibId;
 extern bool DylibsUsed;

diff  --git a/llvm/tools/llvm-objdump/ObjdumpOpts.td b/llvm/tools/llvm-objdump/ObjdumpOpts.td
index 00d7d8ccff171..acfdf0010131e 100644
--- a/llvm/tools/llvm-objdump/ObjdumpOpts.td
+++ b/llvm/tools/llvm-objdump/ObjdumpOpts.td
@@ -299,11 +299,15 @@ def info_plist : Flag<["--"], "info-plist">,
            "Mach-O objects (requires --macho)">,
   Group<grp_mach_o>;
 
+def chained_fixups : Flag<["--"], "chained-fixups">,
+  HelpText<"Print chained fixup information (requires --macho)">,
+  Group<grp_mach_o>;
+
 def dyld_info : Flag<["--"], "dyld_info">,
-      HelpText<"Print bind and rebase information used by dyld to resolve "
-               "external references in a final linked binary "
-               "(requires --macho)">,
-      Group<grp_mach_o>;
+  HelpText<"Print bind and rebase information used by dyld to resolve "
+           "external references in a final linked binary "
+           "(requires --macho)">,
+  Group<grp_mach_o>;
 
 def dylibs_used : Flag<["--"], "dylibs-used">,
   HelpText<"Print the shared libraries used for linked "

diff  --git a/llvm/tools/llvm-objdump/OtoolOpts.td b/llvm/tools/llvm-objdump/OtoolOpts.td
index e8bef284c0e91..71ac541d06289 100644
--- a/llvm/tools/llvm-objdump/OtoolOpts.td
+++ b/llvm/tools/llvm-objdump/OtoolOpts.td
@@ -37,13 +37,15 @@ def V : Flag<["-"], "V">,
 def x : Flag<["-"], "x">, HelpText<"print all text sections">;
 def X : Flag<["-"], "X">, HelpText<"omit leading addresses or headers">;
 
+def chained_fixups : Flag<["-"], "chained_fixups">,
+  HelpText<"print chained fixup information">;
+
 // Not (yet?) implemented:
 // def a : Flag<["-"], "a">, HelpText<"print archive header">;
 // -c print argument strings of a core file
 // -m don't use archive(member) syntax
 // -dyld_info
 // -dyld_opcodes
-// -chained_fixups
 // -addr_slide=arg
 // -function_offsets
 

diff  --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index efac3a883b5a2..f7b48148273c8 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -2787,6 +2787,8 @@ static void parseOtoolOptions(const llvm::opt::InputArgList &InputArgs) {
     FilterSections.push_back(",__text");
   LeadingAddr = LeadingHeaders = !InputArgs.hasArg(OTOOL_X);
 
+  ChainedFixups = InputArgs.hasArg(OTOOL_chained_fixups);
+
   InputFilenames = InputArgs.getAllArgValues(OTOOL_INPUT);
   if (InputFilenames.empty())
     reportCmdLineError("no input file");
@@ -2990,11 +2992,12 @@ int main(int argc, char **argv) {
       !DynamicRelocations && !FileHeaders && !PrivateHeaders && !RawClangAST &&
       !Relocations && !SectionHeaders && !SectionContents && !SymbolTable &&
       !DynamicSymbolTable && !UnwindInfo && !FaultMapSection && !Offloading &&
-      !(MachOOpt && (Bind || DataInCode || DyldInfo || DylibId || DylibsUsed ||
-                     ExportsTrie || FirstPrivateHeader || FunctionStarts ||
-                     IndirectSymbols || InfoPlist || LazyBind || LinkOptHints ||
-                     ObjcMetaData || Rebase || Rpaths || UniversalHeaders ||
-                     WeakBind || !FilterSections.empty()))) {
+      !(MachOOpt &&
+        (Bind || DataInCode || ChainedFixups || DyldInfo || DylibId ||
+         DylibsUsed || ExportsTrie || FirstPrivateHeader || FunctionStarts ||
+         IndirectSymbols || InfoPlist || LazyBind || LinkOptHints ||
+         ObjcMetaData || Rebase || Rpaths || UniversalHeaders || WeakBind ||
+         !FilterSections.empty()))) {
     T->printHelp(ToolName);
     return 2;
   }


        


More information about the llvm-commits mailing list