PDBSymbol.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//
  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/PDBSymbol.h"
  9. #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
  10. #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
  11. #include "llvm/DebugInfo/PDB/IPDBSession.h"
  12. #include "llvm/DebugInfo/PDB/PDBExtras.h"
  13. #include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
  15. #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
  16. #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
  17. #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
  18. #include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
  19. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  20. #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
  21. #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
  22. #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
  23. #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
  24. #include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
  25. #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
  26. #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
  27. #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
  28. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
  29. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
  30. #include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
  31. #include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
  32. #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
  33. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
  34. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
  35. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
  36. #include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
  37. #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
  38. #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
  39. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  40. #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
  41. #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
  42. #include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
  43. #include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
  44. #include "llvm/DebugInfo/PDB/PDBTypes.h"
  45. #include <algorithm>
  46. #include <memory>
  47. using namespace llvm;
  48. using namespace llvm::pdb;
  49. PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}
  50. PDBSymbol::PDBSymbol(PDBSymbol &&Other)
  51. : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}
  52. PDBSymbol::~PDBSymbol() = default;
  53. #define FACTORY_SYMTAG_CASE(Tag, Type) \
  54. case PDB_SymType::Tag: \
  55. return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
  56. std::unique_ptr<PDBSymbol>
  57. PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {
  58. switch (Tag) {
  59. FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)
  60. FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)
  61. FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)
  62. FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv)
  63. FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc)
  64. FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock)
  65. FACTORY_SYMTAG_CASE(Data, PDBSymbolData)
  66. FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation)
  67. FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel)
  68. FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol)
  69. FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT)
  70. FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum)
  71. FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig)
  72. FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer)
  73. FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray)
  74. FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin)
  75. FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef)
  76. FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass)
  77. FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend)
  78. FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg)
  79. FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart)
  80. FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd)
  81. FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace)
  82. FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape)
  83. FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable)
  84. FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom)
  85. FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk)
  86. FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom)
  87. FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)
  88. FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)
  89. default:
  90. return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));
  91. }
  92. }
  93. std::unique_ptr<PDBSymbol>
  94. PDBSymbol::create(const IPDBSession &PDBSession,
  95. std::unique_ptr<IPDBRawSymbol> RawSymbol) {
  96. auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());
  97. SymbolPtr->RawSymbol = RawSymbol.get();
  98. SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);
  99. return SymbolPtr;
  100. }
  101. std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,
  102. IPDBRawSymbol &RawSymbol) {
  103. auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());
  104. SymbolPtr->RawSymbol = &RawSymbol;
  105. return SymbolPtr;
  106. }
  107. void PDBSymbol::defaultDump(raw_ostream &OS, int Indent,
  108. PdbSymbolIdField ShowFlags,
  109. PdbSymbolIdField RecurseFlags) const {
  110. RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);
  111. }
  112. void PDBSymbol::dumpProperties() const {
  113. outs() << "\n";
  114. defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);
  115. outs().flush();
  116. }
  117. void PDBSymbol::dumpChildStats() const {
  118. TagStats Stats;
  119. getChildStats(Stats);
  120. outs() << "\n";
  121. for (auto &Stat : Stats) {
  122. outs() << Stat.first << ": " << Stat.second << "\n";
  123. }
  124. outs().flush();
  125. }
  126. PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
  127. uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
  128. std::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const {
  129. return findAllChildren(PDB_SymType::None);
  130. }
  131. std::unique_ptr<IPDBEnumSymbols>
  132. PDBSymbol::findAllChildren(PDB_SymType Type) const {
  133. return RawSymbol->findChildren(Type);
  134. }
  135. std::unique_ptr<IPDBEnumSymbols>
  136. PDBSymbol::findChildren(PDB_SymType Type, StringRef Name,
  137. PDB_NameSearchFlags Flags) const {
  138. return RawSymbol->findChildren(Type, Name, Flags);
  139. }
  140. std::unique_ptr<IPDBEnumSymbols>
  141. PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
  142. PDB_NameSearchFlags Flags, uint32_t RVA) const {
  143. return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA);
  144. }
  145. std::unique_ptr<IPDBEnumSymbols>
  146. PDBSymbol::findInlineFramesByVA(uint64_t VA) const {
  147. return RawSymbol->findInlineFramesByVA(VA);
  148. }
  149. std::unique_ptr<IPDBEnumSymbols>
  150. PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
  151. return RawSymbol->findInlineFramesByRVA(RVA);
  152. }
  153. std::unique_ptr<IPDBEnumLineNumbers>
  154. PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
  155. return RawSymbol->findInlineeLinesByVA(VA, Length);
  156. }
  157. std::unique_ptr<IPDBEnumLineNumbers>
  158. PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
  159. return RawSymbol->findInlineeLinesByRVA(RVA, Length);
  160. }
  161. std::string PDBSymbol::getName() const { return RawSymbol->getName(); }
  162. std::unique_ptr<IPDBEnumSymbols>
  163. PDBSymbol::getChildStats(TagStats &Stats) const {
  164. std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
  165. if (!Result)
  166. return nullptr;
  167. Stats.clear();
  168. while (auto Child = Result->getNext()) {
  169. ++Stats[Child->getSymTag()];
  170. }
  171. Result->reset();
  172. return Result;
  173. }
  174. std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
  175. return Session.getSymbolById(Id);
  176. }
  177. void llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,
  178. SymIndexId Value, int Indent,
  179. const IPDBSession &Session,
  180. PdbSymbolIdField FieldId,
  181. PdbSymbolIdField ShowFlags,
  182. PdbSymbolIdField RecurseFlags) {
  183. if ((FieldId & ShowFlags) == PdbSymbolIdField::None)
  184. return;
  185. OS << "\n";
  186. OS.indent(Indent);
  187. OS << Name << ": " << Value;
  188. // Don't recurse unless the user requested it.
  189. if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)
  190. return;
  191. // And obviously don't recurse on the symbol itself.
  192. if (FieldId == PdbSymbolIdField::SymIndexId)
  193. return;
  194. auto Child = Session.getSymbolById(Value);
  195. // It could have been a placeholder symbol for a type we don't yet support,
  196. // so just exit in that case.
  197. if (!Child)
  198. return;
  199. // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
  200. // recurse flags.
  201. Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);
  202. }