From 8c590fd08dc7ccaad836878a0d365c572d1c6fcd Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Mon, 17 Oct 2011 23:55:22 +0000 Subject: [PATCH] llvm-objdump: Add static symbol table dumping. llvm-svn: 142319 --- test/Object/objdump-symbol-table.test | 6 +- tools/llvm-objdump/llvm-objdump.cpp | 119 +++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 5 deletions(-) diff --git a/test/Object/objdump-symbol-table.test b/test/Object/objdump-symbol-table.test index f3b9c88dde9..16b0d773e5a 100644 --- a/test/Object/objdump-symbol-table.test +++ b/test/Object/objdump-symbol-table.test @@ -3,9 +3,7 @@ RUN: | FileCheck %s -check-prefix COFF-i386 RUN: llvm-objdump -t %p/TestObjectFiles/trivial-object-test.elf-i386 \ RUN: | FileCheck %s -check-prefix ELF-i386 -XFAIL: * - -COFF-i386: trivial-object-test.coff-i386: file format pe-i386 +COFF-i386: trivial-object-test.coff-i386: file format COFF-i386: SYMBOL TABLE: COFF-i386: [ 0](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text COFF-i386: AUX scnlen 0x24 nreloc 3 nlnno 0 checksum 0x0 assoc 1 comdat 0 @@ -16,7 +14,7 @@ COFF-i386: [ 5](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 L_.str COFF-i386: [ 6](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _puts COFF-i386: [ 7](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _SomeOtherFunction -ELF-i386: trivial-object-test.elf-i386: file format elf32-i386 +ELF-i386: trivial-object-test.elf-i386: file format ELF-i386: SYMBOL TABLE: ELF-i386: 00000000 l df *ABS* 00000000 trivial-object-test.s ELF-i386: 00000000 l d .text 00000000 .text diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 34f27e8a63a..f9ebf59e195 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,113 @@ 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 " + , asd->Length + , asd->NumberOfRelocations + , asd->NumberOfLinenumbers + , asd->CheckSum) + << format("assoc %d comdat %d\n", asd->Number, 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", int16_t(symbol->SectionNumber)) << ")" + << "(fl 0x" << format("%02x", symbol->Type.BaseType) << ")" + << "(ty " << format("%3x", symbol->Type) << ")" + << "(scl " << format("%3x", symbol->StorageClass) << ") " + << "(nx " << unsigned(symbol->NumberOfAuxSymbols) << ") " + << "0x" << format("%08x", 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 +535,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 +607,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; }