diff options
author | Nico Weber <thakis@chromium.org> | 2022-08-15 09:06:57 -0400 |
---|---|---|
committer | Nico Weber <thakis@chromium.org> | 2022-08-15 10:58:52 -0400 |
commit | 940e178c0018b32af2f1478d331fc41a92a7dac7 (patch) | |
tree | ad7d2d9517d7d679444f196caffead76385c6955 /llvm | |
parent | e114ecc5feafe849cbaf1a1df49dc7b3650f06ba (diff) | |
download | llvm-940e178c0018b32af2f1478d331fc41a92a7dac7.zip llvm-940e178c0018b32af2f1478d331fc41a92a7dac7.tar.gz llvm-940e178c0018b32af2f1478d331fc41a92a7dac7.tar.bz2 |
[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
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/docs/CommandGuide/llvm-objdump.rst | 4 | ||||
-rw-r--r-- | llvm/docs/CommandGuide/llvm-otool.rst | 4 | ||||
-rw-r--r-- | llvm/include/llvm/BinaryFormat/MachO.h | 13 | ||||
-rw-r--r-- | llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml | 225 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 51 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.h | 1 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/ObjdumpOpts.td | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/OtoolOpts.td | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 13 |
9 files changed, 155 insertions, 172 deletions
diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst index a06e8ae..19b3339 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 c467350..f2ed563 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 3895965..ac1af5d 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 4072d8d..a3532098 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 cdbecd5..a2593cf 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 12783e1..3292042 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 00d7d8c..acfdf00 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 e8bef28..71ac541 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 efac3a8..f7b4814 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; } |