From 86b98c60c54cbb661500058c6e0d2f5cffec2690 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 19 Apr 2021 11:09:59 -0700 Subject: [PATCH] llvm-objdump: add --rpaths to macho support This prints the rpaths for the given binary Reviewed By: kastiglione Differential Revision: https://reviews.llvm.org/D100681 --- llvm/docs/CommandGuide/llvm-objdump.rst | 4 ++++ llvm/test/tools/llvm-objdump/MachO/rpaths.test | 13 +++++++++++++ llvm/tools/llvm-objdump/MachODump.cpp | 16 +++++++++++++++- llvm/tools/llvm-objdump/MachODump.h | 1 + llvm/tools/llvm-objdump/ObjdumpOpts.td | 5 +++++ llvm/tools/llvm-objdump/llvm-objdump.cpp | 2 +- 6 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/MachO/rpaths.test diff --git a/llvm/docs/CommandGuide/llvm-objdump.rst b/llvm/docs/CommandGuide/llvm-objdump.rst index acfe80763661d..6e47b4a1bf153 100644 --- a/llvm/docs/CommandGuide/llvm-objdump.rst +++ b/llvm/docs/CommandGuide/llvm-objdump.rst @@ -367,6 +367,10 @@ MACH-O ONLY OPTIONS AND COMMANDS Display rebasing information. +.. option:: --rpaths + + Display runtime search paths for the binary. + .. option:: --universal-headers Display universal headers. diff --git a/llvm/test/tools/llvm-objdump/MachO/rpaths.test b/llvm/test/tools/llvm-objdump/MachO/rpaths.test new file mode 100644 index 0000000000000..2525756ea90fe --- /dev/null +++ b/llvm/test/tools/llvm-objdump/MachO/rpaths.test @@ -0,0 +1,13 @@ +## Validate fetching rpaths from a binary results in the correct output. +# RUN: llvm-objdump --macho --rpaths --arch x86_64 %p/Inputs/Objc2.64bit.exe.macho-x86_64 | FileCheck --implicit-check-not={{.}} %s +# RUN: llvm-objdump --macho --rpaths %p/Inputs/Objc2.64bit.exe.macho-x86_64 | FileCheck --implicit-check-not={{.}} %s + +# CHECK: {{.*}}Objc2.64bit.exe.macho-x86_64: +# CHECK: @executable_path/../Frameworks + +## Validate binaries with no rpaths should print nothing. +# RUN: llvm-objdump --macho --no-leading-headers --rpaths %p/Inputs/hello.exe.macho-i386 | count 0 + +## Validate passing --rpaths without --macho fails. +# RUN: not llvm-objdump --rpaths %p/Inputs/hello.exe.macho-i386 2>&1 | FileCheck --check-prefix=ERROR %s +# ERROR: USAGE diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 77d74fc848e25..5b61aab065522 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -66,6 +66,7 @@ using namespace llvm::objdump; bool objdump::FirstPrivateHeader; bool objdump::ExportsTrie; bool objdump::Rebase; +bool objdump::Rpaths; bool objdump::Bind; bool objdump::LazyBind; bool objdump::WeakBind; @@ -95,6 +96,7 @@ void objdump::parseMachOOptions(const llvm::opt::InputArgList &InputArgs) { FirstPrivateHeader = InputArgs.hasArg(OBJDUMP_private_header); ExportsTrie = InputArgs.hasArg(OBJDUMP_exports_trie); Rebase = InputArgs.hasArg(OBJDUMP_rebase); + Rpaths = InputArgs.hasArg(OBJDUMP_rpaths); Bind = InputArgs.hasArg(OBJDUMP_bind); LazyBind = InputArgs.hasArg(OBJDUMP_lazy_bind); WeakBind = InputArgs.hasArg(OBJDUMP_weak_bind); @@ -1233,6 +1235,16 @@ static void PrintDylibs(MachOObjectFile *O, bool JustId) { } } +static void printRpaths(MachOObjectFile *O) { + for (const auto &Command : O->load_commands()) { + if (Command.C.cmd == MachO::LC_RPATH) { + auto Rpath = O->getRpathCommand(Command); + const char *P = (const char *)(Command.Ptr) + Rpath.path; + outs() << P << "\n"; + } + } +} + typedef DenseMap SymbolAddressMap; static void CreateSymbolAddressMap(MachOObjectFile *O, @@ -1885,7 +1897,7 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF, if (Disassemble || Relocations || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols || DataInCode || FunctionStarts || LinkOptHints || DylibsUsed || DylibId || - ObjcMetaData || (!FilterSections.empty())) { + Rpaths || ObjcMetaData || (!FilterSections.empty())) { if (LeadingHeaders) { outs() << Name; if (!ArchiveMemberName.empty()) @@ -1974,6 +1986,8 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF, printExportsTrie(MachOOF); if (Rebase) printRebaseTable(MachOOF); + if (Rpaths) + printRpaths(MachOOF); if (Bind) printBindTable(MachOOF); if (LazyBind) diff --git a/llvm/tools/llvm-objdump/MachODump.h b/llvm/tools/llvm-objdump/MachODump.h index 1d514617e7ee8..7568062bd6b0e 100644 --- a/llvm/tools/llvm-objdump/MachODump.h +++ b/llvm/tools/llvm-objdump/MachODump.h @@ -49,6 +49,7 @@ extern bool LeadingHeaders; extern bool LinkOptHints; extern bool ObjcMetaData; extern bool Rebase; +extern bool Rpaths; extern bool SymbolicOperands; extern bool UniversalHeaders; extern bool Verbose; diff --git a/llvm/tools/llvm-objdump/ObjdumpOpts.td b/llvm/tools/llvm-objdump/ObjdumpOpts.td index 2fcae84998214..17a6acdf83e1c 100644 --- a/llvm/tools/llvm-objdump/ObjdumpOpts.td +++ b/llvm/tools/llvm-objdump/ObjdumpOpts.td @@ -396,6 +396,11 @@ def dylib_id : Flag<["--"], "dylib-id">, "dylib Mach-O file (requires --macho)">, Group; +def rpaths : Flag<["--"], "rpaths">, + HelpText<"Print the runtime search paths for the " + "Mach-O file (requires --macho)">, + Group; + def non_verbose : Flag<["--"], "non-verbose">, HelpText<"Print the info for Mach-O objects in non-verbose or " "numeric form (requires --macho)">, diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 265cb528a252b..d6700b6bcca9a 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -3075,7 +3075,7 @@ int main(int argc, char **argv) { !(MachOOpt && (Bind || DataInCode || DylibId || DylibsUsed || ExportsTrie || FirstPrivateHeader || FunctionStarts || IndirectSymbols || InfoPlist || - LazyBind || LinkOptHints || ObjcMetaData || Rebase || + LazyBind || LinkOptHints || ObjcMetaData || Rebase || Rpaths || UniversalHeaders || WeakBind || !FilterSections.empty()))) { T->printHelp(ToolName); return 2;