diff --git a/llvm/test/tools/llvm-objdump/MachO/rpaths.test b/llvm/test/tools/llvm-objdump/MachO/rpaths.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/MachO/rpaths.test @@ -0,0 +1,7 @@ +# RUN: llvm-objdump --macho --rpaths --arch x86_64 %p/Inputs/Objc2.64bit.exe.macho-x86_64 | FileCheck %s +# RUN: llvm-objdump --macho --rpaths %p/Inputs/Objc2.64bit.exe.macho-x86_64 | FileCheck %s + +# CHECK: @executable_path/../Frameworks + +# RUN: llvm-objdump --macho --no-leading-headers --rpaths %p/Inputs/hello.exe.macho-i386 | count 0 + diff --git a/llvm/tools/llvm-objdump/MachODump.h b/llvm/tools/llvm-objdump/MachODump.h --- a/llvm/tools/llvm-objdump/MachODump.h +++ b/llvm/tools/llvm-objdump/MachODump.h @@ -47,6 +47,7 @@ extern bool LinkOptHints; extern bool ObjcMetaData; extern bool Rebase; +extern bool Rpaths; extern bool UniversalHeaders; extern bool WeakBind; diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -66,6 +66,7 @@ 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 @@ 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 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 @@ if (Disassemble || Relocations || PrivateHeaders || ExportsTrie || Rebase || Bind || SymbolTable || LazyBind || WeakBind || IndirectSymbols || DataInCode || FunctionStarts || LinkOptHints || DylibsUsed || DylibId || - ObjcMetaData || (!FilterSections.empty())) { + Rpaths || ObjcMetaData || (!FilterSections.empty())) { if (!NoLeadingHeaders) { outs() << Name; if (!ArchiveMemberName.empty()) @@ -1974,6 +1986,8 @@ printExportsTrie(MachOOF); if (Rebase) printRebaseTable(MachOOF); + if (Rpaths) + PrintRpaths(MachOOF); if (Bind) printBindTable(MachOOF); if (LazyBind) diff --git a/llvm/tools/llvm-objdump/ObjdumpOpts.td b/llvm/tools/llvm-objdump/ObjdumpOpts.td --- a/llvm/tools/llvm-objdump/ObjdumpOpts.td +++ b/llvm/tools/llvm-objdump/ObjdumpOpts.td @@ -396,6 +396,11 @@ "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 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2952,7 +2952,7 @@ !(MachOOpt && (Bind || DataInCode || DylibId || DylibsUsed || ExportsTrie || FirstPrivateHeader || FunctionStarts || IndirectSymbols || InfoPlist || - LazyBind || LinkOptHints || ObjcMetaData || Rebase || + LazyBind || LinkOptHints || ObjcMetaData || Rebase || Rpaths || UniversalHeaders || WeakBind || !FilterSections.empty()))) { T.PrintObjdumpHelp(ToolName); return 2;