UDTLayout.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. //===- UDTLayout.cpp ------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/PDB/UDTLayout.h"
  9. #include "llvm/ADT/ArrayRef.h"
  10. #include "llvm/ADT/BitVector.h"
  11. #include "llvm/ADT/STLExtras.h"
  12. #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
  13. #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/PDBSymbolFunc.h"
  17. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
  18. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
  19. #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
  20. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  21. #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
  22. #include "llvm/DebugInfo/PDB/PDBTypes.h"
  23. #include "llvm/Support/Casting.h"
  24. #include <algorithm>
  25. #include <cassert>
  26. #include <cstdint>
  27. #include <memory>
  28. using namespace llvm;
  29. using namespace llvm::pdb;
  30. static std::unique_ptr<PDBSymbol> getSymbolType(const PDBSymbol &Symbol) {
  31. const IPDBSession &Session = Symbol.getSession();
  32. const IPDBRawSymbol &RawSymbol = Symbol.getRawSymbol();
  33. uint32_t TypeId = RawSymbol.getTypeId();
  34. return Session.getSymbolById(TypeId);
  35. }
  36. static uint32_t getTypeLength(const PDBSymbol &Symbol) {
  37. auto SymbolType = getSymbolType(Symbol);
  38. const IPDBRawSymbol &RawType = SymbolType->getRawSymbol();
  39. return RawType.getLength();
  40. }
  41. LayoutItemBase::LayoutItemBase(const UDTLayoutBase *Parent,
  42. const PDBSymbol *Symbol, const std::string &Name,
  43. uint32_t OffsetInParent, uint32_t Size,
  44. bool IsElided)
  45. : Symbol(Symbol), Parent(Parent), Name(Name),
  46. OffsetInParent(OffsetInParent), SizeOf(Size), LayoutSize(Size),
  47. IsElided(IsElided) {
  48. UsedBytes.resize(SizeOf, true);
  49. }
  50. uint32_t LayoutItemBase::deepPaddingSize() const {
  51. return UsedBytes.size() - UsedBytes.count();
  52. }
  53. uint32_t LayoutItemBase::tailPadding() const {
  54. int Last = UsedBytes.find_last();
  55. return UsedBytes.size() - (Last + 1);
  56. }
  57. DataMemberLayoutItem::DataMemberLayoutItem(
  58. const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
  59. : LayoutItemBase(&Parent, Member.get(), Member->getName(),
  60. Member->getOffset(), getTypeLength(*Member), false),
  61. DataMember(std::move(Member)) {
  62. auto Type = DataMember->getType();
  63. if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
  64. UdtLayout = std::make_unique<ClassLayout>(std::move(UDT));
  65. UsedBytes = UdtLayout->usedBytes();
  66. }
  67. }
  68. VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
  69. std::unique_ptr<PDBSymbolTypeBuiltin> Sym,
  70. uint32_t Offset, uint32_t Size)
  71. : LayoutItemBase(&Parent, Sym.get(), "<vbptr>", Offset, Size, false),
  72. Type(std::move(Sym)) {
  73. }
  74. const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
  75. return *cast<PDBSymbolData>(Symbol);
  76. }
  77. bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
  78. const ClassLayout &DataMemberLayoutItem::getUDTLayout() const {
  79. return *UdtLayout;
  80. }
  81. VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
  82. std::unique_ptr<PDBSymbolTypeVTable> VT)
  83. : LayoutItemBase(&Parent, VT.get(), "<vtbl>", 0, getTypeLength(*VT), false),
  84. VTable(std::move(VT)) {
  85. auto VTableType = cast<PDBSymbolTypePointer>(VTable->getType());
  86. ElementSize = VTableType->getLength();
  87. }
  88. UDTLayoutBase::UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
  89. const std::string &Name, uint32_t OffsetInParent,
  90. uint32_t Size, bool IsElided)
  91. : LayoutItemBase(Parent, &Sym, Name, OffsetInParent, Size, IsElided) {
  92. // UDT storage comes from a union of all the children's storage, so start out
  93. // uninitialized.
  94. UsedBytes.reset(0, Size);
  95. initializeChildren(Sym);
  96. if (LayoutSize < Size)
  97. UsedBytes.resize(LayoutSize);
  98. }
  99. uint32_t UDTLayoutBase::tailPadding() const {
  100. uint32_t Abs = LayoutItemBase::tailPadding();
  101. if (!LayoutItems.empty()) {
  102. const LayoutItemBase *Back = LayoutItems.back();
  103. uint32_t ChildPadding = Back->LayoutItemBase::tailPadding();
  104. if (Abs < ChildPadding)
  105. Abs = 0;
  106. else
  107. Abs -= ChildPadding;
  108. }
  109. return Abs;
  110. }
  111. ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
  112. : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
  113. UDT(UDT) {
  114. ImmediateUsedBytes.resize(SizeOf, false);
  115. for (auto &LI : LayoutItems) {
  116. uint32_t Begin = LI->getOffsetInParent();
  117. uint32_t End = Begin + LI->getLayoutSize();
  118. End = std::min(SizeOf, End);
  119. ImmediateUsedBytes.set(Begin, End);
  120. }
  121. }
  122. ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
  123. : ClassLayout(*UDT) {
  124. OwnedStorage = std::move(UDT);
  125. }
  126. uint32_t ClassLayout::immediatePadding() const {
  127. return SizeOf - ImmediateUsedBytes.count();
  128. }
  129. BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
  130. uint32_t OffsetInParent, bool Elide,
  131. std::unique_ptr<PDBSymbolTypeBaseClass> B)
  132. : UDTLayoutBase(&Parent, *B, B->getName(), OffsetInParent, B->getLength(),
  133. Elide),
  134. Base(std::move(B)) {
  135. if (isEmptyBase()) {
  136. // Special case an empty base so that it doesn't get treated as padding.
  137. UsedBytes.resize(1);
  138. UsedBytes.set(0);
  139. }
  140. IsVirtualBase = Base->isVirtualBaseClass();
  141. }
  142. void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
  143. // Handled bases first, followed by VTables, followed by data members,
  144. // followed by functions, followed by other. This ordering is necessary
  145. // so that bases and vtables get initialized before any functions which
  146. // may override them.
  147. UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
  148. UniquePtrVector<PDBSymbolTypeVTable> VTables;
  149. UniquePtrVector<PDBSymbolData> Members;
  150. UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBaseSyms;
  151. auto Children = Sym.findAllChildren();
  152. while (auto Child = Children->getNext()) {
  153. if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
  154. if (Base->isVirtualBaseClass())
  155. VirtualBaseSyms.push_back(std::move(Base));
  156. else
  157. Bases.push_back(std::move(Base));
  158. }
  159. else if (auto Data = unique_dyn_cast<PDBSymbolData>(Child)) {
  160. if (Data->getDataKind() == PDB_DataKind::Member)
  161. Members.push_back(std::move(Data));
  162. else
  163. Other.push_back(std::move(Data));
  164. } else if (auto VT = unique_dyn_cast<PDBSymbolTypeVTable>(Child))
  165. VTables.push_back(std::move(VT));
  166. else if (auto Func = unique_dyn_cast<PDBSymbolFunc>(Child))
  167. Funcs.push_back(std::move(Func));
  168. else {
  169. Other.push_back(std::move(Child));
  170. }
  171. }
  172. // We don't want to have any re-allocations in the list of bases, so make
  173. // sure to reserve enough space so that our ArrayRefs don't get invalidated.
  174. AllBases.reserve(Bases.size() + VirtualBaseSyms.size());
  175. // Only add non-virtual bases to the class first. Only at the end of the
  176. // class, after all non-virtual bases and data members have been added do we
  177. // add virtual bases. This way the offsets are correctly aligned when we go
  178. // to lay out virtual bases.
  179. for (auto &Base : Bases) {
  180. uint32_t Offset = Base->getOffset();
  181. // Non-virtual bases never get elided.
  182. auto BL = std::make_unique<BaseClassLayout>(*this, Offset, false,
  183. std::move(Base));
  184. AllBases.push_back(BL.get());
  185. addChildToLayout(std::move(BL));
  186. }
  187. NonVirtualBases = AllBases;
  188. assert(VTables.size() <= 1);
  189. if (!VTables.empty()) {
  190. auto VTLayout =
  191. std::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
  192. VTable = VTLayout.get();
  193. addChildToLayout(std::move(VTLayout));
  194. }
  195. for (auto &Data : Members) {
  196. auto DM = std::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
  197. addChildToLayout(std::move(DM));
  198. }
  199. // Make sure add virtual bases before adding functions, since functions may be
  200. // overrides of virtual functions declared in a virtual base, so the VTables
  201. // and virtual intros need to be correctly initialized.
  202. for (auto &VB : VirtualBaseSyms) {
  203. int VBPO = VB->getVirtualBasePointerOffset();
  204. if (!hasVBPtrAtOffset(VBPO)) {
  205. if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
  206. auto VBPL = std::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
  207. VBPO, VBP->getLength());
  208. VBPtr = VBPL.get();
  209. addChildToLayout(std::move(VBPL));
  210. }
  211. }
  212. // Virtual bases always go at the end. So just look for the last place we
  213. // ended when writing something, and put our virtual base there.
  214. // Note that virtual bases get elided unless this is a top-most derived
  215. // class.
  216. uint32_t Offset = UsedBytes.find_last() + 1;
  217. bool Elide = (Parent != nullptr);
  218. auto BL =
  219. std::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
  220. AllBases.push_back(BL.get());
  221. // Only lay this virtual base out directly inside of *this* class if this
  222. // is a top-most derived class. Keep track of it regardless, but only
  223. // physically lay it out if it's a topmost derived class.
  224. addChildToLayout(std::move(BL));
  225. }
  226. VirtualBases = makeArrayRef(AllBases).drop_front(NonVirtualBases.size());
  227. if (Parent != nullptr)
  228. LayoutSize = UsedBytes.find_last() + 1;
  229. }
  230. bool UDTLayoutBase::hasVBPtrAtOffset(uint32_t Off) const {
  231. if (VBPtr && VBPtr->getOffsetInParent() == Off)
  232. return true;
  233. for (BaseClassLayout *BL : AllBases) {
  234. if (BL->hasVBPtrAtOffset(Off - BL->getOffsetInParent()))
  235. return true;
  236. }
  237. return false;
  238. }
  239. void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
  240. uint32_t Begin = Child->getOffsetInParent();
  241. if (!Child->isElided()) {
  242. BitVector ChildBytes = Child->usedBytes();
  243. // Suppose the child occupies 4 bytes starting at offset 12 in a 32 byte
  244. // class. When we call ChildBytes.resize(32), the Child's storage will
  245. // still begin at offset 0, so we need to shift it left by offset bytes
  246. // to get it into the right position.
  247. ChildBytes.resize(UsedBytes.size());
  248. ChildBytes <<= Child->getOffsetInParent();
  249. UsedBytes |= ChildBytes;
  250. if (ChildBytes.count() > 0) {
  251. auto Loc = llvm::upper_bound(
  252. LayoutItems, Begin, [](uint32_t Off, const LayoutItemBase *Item) {
  253. return (Off < Item->getOffsetInParent());
  254. });
  255. LayoutItems.insert(Loc, Child.get());
  256. }
  257. }
  258. ChildStorage.push_back(std::move(Child));
  259. }