Slightly refactor things for llvm-objdump and the -macho option so it can be used...
authorKevin Enderby <enderby@apple.com>
Wed, 7 Jan 2015 21:02:18 +0000 (21:02 +0000)
committerKevin Enderby <enderby@apple.com>
Wed, 7 Jan 2015 21:02:18 +0000 (21:02 +0000)
options other than just -disassemble so that universal files can be used with other
options combined with -arch options.

No functional change to existing options and use.  One test case added for the
additional functionality with a universal file an a -arch option.

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

test/tools/llvm-objdump/X86/macho-private-headers.test
tools/llvm-objdump/MachODump.cpp
tools/llvm-objdump/llvm-objdump.cpp
tools/llvm-objdump/llvm-objdump.h

index 5bea041c8879e4c424527e936b3d1fe2895e9947..c80bb083af3748a3e0a24472f6d45f4c10f1ec3f 100644 (file)
@@ -17,6 +17,8 @@
 // RUN:     | FileCheck %s -check-prefix=ROUTINE
 // RUN: llvm-objdump -p %p/Inputs/exeThread.macho-x86_64 \
 // RUN:     | FileCheck %s -check-prefix=THREAD
+// RUN: llvm-objdump -macho -p -arch i386 %p/Inputs/macho-universal.x86_64.i386 \
+// RUN:     | FileCheck %s -check-prefix=FATi386
 
 CHECK: Mach header
 CHECK:       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
@@ -437,3 +439,7 @@ THREAD:    r12  0x0000000000000000 r13 0x0000000000000000 r14  0x000000000000000
 THREAD:    r15  0x0000000000000000 rip 0x0000000100000d00
 THREAD: rflags  0x0000000000000000 cs  0x0000000000000000 fs   0x0000000000000000
 THREAD:     gs  0x0000000000000000
+
+FATi386: Mach header
+FATi386:       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
+FATi386:    MH_MAGIC    I386        ALL  0x00     EXECUTE    16        716   NOUNDEFS DYLDLINK TWOLEVEL PIE MH_NO_HEAP_EXECUTION
index 935696be04ca2044ca20ed74962ae4f3edc112ac..68f46a72cae22914e27b630222b4c564ebcbeffb 100644 (file)
@@ -285,11 +285,57 @@ static bool checkMachOAndArchFlags(ObjectFile *O, StringRef Filename) {
   return true;
 }
 
-static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
-                                   StringRef ArchiveMemberName = StringRef(),
-                                   StringRef ArchitectureName = StringRef());
+static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF);
+
+// ProcessMachO() is passed a single opened Mach-O file, which may be an
+// archive member and or in a slice of a universal file.  It prints the
+// the file name and header info and then processes it according to the
+// command line options.
+static void ProcessMachO(StringRef Filename, MachOObjectFile *MachOOF,
+                         StringRef ArchiveMemberName = StringRef(),
+                         StringRef ArchitectureName = StringRef()) {
+  outs() << Filename;
+  if (!ArchiveMemberName.empty())
+    outs() << '(' << ArchiveMemberName << ')';
+  if (!ArchitectureName.empty())
+    outs() << " (architecture " << ArchitectureName << ")";
+  outs() << ":\n";
+
+  if (Disassemble)
+    DisassembleMachO(Filename, MachOOF);
+  // TODO: These should/could be printed in Darwin's otool(1) or nm(1) style
+  //       for -macho. Or just used a new option that maps to the otool(1)
+  //       option like -r, -l, etc.  Or just the normal llvm-objdump option
+  //       but now for this slice so that the -arch options can be used.
+  // if (Relocations)
+  //   PrintRelocations(MachOOF);
+  // if (SectionHeaders)
+  //   PrintSectionHeaders(MachOOF);
+  // if (SectionContents)
+  //   PrintSectionContents(MachOOF);
+  // if (SymbolTable)
+  //   PrintSymbolTable(MachOOF);
+  // if (UnwindInfo)
+  //   PrintUnwindInfo(MachOOF);
+  if (PrivateHeaders)
+    printMachOFileHeader(MachOOF);
+  if (ExportsTrie)
+    printExportsTrie(MachOOF);
+  if (Rebase)
+    printRebaseTable(MachOOF);
+  if (Bind)
+    printBindTable(MachOOF);
+  if (LazyBind)
+    printLazyBindTable(MachOOF);
+  if (WeakBind)
+    printWeakBindTable(MachOOF);
+}
 
-void llvm::DisassembleInputMachO(StringRef Filename) {
+// ParseInputMachO() parses the named Mach-O file in Filename and handles the
+// -arch flags selecting just those slices as specified by them and also parses
+// archive files.  Then for each individual Mach-O file ProcessMachO() is
+// called to process the file based on the command line options.
+void llvm::ParseInputMachO(StringRef Filename) {
   // Check for -arch all and verifiy the -arch flags are valid.
   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
     if (ArchFlags[i] == "all") {
@@ -321,7 +367,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
       if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
         if (!checkMachOAndArchFlags(O, Filename))
           return;
-        DisassembleInputMachO2(Filename, O, O->getFileName());
+        ProcessMachO(Filename, O, O->getFileName());
       }
     }
     return;
@@ -346,7 +392,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
             if (ObjOrErr) {
               ObjectFile &O = *ObjOrErr.get();
               if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
-                DisassembleInputMachO2(Filename, MachOOF, "", ArchitectureName);
+                ProcessMachO(Filename, MachOOF, "", ArchitectureName);
             } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
                            I->getAsArchive()) {
               std::unique_ptr<Archive> &A = *AOrErr;
@@ -362,8 +408,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
                   continue;
                 if (MachOObjectFile *O =
                         dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
-                  DisassembleInputMachO2(Filename, O, O->getFileName(),
-                                         ArchitectureName);
+                  ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
               }
             }
           }
@@ -390,7 +435,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
           if (ObjOrErr) {
             ObjectFile &O = *ObjOrErr.get();
             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&O))
-              DisassembleInputMachO2(Filename, MachOOF);
+              ProcessMachO(Filename, MachOOF);
           } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
                          I->getAsArchive()) {
             std::unique_ptr<Archive> &A = *AOrErr;
@@ -403,7 +448,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
                 continue;
               if (MachOObjectFile *O =
                       dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
-                DisassembleInputMachO2(Filename, O, O->getFileName());
+                ProcessMachO(Filename, O, O->getFileName());
             }
           }
           return;
@@ -423,7 +468,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
       if (ObjOrErr) {
         ObjectFile &Obj = *ObjOrErr.get();
         if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&Obj))
-          DisassembleInputMachO2(Filename, MachOOF, "", ArchitectureName);
+          ProcessMachO(Filename, MachOOF, "", ArchitectureName);
       } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
         std::unique_ptr<Archive> &A = *AOrErr;
         outs() << "Archive : " << Filename;
@@ -438,8 +483,8 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
           if (MachOObjectFile *O =
                   dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
             if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(O))
-              DisassembleInputMachO2(Filename, MachOOF, MachOOF->getFileName(),
-                                     ArchitectureName);
+              ProcessMachO(Filename, MachOOF, MachOOF->getFileName(),
+                           ArchitectureName);
           }
         }
       }
@@ -450,7 +495,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
     if (!checkMachOAndArchFlags(O, Filename))
       return;
     if (MachOObjectFile *MachOOF = dyn_cast<MachOObjectFile>(&*O)) {
-      DisassembleInputMachO2(Filename, MachOOF);
+      ProcessMachO(Filename, MachOOF);
     } else
       errs() << "llvm-objdump: '" << Filename << "': "
              << "Object is not a Mach-O file type.\n";
@@ -1785,9 +1830,7 @@ static void emitComments(raw_svector_ostream &CommentStream,
   CommentStream.resync();
 }
 
-static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
-                                   StringRef ArchiveMemberName,
-                                   StringRef ArchitectureName) {
+static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF) {
   const char *McpuDefault = nullptr;
   const Target *ThumbTarget = nullptr;
   const Target *TheTarget = GetTarget(MachOOF, &McpuDefault, &ThumbTarget);
@@ -1894,13 +1937,6 @@ static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF,
     return;
   }
 
-  outs() << Filename;
-  if (!ArchiveMemberName.empty())
-    outs() << '(' << ArchiveMemberName << ')';
-  if (!ArchitectureName.empty())
-    outs() << " (architecture " << ArchitectureName << ")";
-  outs() << ":\n";
-
   MachO::mach_header Header = MachOOF->getHeader();
 
   // FIXME: Using the -cfg command line option, this code used to be able to
index 284b334a9d207d76a6115f894bc7287f8c7cefce..74fd9710b3fda5fe892c23ca4b92830cdc6d7ba2 100644 (file)
@@ -61,8 +61,8 @@ using namespace object;
 static cl::list<std::string>
 InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
 
-static cl::opt<bool>
-Disassemble("disassemble",
+cl::opt<bool>
+llvm::Disassemble("disassemble",
   cl::desc("Display assembler mnemonics for the machine instructions"));
 static cl::alias
 Disassembled("d", cl::desc("Alias for --disassemble"),
@@ -77,20 +77,20 @@ SectionContents("s", cl::desc("Display the content of each section"));
 static cl::opt<bool>
 SymbolTable("t", cl::desc("Display the symbol table"));
 
-static cl::opt<bool>
-ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
+cl::opt<bool>
+llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
 
-static cl::opt<bool>
-Rebase("rebase", cl::desc("Display mach-o rebasing info"));
+cl::opt<bool>
+llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
 
-static cl::opt<bool>
-Bind("bind", cl::desc("Display mach-o binding info"));
+cl::opt<bool>
+llvm::Bind("bind", cl::desc("Display mach-o binding info"));
 
-static cl::opt<bool>
-LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
+cl::opt<bool>
+llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
 
-static cl::opt<bool>
-WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
+cl::opt<bool>
+llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
 
 static cl::opt<bool>
 MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
@@ -139,9 +139,9 @@ static cl::alias
 UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
                 cl::aliasopt(UnwindInfo));
 
-static cl::opt<bool>
-PrivateHeaders("private-headers",
-               cl::desc("Display format specific file headers"));
+cl::opt<bool>
+llvm::PrivateHeaders("private-headers",
+                     cl::desc("Display format specific file headers"));
 
 static cl::alias
 PrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
@@ -708,7 +708,7 @@ static void PrintUnwindInfo(const ObjectFile *o) {
   }
 }
 
-static void printExportsTrie(const ObjectFile *o) {
+void llvm::printExportsTrie(const ObjectFile *o) {
   outs() << "Exports trie:\n";
   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOExportsTrie(MachO);
@@ -719,7 +719,7 @@ static void printExportsTrie(const ObjectFile *o) {
   }
 }
 
-static void printRebaseTable(const ObjectFile *o) {
+void llvm::printRebaseTable(const ObjectFile *o) {
   outs() << "Rebase table:\n";
   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachORebaseTable(MachO);
@@ -730,7 +730,7 @@ static void printRebaseTable(const ObjectFile *o) {
   }
 }
 
-static void printBindTable(const ObjectFile *o) {
+void llvm::printBindTable(const ObjectFile *o) {
   outs() << "Bind table:\n";
   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOBindTable(MachO);
@@ -741,7 +741,7 @@ static void printBindTable(const ObjectFile *o) {
   }
 }
 
-static void printLazyBindTable(const ObjectFile *o) {
+void llvm::printLazyBindTable(const ObjectFile *o) {
   outs() << "Lazy bind table:\n";
   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOLazyBindTable(MachO);
@@ -752,7 +752,7 @@ static void printLazyBindTable(const ObjectFile *o) {
   }
 }
 
-static void printWeakBindTable(const ObjectFile *o) {
+void llvm::printWeakBindTable(const ObjectFile *o) {
   outs() << "Weak bind table:\n";
   if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
     printMachOWeakBindTable(MachO);
@@ -832,8 +832,11 @@ static void DumpInput(StringRef file) {
     return;
   }
 
-  if (MachOOpt && Disassemble) {
-    DisassembleInputMachO(file);
+  // If we are using the Mach-O specific object file parser, then let it parse
+  // the file and process the command line options.  So the -arch flags can
+  // be used to select specific slices, etc.
+  if (MachOOpt) {
+    ParseInputMachO(file);
     return;
   }
 
index ef1509f933a0029a5d73d0bdca6297a273202a51..01e2b75a9e15bb5760945aacb57cdc2a3d269c77 100644 (file)
@@ -26,13 +26,20 @@ extern cl::opt<std::string> TripleName;
 extern cl::opt<std::string> ArchName;
 extern cl::opt<std::string> MCPU;
 extern cl::list<std::string> MAttrs;
+extern cl::opt<bool> Disassemble;
 extern cl::opt<bool> NoShowRawInsn;
+extern cl::opt<bool> PrivateHeaders;
+extern cl::opt<bool> ExportsTrie;
+extern cl::opt<bool> Rebase;
+extern cl::opt<bool> Bind;
+extern cl::opt<bool> LazyBind;
+extern cl::opt<bool> WeakBind;
 
 // Various helper functions.
 bool error(std::error_code ec);
 bool RelocAddressLess(object::RelocationRef a, object::RelocationRef b);
 void DumpBytes(StringRef bytes);
-void DisassembleInputMachO(StringRef Filename);
+void ParseInputMachO(StringRef Filename);
 void printCOFFUnwindInfo(const object::COFFObjectFile* o);
 void printMachOUnwindInfo(const object::MachOObjectFile* o);
 void printMachOExportsTrie(const object::MachOObjectFile* o);
@@ -43,6 +50,11 @@ void printMachOWeakBindTable(const object::MachOObjectFile* o);
 void printELFFileHeader(const object::ObjectFile *o);
 void printCOFFFileHeader(const object::ObjectFile *o);
 void printMachOFileHeader(const object::ObjectFile *o);
+void printExportsTrie(const object::ObjectFile *o);
+void printRebaseTable(const object::ObjectFile *o);
+void printBindTable(const object::ObjectFile *o);
+void printLazyBindTable(const object::ObjectFile *o);
+void printWeakBindTable(const object::ObjectFile *o);
 
 } // end namespace llvm