From 22ff0f33dbfe99d7308658f07986c1014ea5aff2 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Tue, 18 Oct 2011 19:32:17 +0000 Subject: llvm-objdump: Add static symbol table dumping. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142404 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/llvm-objdump.cpp | 121 +++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 34f27e8a63..0b6bd22017 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -16,6 +16,7 @@ #include "llvm-objdump.h" #include "MCFunction.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringExtras.h" @@ -64,6 +65,9 @@ Relocations("r", cl::desc("Display the relocation entries in the file")); static cl::opt SectionContents("s", cl::desc("Display the content of each section")); +static cl::opt +SymbolTable("t", cl::desc("Display the symbol table")); + static cl::opt MachO("macho", cl::desc("Use MachO specific object file parser")); static cl::alias @@ -411,6 +415,115 @@ static void PrintSectionContents(const ObjectFile *o) { } } +static void PrintCOFFSymbolTable(const COFFObjectFile *coff) { + const coff_file_header *header; + if (error(coff->getHeader(header))) return; + int aux_count = 0; + const coff_symbol *symbol = 0; + for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) { + if (aux_count--) { + // Figure out which type of aux this is. + if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC + && symbol->Value == 0) { // Section definition. + const coff_aux_section_definition *asd; + if (error(coff->getAuxSymbol(i, asd))) + return; + outs() << "AUX " + << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x " + , unsigned(asd->Length) + , unsigned(asd->NumberOfRelocations) + , unsigned(asd->NumberOfLinenumbers) + , unsigned(asd->CheckSum)) + << format("assoc %d comdat %d\n" + , unsigned(asd->Number) + , unsigned(asd->Selection)); + } else { + outs() << "AUX Unknown\n"; + } + } else { + StringRef name; + if (error(coff->getSymbol(i, symbol))) return; + if (error(coff->getSymbolName(symbol, name))) return; + outs() << "[" << format("%2d", i) << "]" + << "(sec " << format("%2d", int(symbol->SectionNumber)) << ")" + << "(fl 0x00)" // Flag bits, which COFF doesn't have. + << "(ty " << format("%3x", unsigned(symbol->Type)) << ")" + << "(scl " << format("%3x", unsigned(symbol->StorageClass)) << ") " + << "(nx " << unsigned(symbol->NumberOfAuxSymbols) << ") " + << "0x" << format("%08x", unsigned(symbol->Value)) << " " + << name << "\n"; + aux_count = symbol->NumberOfAuxSymbols; + } + } +} + +static void PrintSymbolTable(const ObjectFile *o) { + outs() << "SYMBOL TABLE:\n"; + + if (const COFFObjectFile *coff = dyn_cast(o)) + PrintCOFFSymbolTable(coff); + else { + error_code ec; + for (symbol_iterator si = o->begin_symbols(), + se = o->end_symbols(); si != se; si.increment(ec)) { + if (error(ec)) return; + StringRef Name; + uint64_t Offset; + bool Global; + SymbolRef::Type Type; + bool Weak; + bool Absolute; + uint64_t Size; + section_iterator Section = o->end_sections(); + if (error(si->getName(Name))) continue; + if (error(si->getOffset(Offset))) continue; + if (error(si->isGlobal(Global))) continue; + if (error(si->getType(Type))) continue; + if (error(si->isWeak(Weak))) continue; + if (error(si->isAbsolute(Absolute))) continue; + if (error(si->getSize(Size))) continue; + if (error(si->getSection(Section))) continue; + + if (Offset == UnknownAddressOrSize) + Offset = 0; + char GlobLoc = ' '; + if (Type != SymbolRef::ST_External) + GlobLoc = Global ? 'g' : 'l'; + char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File) + ? 'd' : ' '; + char FileFunc = ' '; + if (Type == SymbolRef::ST_File) + FileFunc = 'f'; + else if (Type == SymbolRef::ST_Function) + FileFunc = 'F'; + + outs() << format("%08x", Offset) << " " + << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' ' + << (Weak ? 'w' : ' ') // Weak? + << ' ' // Constructor. Not supported yet. + << ' ' // Warning. Not supported yet. + << ' ' // Indirect reference to another symbol. + << Debug // Debugging (d) or dynamic (D) symbol. + << FileFunc // Name of function (F), file (f) or object (O). + << ' '; + if (Absolute) + outs() << "*ABS*"; + else if (Section == o->end_sections()) + outs() << "*UND*"; + else { + StringRef SectionName; + if (error(Section->getName(SectionName))) + SectionName = ""; + outs() << SectionName; + } + outs() << '\t' + << format("%08x ", Size) + << Name + << '\n'; + } + } +} + static void DumpObject(const ObjectFile *o) { outs() << '\n'; outs() << o->getFileName() @@ -424,6 +537,8 @@ static void DumpObject(const ObjectFile *o) { PrintSectionHeaders(o); if (SectionContents) PrintSectionContents(o); + if (SymbolTable) + PrintSymbolTable(o); } /// @brief Dump each object file in \a a; @@ -494,7 +609,11 @@ int main(int argc, char **argv) { if (InputFilenames.size() == 0) InputFilenames.push_back("a.out"); - if (!Disassemble && !Relocations && !SectionHeaders && !SectionContents) { + if (!Disassemble + && !Relocations + && !SectionHeaders + && !SectionContents + && !SymbolTable) { cl::PrintHelpMessage(); return 2; } -- cgit v1.2.3