Add the options, -dylibs-used and -dylib-id to llvm-objdump used with -macho
authorKevin Enderby <enderby@apple.com>
Mon, 16 Mar 2015 20:08:09 +0000 (20:08 +0000)
committerKevin Enderby <enderby@apple.com>
Mon, 16 Mar 2015 20:08:09 +0000 (20:08 +0000)
to print the Mach-O dynamic shared libraries used by a linked image or the
library id of a shared library.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232406 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-objdump/X86/macho-dylib.test [new file with mode: 0644]
tools/llvm-objdump/MachODump.cpp
tools/llvm-objdump/llvm-objdump.cpp
tools/llvm-objdump/llvm-objdump.h

diff --git a/test/tools/llvm-objdump/X86/macho-dylib.test b/test/tools/llvm-objdump/X86/macho-dylib.test
new file mode 100644 (file)
index 0000000..0e31b8b
--- /dev/null
@@ -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
index 0e917e9ad5ca71c496564c2ebc0bc06f0fed8dd9..625820f273d6487cc41ef49e428aa6d1193d7c39 100644 (file)
@@ -101,6 +101,16 @@ cl::opt<bool>
                     cl::desc("Print the info plist section as strings for "
                              "Mach-O objects (requires -macho)"));
 
                     cl::desc("Print the info plist section as strings for "
                              "Mach-O objects (requires -macho)"));
 
+cl::opt<bool>
+    llvm::DylibsUsed("dylibs-used",
+                     cl::desc("Print the shared libraries used for linked "
+                              "Mach-O files (requires -macho)"));
+
+cl::opt<bool>
+    llvm::DylibId("dylib-id",
+                  cl::desc("Print the shared library's id for the dylib Mach-O "
+                           "file (requires -macho)"));
+
 cl::opt<bool>
     llvm::NonVerbose("non-verbose",
                      cl::desc("Print the info for Mach-O objects in "
 cl::opt<bool>
     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<uint64_t, StringRef> SymbolAddressMap;
 
 static void CreateSymbolAddressMap(MachOObjectFile *O,
 typedef DenseMap<uint64_t, StringRef> 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 ||
   // 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 << ')';
     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);
     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)
   if (SymbolTable)
     PrintSymbolTable(MachOOF);
   if (UnwindInfo)
index 4bae053b4037d187bb6eee237457395c1eea871c..9e51c19bd7ce9882214b91cd7d7ffa73a485676e 100644 (file)
@@ -908,6 +908,8 @@ int main(int argc, char **argv) {
       && !(DataInCode && MachOOpt)
       && !(LinkOptHints && MachOOpt)
       && !(InfoPlist && MachOOpt)
       && !(DataInCode && MachOOpt)
       && !(LinkOptHints && MachOOpt)
       && !(InfoPlist && MachOOpt)
+      && !(DylibsUsed && MachOOpt)
+      && !(DylibId && MachOOpt)
       && !(DumpSections.size() != 0 && MachOOpt)) {
     cl::PrintHelpMessage();
     return 2;
       && !(DumpSections.size() != 0 && MachOOpt)) {
     cl::PrintHelpMessage();
     return 2;
index 434a10e677dabcf54430cadaae6a374e0780c2ae..68cb4374dffda885f7ee0db9483ed34a7fb3b032 100644 (file)
@@ -41,6 +41,8 @@ extern cl::opt<bool> IndirectSymbols;
 extern cl::opt<bool> DataInCode;
 extern cl::opt<bool> LinkOptHints;
 extern cl::opt<bool> InfoPlist;
 extern cl::opt<bool> DataInCode;
 extern cl::opt<bool> LinkOptHints;
 extern cl::opt<bool> InfoPlist;
+extern cl::opt<bool> DylibsUsed;
+extern cl::opt<bool> DylibId;
 extern cl::opt<bool> NonVerbose;
 extern cl::opt<bool> Relocations;
 extern cl::opt<bool> SectionHeaders;
 extern cl::opt<bool> NonVerbose;
 extern cl::opt<bool> Relocations;
 extern cl::opt<bool> SectionHeaders;