summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp15
-rw-r--r--llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbol.cpp9
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolExe.cpp11
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/UDTLayout.cpp194
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
OpenPOWER on IntegriCloud