From 60e9ca4c0fd19a5238971488ce5ad2040cce6573 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Wed, 7 Jan 2015 21:02:18 +0000 Subject: [PATCH] Slightly refactor things for llvm-objdump and the -macho option so it can be used with 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 --- .../X86/macho-private-headers.test | 6 ++ tools/llvm-objdump/MachODump.cpp | 84 +++++++++++++------ tools/llvm-objdump/llvm-objdump.cpp | 47 ++++++----- tools/llvm-objdump/llvm-objdump.h | 14 +++- 4 files changed, 104 insertions(+), 47 deletions(-) diff --git a/test/tools/llvm-objdump/X86/macho-private-headers.test b/test/tools/llvm-objdump/X86/macho-private-headers.test index 5bea041c887..c80bb083af3 100644 --- a/test/tools/llvm-objdump/X86/macho-private-headers.test +++ b/test/tools/llvm-objdump/X86/macho-private-headers.test @@ -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 diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 935696be04c..68f46a72cae 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -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(&*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(&O)) - DisassembleInputMachO2(Filename, MachOOF, "", ArchitectureName); + ProcessMachO(Filename, MachOOF, "", ArchitectureName); } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; @@ -362,8 +408,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { continue; if (MachOObjectFile *O = dyn_cast(&*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(&O)) - DisassembleInputMachO2(Filename, MachOOF); + ProcessMachO(Filename, MachOOF); } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; @@ -403,7 +448,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { continue; if (MachOObjectFile *O = dyn_cast(&*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(&Obj)) - DisassembleInputMachO2(Filename, MachOOF, "", ArchitectureName); + ProcessMachO(Filename, MachOOF, "", ArchitectureName); } else if (ErrorOr> AOrErr = I->getAsArchive()) { std::unique_ptr &A = *AOrErr; outs() << "Archive : " << Filename; @@ -438,8 +483,8 @@ void llvm::DisassembleInputMachO(StringRef Filename) { if (MachOObjectFile *O = dyn_cast(&*ChildOrErr.get())) { if (MachOObjectFile *MachOOF = dyn_cast(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(&*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 diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 284b334a9d2..74fd9710b3f 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -61,8 +61,8 @@ using namespace object; static cl::list InputFilenames(cl::Positional, cl::desc(""),cl::ZeroOrMore); -static cl::opt -Disassemble("disassemble", +cl::opt +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 SymbolTable("t", cl::desc("Display the symbol table")); -static cl::opt -ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols")); +cl::opt +llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols")); -static cl::opt -Rebase("rebase", cl::desc("Display mach-o rebasing info")); +cl::opt +llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info")); -static cl::opt -Bind("bind", cl::desc("Display mach-o binding info")); +cl::opt +llvm::Bind("bind", cl::desc("Display mach-o binding info")); -static cl::opt -LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info")); +cl::opt +llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info")); -static cl::opt -WeakBind("weak-bind", cl::desc("Display mach-o weak binding info")); +cl::opt +llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info")); static cl::opt 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 -PrivateHeaders("private-headers", - cl::desc("Display format specific file headers")); +cl::opt +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(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(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(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(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(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; } diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index ef1509f933a..01e2b75a9e1 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -26,13 +26,20 @@ extern cl::opt TripleName; extern cl::opt ArchName; extern cl::opt MCPU; extern cl::list MAttrs; +extern cl::opt Disassemble; extern cl::opt NoShowRawInsn; +extern cl::opt PrivateHeaders; +extern cl::opt ExportsTrie; +extern cl::opt Rebase; +extern cl::opt Bind; +extern cl::opt LazyBind; +extern cl::opt 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 -- 2.34.1