summaryrefslogtreecommitdiff
path: root/tools/llvm-objdump
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2011-10-17 23:55:22 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2011-10-17 23:55:22 +0000
commitb12715de41029162baed99a14032b530e85661a1 (patch)
tree60835a1aba3b5ddb1a1ac0ab8c118a95b9074b71 /tools/llvm-objdump
parent206d17cf605293f1c12d8bfa8cf72826a29b253f (diff)
downloadllvm-b12715de41029162baed99a14032b530e85661a1.tar.gz
llvm-b12715de41029162baed99a14032b530e85661a1.tar.bz2
llvm-b12715de41029162baed99a14032b530e85661a1.tar.xz
llvm-objdump: Add static symbol table dumping.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142319 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-objdump')
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp119
1 files changed, 118 insertions, 1 deletions
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 34f27e8a63..f9ebf59e19 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"
@@ -65,6 +66,9 @@ static cl::opt<bool>
SectionContents("s", cl::desc("Display the content of each section"));
static cl::opt<bool>
+SymbolTable("t", cl::desc("Display the symbol table"));
+
+static cl::opt<bool>
MachO("macho", cl::desc("Use MachO specific object file parser"));
static cl::alias
MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
@@ -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<coff_aux_section_definition>(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<const COFFObjectFile>(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;
}