From: Zachary Turner Date: Fri, 1 May 2015 20:24:26 +0000 (+0000) Subject: [llvm-pdbdump] Support dynamic load address and external symbols. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7c69a5821492050ce95eb489a6411b8320277405;p=oota-llvm.git [llvm-pdbdump] Support dynamic load address and external symbols. This patch adds the --load-address command line option to llvm-pdbdump, which dumps all addresses assuming the module has loaded at the specified address. Additionally, this patch adds an option to llvm-pdbdump to support dumping of public symbols (i.e. symbols with external linkage). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236342 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index b8d1f1ca5bf..9a8600fb85e 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -30,7 +30,8 @@ public: std::unique_ptr getSymbolById(uint32_t SymbolId) const override; std::unique_ptr - findSymbolByAddress(uint64_t Address) const override; + findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override; + std::unique_ptr findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override; diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index f1debc02bc6..a130a38a653 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -44,7 +44,7 @@ public: } virtual std::unique_ptr - findSymbolByAddress(uint64_t Address) const = 0; + findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0; virtual std::unique_ptr findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0; diff --git a/include/llvm/DebugInfo/PDB/PDBContext.h b/include/llvm/DebugInfo/PDB/PDBContext.h index 88a11c13caa..2454a7c1921 100644 --- a/include/llvm/DebugInfo/PDB/PDBContext.h +++ b/include/llvm/DebugInfo/PDB/PDBContext.h @@ -32,7 +32,7 @@ class PDBContext : public DIContext { public: PDBContext(const object::COFFObjectFile &Object, - std::unique_ptr PDBSession); + std::unique_ptr PDBSession, bool RelativeAddress); static bool classof(const DIContext *DICtx) { return DICtx->getKind() == CK_PDB; diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp index e3e3fc05ab3..99fe750ebac 100644 --- a/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ b/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -141,10 +141,18 @@ std::unique_ptr DIASession::getSymbolById(uint32_t SymbolId) const { } std::unique_ptr -DIASession::findSymbolByAddress(uint64_t Address) const { +DIASession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const { + enum SymTagEnum EnumVal = static_cast(Type); + CComPtr Symbol; - if (S_OK != Session->findSymbolByVA(Address, SymTagNull, &Symbol)) - return nullptr; + if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) { + ULONGLONG LoadAddr = 0; + if (S_OK != Session->get_loadAddress(&LoadAddr)) + return nullptr; + DWORD RVA = static_cast(Address - LoadAddr); + if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol)) + return nullptr; + } auto RawSymbol = llvm::make_unique(*this, Symbol); return PDBSymbol::create(*this, std::move(RawSymbol)); } diff --git a/test/tools/llvm-pdbdump/Inputs/LoadAddressTest.cpp b/test/tools/llvm-pdbdump/Inputs/LoadAddressTest.cpp new file mode 100644 index 00000000000..bb6ed4ac553 --- /dev/null +++ b/test/tools/llvm-pdbdump/Inputs/LoadAddressTest.cpp @@ -0,0 +1,6 @@ +// Compile with "cl /c /Zi /GR- LoadAddressTest.cpp" +// Link with "link LoadAddressTest.obj /debug /nodefaultlib /entry:main" + +int main(int argc, char **argv) { + return 0; +} diff --git a/test/tools/llvm-pdbdump/Inputs/LoadAddressTest.pdb b/test/tools/llvm-pdbdump/Inputs/LoadAddressTest.pdb new file mode 100644 index 00000000000..e302e9bf3b6 Binary files /dev/null and b/test/tools/llvm-pdbdump/Inputs/LoadAddressTest.pdb differ diff --git a/test/tools/llvm-pdbdump/load-address.test b/test/tools/llvm-pdbdump/load-address.test new file mode 100644 index 00000000000..7a5a4dbff67 --- /dev/null +++ b/test/tools/llvm-pdbdump/load-address.test @@ -0,0 +1,10 @@ +; RUN: llvm-pdbdump -externals %p/Inputs/LoadAddressTest.pdb \ +; RUN: | FileCheck --check-prefix=RVA %s +; RUN: llvm-pdbdump -externals -load-address=0x40000000 \ +; RUN: %p/Inputs/LoadAddressTest.pdb | FileCheck --check-prefix=VA %s + +; RVA: ---EXTERNALS--- +; RVA: [0x00001010] _main + +; VA: ---EXTERNALS--- +; VA: [0x40001010] _main diff --git a/tools/llvm-pdbdump/CMakeLists.txt b/tools/llvm-pdbdump/CMakeLists.txt index 4dd339cee57..1907f917079 100644 --- a/tools/llvm-pdbdump/CMakeLists.txt +++ b/tools/llvm-pdbdump/CMakeLists.txt @@ -9,6 +9,7 @@ add_llvm_tool(llvm-pdbdump ClassDefinitionDumper.cpp CompilandDumper.cpp EnumDumper.cpp + ExternalSymbolDumper.cpp FunctionDumper.cpp LinePrinter.cpp TypeDumper.cpp diff --git a/tools/llvm-pdbdump/CompilandDumper.cpp b/tools/llvm-pdbdump/CompilandDumper.cpp index 86bf32d77d8..68ceb620627 100644 --- a/tools/llvm-pdbdump/CompilandDumper.cpp +++ b/tools/llvm-pdbdump/CompilandDumper.cpp @@ -69,7 +69,7 @@ void CompilandDumper::dump(const PDBSymbolData &Symbol) { case PDB_LocType::Static: Printer << "data: "; WithColor(Printer, PDB_ColorItem::Address).get() - << "[" << format_hex(Symbol.getRelativeVirtualAddress(), 10) << "]"; + << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "]"; break; case PDB_LocType::Constant: Printer << "constant: "; @@ -102,7 +102,7 @@ void CompilandDumper::dump(const PDBSymbolLabel &Symbol) { Printer.NewLine(); Printer << "label "; WithColor(Printer, PDB_ColorItem::Address).get() - << "[" << format_hex(Symbol.getRelativeVirtualAddress(), 10) << "] "; + << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "] "; WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); } @@ -113,16 +113,16 @@ void CompilandDumper::dump(const PDBSymbolThunk &Symbol) { Printer.NewLine(); Printer << "thunk "; PDB_ThunkOrdinal Ordinal = Symbol.getThunkOrdinal(); - uint32_t RVA = Symbol.getRelativeVirtualAddress(); + uint64_t VA = Symbol.getVirtualAddress(); if (Ordinal == PDB_ThunkOrdinal::TrampIncremental) { - uint32_t Target = Symbol.getTargetRelativeVirtualAddress(); - WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(RVA, 10); + uint64_t Target = Symbol.getTargetVirtualAddress(); + WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(VA, 10); Printer << " -> "; WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Target, 10); } else { WithColor(Printer, PDB_ColorItem::Address).get() - << "[" << format_hex(RVA, 10) << " - " - << format_hex(RVA + Symbol.getLength(), 10) << "]"; + << "[" << format_hex(VA, 10) << " - " + << format_hex(VA + Symbol.getLength(), 10) << "]"; } Printer << " ("; WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal; diff --git a/tools/llvm-pdbdump/ExternalSymbolDumper.cpp b/tools/llvm-pdbdump/ExternalSymbolDumper.cpp new file mode 100644 index 00000000000..c4e9f474880 --- /dev/null +++ b/tools/llvm-pdbdump/ExternalSymbolDumper.cpp @@ -0,0 +1,40 @@ +//===- ExternalSymbolDumper.cpp -------------------------------- *- C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ExternalSymbolDumper.h" +#include "LinePrinter.h" + +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" +#include "llvm/Support/Format.h" + +using namespace llvm; + +ExternalSymbolDumper::ExternalSymbolDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} + +void ExternalSymbolDumper::start(const PDBSymbolExe &Symbol) { + auto Vars = Symbol.findAllChildren(); + while (auto Var = Vars->getNext()) + Var->dump(*this); +} + +void ExternalSymbolDumper::dump(const PDBSymbolPublicSymbol &Symbol) { + std::string LinkageName = Symbol.getName(); + if (Printer.IsSymbolExcluded(LinkageName)) + return; + + Printer.NewLine(); + uint64_t Addr = Symbol.getVirtualAddress(); + + Printer << "["; + WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Addr, 10); + Printer << "] "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << LinkageName; +} diff --git a/tools/llvm-pdbdump/ExternalSymbolDumper.h b/tools/llvm-pdbdump/ExternalSymbolDumper.h new file mode 100644 index 00000000000..d77b09cdebf --- /dev/null +++ b/tools/llvm-pdbdump/ExternalSymbolDumper.h @@ -0,0 +1,32 @@ +//===- ExternalSymbolDumper.h --------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVMPDBDUMP_EXTERNALSYMBOLDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_EXTERNALSYMBOLDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class ExternalSymbolDumper : public PDBSymDumper { +public: + ExternalSymbolDumper(LinePrinter &P); + + void start(const PDBSymbolExe &Symbol); + + void dump(const PDBSymbolPublicSymbol &Symbol) override; + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/tools/llvm-pdbdump/FunctionDumper.cpp b/tools/llvm-pdbdump/FunctionDumper.cpp index 419f888ef2f..9584812e81a 100644 --- a/tools/llvm-pdbdump/FunctionDumper.cpp +++ b/tools/llvm-pdbdump/FunctionDumper.cpp @@ -109,19 +109,19 @@ void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol, } void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) { - uint32_t FuncStart = Symbol.getRelativeVirtualAddress(); - uint32_t FuncEnd = FuncStart + Symbol.getLength(); + uint64_t FuncStart = Symbol.getVirtualAddress(); + uint64_t FuncEnd = FuncStart + Symbol.getLength(); Printer << "func ["; WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10); if (auto DebugStart = Symbol.findOneChild()) { - uint32_t Prologue = DebugStart->getRelativeVirtualAddress() - FuncStart; + uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart; WithColor(Printer, PDB_ColorItem::Offset).get() << "+" << Prologue; } Printer << " - "; WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10); if (auto DebugEnd = Symbol.findOneChild()) { - uint32_t Epilogue = FuncEnd - DebugEnd->getRelativeVirtualAddress(); + uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress(); WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue; } Printer << "] ("; diff --git a/tools/llvm-pdbdump/VariableDumper.cpp b/tools/llvm-pdbdump/VariableDumper.cpp index 030610c8c58..e5665b5fcaf 100644 --- a/tools/llvm-pdbdump/VariableDumper.cpp +++ b/tools/llvm-pdbdump/VariableDumper.cpp @@ -44,7 +44,7 @@ void VariableDumper::start(const PDBSymbolData &Var) { Printer.NewLine(); Printer << "data ["; WithColor(Printer, PDB_ColorItem::Address).get() - << format_hex(Var.getRelativeVirtualAddress(), 10); + << format_hex(Var.getVirtualAddress(), 10); Printer << "] "; WithColor(Printer, PDB_ColorItem::Keyword).get() << "static "; dumpSymbolTypeAndName(*VarType, Var.getName()); diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 597683291ff..4a4c64b80cc 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -15,6 +15,7 @@ #include "llvm-pdbdump.h" #include "CompilandDumper.h" +#include "ExternalSymbolDumper.h" #include "FunctionDumper.h" #include "LinePrinter.h" #include "TypeDumper.h" @@ -58,6 +59,7 @@ cl::list InputFilenames(cl::Positional, cl::OptionCategory TypeCategory("Symbol Type Options"); cl::OptionCategory FilterCategory("Filtering Options"); +cl::OptionCategory OtherOptions("Other Options"); cl::opt Compilands("compilands", cl::desc("Display compilands"), cl::cat(TypeCategory)); @@ -65,11 +67,18 @@ cl::opt Symbols("symbols", cl::desc("Display symbols for each compiland"), cl::cat(TypeCategory)); cl::opt Globals("globals", cl::desc("Dump global symbols"), cl::cat(TypeCategory)); +cl::opt Externals("externals", cl::desc("Dump external symbols"), + cl::cat(TypeCategory)); cl::opt Types("types", cl::desc("Display types"), cl::cat(TypeCategory)); cl::opt All("all", cl::desc("Implies all other options in 'Symbol Types' category"), cl::cat(TypeCategory)); +cl::opt LoadAddress( + "load-address", + cl::desc("Assume the module is loaded at the specified address"), + cl::cat(OtherOptions)); + cl::list ExcludeTypes("exclude-types", cl::desc("Exclude types by regular expression"), @@ -121,6 +130,8 @@ static void dumpInput(StringRef Path) { << "'. An unknown error occured.\n"; return; } + if (opts::LoadAddress) + Session->setLoadAddress(opts::LoadAddress); LinePrinter Printer(2, outs()); @@ -215,6 +226,13 @@ static void dumpInput(StringRef Path) { } Printer.Unindent(); } + if (opts::Externals) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---EXTERNALS---"; + Printer.Indent(); + ExternalSymbolDumper Dumper(Printer); + Dumper.start(*GlobalScope); + } outs().flush(); } @@ -240,6 +258,7 @@ int main(int argc_, const char *argv_[]) { opts::Symbols = true; opts::Globals = true; opts::Types = true; + opts::Externals = true; } if (opts::ExcludeCompilerGenerated) { opts::ExcludeTypes.push_back("__vc_attributes");