aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2022-08-15 09:06:57 -0400
committerNico Weber <thakis@chromium.org>2022-08-15 10:58:52 -0400
commit940e178c0018b32af2f1478d331fc41a92a7dac7 (patch)
treead7d2d9517d7d679444f196caffead76385c6955 /llvm
parente114ecc5feafe849cbaf1a1df49dc7b3650f06ba (diff)
downloadllvm-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.rst4
-rw-r--r--llvm/docs/CommandGuide/llvm-otool.rst4
-rw-r--r--llvm/include/llvm/BinaryFormat/MachO.h13
-rw-r--r--llvm/test/tools/llvm-objdump/MachO/chained-fixups.yaml225
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp51
-rw-r--r--llvm/tools/llvm-objdump/MachODump.h1
-rw-r--r--llvm/tools/llvm-objdump/ObjdumpOpts.td12
-rw-r--r--llvm/tools/llvm-objdump/OtoolOpts.td4
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp13
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;
}