From a93560b336fa62579d438e61f461942aaf2e576f Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Mon, 1 Oct 2018 17:55:16 +0000 Subject: [PATCH] [PDB] Add support for parsing VFTable Shape records. This allows them to be returned from the native API. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343506 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h | 46 ++++++++++++++++++++++ lib/DebugInfo/PDB/CMakeLists.txt | 1 + lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp | 2 + lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp | 3 +- lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp | 35 ++++++++++++++++ lib/DebugInfo/PDB/Native/SymbolCache.cpp | 14 ++++++- tools/llvm-pdbutil/PrettyFunctionDumper.cpp | 12 ++++-- tools/llvm-pdbutil/PrettyTypeDumper.cpp | 16 +++++++- tools/llvm-pdbutil/PrettyTypeDumper.h | 2 + tools/llvm-pdbutil/llvm-pdbutil.cpp | 9 ++++- tools/llvm-pdbutil/llvm-pdbutil.h | 1 + 11 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h create mode 100644 lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp diff --git a/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h b/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h new file mode 100644 index 00000000000..afa1937d127 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h @@ -0,0 +1,46 @@ +//===- NativeTypeVTShape.h - info about virtual table shape ------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeTypeVTShape : public NativeRawSymbol { +public: + // Create a pointer record for a non-simple type. + NativeTypeVTShape(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, codeview::VFTableShapeRecord SR); + + ~NativeTypeVTShape() override; + + void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const override; + + bool isConstType() const override; + bool isVolatileType() const override; + bool isUnalignedType() const override; + uint32_t getCount() const override; + +protected: + codeview::TypeIndex TI; + codeview::VFTableShapeRecord Record; +}; + +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H \ No newline at end of file diff --git a/lib/DebugInfo/PDB/CMakeLists.txt b/lib/DebugInfo/PDB/CMakeLists.txt index ae79c9ef498..77c09ae2184 100644 --- a/lib/DebugInfo/PDB/CMakeLists.txt +++ b/lib/DebugInfo/PDB/CMakeLists.txt @@ -58,6 +58,7 @@ add_pdb_impl_folder(Native Native/NativeTypeFunctionSig.cpp Native/NativeTypePointer.cpp Native/NativeTypeUDT.cpp + Native/NativeTypeVTShape.cpp Native/NamedStreamMap.cpp Native/NativeSession.cpp Native/PDBFile.cpp diff --git a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp index 14a0fb4c93a..e86f836ee14 100644 --- a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp +++ b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp @@ -51,6 +51,8 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const { return Session.getSymbolCache().createTypeEnumerator( {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION, codeview::LF_INTERFACE}); + case PDB_SymType::VTableShape: + return Session.getSymbolCache().createTypeEnumerator(codeview::LF_VTSHAPE); case PDB_SymType::FunctionSig: return Session.getSymbolCache().createTypeEnumerator( {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION}); diff --git a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp index a72c8d204c6..a9590fffdb8 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp @@ -162,7 +162,8 @@ SymIndexId NativeTypeFunctionSig::getTypeId() const { TypeIndex ReturnTI = IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType(); - return Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI); + SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI); + return Result; } int32_t NativeTypeFunctionSig::getThisAdjust() const { diff --git a/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp b/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp new file mode 100644 index 00000000000..837fe19ec88 --- /dev/null +++ b/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp @@ -0,0 +1,35 @@ +#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h" + +using namespace llvm; +using namespace llvm::pdb; + +// Create a pointer record for a non-simple type. +NativeTypeVTShape::NativeTypeVTShape(NativeSession &Session, SymIndexId Id, + codeview::TypeIndex TI, + codeview::VFTableShapeRecord SR) + : NativeRawSymbol(Session, PDB_SymType::VTableShape, Id), TI(TI), + Record(std::move(SR)) {} + +NativeTypeVTShape::~NativeTypeVTShape() {} + +void NativeTypeVTShape::dump(raw_ostream &OS, int Indent, + PdbSymbolIdField ShowIdFields, + PdbSymbolIdField RecurseIdFields) const { + NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields); + + dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session, + PdbSymbolIdField::LexicalParent, ShowIdFields, + RecurseIdFields); + dumpSymbolField(OS, "count", getCount(), Indent); + dumpSymbolField(OS, "constType", isConstType(), Indent); + dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent); + dumpSymbolField(OS, "volatileType", isVolatileType(), Indent); +} + +bool NativeTypeVTShape::isConstType() const { return false; } + +bool NativeTypeVTShape::isVolatileType() const { return false; } + +bool NativeTypeVTShape::isUnalignedType() const { return false; } + +uint32_t NativeTypeVTShape::getCount() const { return Record.Slots.size(); } diff --git a/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/lib/DebugInfo/PDB/Native/SymbolCache.cpp index 40b352a844c..eb254493131 100644 --- a/lib/DebugInfo/PDB/Native/SymbolCache.cpp +++ b/lib/DebugInfo/PDB/Native/SymbolCache.cpp @@ -13,6 +13,7 @@ #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h" +#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" @@ -32,6 +33,7 @@ static const struct BuiltinTypeEntry { } BuiltinTypes[] = { {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0}, {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0}, + {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4}, {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2}, {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2}, {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4}, @@ -41,9 +43,15 @@ static const struct BuiltinTypeEntry { {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8}, {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8}, {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1}, + {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2}, + {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2}, + {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4}, {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1}, {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1}, - {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1} + {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4}, + {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8}, + {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10}, + {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}, // This table can be grown as necessary, but these are the only types we've // needed so far. }; @@ -196,6 +204,10 @@ SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) { Id = createSymbolForType( Index, std::move(CVT)); break; + case codeview::LF_VTSHAPE: + Id = createSymbolForType( + Index, std::move(CVT)); + break; default: Id = createSymbolPlaceholder(); break; diff --git a/tools/llvm-pdbutil/PrettyFunctionDumper.cpp b/tools/llvm-pdbutil/PrettyFunctionDumper.cpp index 177d8a009a2..836ede41054 100644 --- a/tools/llvm-pdbutil/PrettyFunctionDumper.cpp +++ b/tools/llvm-pdbutil/PrettyFunctionDumper.cpp @@ -53,7 +53,10 @@ FunctionDumper::FunctionDumper(LinePrinter &P) void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol, const char *Name, PointerType Pointer) { auto ReturnType = Symbol.getReturnType(); - ReturnType->dump(*this); + if (!ReturnType) + Printer << ""; + else + ReturnType->dump(*this); Printer << " "; uint32_t ClassParentId = Symbol.getClassParentId(); auto ClassParent = @@ -225,9 +228,10 @@ void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) { // 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); + if (Type) + Printer << ""; + else + Type->dump(*this); } void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) { diff --git a/tools/llvm-pdbutil/PrettyTypeDumper.cpp b/tools/llvm-pdbutil/PrettyTypeDumper.cpp index 6f924521a75..daf3cd45b32 100644 --- a/tools/llvm-pdbutil/PrettyTypeDumper.cpp +++ b/tools/llvm-pdbutil/PrettyTypeDumper.cpp @@ -208,6 +208,10 @@ void TypeDumper::start(const PDBSymbolExe &Exe) { if (opts::pretty::Pointers) dumpSymbolCategory(Printer, Exe, *this, "Pointers"); + if (opts::pretty::VTShapes) + dumpSymbolCategory(Printer, Exe, *this, + "VFTable Shapes"); + if (opts::pretty::Classes) { if (auto Classes = Exe.findAllChildren()) { uint32_t All = Classes->getChildCount(); @@ -281,6 +285,10 @@ void TypeDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { BD.start(Symbol); } +void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) { + printClassDecl(Printer, Symbol); +} + void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) { assert(opts::pretty::Typedefs); @@ -305,7 +313,7 @@ void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) { void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) { std::unique_ptr P = Symbol.getPointeeType(); - if (auto *FS = dyn_cast_or_null(P.get())) { + if (auto *FS = dyn_cast(P.get())) { FunctionDumper Dumper(Printer); FunctionDumper::PointerType PT = Symbol.isReference() ? FunctionDumper::PointerType::Reference @@ -314,7 +322,7 @@ void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) { return; } - if (auto *UDT = dyn_cast_or_null(P.get())) { + if (auto *UDT = dyn_cast(P.get())) { printClassDecl(Printer, *UDT); } else if (P) { P->dump(*this); @@ -334,6 +342,10 @@ void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) { Printer << "*"; } +void TypeDumper::dump(const PDBSymbolTypeVTableShape &Symbol) { + Printer.format("", Symbol.getCount()); +} + void TypeDumper::dumpClassLayout(const ClassLayout &Class) { assert(opts::pretty::Classes); diff --git a/tools/llvm-pdbutil/PrettyTypeDumper.h b/tools/llvm-pdbutil/PrettyTypeDumper.h index e63ebe03055..36e586fea7e 100644 --- a/tools/llvm-pdbutil/PrettyTypeDumper.h +++ b/tools/llvm-pdbutil/PrettyTypeDumper.h @@ -29,6 +29,8 @@ public: void dump(const PDBSymbolTypeArray &Symbol) override; void dump(const PDBSymbolTypeBuiltin &Symbol) override; void dump(const PDBSymbolTypePointer &Symbol) override; + void dump(const PDBSymbolTypeVTableShape &Symbol) override; + void dump(const PDBSymbolTypeUDT &Symbol) override; void dumpClassLayout(const ClassLayout &Class); diff --git a/tools/llvm-pdbutil/llvm-pdbutil.cpp b/tools/llvm-pdbutil/llvm-pdbutil.cpp index f71ff9ff1af..49bcc55f279 100644 --- a/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -195,6 +195,8 @@ static cl::opt Funcsigs("funcsigs", cl::sub(DiaDumpSubcommand)); static cl::opt Arrays("arrays", cl::desc("Dump array types"), cl::sub(DiaDumpSubcommand)); +static cl::opt VTShapes("vtshapes", cl::desc("Dump virtual table shapes"), + cl::sub(DiaDumpSubcommand)); } // namespace diadump namespace pretty { @@ -249,6 +251,8 @@ cl::opt Pointers("pointers", cl::desc("Display pointer types"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Arrays("arrays", cl::desc("Display arrays"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); +cl::opt VTShapes("vtshapes", cl::desc("Display vftable shapes"), + cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt SymbolOrder( "symbol-order", cl::desc("symbol sort order"), @@ -1021,8 +1025,11 @@ static void dumpDia(StringRef Path) { SymTypes.push_back(PDB_SymType::FunctionSig); if (opts::diadump::Arrays) SymTypes.push_back(PDB_SymType::ArrayType); + if (opts::diadump::VTShapes) + SymTypes.push_back(PDB_SymType::VTableShape); PdbSymbolIdField Ids = opts::diadump::NoSymIndexIds ? PdbSymbolIdField::None : PdbSymbolIdField::All; + PdbSymbolIdField Recurse = PdbSymbolIdField::None; if (opts::diadump::Recurse) Recurse = PdbSymbolIdField::All; @@ -1188,7 +1195,7 @@ static void dumpPretty(StringRef Path) { if (opts::pretty::Classes || opts::pretty::Enums || opts::pretty::Typedefs || opts::pretty::Funcsigs || opts::pretty::Pointers || - opts::pretty::Arrays) { + opts::pretty::Arrays || opts::pretty::VTShapes) { Printer.NewLine(); WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---"; Printer.Indent(); diff --git a/tools/llvm-pdbutil/llvm-pdbutil.h b/tools/llvm-pdbutil/llvm-pdbutil.h index cbccac29599..36c20b74397 100644 --- a/tools/llvm-pdbutil/llvm-pdbutil.h +++ b/tools/llvm-pdbutil/llvm-pdbutil.h @@ -86,6 +86,7 @@ extern llvm::cl::opt Funcsigs; extern llvm::cl::opt Arrays; extern llvm::cl::opt Typedefs; extern llvm::cl::opt Pointers; +extern llvm::cl::opt VTShapes; extern llvm::cl::opt All; extern llvm::cl::opt ExcludeCompilerGenerated; -- 2.11.0