forked from OSchip/llvm-project
[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). llvm-svn: 236342
This commit is contained in:
parent
e6892c8149
commit
e5cb269352
|
@ -30,7 +30,8 @@ public:
|
|||
std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
|
||||
|
||||
std::unique_ptr<PDBSymbol>
|
||||
findSymbolByAddress(uint64_t Address) const override;
|
||||
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
|
||||
|
||||
std::unique_ptr<IPDBEnumLineNumbers>
|
||||
findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
}
|
||||
|
||||
virtual std::unique_ptr<PDBSymbol>
|
||||
findSymbolByAddress(uint64_t Address) const = 0;
|
||||
findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0;
|
||||
virtual std::unique_ptr<IPDBEnumLineNumbers>
|
||||
findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class PDBContext : public DIContext {
|
|||
|
||||
public:
|
||||
PDBContext(const object::COFFObjectFile &Object,
|
||||
std::unique_ptr<IPDBSession> PDBSession);
|
||||
std::unique_ptr<IPDBSession> PDBSession, bool RelativeAddress);
|
||||
|
||||
static bool classof(const DIContext *DICtx) {
|
||||
return DICtx->getKind() == CK_PDB;
|
||||
|
|
|
@ -141,10 +141,18 @@ std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
|
|||
}
|
||||
|
||||
std::unique_ptr<PDBSymbol>
|
||||
DIASession::findSymbolByAddress(uint64_t Address) const {
|
||||
DIASession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
|
||||
enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
|
||||
|
||||
CComPtr<IDiaSymbol> 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<DWORD>(Address - LoadAddr);
|
||||
if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
|
||||
return nullptr;
|
||||
}
|
||||
auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
|
||||
return PDBSymbol::create(*this, std::move(RawSymbol));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -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
|
|
@ -9,6 +9,7 @@ add_llvm_tool(llvm-pdbdump
|
|||
ClassDefinitionDumper.cpp
|
||||
CompilandDumper.cpp
|
||||
EnumDumper.cpp
|
||||
ExternalSymbolDumper.cpp
|
||||
FunctionDumper.cpp
|
||||
LinePrinter.cpp
|
||||
TypeDumper.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;
|
||||
|
|
|
@ -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<PDBSymbolPublicSymbol>();
|
||||
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;
|
||||
}
|
|
@ -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
|
|
@ -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<PDBSymbolFuncDebugStart>()) {
|
||||
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<PDBSymbolFuncDebugEnd>()) {
|
||||
uint32_t Epilogue = FuncEnd - DebugEnd->getRelativeVirtualAddress();
|
||||
uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();
|
||||
WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue;
|
||||
}
|
||||
Printer << "] (";
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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<std::string> InputFilenames(cl::Positional,
|
|||
|
||||
cl::OptionCategory TypeCategory("Symbol Type Options");
|
||||
cl::OptionCategory FilterCategory("Filtering Options");
|
||||
cl::OptionCategory OtherOptions("Other Options");
|
||||
|
||||
cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"),
|
||||
cl::cat(TypeCategory));
|
||||
|
@ -65,11 +67,18 @@ cl::opt<bool> Symbols("symbols", cl::desc("Display symbols for each compiland"),
|
|||
cl::cat(TypeCategory));
|
||||
cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"),
|
||||
cl::cat(TypeCategory));
|
||||
cl::opt<bool> Externals("externals", cl::desc("Dump external symbols"),
|
||||
cl::cat(TypeCategory));
|
||||
cl::opt<bool> Types("types", cl::desc("Display types"), cl::cat(TypeCategory));
|
||||
cl::opt<bool>
|
||||
All("all", cl::desc("Implies all other options in 'Symbol Types' category"),
|
||||
cl::cat(TypeCategory));
|
||||
|
||||
cl::opt<uint64_t> LoadAddress(
|
||||
"load-address",
|
||||
cl::desc("Assume the module is loaded at the specified address"),
|
||||
cl::cat(OtherOptions));
|
||||
|
||||
cl::list<std::string>
|
||||
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");
|
||||
|
|
Loading…
Reference in New Issue