FunctionDumper.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. //===- FunctionDumper.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. #include "FunctionDumper.h"
  10. #include "BuiltinDumper.h"
  11. #include "LinePrinter.h"
  12. #include "llvm-pdbdump.h"
  13. #include "llvm/DebugInfo/PDB/IPDBSession.h"
  14. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  15. #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
  16. #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
  17. #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
  18. #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
  19. #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
  20. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
  21. #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
  22. #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
  23. #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
  24. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  25. #include "llvm/Support/Format.h"
  26. using namespace llvm;
  27. namespace {
  28. template <class T>
  29. void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer,
  30. llvm::FunctionDumper &Dumper) {
  31. uint32_t ClassParentId = Symbol.getClassParentId();
  32. auto ClassParent =
  33. Symbol.getSession().template getConcreteSymbolById<PDBSymbolTypeUDT>(
  34. ClassParentId);
  35. if (!ClassParent)
  36. return;
  37. WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName();
  38. Printer << "::";
  39. }
  40. }
  41. FunctionDumper::FunctionDumper(LinePrinter &P)
  42. : PDBSymDumper(true), Printer(P) {}
  43. void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
  44. const char *Name, PointerType Pointer) {
  45. auto ReturnType = Symbol.getReturnType();
  46. ReturnType->dump(*this);
  47. Printer << " ";
  48. uint32_t ClassParentId = Symbol.getClassParentId();
  49. auto ClassParent =
  50. Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
  51. ClassParentId);
  52. PDB_CallingConv CC = Symbol.getCallingConvention();
  53. bool ShouldDumpCallingConvention = true;
  54. if ((ClassParent && CC == PDB_CallingConv::Thiscall) ||
  55. (!ClassParent && CC == PDB_CallingConv::NearStdcall)) {
  56. ShouldDumpCallingConvention = false;
  57. }
  58. if (Pointer == PointerType::None) {
  59. if (ShouldDumpCallingConvention)
  60. WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
  61. if (ClassParent) {
  62. Printer << "(";
  63. WithColor(Printer, PDB_ColorItem::Identifier).get()
  64. << ClassParent->getName();
  65. Printer << "::)";
  66. }
  67. } else {
  68. Printer << "(";
  69. if (ShouldDumpCallingConvention)
  70. WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
  71. if (ClassParent) {
  72. WithColor(Printer, PDB_ColorItem::Identifier).get()
  73. << ClassParent->getName();
  74. Printer << "::";
  75. }
  76. if (Pointer == PointerType::Reference)
  77. Printer << "&";
  78. else
  79. Printer << "*";
  80. if (Name)
  81. WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
  82. Printer << ")";
  83. }
  84. Printer << "(";
  85. if (auto ChildEnum = Symbol.getArguments()) {
  86. uint32_t Index = 0;
  87. while (auto Arg = ChildEnum->getNext()) {
  88. Arg->dump(*this);
  89. if (++Index < ChildEnum->getChildCount())
  90. Printer << ", ";
  91. }
  92. }
  93. Printer << ")";
  94. if (Symbol.isConstType())
  95. WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
  96. if (Symbol.isVolatileType())
  97. WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
  98. }
  99. void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) {
  100. uint64_t FuncStart = Symbol.getVirtualAddress();
  101. uint64_t FuncEnd = FuncStart + Symbol.getLength();
  102. Printer << "func [";
  103. WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10);
  104. if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>()) {
  105. uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart;
  106. WithColor(Printer, PDB_ColorItem::Offset).get() << "+" << Prologue;
  107. }
  108. Printer << " - ";
  109. WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);
  110. if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {
  111. uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();
  112. WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue;
  113. }
  114. Printer << "] (";
  115. if (Symbol.hasFramePointer()) {
  116. WithColor(Printer, PDB_ColorItem::Register).get()
  117. << Symbol.getLocalBasePointerRegisterId();
  118. } else {
  119. WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";
  120. }
  121. Printer << ") ";
  122. if (Symbol.isVirtual() || Symbol.isPureVirtual())
  123. WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";
  124. auto Signature = Symbol.getSignature();
  125. if (!Signature) {
  126. WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
  127. if (Pointer == PointerType::Pointer)
  128. Printer << "*";
  129. else if (Pointer == FunctionDumper::PointerType::Reference)
  130. Printer << "&";
  131. return;
  132. }
  133. auto ReturnType = Signature->getReturnType();
  134. ReturnType->dump(*this);
  135. Printer << " ";
  136. auto ClassParent = Symbol.getClassParent();
  137. PDB_CallingConv CC = Signature->getCallingConvention();
  138. if (Pointer != FunctionDumper::PointerType::None)
  139. Printer << "(";
  140. if ((ClassParent && CC != PDB_CallingConv::Thiscall) ||
  141. (!ClassParent && CC != PDB_CallingConv::NearStdcall)) {
  142. WithColor(Printer, PDB_ColorItem::Keyword).get()
  143. << Signature->getCallingConvention() << " ";
  144. }
  145. WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
  146. if (Pointer != FunctionDumper::PointerType::None) {
  147. if (Pointer == PointerType::Pointer)
  148. Printer << "*";
  149. else if (Pointer == FunctionDumper::PointerType::Reference)
  150. Printer << "&";
  151. Printer << ")";
  152. }
  153. Printer << "(";
  154. if (auto Arguments = Symbol.getArguments()) {
  155. uint32_t Index = 0;
  156. while (auto Arg = Arguments->getNext()) {
  157. auto ArgType = Arg->getType();
  158. ArgType->dump(*this);
  159. WithColor(Printer, PDB_ColorItem::Identifier).get() << " "
  160. << Arg->getName();
  161. if (++Index < Arguments->getChildCount())
  162. Printer << ", ";
  163. }
  164. }
  165. Printer << ")";
  166. if (Symbol.isConstType())
  167. WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
  168. if (Symbol.isVolatileType())
  169. WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
  170. if (Symbol.isPureVirtual())
  171. Printer << " = 0";
  172. }
  173. void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) {
  174. uint32_t ElementTypeId = Symbol.getTypeId();
  175. auto ElementType = Symbol.getSession().getSymbolById(ElementTypeId);
  176. if (!ElementType)
  177. return;
  178. ElementType->dump(*this);
  179. Printer << "[";
  180. WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength();
  181. Printer << "]";
  182. }
  183. void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
  184. BuiltinDumper Dumper(Printer);
  185. Dumper.start(Symbol);
  186. }
  187. void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) {
  188. dumpClassParentWithScopeOperator(Symbol, Printer, *this);
  189. WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
  190. }
  191. void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
  192. // PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
  193. // through to the real thing and dump it.
  194. uint32_t TypeId = Symbol.getTypeId();
  195. auto Type = Symbol.getSession().getSymbolById(TypeId);
  196. if (!Type)
  197. return;
  198. Type->dump(*this);
  199. }
  200. void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
  201. dumpClassParentWithScopeOperator(Symbol, Printer, *this);
  202. WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
  203. }
  204. void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {
  205. uint32_t PointeeId = Symbol.getTypeId();
  206. auto PointeeType = Symbol.getSession().getSymbolById(PointeeId);
  207. if (!PointeeType)
  208. return;
  209. if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
  210. FunctionDumper NestedDumper(Printer);
  211. PointerType Pointer =
  212. Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
  213. NestedDumper.start(*FuncSig, nullptr, Pointer);
  214. } else {
  215. if (Symbol.isConstType())
  216. WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
  217. if (Symbol.isVolatileType())
  218. WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
  219. PointeeType->dump(*this);
  220. Printer << (Symbol.isReference() ? "&" : "*");
  221. }
  222. }
  223. void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) {
  224. WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
  225. }