From 739b65bf85cf7221b8a615e83dee11ec729e2649 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 15 Jul 2011 18:39:24 +0000 Subject: Teach llvm-objdump to disassemble sections symbol by symbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135289 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ObjectFile.h | 4 ++ tools/llvm-objdump/llvm-objdump.cpp | 79 ++++++++++++++++++++++++++----------- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 30246a3866..98ac067279 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -172,6 +172,10 @@ public: return &Current; } + const content_type &operator*() const { + return Current; + } + bool operator==(const content_iterator &other) const { return Current == other.Current; } diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index b47c04eaf9..4079e4aabe 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -16,6 +16,7 @@ #include "llvm/Object/ObjectFile.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" @@ -158,7 +159,7 @@ static void DisassembleInput(const StringRef &Filename) { 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(), @@ -169,9 +170,32 @@ static void DisassembleInput(const StringRef &Filename) { 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->getAddress(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 << ":\n\n"; + 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->createMCAsmInfo(TripleName)); @@ -200,27 +224,36 @@ static void DisassembleInput(const StringRef &Filename) { 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)) { - 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 + 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"; + + for (Index = Start; Index < End; 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)) { + 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 + } } } } -- cgit v1.2.3