From bc847fa4eddb28fbc18d8b28f1dc2c431ee0977e Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Mon, 16 Mar 2015 20:08:09 +0000 Subject: [PATCH] Add the options, -dylibs-used and -dylib-id to llvm-objdump used with -macho to print the Mach-O dynamic shared libraries used by a linked image or the library id of a shared library. llvm-svn: 232406 --- .../tools/llvm-objdump/X86/macho-dylib.test | 6 ++ llvm/tools/llvm-objdump/MachODump.cpp | 69 ++++++++++++++++++- llvm/tools/llvm-objdump/llvm-objdump.cpp | 2 + llvm/tools/llvm-objdump/llvm-objdump.h | 2 + 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 llvm/test/tools/llvm-objdump/X86/macho-dylib.test diff --git a/llvm/test/tools/llvm-objdump/X86/macho-dylib.test b/llvm/test/tools/llvm-objdump/X86/macho-dylib.test new file mode 100644 index 000000000000..0e31b8b930e6 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/macho-dylib.test @@ -0,0 +1,6 @@ +RUN: llvm-objdump -m -dylibs-used %p/Inputs/hello.exe.macho-x86_64 | FileCheck %s -check-prefix=USED +RUN: llvm-objdump -m -dylib-id %p/Inputs/dylibLoadKinds.macho-x86_64 | FileCheck %s -check-prefix=ID + +USED: /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1) + +ID: /usr/lib/foo.dylib diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 0e917e9ad5ca..625820f273d6 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -101,6 +101,16 @@ cl::opt cl::desc("Print the info plist section as strings for " "Mach-O objects (requires -macho)")); +cl::opt + llvm::DylibsUsed("dylibs-used", + cl::desc("Print the shared libraries used for linked " + "Mach-O files (requires -macho)")); + +cl::opt + llvm::DylibId("dylib-id", + cl::desc("Print the shared library's id for the dylib Mach-O " + "file (requires -macho)")); + cl::opt llvm::NonVerbose("non-verbose", cl::desc("Print the info for Mach-O objects in " @@ -516,6 +526,59 @@ static void PrintLinkOptHints(MachOObjectFile *O) { } } +static void PrintDylibs(MachOObjectFile *O, bool JustId) { + uint32_t LoadCommandCount = O->getHeader().ncmds; + MachOObjectFile::LoadCommandInfo Load = O->getFirstLoadCommandInfo(); + for (unsigned I = 0;; ++I) { + if ((JustId && Load.C.cmd == MachO::LC_ID_DYLIB) || + (!JustId && (Load.C.cmd == MachO::LC_ID_DYLIB || + Load.C.cmd == MachO::LC_LOAD_DYLIB || + Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB || + Load.C.cmd == MachO::LC_REEXPORT_DYLIB || + Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB || + Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB))) { + MachO::dylib_command dl = O->getDylibIDLoadCommand(Load); + if (dl.dylib.name < dl.cmdsize) { + const char *p = (const char *)(Load.Ptr) + dl.dylib.name; + if (JustId) + outs() << p << "\n"; + else { + outs() << "\t" << p; + outs() << " (compatibility version " + << ((dl.dylib.compatibility_version >> 16) & 0xffff) << "." + << ((dl.dylib.compatibility_version >> 8) & 0xff) << "." + << (dl.dylib.compatibility_version & 0xff) << ","; + outs() << " current version " + << ((dl.dylib.current_version >> 16) & 0xffff) << "." + << ((dl.dylib.current_version >> 8) & 0xff) << "." + << (dl.dylib.current_version & 0xff) << ")\n"; + } + } else { + outs() << "\tBad offset (" << dl.dylib.name << ") for name of "; + if (Load.C.cmd == MachO::LC_ID_DYLIB) + outs() << "LC_ID_DYLIB "; + else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) + outs() << "LC_LOAD_DYLIB "; + else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) + outs() << "LC_LOAD_WEAK_DYLIB "; + else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) + outs() << "LC_LAZY_LOAD_DYLIB "; + else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) + outs() << "LC_REEXPORT_DYLIB "; + else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) + outs() << "LC_LOAD_UPWARD_DYLIB "; + else + outs() << "LC_??? "; + outs() << "command " << I << "\n"; + } + } + if (I == LoadCommandCount - 1) + break; + else + Load = O->getNextLoadCommandInfo(Load); + } +} + typedef DenseMap SymbolAddressMap; static void CreateSymbolAddressMap(MachOObjectFile *O, @@ -1106,7 +1169,7 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, // UniversalHeaders or ArchiveHeaders. if (Disassemble || PrivateHeaders || ExportsTrie || Rebase || Bind || LazyBind || WeakBind || IndirectSymbols || DataInCode || LinkOptHints || - DumpSections.size() != 0) { + DylibsUsed || DylibId || DumpSections.size() != 0) { outs() << Filename; if (!ArchiveMemberName.empty()) outs() << '(' << ArchiveMemberName << ')'; @@ -1133,6 +1196,10 @@ static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF, DumpSectionContents(Filename, MachOOF, !NonVerbose); if (InfoPlist) DumpInfoPlistSectionContents(Filename, MachOOF); + if (DylibsUsed) + PrintDylibs(MachOOF, false); + if (DylibId) + PrintDylibs(MachOOF, true); if (SymbolTable) PrintSymbolTable(MachOOF); if (UnwindInfo) diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 4bae053b4037..9e51c19bd7ce 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -908,6 +908,8 @@ int main(int argc, char **argv) { && !(DataInCode && MachOOpt) && !(LinkOptHints && MachOOpt) && !(InfoPlist && MachOOpt) + && !(DylibsUsed && MachOOpt) + && !(DylibId && MachOOpt) && !(DumpSections.size() != 0 && MachOOpt)) { cl::PrintHelpMessage(); return 2; diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h index 434a10e677da..68cb4374dffd 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.h +++ b/llvm/tools/llvm-objdump/llvm-objdump.h @@ -41,6 +41,8 @@ extern cl::opt IndirectSymbols; extern cl::opt DataInCode; extern cl::opt LinkOptHints; extern cl::opt InfoPlist; +extern cl::opt DylibsUsed; +extern cl::opt DylibId; extern cl::opt NonVerbose; extern cl::opt Relocations; extern cl::opt SectionHeaders;