[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