blob: 61cef093d4ce31c3154b4fe1e62577aa504c1e2f [file] [log] [blame]
Zachary Turnerc883a8c2017-04-12 23:18:21 +00001//===- UDTLayout.cpp --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/DebugInfo/PDB/UDTLayout.h"
11
Zachary Turner4dc4f012017-04-13 21:11:00 +000012#include "llvm/ADT/STLExtras.h"
Zachary Turnerc883a8c2017-04-12 23:18:21 +000013#include "llvm/DebugInfo/PDB/IPDBSession.h"
14#include "llvm/DebugInfo/PDB/PDBSymbol.h"
15#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
16#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
17#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
18#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
19#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
20#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
21#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
22
23#include <utility>
24
25using namespace llvm;
26using namespace llvm::pdb;
27
28static std::unique_ptr<PDBSymbol> getSymbolType(const PDBSymbol &Symbol) {
29 const IPDBSession &Session = Symbol.getSession();
30 const IPDBRawSymbol &RawSymbol = Symbol.getRawSymbol();
31 uint32_t TypeId = RawSymbol.getTypeId();
32 return Session.getSymbolById(TypeId);
33}
34
35static uint32_t getTypeLength(const PDBSymbol &Symbol) {
36 auto SymbolType = getSymbolType(Symbol);
37 const IPDBRawSymbol &RawType = SymbolType->getRawSymbol();
38
39 return RawType.getLength();
40}
41
42StorageItemBase::StorageItemBase(const UDTLayoutBase &Parent,
43 const PDBSymbol &Symbol,
44 const std::string &Name,
45 uint32_t OffsetInParent, uint32_t Size)
Zachary Turner75999df2017-04-12 23:27:43 +000046 : Parent(Parent), Symbol(Symbol), Name(Name),
47 OffsetInParent(OffsetInParent), SizeOf(Size) {
Zachary Turnerc883a8c2017-04-12 23:18:21 +000048 UsedBytes.resize(SizeOf, true);
49}
50
51uint32_t StorageItemBase::deepPaddingSize() const {
52 // sizeof(Field) - sizeof(typeof(Field)) is trailing padding.
53 return SizeOf - getTypeLength(Symbol);
54}
55
56DataMemberLayoutItem::DataMemberLayoutItem(
57 const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> DataMember)
58 : StorageItemBase(Parent, *DataMember, DataMember->getName(),
59 DataMember->getOffset(), getTypeLength(*DataMember)),
60 DataMember(std::move(DataMember)) {
61 auto Type = this->DataMember->getType();
62 if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
63 // UDT data members might have padding in between fields, but otherwise
64 // a member should occupy its entire storage.
65 UsedBytes.resize(SizeOf, false);
66 UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT));
67 }
68}
69
70const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
71 return *dyn_cast<PDBSymbolData>(&Symbol);
72}
73
Zachary Turner4dc4f012017-04-13 21:11:00 +000074bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
75
76const ClassLayout &DataMemberLayoutItem::getUDTLayout() const {
77 return *UdtLayout;
78}
79
Zachary Turnerc883a8c2017-04-12 23:18:21 +000080uint32_t DataMemberLayoutItem::deepPaddingSize() const {
81 uint32_t Result = StorageItemBase::deepPaddingSize();
82 if (UdtLayout)
83 Result += UdtLayout->deepPaddingSize();
84 return Result;
85}
86
87VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
88 std::unique_ptr<PDBSymbolTypeVTable> VTable)
89 : StorageItemBase(Parent, *VTable, "<vtbl>", 0, getTypeLength(*VTable)),
90 VTable(std::move(VTable)) {
Zachary Turnerc883a8c2017-04-12 23:18:21 +000091 auto VTableType = cast<PDBSymbolTypePointer>(this->VTable->getType());
Zachary Turner4dc4f012017-04-13 21:11:00 +000092 ElementSize = VTableType->getLength();
Zachary Turnerc883a8c2017-04-12 23:18:21 +000093
Zachary Turner4dc4f012017-04-13 21:11:00 +000094 Shape =
95 unique_dyn_cast<PDBSymbolTypeVTableShape>(VTableType->getPointeeType());
96 if (Shape)
Zachary Turnerc883a8c2017-04-12 23:18:21 +000097 VTableFuncs.resize(Shape->getCount());
Zachary Turnerc883a8c2017-04-12 23:18:21 +000098}
99
100UDTLayoutBase::UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name,
101 uint32_t Size)
Zachary Turner9e7dda32017-04-12 23:18:51 +0000102 : SymbolBase(Symbol), Name(Name), SizeOf(Size) {
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000103 UsedBytes.resize(Size);
104 ChildrenPerByte.resize(Size);
105 initializeChildren(Symbol);
106}
107
Zachary Turner9e7dda32017-04-12 23:18:51 +0000108ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
109 : UDTLayoutBase(UDT, UDT.getName(), UDT.getLength()), UDT(UDT) {}
110
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000111ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
Zachary Turner9e7dda32017-04-12 23:18:51 +0000112 : ClassLayout(*UDT) {
113 OwnedStorage = std::move(UDT);
114}
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000115
116BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
117 std::unique_ptr<PDBSymbolTypeBaseClass> Base)
118 : UDTLayoutBase(*Base, Base->getName(), Base->getLength()),
119 StorageItemBase(Parent, *Base, Base->getName(), Base->getOffset(),
120 Base->getLength()),
121 Base(std::move(Base)) {
122 IsVirtualBase = this->Base->isVirtualBaseClass();
123}
124
125uint32_t UDTLayoutBase::shallowPaddingSize() const {
126 return UsedBytes.size() - UsedBytes.count();
127}
128
129uint32_t UDTLayoutBase::deepPaddingSize() const {
130 uint32_t Result = shallowPaddingSize();
131 for (auto &Child : ChildStorage)
132 Result += Child->deepPaddingSize();
133 return Result;
134}
135
136void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
Zachary Turner4dc4f012017-04-13 21:11:00 +0000137 // Handled bases first, followed by VTables, followed by data members,
138 // followed by functions, followed by other. This ordering is necessary
139 // so that bases and vtables get initialized before any functions which
140 // may override them.
141
142 UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
143 UniquePtrVector<PDBSymbolTypeVTable> VTables;
144 UniquePtrVector<PDBSymbolData> Members;
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000145 auto Children = Sym.findAllChildren();
146 while (auto Child = Children->getNext()) {
Zachary Turner4dc4f012017-04-13 21:11:00 +0000147 if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
148 if (Base->isVirtualBaseClass())
149 VirtualBases.push_back(std::move(Base));
150 else
151 Bases.push_back(std::move(Base));
152 }
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000153
Zachary Turner4dc4f012017-04-13 21:11:00 +0000154 else if (auto Data = unique_dyn_cast<PDBSymbolData>(Child)) {
155 if (Data->getDataKind() == PDB_DataKind::Member)
156 Members.push_back(std::move(Data));
157 else
158 Other.push_back(std::move(Child));
159 } else if (auto VT = unique_dyn_cast<PDBSymbolTypeVTable>(Child))
160 VTables.push_back(std::move(VT));
161 else if (auto Func = unique_dyn_cast<PDBSymbolFunc>(Child))
162 Funcs.push_back(std::move(Func));
163 else
164 Other.push_back(std::move(Child));
165 }
166
167 for (auto &Base : Bases) {
168 auto BL = llvm::make_unique<BaseClassLayout>(*this, std::move(Base));
169 BaseClasses.push_back(BL.get());
170
171 addChildToLayout(std::move(BL));
172 }
173
174 for (auto &VT : VTables) {
175 auto VTLayout = llvm::make_unique<VTableLayoutItem>(*this, std::move(VT));
176
177 VTable = VTLayout.get();
178
179 addChildToLayout(std::move(VTLayout));
180 continue;
181 }
182
183 for (auto &Data : Members) {
184 auto DM = llvm::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
185
186 addChildToLayout(std::move(DM));
187 }
188
189 for (auto &Func : Funcs) {
190 if (!Func->isVirtual())
191 continue;
192
193 if (Func->isIntroVirtualFunction())
194 addVirtualIntro(*Func);
195 else
196 addVirtualOverride(*Func);
197 }
198}
199
200void UDTLayoutBase::addVirtualIntro(PDBSymbolFunc &Func) {
201 // Kind of a hack, but we prefer the more common destructor name that people
202 // are familiar with, e.g. ~ClassName. It seems there are always both and
203 // the vector deleting destructor overwrites the nice destructor, so just
204 // ignore the vector deleting destructor.
205 if (Func.getName() == "__vecDelDtor")
206 return;
207
208 if (!VTable) {
209 // FIXME: Handle this. What's most likely happening is we have an intro
210 // virtual in a derived class where the base also has an intro virtual.
211 // In this case the vtable lives in the base. What we really need is
212 // for each UDTLayoutBase to contain a list of all its vtables, and
213 // then propagate this list up the hierarchy so that derived classes have
214 // direct access to their bases' vtables.
215 return;
216 }
217
218 uint32_t Stride = VTable->getElementSize();
219
220 uint32_t Index = Func.getVirtualBaseOffset();
221 assert(Index % Stride == 0);
222 Index /= Stride;
223
224 VTable->setFunction(Index, Func);
225}
226
227VTableLayoutItem *UDTLayoutBase::findVTableAtOffset(uint32_t RelativeOffset) {
228 if (VTable && VTable->getOffsetInParent() == RelativeOffset)
229 return VTable;
230 for (auto Base : BaseClasses) {
231 uint32_t Begin = Base->getOffsetInParent();
232 uint32_t End = Begin + Base->getSize();
233 if (RelativeOffset < Begin || RelativeOffset >= End)
234 continue;
235
236 return Base->findVTableAtOffset(RelativeOffset - Begin);
237 }
238
239 return nullptr;
240}
241
242void UDTLayoutBase::addVirtualOverride(PDBSymbolFunc &Func) {
243 auto Signature = Func.getSignature();
244 auto ThisAdjust = Signature->getThisAdjust();
245 // ThisAdjust tells us which VTable we're looking for. Specifically, it's
246 // the offset into the current class of the VTable we're looking for. So
247 // look through the base hierarchy until we find one such that
248 // AbsoluteOffset(VT) == ThisAdjust
249 VTableLayoutItem *VT = findVTableAtOffset(ThisAdjust);
250 if (!VT) {
251 // FIXME: There really should be a vtable here. If there's not it probably
252 // means that the vtable is in a virtual base, which we don't yet support.
253 assert(!VirtualBases.empty());
254 return;
255 }
256 int32_t OverrideIndex = -1;
257 // Now we've found the VTable. Func will not have a virtual base offset set,
258 // so instead we need to compare names and signatures. We iterate each item
259 // in the VTable. All items should already have non null entries because they
260 // were initialized by the intro virtual, which was guaranteed to come before.
261 for (auto ItemAndIndex : enumerate(VT->funcs())) {
262 auto Item = ItemAndIndex.value();
263 assert(Item);
264 // If the name doesn't match, this isn't an override. Note that it's ok
265 // for the return type to not match (e.g. co-variant return).
266 if (Item->getName() != Func.getName()) {
267 if (Item->isDestructor() && Func.isDestructor()) {
268 OverrideIndex = ItemAndIndex.index();
269 break;
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000270 }
271 continue;
272 }
Zachary Turner4dc4f012017-04-13 21:11:00 +0000273 // Now make sure it's the right overload. Get the signature of the existing
274 // vtable method and make sure it has the same arglist and the same cv-ness.
275 auto ExistingSig = Item->getSignature();
276 if (ExistingSig->isConstType() != Signature->isConstType())
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000277 continue;
Zachary Turner4dc4f012017-04-13 21:11:00 +0000278 if (ExistingSig->isVolatileType() != Signature->isVolatileType())
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000279 continue;
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000280
Zachary Turner4dc4f012017-04-13 21:11:00 +0000281 // Now compare arguments. Using the raw bytes of the PDB this would be
282 // trivial
283 // because there is an ArgListId and they should be identical. But DIA
284 // doesn't
285 // expose this, so the best we can do is iterate each argument and confirm
286 // that
287 // each one is identical.
288 if (ExistingSig->getCount() != Signature->getCount())
289 continue;
290 bool IsMatch = true;
291 auto ExistingEnumerator = ExistingSig->getArguments();
292 auto NewEnumerator = Signature->getArguments();
293 for (uint32_t I = 0; I < ExistingEnumerator->getChildCount(); ++I) {
294 auto ExistingArg = ExistingEnumerator->getNext();
295 auto NewArg = NewEnumerator->getNext();
296 if (ExistingArg->getSymIndexId() != NewArg->getSymIndexId()) {
297 IsMatch = false;
298 break;
299 }
300 }
301 if (!IsMatch)
302 continue;
303
304 // It's a match! Stick the new function into the VTable.
305 OverrideIndex = ItemAndIndex.index();
306 break;
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000307 }
Zachary Turner4dc4f012017-04-13 21:11:00 +0000308 if (OverrideIndex == -1) {
309 // FIXME: This is probably due to one of the other FIXMEs in this file.
310 return;
311 }
312 VT->setFunction(OverrideIndex, Func);
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000313}
314
315void UDTLayoutBase::addChildToLayout(std::unique_ptr<StorageItemBase> Child) {
316 uint32_t Begin = Child->getOffsetInParent();
317 uint32_t End = Begin + Child->getSize();
Zachary Turner4dc4f012017-04-13 21:11:00 +0000318 // Due to the empty base optimization, End might point outside the bounds of
319 // the parent class. If that happens, just clamp the value.
320 End = std::min(End, getClassSize());
321
Zachary Turnerc883a8c2017-04-12 23:18:21 +0000322 UsedBytes.set(Begin, End);
323 while (Begin != End) {
324 ChildrenPerByte[Begin].push_back(Child.get());
325 ++Begin;
326 }
327
328 auto Loc = std::upper_bound(
329 ChildStorage.begin(), ChildStorage.end(), Begin,
330 [](uint32_t Off, const std::unique_ptr<StorageItemBase> &Item) {
331 return Off < Item->getOffsetInParent();
332 });
333
334 ChildStorage.insert(Loc, std::move(Child));
335}