X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-objdump%2Fllvm-objdump.cpp;h=78824e9e067b58a0a5cabaa5b0f776a76004b0c1;hb=adf01b3f18442ae8db6b8948e70d82d9df415119;hp=de0165690aecfbc7463390d4ecd76e3d8190786a;hpb=a5c177e70a42f48e4885075c4c48aad0816a2817;p=oota-llvm.git diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index de0165690ae..78824e9e067 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -13,22 +13,24 @@ // //===----------------------------------------------------------------------===// +#include "llvm-objdump.h" +#include "MCFunction.h" #include "llvm/Object/ObjectFile.h" -// This config must be included before llvm-config.h. -#include "llvm/Config/config.h" -#include "../../lib/MC/MCDisassembler/EDDisassembler.h" -#include "../../lib/MC/MCDisassembler/EDInst.h" -#include "../../lib/MC/MCDisassembler/EDOperand.h" -#include "../../lib/MC/MCDisassembler/EDToken.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrAnalysis.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" +#include "llvm/Support/GraphWriter.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -36,40 +38,46 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" #include -#include -#include #include -#include using namespace llvm; using namespace object; -namespace { - cl::list - InputFilenames(cl::Positional, cl::desc(""), - cl::ZeroOrMore); +static cl::list +InputFilenames(cl::Positional, cl::desc(""),cl::ZeroOrMore); - cl::opt - Disassemble("disassemble", - cl::desc("Display assembler mnemonics for the machine instructions")); - cl::alias - Disassembled("d", cl::desc("Alias for --disassemble"), - cl::aliasopt(Disassemble)); +static cl::opt +Disassemble("disassemble", + cl::desc("Display assembler mnemonics for the machine instructions")); +static cl::alias +Disassembled("d", cl::desc("Alias for --disassemble"), + cl::aliasopt(Disassemble)); - cl::opt - TripleName("triple", cl::desc("Target triple to disassemble for, " +static cl::opt +MachO("macho", cl::desc("Use MachO specific object file parser")); +static cl::alias +MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO)); + +cl::opt +llvm::TripleName("triple", cl::desc("Target triple to disassemble for, " + "see -version for available targets")); + +cl::opt +llvm::ArchName("arch", cl::desc("Target arch to disassemble for, " "see -version for available targets")); - cl::opt - ArchName("arch", cl::desc("Target arch to disassemble for, " - "see -version for available targets")); +static StringRef ToolName; + +static bool error(error_code ec) { + if (!ec) return false; - StringRef ToolName; + outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; + outs().flush(); + return true; } static const Target *GetTarget(const ObjectFile *Obj = NULL) { @@ -97,27 +105,8 @@ static const Target *GetTarget(const ObjectFile *Obj = NULL) { return 0; } -namespace { -class StringRefMemoryObject : public MemoryObject { -private: - StringRef Bytes; -public: - StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} - - uint64_t getBase() const { return 0; } - uint64_t getExtent() const { return Bytes.size(); } - - int readByte(uint64_t Addr, uint8_t *Byte) const { - if (Addr > getExtent()) - return -1; - *Byte = Bytes[Addr]; - return 0; - } -}; -} - -static void DumpBytes(StringRef bytes) { - static char hex_rep[] = "0123456789abcdef"; +void llvm::DumpBytes(StringRef bytes) { + static const char hex_rep[] = "0123456789abcdef"; // FIXME: The real way to do this is to figure out the longest instruction // and align to that size before printing. I'll fix this when I get // around to outputting relocations. @@ -142,7 +131,7 @@ static void DumpBytes(StringRef bytes) { outs() << output; } -static void DisassembleInput(const StringRef &Filename) { +void llvm::DisassembleInputLibObject(StringRef Filename) { OwningPtr Buff; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { @@ -157,75 +146,115 @@ static void DisassembleInput(const StringRef &Filename) { // GetTarget prints out stuff. return; } + const MCInstrInfo *InstrInfo = TheTarget->createMCInstrInfo(); + OwningPtr + InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo)); outs() << '\n'; outs() << Filename - << ":\tfile format " << Obj->getFileFormatName() << "\n\n\n"; + << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; + error_code ec; for (ObjectFile::section_iterator i = Obj->begin_sections(), e = Obj->end_sections(); - i != e; ++i) { - if (!i->isText()) - continue; - outs() << "Disassembly of section " << i->getName() << ":\n\n"; + i != e; i.increment(ec)) { + if (error(ec)) break; + bool text; + if (error(i->isText(text))) break; + if (!text) continue; + + // Make a list of all the symbols in this section. + std::vector > Symbols; + for (ObjectFile::symbol_iterator si = Obj->begin_symbols(), + se = Obj->end_symbols(); + si != se; si.increment(ec)) { + bool contains; + if (!error(i->containsSymbol(*si, contains)) && contains) { + uint64_t Address; + if (error(si->getOffset(Address))) break; + StringRef Name; + if (error(si->getName(Name))) break; + Symbols.push_back(std::make_pair(Address, Name)); + } + } + + // Sort the symbols by address, just in case they didn't come in that way. + array_pod_sort(Symbols.begin(), Symbols.end()); + + StringRef name; + if (error(i->getName(name))) break; + outs() << "Disassembly of section " << name << ':'; + + // If the section has no symbols just insert a dummy one and disassemble + // the whole section. + if (Symbols.empty()) + Symbols.push_back(std::make_pair(0, name)); // Set up disassembler. - OwningPtr AsmInfo(TheTarget->createAsmInfo(TripleName)); + OwningPtr AsmInfo(TheTarget->createMCAsmInfo(TripleName)); if (!AsmInfo) { errs() << "error: no assembly info for target " << TripleName << "\n"; return; } - OwningPtr DisAsm(TheTarget->createMCDisassembler()); - if (!DisAsm) { - errs() << "error: no disassembler for target " << TripleName << "\n"; + OwningPtr STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); + + if (!STI) { + errs() << "error: no subtarget info for target " << TripleName << "\n"; return; } - // FIXME: We shouldn't need to do this (and link in codegen). - // When we split this out, we should do it in a way that makes - // it straightforward to switch subtargets on the fly (.e.g, - // the .cpu and .code16 directives). - std::string FeaturesStr; - OwningPtr TM(TheTarget->createTargetMachine(TripleName, - FeaturesStr)); - if (!TM) { - errs() << "error: could not create target for triple " << TripleName << "\n"; + OwningPtr DisAsm(TheTarget->createMCDisassembler(*STI)); + if (!DisAsm) { + errs() << "error: no disassembler for target " << TripleName << "\n"; return; } int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr IP(TheTarget->createMCInstPrinter( - *TM, AsmPrinterVariant, *AsmInfo)); + AsmPrinterVariant, *AsmInfo, *STI)); if (!IP) { errs() << "error: no instruction printer for target " << TripleName << '\n'; return; } - StringRef Bytes = i->getContents(); + StringRef Bytes; + if (error(i->getContents(Bytes))) break; StringRefMemoryObject memoryObject(Bytes); uint64_t Size; uint64_t Index; - - for (Index = 0; Index < Bytes.size(); Index += Size) { - MCInst Inst; - -# ifndef NDEBUG - raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); -# else - raw_ostream &DebugOut = nulls(); -# endif - - if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) { - outs() << format("%8x:\t", i->getAddress() + Index); - DumpBytes(StringRef(Bytes.data() + Index, Size)); - IP->printInst(&Inst, outs()); - outs() << "\n"; - } else { - errs() << ToolName << ": warning: invalid instruction encoding\n"; - if (Size == 0) - Size = 1; // skip illegible bytes + uint64_t SectSize; + if (error(i->getSize(SectSize))) break; + + // Disassemble symbol by symbol. + for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { + uint64_t Start = Symbols[si].first; + uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1; + outs() << '\n' << Symbols[si].second << ":\n"; + +#ifndef NDEBUG + raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); +#else + raw_ostream &DebugOut = nulls(); +#endif + + for (Index = Start; Index < End; Index += Size) { + MCInst Inst; + + if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, + DebugOut, nulls())) { + uint64_t addr; + if (error(i->getAddress(addr))) break; + outs() << format("%8x:\t", addr + Index); + DumpBytes(StringRef(Bytes.data() + Index, Size)); + IP->printInst(&Inst, outs(), ""); + outs() << "\n"; + } else { + errs() << ToolName << ": warning: invalid instruction encoding\n"; + if (Size == 0) + Size = 1; // skip illegible bytes + } } } } @@ -239,9 +268,7 @@ int main(int argc, char **argv) { // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); - // FIXME: We shouldn't need to initialize the Target(Machine)s. - llvm::InitializeAllTargets(); - llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); @@ -261,8 +288,12 @@ int main(int argc, char **argv) { return 2; } - std::for_each(InputFilenames.begin(), InputFilenames.end(), - DisassembleInput); + if (MachO) + std::for_each(InputFilenames.begin(), InputFilenames.end(), + DisassembleInputMachO); + else + std::for_each(InputFilenames.begin(), InputFilenames.end(), + DisassembleInputLibObject); return 0; }