diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/PDBSymbol.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/UDTLayout.cpp | 194 |
9 files changed, 243 insertions, 9 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index 1295d2a19ce..f87a0b0a72e 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -101,6 +101,7 @@ add_llvm_library(LLVMDebugInfoPDB PDBSymbolUnknown.cpp PDBSymbolUsingNamespace.cpp PDBSymDumper.cpp + UDTLayout.cpp ${PDB_IMPL_SOURCES} ADDITIONAL_HEADER_DIRS diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp index 6182dab213c..5e8c0bdc171 100644 --- a/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp @@ -14,6 +14,9 @@ #include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h" #include "llvm/DebugInfo/PDB/DIA/DIASession.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/raw_ostream.h" @@ -717,6 +720,18 @@ uint32_t DIARawSymbol::getVirtualTableShapeId() const { return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualTableShapeId); } +std::unique_ptr<PDBSymbolTypeVTable> +DIARawSymbol::getVirtualBaseTableType() const { + CComPtr<IDiaSymbol> TableType; + if (FAILED(Symbol->get_virtualBaseTableType(&TableType)) || !TableType) + return nullptr; + + auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType); + auto Pointer = + llvm::make_unique<PDBSymbolTypePointer>(Session, std::move(RawVT)); + return unique_dyn_cast<PDBSymbolTypeVTable>(Pointer->getPointeeType()); +} + PDB_DataKind DIARawSymbol::getDataKind() const { return PrivateGetDIAValue<DWORD, PDB_DataKind>(Symbol, &IDiaSymbol::get_dataKind); diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp index 7077bda4a53..6ecf335812b 100644 --- a/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ b/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -140,7 +140,7 @@ void DIASession::setLoadAddress(uint64_t Address) { Session->put_loadAddress(Address); } -std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() { +std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const { CComPtr<IDiaSymbol> GlobalScope; if (S_OK != Session->get_globalScope(&GlobalScope)) return nullptr; diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp index 4841ded7410..3aba35adb53 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp @@ -13,6 +13,8 @@ #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/raw_ostream.h" @@ -318,6 +320,11 @@ uint32_t NativeRawSymbol::getVirtualTableShapeId() const { return 0; } +std::unique_ptr<PDBSymbolTypeVTable> +NativeRawSymbol::getVirtualBaseTableType() const { + return nullptr; +} + PDB_DataKind NativeRawSymbol::getDataKind() const { return PDB_DataKind::Unknown; } diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp index 3a83a326cfe..7e6843bceb7 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp @@ -70,8 +70,9 @@ uint64_t NativeSession::getLoadAddress() const { return 0; } void NativeSession::setLoadAddress(uint64_t Address) {} -std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() { - auto RawSymbol = llvm::make_unique<NativeExeSymbol>(*this); +std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() const { + auto RawSymbol = + llvm::make_unique<NativeExeSymbol>(const_cast<NativeSession &>(*this)); auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol))); std::unique_ptr<PDBSymbolExe> ExeSymbol( static_cast<PDBSymbolExe *>(PdbSymbol.release())); diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp index 2c8438f9c23..14eb6ba8ad8 100644 --- a/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp +++ b/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp @@ -54,6 +54,9 @@ PDBSymbol::PDBSymbol(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol) : Session(PDBSession), RawSymbol(std::move(Symbol)) {} +PDBSymbol::PDBSymbol(PDBSymbol &Symbol) + : Session(Symbol.Session), RawSymbol(std::move(Symbol.RawSymbol)) {} + PDBSymbol::~PDBSymbol() = default; #define FACTORY_SYMTAG_CASE(Tag, Type) \ @@ -100,12 +103,6 @@ PDBSymbol::create(const IPDBSession &PDBSession, } } -#define TRY_DUMP_TYPE(Type) \ - if (const Type *DerivedThis = this->cast<Type>()) \ - Dumper.dump(OS, Indent, *DerivedThis); - -#define ELSE_TRY_DUMP_TYPE(Type, Dumper) else TRY_DUMP_TYPE(Type, Dumper) - void PDBSymbol::defaultDump(raw_ostream &OS, int Indent) const { RawSymbol->dump(OS, Indent); } diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp index b9fcac78c36..7417167b61a 100644 --- a/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp +++ b/llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp @@ -10,6 +10,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymDumper.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" #include <utility> @@ -23,3 +24,13 @@ PDBSymbolExe::PDBSymbolExe(const IPDBSession &PDBSession, } void PDBSymbolExe::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } + +uint32_t PDBSymbolExe::getPointerByteSize() const { + auto Pointer = findOneChild<PDBSymbolTypePointer>(); + if (Pointer) + return Pointer->getLength(); + + if (getMachineType() == PDB_Machine::x86) + return 4; + return 8; +} diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp index 4a9a9ed5fda..15dc1535216 100644 --- a/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp +++ b/llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp @@ -9,7 +9,15 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDBSymDumper.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" +#include "llvm/DebugInfo/PDB/UDTLayout.h" #include <utility> diff --git a/llvm/lib/DebugInfo/PDB/UDTLayout.cpp b/llvm/lib/DebugInfo/PDB/UDTLayout.cpp new file mode 100644 index 00000000000..71443fe7587 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/UDTLayout.cpp @@ -0,0 +1,194 @@ +//===- UDTLayout.cpp --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/UDTLayout.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" + +#include <utility> + +using namespace llvm; +using namespace llvm::pdb; + +static std::unique_ptr<PDBSymbol> getSymbolType(const PDBSymbol &Symbol) { + const IPDBSession &Session = Symbol.getSession(); + const IPDBRawSymbol &RawSymbol = Symbol.getRawSymbol(); + uint32_t TypeId = RawSymbol.getTypeId(); + return Session.getSymbolById(TypeId); +} + +static uint32_t getTypeLength(const PDBSymbol &Symbol) { + auto SymbolType = getSymbolType(Symbol); + const IPDBRawSymbol &RawType = SymbolType->getRawSymbol(); + + return RawType.getLength(); +} + +StorageItemBase::StorageItemBase(const UDTLayoutBase &Parent, + const PDBSymbol &Symbol, + const std::string &Name, + uint32_t OffsetInParent, uint32_t Size) + : Parent(Parent), Symbol(Symbol), Name(Name), SizeOf(Size), + OffsetInParent(OffsetInParent) { + UsedBytes.resize(SizeOf, true); +} + +uint32_t StorageItemBase::deepPaddingSize() const { + // sizeof(Field) - sizeof(typeof(Field)) is trailing padding. + return SizeOf - getTypeLength(Symbol); +} + +DataMemberLayoutItem::DataMemberLayoutItem( + const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> DataMember) + : StorageItemBase(Parent, *DataMember, DataMember->getName(), + DataMember->getOffset(), getTypeLength(*DataMember)), + DataMember(std::move(DataMember)) { + auto Type = this->DataMember->getType(); + if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) { + // UDT data members might have padding in between fields, but otherwise + // a member should occupy its entire storage. + UsedBytes.resize(SizeOf, false); + UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT)); + } +} + +const PDBSymbolData &DataMemberLayoutItem::getDataMember() { + return *dyn_cast<PDBSymbolData>(&Symbol); +} + +uint32_t DataMemberLayoutItem::deepPaddingSize() const { + uint32_t Result = StorageItemBase::deepPaddingSize(); + if (UdtLayout) + Result += UdtLayout->deepPaddingSize(); + return Result; +} + +VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent, + std::unique_ptr<PDBSymbolTypeVTable> VTable) + : StorageItemBase(Parent, *VTable, "<vtbl>", 0, getTypeLength(*VTable)), + VTable(std::move(VTable)) { + // initialize vtbl methods. + auto VTableType = cast<PDBSymbolTypePointer>(this->VTable->getType()); + uint32_t PointerSize = VTableType->getLength(); + + if (auto Shape = unique_dyn_cast<PDBSymbolTypeVTableShape>( + VTableType->getPointeeType())) { + VTableFuncs.resize(Shape->getCount()); + + auto ParentFunctions = Parent.getSymbol().findAllChildren<PDBSymbolFunc>(); + while (auto Func = ParentFunctions->getNext()) { + if (Func->isVirtual()) { + uint32_t Index = Func->getVirtualBaseOffset(); + assert(Index % PointerSize == 0); + Index /= PointerSize; + + // Don't allow a compiler generated function to overwrite a user + // function in the VTable. Not sure why this happens, but a function + // named __vecDelDtor sometimes shows up on top of the destructor. + if (Func->isCompilerGenerated() && VTableFuncs[Index]) + continue; + VTableFuncs[Index] = std::move(Func); + } + } + } +} + +UDTLayoutBase::UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name, + uint32_t Size) + : Symbol(Symbol), Name(Name), SizeOf(Size) { + UsedBytes.resize(Size); + ChildrenPerByte.resize(Size); + initializeChildren(Symbol); +} + +ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT) + : UDTLayoutBase(*UDT, UDT->getName(), UDT->getLength()), + Type(std::move(UDT)) {} + +BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent, + std::unique_ptr<PDBSymbolTypeBaseClass> Base) + : UDTLayoutBase(*Base, Base->getName(), Base->getLength()), + StorageItemBase(Parent, *Base, Base->getName(), Base->getOffset(), + Base->getLength()), + Base(std::move(Base)) { + IsVirtualBase = this->Base->isVirtualBaseClass(); +} + +uint32_t UDTLayoutBase::shallowPaddingSize() const { + return UsedBytes.size() - UsedBytes.count(); +} + +uint32_t UDTLayoutBase::deepPaddingSize() const { + uint32_t Result = shallowPaddingSize(); + for (auto &Child : ChildStorage) + Result += Child->deepPaddingSize(); + return Result; +} + +void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) { + auto Children = Sym.findAllChildren(); + while (auto Child = Children->getNext()) { + if (auto Data = unique_dyn_cast<PDBSymbolData>(Child)) { + if (Data->getDataKind() == PDB_DataKind::Member) { + auto DM = + llvm::make_unique<DataMemberLayoutItem>(*this, std::move(Data)); + + addChildToLayout(std::move(DM)); + } else { + NonStorageItems.push_back(std::move(Data)); + } + continue; + } + + if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) { + auto BL = llvm::make_unique<BaseClassLayout>(*this, std::move(Base)); + BaseClasses.push_back(BL.get()); + + addChildToLayout(std::move(BL)); + continue; + } + + if (auto VT = unique_dyn_cast<PDBSymbolTypeVTable>(Child)) { + auto VTLayout = llvm::make_unique<VTableLayoutItem>(*this, std::move(VT)); + + VTable = VTLayout.get(); + + addChildToLayout(std::move(VTLayout)); + continue; + } + + NonStorageItems.push_back(std::move(Child)); + } +} + +void UDTLayoutBase::addChildToLayout(std::unique_ptr<StorageItemBase> Child) { + uint32_t Begin = Child->getOffsetInParent(); + uint32_t End = Begin + Child->getSize(); + UsedBytes.set(Begin, End); + while (Begin != End) { + ChildrenPerByte[Begin].push_back(Child.get()); + ++Begin; + } + + auto Loc = std::upper_bound( + ChildStorage.begin(), ChildStorage.end(), Begin, + [](uint32_t Off, const std::unique_ptr<StorageItemBase> &Item) { + return Off < Item->getOffsetInParent(); + }); + + ChildStorage.insert(Loc, std::move(Child)); +}
\ No newline at end of file |