diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-pdbdump')
22 files changed, 1985 insertions, 0 deletions
diff --git a/contrib/llvm/tools/llvm-pdbdump/BuiltinDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/BuiltinDumper.cpp new file mode 100644 index 0000000..d808298 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/BuiltinDumper.cpp @@ -0,0 +1,87 @@ +//===- BuiltinDumper.cpp ---------------------------------------- *- C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "BuiltinDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" + +using namespace llvm; + +BuiltinDumper::BuiltinDumper(LinePrinter &P) + : PDBSymDumper(false), Printer(P) {} + +void BuiltinDumper::start(const PDBSymbolTypeBuiltin &Symbol) { + PDB_BuiltinType Type = Symbol.getBuiltinType(); + switch (Type) { + case PDB_BuiltinType::Float: + if (Symbol.getLength() == 4) + WithColor(Printer, PDB_ColorItem::Type).get() << "float"; + else + WithColor(Printer, PDB_ColorItem::Type).get() << "double"; + break; + case PDB_BuiltinType::UInt: + WithColor(Printer, PDB_ColorItem::Type).get() << "unsigned"; + if (Symbol.getLength() == 8) + WithColor(Printer, PDB_ColorItem::Type).get() << " __int64"; + break; + case PDB_BuiltinType::Int: + if (Symbol.getLength() == 4) + WithColor(Printer, PDB_ColorItem::Type).get() << "int"; + else + WithColor(Printer, PDB_ColorItem::Type).get() << "__int64"; + break; + case PDB_BuiltinType::Char: + WithColor(Printer, PDB_ColorItem::Type).get() << "char"; + break; + case PDB_BuiltinType::WCharT: + WithColor(Printer, PDB_ColorItem::Type).get() << "wchar_t"; + break; + case PDB_BuiltinType::Void: + WithColor(Printer, PDB_ColorItem::Type).get() << "void"; + break; + case PDB_BuiltinType::Long: + WithColor(Printer, PDB_ColorItem::Type).get() << "long"; + break; + case PDB_BuiltinType::ULong: + WithColor(Printer, PDB_ColorItem::Type).get() << "unsigned long"; + break; + case PDB_BuiltinType::Bool: + WithColor(Printer, PDB_ColorItem::Type).get() << "bool"; + break; + case PDB_BuiltinType::Currency: + WithColor(Printer, PDB_ColorItem::Type).get() << "CURRENCY"; + break; + case PDB_BuiltinType::Date: + WithColor(Printer, PDB_ColorItem::Type).get() << "DATE"; + break; + case PDB_BuiltinType::Variant: + WithColor(Printer, PDB_ColorItem::Type).get() << "VARIANT"; + break; + case PDB_BuiltinType::Complex: + WithColor(Printer, PDB_ColorItem::Type).get() << "complex"; + break; + case PDB_BuiltinType::Bitfield: + WithColor(Printer, PDB_ColorItem::Type).get() << "bitfield"; + break; + case PDB_BuiltinType::BSTR: + WithColor(Printer, PDB_ColorItem::Type).get() << "BSTR"; + break; + case PDB_BuiltinType::HResult: + WithColor(Printer, PDB_ColorItem::Type).get() << "HRESULT"; + break; + case PDB_BuiltinType::BCD: + WithColor(Printer, PDB_ColorItem::Type).get() << "HRESULT"; + break; + default: + WithColor(Printer, PDB_ColorItem::Type).get() << "void"; + break; + } +} diff --git a/contrib/llvm/tools/llvm-pdbdump/BuiltinDumper.h b/contrib/llvm/tools/llvm-pdbdump/BuiltinDumper.h new file mode 100644 index 0000000..8cf984a0 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/BuiltinDumper.h @@ -0,0 +1,30 @@ +//===- BuiltinDumper.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_BUILTINDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_BUILTINDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class BuiltinDumper : public PDBSymDumper { +public: + BuiltinDumper(LinePrinter &P); + + void start(const PDBSymbolTypeBuiltin &Symbol); + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp new file mode 100644 index 0000000..8abf3fa --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp @@ -0,0 +1,190 @@ +//===- ClassDefinitionDumper.cpp --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClassDefinitionDumper.h" +#include "EnumDumper.h" +#include "FunctionDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" +#include "TypedefDumper.h" +#include "VariableDumper.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBExtras.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/Support/Format.h" + +using namespace llvm; + +ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} + +void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) { + std::string Name = Class.getName(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " "; + WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName(); + + auto Bases = Class.findAllChildren<PDBSymbolTypeBaseClass>(); + if (Bases->getChildCount() > 0) { + Printer.Indent(); + Printer.NewLine(); + Printer << ":"; + uint32_t BaseIndex = 0; + while (auto Base = Bases->getNext()) { + Printer << " "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << Base->getAccess(); + if (Base->isVirtualBaseClass()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual"; + WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base->getName(); + if (++BaseIndex < Bases->getChildCount()) { + Printer.NewLine(); + Printer << ","; + } + } + Printer.Unindent(); + } + + Printer << " {"; + auto Children = Class.findAllChildren(); + if (Children->getChildCount() == 0) { + Printer << "}"; + return; + } + + // Try to dump symbols organized by member access level. Public members + // first, then protected, then private. This might be slow, so it's worth + // reconsidering the value of this if performance of large PDBs is a problem. + // NOTE: Access level of nested types is not recorded in the PDB, so we have + // a special case for them. + SymbolGroupByAccess Groups; + Groups.insert(std::make_pair(0, SymbolGroup())); + Groups.insert(std::make_pair((int)PDB_MemberAccess::Private, SymbolGroup())); + Groups.insert( + std::make_pair((int)PDB_MemberAccess::Protected, SymbolGroup())); + Groups.insert(std::make_pair((int)PDB_MemberAccess::Public, SymbolGroup())); + + while (auto Child = Children->getNext()) { + PDB_MemberAccess Access = Child->getRawSymbol().getAccess(); + if (isa<PDBSymbolTypeBaseClass>(*Child)) + continue; + + auto &AccessGroup = Groups.find((int)Access)->second; + + if (auto Func = dyn_cast<PDBSymbolFunc>(Child.get())) { + if (Func->isCompilerGenerated() && opts::ExcludeCompilerGenerated) + continue; + if (Func->getLength() == 0 && !Func->isPureVirtual() && + !Func->isIntroVirtualFunction()) + continue; + Child.release(); + AccessGroup.Functions.push_back(std::unique_ptr<PDBSymbolFunc>(Func)); + } else if (auto Data = dyn_cast<PDBSymbolData>(Child.get())) { + Child.release(); + AccessGroup.Data.push_back(std::unique_ptr<PDBSymbolData>(Data)); + } else { + AccessGroup.Unknown.push_back(std::move(Child)); + } + } + + int Count = 0; + Count += dumpAccessGroup((PDB_MemberAccess)0, Groups[0]); + Count += dumpAccessGroup(PDB_MemberAccess::Public, + Groups[(int)PDB_MemberAccess::Public]); + Count += dumpAccessGroup(PDB_MemberAccess::Protected, + Groups[(int)PDB_MemberAccess::Protected]); + Count += dumpAccessGroup(PDB_MemberAccess::Private, + Groups[(int)PDB_MemberAccess::Private]); + if (Count > 0) + Printer.NewLine(); + Printer << "}"; +} + +int ClassDefinitionDumper::dumpAccessGroup(PDB_MemberAccess Access, + const SymbolGroup &Group) { + if (Group.Functions.empty() && Group.Data.empty() && Group.Unknown.empty()) + return 0; + + int Count = 0; + if (Access == PDB_MemberAccess::Private) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "private"; + Printer << ":"; + } else if (Access == PDB_MemberAccess::Protected) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "protected"; + Printer << ":"; + } else if (Access == PDB_MemberAccess::Public) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Keyword).get() << "public"; + Printer << ":"; + } + Printer.Indent(); + for (auto iter = Group.Functions.begin(), end = Group.Functions.end(); + iter != end; ++iter) { + ++Count; + (*iter)->dump(*this); + } + for (auto iter = Group.Data.begin(), end = Group.Data.end(); iter != end; + ++iter) { + ++Count; + (*iter)->dump(*this); + } + for (auto iter = Group.Unknown.begin(), end = Group.Unknown.end(); + iter != end; ++iter) { + ++Count; + (*iter)->dump(*this); + } + Printer.Unindent(); + return Count; +} + +void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {} + +void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol) { + VariableDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, FunctionDumper::PointerType::None); +} + +void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol) {} + +void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol) { + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + EnumDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + TypedefDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol) {} diff --git a/contrib/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h b/contrib/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h new file mode 100644 index 0000000..5b48ba8 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h @@ -0,0 +1,62 @@ +//===- ClassDefinitionDumper.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_CLASSDEFINITIONDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_CLASSDEFINITIONDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" + +#include <list> +#include <memory> +#include <unordered_map> + +namespace llvm { + +class LinePrinter; + +class ClassDefinitionDumper : public PDBSymDumper { +public: + ClassDefinitionDumper(LinePrinter &P); + + void start(const PDBSymbolTypeUDT &Exe); + + void dump(const PDBSymbolTypeBaseClass &Symbol) override; + void dump(const PDBSymbolData &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolFunc &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + void dump(const PDBSymbolTypeVTable &Symbol) override; + +private: + LinePrinter &Printer; + + struct SymbolGroup { + SymbolGroup() {} + SymbolGroup(SymbolGroup &&Other) { + Functions = std::move(Other.Functions); + Data = std::move(Other.Data); + Unknown = std::move(Other.Unknown); + } + + std::list<std::unique_ptr<PDBSymbolFunc>> Functions; + std::list<std::unique_ptr<PDBSymbolData>> Data; + std::list<std::unique_ptr<PDBSymbol>> Unknown; + SymbolGroup(const SymbolGroup &other) = delete; + SymbolGroup &operator=(const SymbolGroup &other) = delete; + }; + typedef std::unordered_map<int, SymbolGroup> SymbolGroupByAccess; + + int dumpAccessGroup(PDB_MemberAccess Access, const SymbolGroup &Group); +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/CompilandDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/CompilandDumper.cpp new file mode 100644 index 0000000..68ceb62 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/CompilandDumper.cpp @@ -0,0 +1,140 @@ +//===- CompilandDumper.cpp - llvm-pdbdump compiland symbol dumper *- C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CompilandDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBExtras.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" +#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h" +#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" +#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" + +#include "FunctionDumper.h" + +#include <utility> +#include <vector> + +using namespace llvm; + +CompilandDumper::CompilandDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} + +void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol) {} + +void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {} + +void CompilandDumper::start(const PDBSymbolCompiland &Symbol, bool Children) { + std::string FullName = Symbol.getName(); + if (Printer.IsCompilandExcluded(FullName)) + return; + + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Path).get() << FullName; + if (!Children) + return; + + auto ChildrenEnum = Symbol.findAllChildren(); + Printer.Indent(); + while (auto Child = ChildrenEnum->getNext()) + Child->dump(*this); + Printer.Unindent(); +} + +void CompilandDumper::dump(const PDBSymbolData &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + + switch (auto LocType = Symbol.getLocationType()) { + case PDB_LocType::Static: + Printer << "data: "; + WithColor(Printer, PDB_ColorItem::Address).get() + << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "]"; + break; + case PDB_LocType::Constant: + Printer << "constant: "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() + << "[" << Symbol.getValue() << "]"; + break; + default: + Printer << "data(unexpected type=" << LocType << ")"; + } + + Printer << " "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); +} + +void CompilandDumper::dump(const PDBSymbolFunc &Symbol) { + if (Symbol.getLength() == 0) + return; + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, FunctionDumper::PointerType::None); +} + +void CompilandDumper::dump(const PDBSymbolLabel &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + Printer << "label "; + WithColor(Printer, PDB_ColorItem::Address).get() + << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "] "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); +} + +void CompilandDumper::dump(const PDBSymbolThunk &Symbol) { + if (Printer.IsSymbolExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + Printer << "thunk "; + PDB_ThunkOrdinal Ordinal = Symbol.getThunkOrdinal(); + uint64_t VA = Symbol.getVirtualAddress(); + if (Ordinal == PDB_ThunkOrdinal::TrampIncremental) { + 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(VA, 10) << " - " + << format_hex(VA + Symbol.getLength(), 10) << "]"; + } + Printer << " ("; + WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal; + Printer << ") "; + std::string Name = Symbol.getName(); + if (!Name.empty()) + WithColor(Printer, PDB_ColorItem::Identifier).get() << Name; +} + +void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol) {} + +void CompilandDumper::dump(const PDBSymbolUnknown &Symbol) { + Printer.NewLine(); + Printer << "unknown (" << Symbol.getSymTag() << ")"; +} diff --git a/contrib/llvm/tools/llvm-pdbdump/CompilandDumper.h b/contrib/llvm/tools/llvm-pdbdump/CompilandDumper.h new file mode 100644 index 0000000..0d1d27c --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/CompilandDumper.h @@ -0,0 +1,39 @@ +//===- CompilandDumper.h - llvm-pdbdump compiland symbol dumper *- 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_COMPILANDDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_COMPILANDDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class CompilandDumper : public PDBSymDumper { +public: + CompilandDumper(LinePrinter &P); + + void start(const PDBSymbolCompiland &Symbol, bool Children); + + void dump(const PDBSymbolCompilandDetails &Symbol) override; + void dump(const PDBSymbolCompilandEnv &Symbol) override; + void dump(const PDBSymbolData &Symbol) override; + void dump(const PDBSymbolFunc &Symbol) override; + void dump(const PDBSymbolLabel &Symbol) override; + void dump(const PDBSymbolThunk &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolUnknown &Symbol) override; + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/EnumDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/EnumDumper.cpp new file mode 100644 index 0000000..3514c39 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/EnumDumper.cpp @@ -0,0 +1,52 @@ +//===- EnumDumper.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "EnumDumper.h" + +#include "BuiltinDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" + +using namespace llvm; + +EnumDumper::EnumDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} + +void EnumDumper::start(const PDBSymbolTypeEnum &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum "; + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); + if (!opts::NoEnumDefs) { + auto BuiltinType = Symbol.getUnderlyingType(); + if (BuiltinType->getBuiltinType() != PDB_BuiltinType::Int || + BuiltinType->getLength() != 4) { + Printer << " : "; + BuiltinDumper Dumper(Printer); + Dumper.start(*BuiltinType); + } + Printer << " {"; + Printer.Indent(); + auto EnumValues = Symbol.findAllChildren<PDBSymbolData>(); + while (auto EnumValue = EnumValues->getNext()) { + if (EnumValue->getDataKind() != PDB_DataKind::Constant) + continue; + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() + << EnumValue->getName(); + Printer << " = "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() + << EnumValue->getValue(); + } + Printer.Unindent(); + Printer.NewLine(); + Printer << "}"; + } +} diff --git a/contrib/llvm/tools/llvm-pdbdump/EnumDumper.h b/contrib/llvm/tools/llvm-pdbdump/EnumDumper.h new file mode 100644 index 0000000..23de061 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/EnumDumper.h @@ -0,0 +1,30 @@ +//===- EnumDumper.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_ENUMDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_ENUMDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class EnumDumper : public PDBSymDumper { +public: + EnumDumper(LinePrinter &P); + + void start(const PDBSymbolTypeEnum &Symbol); + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/ExternalSymbolDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/ExternalSymbolDumper.cpp new file mode 100644 index 0000000..c4e9f47 --- /dev/null +++ b/contrib/llvm/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<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; +} diff --git a/contrib/llvm/tools/llvm-pdbdump/ExternalSymbolDumper.h b/contrib/llvm/tools/llvm-pdbdump/ExternalSymbolDumper.h new file mode 100644 index 0000000..d77b09c --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/tools/llvm-pdbdump/FunctionDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/FunctionDumper.cpp new file mode 100644 index 0000000..9584812 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/FunctionDumper.cpp @@ -0,0 +1,254 @@ +//===- FunctionDumper.cpp ------------------------------------ *- C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "FunctionDumper.h" +#include "BuiltinDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/Support/Format.h" + +using namespace llvm; + +namespace { +template <class T> +void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer, + llvm::FunctionDumper &Dumper) { + uint32_t ClassParentId = Symbol.getClassParentId(); + auto ClassParent = + Symbol.getSession().template getConcreteSymbolById<PDBSymbolTypeUDT>( + ClassParentId); + if (!ClassParent) + return; + + WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName(); + Printer << "::"; +} +} + +FunctionDumper::FunctionDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} + +void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol, + const char *Name, PointerType Pointer) { + auto ReturnType = Symbol.getReturnType(); + ReturnType->dump(*this); + Printer << " "; + uint32_t ClassParentId = Symbol.getClassParentId(); + auto ClassParent = + Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>( + ClassParentId); + + PDB_CallingConv CC = Symbol.getCallingConvention(); + bool ShouldDumpCallingConvention = true; + if ((ClassParent && CC == PDB_CallingConv::Thiscall) || + (!ClassParent && CC == PDB_CallingConv::NearStdcall)) { + ShouldDumpCallingConvention = false; + } + + if (Pointer == PointerType::None) { + if (ShouldDumpCallingConvention) + WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " "; + if (ClassParent) { + Printer << "("; + WithColor(Printer, PDB_ColorItem::Identifier).get() + << ClassParent->getName(); + Printer << "::)"; + } + } else { + Printer << "("; + if (ShouldDumpCallingConvention) + WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " "; + if (ClassParent) { + WithColor(Printer, PDB_ColorItem::Identifier).get() + << ClassParent->getName(); + Printer << "::"; + } + if (Pointer == PointerType::Reference) + Printer << "&"; + else + Printer << "*"; + if (Name) + WithColor(Printer, PDB_ColorItem::Identifier).get() << Name; + Printer << ")"; + } + + Printer << "("; + if (auto ChildEnum = Symbol.getArguments()) { + uint32_t Index = 0; + while (auto Arg = ChildEnum->getNext()) { + Arg->dump(*this); + if (++Index < ChildEnum->getChildCount()) + Printer << ", "; + } + } + Printer << ")"; + + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " const"; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile"; +} + +void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) { + 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>()) { + 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>()) { + uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress(); + WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue; + } + Printer << "] ("; + + if (Symbol.hasFramePointer()) { + WithColor(Printer, PDB_ColorItem::Register).get() + << Symbol.getLocalBasePointerRegisterId(); + } else { + WithColor(Printer, PDB_ColorItem::Register).get() << "FPO"; + } + Printer << ") "; + + if (Symbol.isVirtual() || Symbol.isPureVirtual()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual "; + + auto Signature = Symbol.getSignature(); + if (!Signature) { + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); + if (Pointer == PointerType::Pointer) + Printer << "*"; + else if (Pointer == FunctionDumper::PointerType::Reference) + Printer << "&"; + return; + } + + auto ReturnType = Signature->getReturnType(); + ReturnType->dump(*this); + Printer << " "; + + auto ClassParent = Symbol.getClassParent(); + PDB_CallingConv CC = Signature->getCallingConvention(); + if (Pointer != FunctionDumper::PointerType::None) + Printer << "("; + + if ((ClassParent && CC != PDB_CallingConv::Thiscall) || + (!ClassParent && CC != PDB_CallingConv::NearStdcall)) { + WithColor(Printer, PDB_ColorItem::Keyword).get() + << Signature->getCallingConvention() << " "; + } + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); + if (Pointer != FunctionDumper::PointerType::None) { + if (Pointer == PointerType::Pointer) + Printer << "*"; + else if (Pointer == FunctionDumper::PointerType::Reference) + Printer << "&"; + Printer << ")"; + } + + Printer << "("; + if (auto Arguments = Symbol.getArguments()) { + uint32_t Index = 0; + while (auto Arg = Arguments->getNext()) { + auto ArgType = Arg->getType(); + ArgType->dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " + << Arg->getName(); + if (++Index < Arguments->getChildCount()) + Printer << ", "; + } + } + Printer << ")"; + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " const"; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile"; + if (Symbol.isPureVirtual()) + Printer << " = 0"; +} + +void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) { + uint32_t ElementTypeId = Symbol.getTypeId(); + auto ElementType = Symbol.getSession().getSymbolById(ElementTypeId); + if (!ElementType) + return; + + ElementType->dump(*this); + Printer << "["; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength(); + Printer << "]"; +} + +void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { + BuiltinDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) { + dumpClassParentWithScopeOperator(Symbol, Printer, *this); + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} + +void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) { + // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill + // through to the real thing and dump it. + uint32_t TypeId = Symbol.getTypeId(); + auto Type = Symbol.getSession().getSymbolById(TypeId); + if (!Type) + return; + Type->dump(*this); +} + +void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + dumpClassParentWithScopeOperator(Symbol, Printer, *this); + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} + +void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) { + uint32_t PointeeId = Symbol.getTypeId(); + auto PointeeType = Symbol.getSession().getSymbolById(PointeeId); + if (!PointeeType) + return; + + if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) { + FunctionDumper NestedDumper(Printer); + PointerType Pointer = + Symbol.isReference() ? PointerType::Reference : PointerType::Pointer; + NestedDumper.start(*FuncSig, nullptr, Pointer); + } else { + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; + PointeeType->dump(*this); + Printer << (Symbol.isReference() ? "&" : "*"); + } +} + +void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) { + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} diff --git a/contrib/llvm/tools/llvm-pdbdump/FunctionDumper.h b/contrib/llvm/tools/llvm-pdbdump/FunctionDumper.h new file mode 100644 index 0000000..19a0014 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/FunctionDumper.h @@ -0,0 +1,42 @@ +//===- FunctionDumper.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_FUNCTIONDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_FUNCTIONDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class FunctionDumper : public PDBSymDumper { +public: + FunctionDumper(LinePrinter &P); + + enum class PointerType { None, Pointer, Reference }; + + void start(const PDBSymbolTypeFunctionSig &Symbol, const char *Name, + PointerType Pointer); + void start(const PDBSymbolFunc &Symbol, PointerType Pointer); + + void dump(const PDBSymbolTypeArray &Symbol) override; + void dump(const PDBSymbolTypeBuiltin &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeFunctionArg &Symbol) override; + void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/LinePrinter.cpp b/contrib/llvm/tools/llvm-pdbdump/LinePrinter.cpp new file mode 100644 index 0000000..6bbc403 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/LinePrinter.cpp @@ -0,0 +1,124 @@ +//===- LinePrinter.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LinePrinter.h" + +#include "llvm-pdbdump.h" + +#include "llvm/Support/Regex.h" + +#include <algorithm> + +using namespace llvm; + +LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream) + : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) { + SetFilters(TypeFilters, opts::ExcludeTypes.begin(), opts::ExcludeTypes.end()); + SetFilters(SymbolFilters, opts::ExcludeSymbols.begin(), + opts::ExcludeSymbols.end()); + SetFilters(CompilandFilters, opts::ExcludeCompilands.begin(), + opts::ExcludeCompilands.end()); +} + +void LinePrinter::Indent() { CurrentIndent += IndentSpaces; } + +void LinePrinter::Unindent() { + CurrentIndent = std::max(0, CurrentIndent - IndentSpaces); +} + +void LinePrinter::NewLine() { + OS << "\n"; + OS.indent(CurrentIndent); +} + +bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName) { + if (TypeName.empty()) + return false; + + for (auto &Expr : TypeFilters) { + if (Expr.match(TypeName)) + return true; + } + return false; +} + +bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) { + if (SymbolName.empty()) + return false; + + for (auto &Expr : SymbolFilters) { + if (Expr.match(SymbolName)) + return true; + } + return false; +} + +bool LinePrinter::IsCompilandExcluded(llvm::StringRef CompilandName) { + if (CompilandName.empty()) + return false; + + for (auto &Expr : CompilandFilters) { + if (Expr.match(CompilandName)) + return true; + } + return false; +} + +WithColor::WithColor(LinePrinter &P, PDB_ColorItem C) : OS(P.OS) { + if (C == PDB_ColorItem::None) + OS.resetColor(); + else { + raw_ostream::Colors Color; + bool Bold; + translateColor(C, Color, Bold); + OS.changeColor(Color, Bold); + } +} + +WithColor::~WithColor() { OS.resetColor(); } + +void WithColor::translateColor(PDB_ColorItem C, raw_ostream::Colors &Color, + bool &Bold) const { + switch (C) { + case PDB_ColorItem::Address: + Color = raw_ostream::YELLOW; + Bold = true; + return; + case PDB_ColorItem::Keyword: + Color = raw_ostream::MAGENTA; + Bold = true; + return; + case PDB_ColorItem::Register: + case PDB_ColorItem::Offset: + Color = raw_ostream::YELLOW; + Bold = false; + return; + case PDB_ColorItem::Type: + Color = raw_ostream::CYAN; + Bold = true; + return; + case PDB_ColorItem::Identifier: + Color = raw_ostream::CYAN; + Bold = false; + return; + case PDB_ColorItem::Path: + Color = raw_ostream::CYAN; + Bold = false; + return; + case PDB_ColorItem::SectionHeader: + Color = raw_ostream::RED; + Bold = true; + return; + case PDB_ColorItem::LiteralValue: + Color = raw_ostream::GREEN; + Bold = true; + default: + return; + } +} diff --git a/contrib/llvm/tools/llvm-pdbdump/LinePrinter.h b/contrib/llvm/tools/llvm-pdbdump/LinePrinter.h new file mode 100644 index 0000000..b985e93 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/LinePrinter.h @@ -0,0 +1,89 @@ +//===- LinePrinter.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_LINEPRINTER_H +#define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Regex.h" + +#include <list> + +namespace llvm { + +class LinePrinter { + friend class WithColor; + +public: + LinePrinter(int Indent, raw_ostream &Stream); + + void Indent(); + void Unindent(); + void NewLine(); + + raw_ostream &getStream() { return OS; } + int getIndentLevel() const { return CurrentIndent; } + + bool IsTypeExcluded(llvm::StringRef TypeName); + bool IsSymbolExcluded(llvm::StringRef SymbolName); + bool IsCompilandExcluded(llvm::StringRef CompilandName); + +private: + template <typename Iter> + void SetFilters(std::list<Regex> &List, Iter Begin, Iter End) { + List.clear(); + for (; Begin != End; ++Begin) + List.emplace_back(StringRef(*Begin)); + } + + raw_ostream &OS; + int IndentSpaces; + int CurrentIndent; + + std::list<Regex> CompilandFilters; + std::list<Regex> TypeFilters; + std::list<Regex> SymbolFilters; +}; + +template <class T> +inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { + Printer.getStream() << Item; + return Printer.getStream(); +} + +enum class PDB_ColorItem { + None, + Address, + Type, + Keyword, + Offset, + Identifier, + Path, + SectionHeader, + LiteralValue, + Register, +}; + +class WithColor { +public: + WithColor(LinePrinter &P, PDB_ColorItem C); + ~WithColor(); + + raw_ostream &get() { return OS; } + +private: + void translateColor(PDB_ColorItem C, raw_ostream::Colors &Color, + bool &Bold) const; + raw_ostream &OS; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/TypeDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/TypeDumper.cpp new file mode 100644 index 0000000..88c0bd6 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/TypeDumper.cpp @@ -0,0 +1,97 @@ +//===- TypeDumper.cpp - PDBSymDumper implementation for types *----- C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TypeDumper.h" + +#include "BuiltinDumper.h" +#include "ClassDefinitionDumper.h" +#include "EnumDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" +#include "TypedefDumper.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" + +using namespace llvm; + +TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} + +void TypeDumper::start(const PDBSymbolExe &Exe) { + auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>(); + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Enums"; + Printer << ": (" << Enums->getChildCount() << " items)"; + Printer.Indent(); + while (auto Enum = Enums->getNext()) + Enum->dump(*this); + Printer.Unindent(); + + auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>(); + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Typedefs"; + Printer << ": (" << Typedefs->getChildCount() << " items)"; + Printer.Indent(); + while (auto Typedef = Typedefs->getNext()) + Typedef->dump(*this); + Printer.Unindent(); + + auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>(); + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes"; + Printer << ": (" << Classes->getChildCount() << " items)"; + Printer.Indent(); + while (auto Class = Classes->getNext()) + Class->dump(*this); + Printer.Unindent(); +} + +void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) { + if (Symbol.getUnmodifiedTypeId() != 0) + return; + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + // Dump member enums when dumping their class definition. + if (Symbol.isNested()) + return; + + Printer.NewLine(); + EnumDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + TypedefDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) { + if (Symbol.getUnmodifiedTypeId() != 0) + return; + if (Printer.IsTypeExcluded(Symbol.getName())) + return; + + Printer.NewLine(); + + if (opts::NoClassDefs) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "class "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName(); + } else { + ClassDefinitionDumper Dumper(Printer); + Dumper.start(Symbol); + } +} diff --git a/contrib/llvm/tools/llvm-pdbdump/TypeDumper.h b/contrib/llvm/tools/llvm-pdbdump/TypeDumper.h new file mode 100644 index 0000000..5c0832e --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/TypeDumper.h @@ -0,0 +1,34 @@ +//===- TypeDumper.h - PDBSymDumper implementation for types *- 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_TYPEDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_TYPEDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class TypeDumper : public PDBSymDumper { +public: + TypeDumper(LinePrinter &P); + + void start(const PDBSymbolExe &Exe); + + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/TypedefDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/TypedefDumper.cpp new file mode 100644 index 0000000..a6b5c53 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/TypedefDumper.cpp @@ -0,0 +1,79 @@ +//===- TypedefDumper.cpp - PDBSymDumper impl for typedefs -------- * C++ *-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "TypedefDumper.h" + +#include "BuiltinDumper.h" +#include "FunctionDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBExtras.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" + +using namespace llvm; + +TypedefDumper::TypedefDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} + +void TypedefDumper::start(const PDBSymbolTypeTypedef &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef "; + uint32_t TargetId = Symbol.getTypeId(); + if (auto TypeSymbol = Symbol.getSession().getSymbolById(TargetId)) + TypeSymbol->dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " + << Symbol.getName(); +} + +void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol) {} + +void TypedefDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { + BuiltinDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void TypedefDumper::dump(const PDBSymbolTypeEnum &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum "; + WithColor(Printer, PDB_ColorItem::Type).get() << " " << Symbol.getName(); +} + +void TypedefDumper::dump(const PDBSymbolTypePointer &Symbol) { + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; + uint32_t PointeeId = Symbol.getTypeId(); + auto PointeeType = Symbol.getSession().getSymbolById(PointeeId); + if (!PointeeType) + return; + if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) { + FunctionDumper::PointerType Pointer = FunctionDumper::PointerType::Pointer; + if (Symbol.isReference()) + Pointer = FunctionDumper::PointerType::Reference; + FunctionDumper NestedDumper(Printer); + NestedDumper.start(*FuncSig, nullptr, Pointer); + } else { + PointeeType->dump(*this); + Printer << ((Symbol.isReference()) ? "&" : "*"); + } +} + +void TypedefDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) { + FunctionDumper Dumper(Printer); + Dumper.start(Symbol, nullptr, FunctionDumper::PointerType::None); +} + +void TypedefDumper::dump(const PDBSymbolTypeUDT &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "class "; + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} diff --git a/contrib/llvm/tools/llvm-pdbdump/TypedefDumper.h b/contrib/llvm/tools/llvm-pdbdump/TypedefDumper.h new file mode 100644 index 0000000..8cd578c --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/TypedefDumper.h @@ -0,0 +1,37 @@ +//===- TypedefDumper.h - llvm-pdbdump typedef dumper ---------*- 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_TYPEDEFDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_TYPEDEFDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" + +namespace llvm { + +class LinePrinter; + +class TypedefDumper : public PDBSymDumper { +public: + TypedefDumper(LinePrinter &P); + + void start(const PDBSymbolTypeTypedef &Symbol); + + void dump(const PDBSymbolTypeArray &Symbol) override; + void dump(const PDBSymbolTypeBuiltin &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeFunctionSig &Symbol) override; + void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + +private: + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/VariableDumper.cpp b/contrib/llvm/tools/llvm-pdbdump/VariableDumper.cpp new file mode 100644 index 0000000..e5665b5 --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/VariableDumper.cpp @@ -0,0 +1,170 @@ +//===- VariableDumper.cpp - -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "VariableDumper.h" + +#include "BuiltinDumper.h" +#include "LinePrinter.h" +#include "llvm-pdbdump.h" +#include "FunctionDumper.h" + +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" + +#include "llvm/Support/Format.h" + +using namespace llvm; + +VariableDumper::VariableDumper(LinePrinter &P) + : PDBSymDumper(true), Printer(P) {} + +void VariableDumper::start(const PDBSymbolData &Var) { + if (Var.isCompilerGenerated() && opts::ExcludeCompilerGenerated) + return; + if (Printer.IsSymbolExcluded(Var.getName())) + return; + + auto VarType = Var.getType(); + + switch (auto LocType = Var.getLocationType()) { + case PDB_LocType::Static: + Printer.NewLine(); + Printer << "data ["; + WithColor(Printer, PDB_ColorItem::Address).get() + << format_hex(Var.getVirtualAddress(), 10); + Printer << "] "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "static "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + break; + case PDB_LocType::Constant: + if (isa<PDBSymbolTypeEnum>(*VarType)) + break; + Printer.NewLine(); + Printer << "data "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + Printer << " = "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue(); + break; + case PDB_LocType::ThisRel: + Printer.NewLine(); + Printer << "data "; + WithColor(Printer, PDB_ColorItem::Offset).get() + << "+" << format_hex(Var.getOffset(), 4) << " "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + break; + case PDB_LocType::BitField: + Printer.NewLine(); + Printer << "data "; + WithColor(Printer, PDB_ColorItem::Offset).get() + << "+" << format_hex(Var.getOffset(), 4) << " "; + dumpSymbolTypeAndName(*VarType, Var.getName()); + Printer << " : "; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength(); + break; + default: + Printer.NewLine(); + Printer << "data "; + Printer << "unknown(" << LocType << ") "; + WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName(); + break; + } +} + +void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { + BuiltinDumper Dumper(Printer); + Dumper.start(Symbol); +} + +void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) { + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} + +void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {} + +void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) { + auto PointeeType = Symbol.getPointeeType(); + if (!PointeeType) + return; + + if (auto Func = dyn_cast<PDBSymbolFunc>(PointeeType.get())) { + FunctionDumper NestedDumper(Printer); + FunctionDumper::PointerType Pointer = + Symbol.isReference() ? FunctionDumper::PointerType::Reference + : FunctionDumper::PointerType::Pointer; + NestedDumper.start(*Func, Pointer); + } else { + if (Symbol.isConstType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; + if (Symbol.isVolatileType()) + WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; + PointeeType->dump(*this); + Printer << (Symbol.isReference() ? "&" : "*"); + } +} + +void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) { + WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef "; + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} + +void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) { + WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); +} + +void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type, + StringRef Name) { + if (auto *ArrayType = dyn_cast<PDBSymbolTypeArray>(&Type)) { + std::string IndexSpec; + raw_string_ostream IndexStream(IndexSpec); + std::unique_ptr<PDBSymbol> ElementType = ArrayType->getElementType(); + while (auto NestedArray = dyn_cast<PDBSymbolTypeArray>(ElementType.get())) { + IndexStream << "["; + IndexStream << NestedArray->getCount(); + IndexStream << "]"; + ElementType = NestedArray->getElementType(); + } + IndexStream << "[" << ArrayType->getCount() << "]"; + ElementType->dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; + Printer << IndexStream.str(); + } else { + if (!tryDumpFunctionPointer(Type, Name)) { + Type.dump(*this); + WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; + } + } +} + +bool VariableDumper::tryDumpFunctionPointer(const PDBSymbol &Type, + StringRef Name) { + // Function pointers come across as pointers to function signatures. But the + // signature carries no name, so we have to handle this case separately. + if (auto *PointerType = dyn_cast<PDBSymbolTypePointer>(&Type)) { + auto PointeeType = PointerType->getPointeeType(); + if (auto *FunctionSig = + dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) { + FunctionDumper Dumper(Printer); + FunctionDumper::PointerType PT = FunctionDumper::PointerType::Pointer; + if (PointerType->isReference()) + PT = FunctionDumper::PointerType::Reference; + std::string NameStr(Name.begin(), Name.end()); + Dumper.start(*FunctionSig, NameStr.c_str(), PT); + return true; + } + } + return false; +} diff --git a/contrib/llvm/tools/llvm-pdbdump/VariableDumper.h b/contrib/llvm/tools/llvm-pdbdump/VariableDumper.h new file mode 100644 index 0000000..db8d8ea --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/VariableDumper.h @@ -0,0 +1,41 @@ +//===- VariableDumper.h - PDBSymDumper implementation for types -*- 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_VARIABLEDUMPER_H +#define LLVM_TOOLS_LLVMPDBDUMP_VARIABLEDUMPER_H + +#include "llvm/DebugInfo/PDB/PDBSymDumper.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { + +class LinePrinter; + +class VariableDumper : public PDBSymDumper { +public: + VariableDumper(LinePrinter &P); + + void start(const PDBSymbolData &Var); + + void dump(const PDBSymbolTypeBuiltin &Symbol) override; + void dump(const PDBSymbolTypeEnum &Symbol) override; + void dump(const PDBSymbolTypeFunctionSig &Symbol) override; + void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeTypedef &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; + +private: + void dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name); + bool tryDumpFunctionPointer(const PDBSymbol &Type, StringRef Name); + + LinePrinter &Printer; +}; +} + +#endif diff --git a/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp new file mode 100644 index 0000000..4a4c64b --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -0,0 +1,284 @@ +//===- llvm-pdbdump.cpp - Dump debug info from a PDB file -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Dumps debug information present in PDB files. This utility makes use of +// the Microsoft Windows SDK, so will not compile or run on non-Windows +// platforms. +// +//===----------------------------------------------------------------------===// + +#include "llvm-pdbdump.h" +#include "CompilandDumper.h" +#include "ExternalSymbolDumper.h" +#include "FunctionDumper.h" +#include "LinePrinter.h" +#include "TypeDumper.h" +#include "VariableDumper.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Config/config.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDB.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" + +#if defined(HAVE_DIA_SDK) +#include <Windows.h> +#endif + +using namespace llvm; + +namespace opts { + +enum class PDB_DumpType { ByType, ByObjFile, Both }; + +cl::list<std::string> InputFilenames(cl::Positional, + cl::desc("<input PDB files>"), + cl::OneOrMore); + +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)); +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"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::list<std::string> + ExcludeSymbols("exclude-symbols", + cl::desc("Exclude symbols by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::list<std::string> + ExcludeCompilands("exclude-compilands", + cl::desc("Exclude compilands by regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::opt<bool> ExcludeCompilerGenerated( + "no-compiler-generated", + cl::desc("Don't show compiler generated types and symbols"), + cl::cat(FilterCategory)); +cl::opt<bool> + ExcludeSystemLibraries("no-system-libs", + cl::desc("Don't show symbols from system libraries"), + cl::cat(FilterCategory)); +cl::opt<bool> NoClassDefs("no-class-definitions", + cl::desc("Don't display full class definitions"), + cl::cat(FilterCategory)); +cl::opt<bool> NoEnumDefs("no-enum-definitions", + cl::desc("Don't display full enum definitions"), + cl::cat(FilterCategory)); +} + +static void dumpInput(StringRef Path) { + std::unique_ptr<IPDBSession> Session; + PDB_ErrorCode Error = + llvm::loadDataForPDB(PDB_ReaderType::DIA, Path, Session); + switch (Error) { + case PDB_ErrorCode::Success: + break; + case PDB_ErrorCode::NoPdbImpl: + outs() << "Reading PDBs is not supported on this platform.\n"; + return; + case PDB_ErrorCode::InvalidPath: + outs() << "Unable to load PDB at '" << Path + << "'. Check that the file exists and is readable.\n"; + return; + case PDB_ErrorCode::InvalidFileFormat: + outs() << "Unable to load PDB at '" << Path + << "'. The file has an unrecognized format.\n"; + return; + default: + outs() << "Unable to load PDB at '" << Path + << "'. An unknown error occured.\n"; + return; + } + if (opts::LoadAddress) + Session->setLoadAddress(opts::LoadAddress); + + LinePrinter Printer(2, outs()); + + auto GlobalScope(Session->getGlobalScope()); + std::string FileName(GlobalScope->getSymbolsFileName()); + + WithColor(Printer, PDB_ColorItem::None).get() << "Summary for "; + WithColor(Printer, PDB_ColorItem::Path).get() << FileName; + Printer.Indent(); + uint64_t FileSize = 0; + + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Size"; + if (!llvm::sys::fs::file_size(FileName, FileSize)) { + Printer << ": " << FileSize << " bytes"; + } else { + Printer << ": (Unable to obtain file size)"; + } + + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Guid"; + Printer << ": " << GlobalScope->getGuid(); + + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Age"; + Printer << ": " << GlobalScope->getAge(); + + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::Identifier).get() << "Attributes"; + Printer << ": "; + if (GlobalScope->hasCTypes()) + outs() << "HasCTypes "; + if (GlobalScope->hasPrivateSymbols()) + outs() << "HasPrivateSymbols "; + Printer.Unindent(); + + if (opts::Compilands) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() + << "---COMPILANDS---"; + Printer.Indent(); + auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>(); + CompilandDumper Dumper(Printer); + while (auto Compiland = Compilands->getNext()) + Dumper.start(*Compiland, false); + Printer.Unindent(); + } + + if (opts::Types) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---"; + Printer.Indent(); + TypeDumper Dumper(Printer); + Dumper.start(*GlobalScope); + Printer.Unindent(); + } + + if (opts::Symbols) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---SYMBOLS---"; + Printer.Indent(); + auto Compilands = GlobalScope->findAllChildren<PDBSymbolCompiland>(); + CompilandDumper Dumper(Printer); + while (auto Compiland = Compilands->getNext()) + Dumper.start(*Compiland, true); + Printer.Unindent(); + } + + if (opts::Globals) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---GLOBALS---"; + Printer.Indent(); + { + FunctionDumper Dumper(Printer); + auto Functions = GlobalScope->findAllChildren<PDBSymbolFunc>(); + while (auto Function = Functions->getNext()) { + Printer.NewLine(); + Dumper.start(*Function, FunctionDumper::PointerType::None); + } + } + { + auto Vars = GlobalScope->findAllChildren<PDBSymbolData>(); + VariableDumper Dumper(Printer); + while (auto Var = Vars->getNext()) + Dumper.start(*Var); + } + { + auto Thunks = GlobalScope->findAllChildren<PDBSymbolThunk>(); + CompilandDumper Dumper(Printer); + while (auto Thunk = Thunks->getNext()) + Dumper.dump(*Thunk); + } + Printer.Unindent(); + } + if (opts::Externals) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---EXTERNALS---"; + Printer.Indent(); + ExternalSymbolDumper Dumper(Printer); + Dumper.start(*GlobalScope); + } + outs().flush(); +} + +int main(int argc_, const char *argv_[]) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc_, argv_); + + SmallVector<const char *, 256> argv; + llvm::SpecificBumpPtrAllocator<char> ArgAllocator; + std::error_code EC = llvm::sys::Process::GetArgumentVector( + argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator); + if (EC) { + llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n'; + return 1; + } + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n"); + if (opts::All) { + opts::Compilands = true; + opts::Symbols = true; + opts::Globals = true; + opts::Types = true; + opts::Externals = true; + } + if (opts::ExcludeCompilerGenerated) { + opts::ExcludeTypes.push_back("__vc_attributes"); + opts::ExcludeCompilands.push_back("* Linker *"); + } + if (opts::ExcludeSystemLibraries) { + opts::ExcludeCompilands.push_back( + "f:\\binaries\\Intermediate\\vctools\\crt_bld"); + } + +#if defined(HAVE_DIA_SDK) + CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + + std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), + dumpInput); + +#if defined(HAVE_DIA_SDK) + CoUninitialize(); +#endif + + return 0; +} diff --git a/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.h new file mode 100644 index 0000000..586a9ea --- /dev/null +++ b/contrib/llvm/tools/llvm-pdbdump/llvm-pdbdump.h @@ -0,0 +1,32 @@ +//===- llvm-pdbdump.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_LLVMPDBDUMP_H +#define LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" + +namespace opts { +extern llvm::cl::opt<bool> Compilands; +extern llvm::cl::opt<bool> Symbols; +extern llvm::cl::opt<bool> Globals; +extern llvm::cl::opt<bool> Types; +extern llvm::cl::opt<bool> All; + +extern llvm::cl::opt<bool> ExcludeCompilerGenerated; + +extern llvm::cl::opt<bool> NoClassDefs; +extern llvm::cl::opt<bool> NoEnumDefs; +extern llvm::cl::list<std::string> ExcludeTypes; +extern llvm::cl::list<std::string> ExcludeSymbols; +extern llvm::cl::list<std::string> ExcludeCompilands; +} + +#endif
\ No newline at end of file |