MinimalSymbolDumper.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. //===- MinimalSymbolDumper.cpp -------------------------------- *- 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 "MinimalSymbolDumper.h"
  9. #include "llvm/DebugInfo/CodeView/CVRecord.h"
  10. #include "llvm/DebugInfo/CodeView/CodeView.h"
  11. #include "llvm/DebugInfo/CodeView/Formatters.h"
  12. #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
  13. #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
  14. #include "llvm/DebugInfo/CodeView/TypeRecord.h"
  15. #include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
  16. #include "llvm/DebugInfo/PDB/Native/InputFile.h"
  17. #include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
  18. #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
  19. #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
  20. #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
  21. #include "llvm/Object/COFF.h"
  22. #include "llvm/Support/FormatVariadic.h"
  23. using namespace llvm;
  24. using namespace llvm::codeview;
  25. using namespace llvm::pdb;
  26. static std::string formatLocalSymFlags(uint32_t IndentLevel,
  27. LocalSymFlags Flags) {
  28. std::vector<std::string> Opts;
  29. if (Flags == LocalSymFlags::None)
  30. return "none";
  31. PUSH_FLAG(LocalSymFlags, IsParameter, Flags, "param");
  32. PUSH_FLAG(LocalSymFlags, IsAddressTaken, Flags, "address is taken");
  33. PUSH_FLAG(LocalSymFlags, IsCompilerGenerated, Flags, "compiler generated");
  34. PUSH_FLAG(LocalSymFlags, IsAggregate, Flags, "aggregate");
  35. PUSH_FLAG(LocalSymFlags, IsAggregated, Flags, "aggregated");
  36. PUSH_FLAG(LocalSymFlags, IsAliased, Flags, "aliased");
  37. PUSH_FLAG(LocalSymFlags, IsAlias, Flags, "alias");
  38. PUSH_FLAG(LocalSymFlags, IsReturnValue, Flags, "return val");
  39. PUSH_FLAG(LocalSymFlags, IsOptimizedOut, Flags, "optimized away");
  40. PUSH_FLAG(LocalSymFlags, IsEnregisteredGlobal, Flags, "enreg global");
  41. PUSH_FLAG(LocalSymFlags, IsEnregisteredStatic, Flags, "enreg static");
  42. return typesetItemList(Opts, 4, IndentLevel, " | ");
  43. }
  44. static std::string formatExportFlags(uint32_t IndentLevel, ExportFlags Flags) {
  45. std::vector<std::string> Opts;
  46. if (Flags == ExportFlags::None)
  47. return "none";
  48. PUSH_FLAG(ExportFlags, IsConstant, Flags, "constant");
  49. PUSH_FLAG(ExportFlags, IsData, Flags, "data");
  50. PUSH_FLAG(ExportFlags, IsPrivate, Flags, "private");
  51. PUSH_FLAG(ExportFlags, HasNoName, Flags, "no name");
  52. PUSH_FLAG(ExportFlags, HasExplicitOrdinal, Flags, "explicit ord");
  53. PUSH_FLAG(ExportFlags, IsForwarder, Flags, "forwarder");
  54. return typesetItemList(Opts, 4, IndentLevel, " | ");
  55. }
  56. static std::string formatCompileSym2Flags(uint32_t IndentLevel,
  57. CompileSym2Flags Flags) {
  58. std::vector<std::string> Opts;
  59. Flags &= ~CompileSym2Flags::SourceLanguageMask;
  60. if (Flags == CompileSym2Flags::None)
  61. return "none";
  62. PUSH_FLAG(CompileSym2Flags, EC, Flags, "edit and continue");
  63. PUSH_FLAG(CompileSym2Flags, NoDbgInfo, Flags, "no dbg info");
  64. PUSH_FLAG(CompileSym2Flags, LTCG, Flags, "ltcg");
  65. PUSH_FLAG(CompileSym2Flags, NoDataAlign, Flags, "no data align");
  66. PUSH_FLAG(CompileSym2Flags, ManagedPresent, Flags, "has managed code");
  67. PUSH_FLAG(CompileSym2Flags, SecurityChecks, Flags, "security checks");
  68. PUSH_FLAG(CompileSym2Flags, HotPatch, Flags, "hot patchable");
  69. PUSH_FLAG(CompileSym2Flags, CVTCIL, Flags, "cvtcil");
  70. PUSH_FLAG(CompileSym2Flags, MSILModule, Flags, "msil module");
  71. return typesetItemList(Opts, 4, IndentLevel, " | ");
  72. }
  73. static std::string formatCompileSym3Flags(uint32_t IndentLevel,
  74. CompileSym3Flags Flags) {
  75. std::vector<std::string> Opts;
  76. Flags &= ~CompileSym3Flags::SourceLanguageMask;
  77. if (Flags == CompileSym3Flags::None)
  78. return "none";
  79. PUSH_FLAG(CompileSym3Flags, EC, Flags, "edit and continue");
  80. PUSH_FLAG(CompileSym3Flags, NoDbgInfo, Flags, "no dbg info");
  81. PUSH_FLAG(CompileSym3Flags, LTCG, Flags, "ltcg");
  82. PUSH_FLAG(CompileSym3Flags, NoDataAlign, Flags, "no data align");
  83. PUSH_FLAG(CompileSym3Flags, ManagedPresent, Flags, "has managed code");
  84. PUSH_FLAG(CompileSym3Flags, SecurityChecks, Flags, "security checks");
  85. PUSH_FLAG(CompileSym3Flags, HotPatch, Flags, "hot patchable");
  86. PUSH_FLAG(CompileSym3Flags, CVTCIL, Flags, "cvtcil");
  87. PUSH_FLAG(CompileSym3Flags, MSILModule, Flags, "msil module");
  88. PUSH_FLAG(CompileSym3Flags, Sdl, Flags, "sdl");
  89. PUSH_FLAG(CompileSym3Flags, PGO, Flags, "pgo");
  90. PUSH_FLAG(CompileSym3Flags, Exp, Flags, "exp");
  91. return typesetItemList(Opts, 4, IndentLevel, " | ");
  92. }
  93. static std::string formatFrameProcedureOptions(uint32_t IndentLevel,
  94. FrameProcedureOptions FPO) {
  95. std::vector<std::string> Opts;
  96. if (FPO == FrameProcedureOptions::None)
  97. return "none";
  98. PUSH_FLAG(FrameProcedureOptions, HasAlloca, FPO, "has alloca");
  99. PUSH_FLAG(FrameProcedureOptions, HasSetJmp, FPO, "has setjmp");
  100. PUSH_FLAG(FrameProcedureOptions, HasLongJmp, FPO, "has longjmp");
  101. PUSH_FLAG(FrameProcedureOptions, HasInlineAssembly, FPO, "has inline asm");
  102. PUSH_FLAG(FrameProcedureOptions, HasExceptionHandling, FPO, "has eh");
  103. PUSH_FLAG(FrameProcedureOptions, MarkedInline, FPO, "marked inline");
  104. PUSH_FLAG(FrameProcedureOptions, HasStructuredExceptionHandling, FPO,
  105. "has seh");
  106. PUSH_FLAG(FrameProcedureOptions, Naked, FPO, "naked");
  107. PUSH_FLAG(FrameProcedureOptions, SecurityChecks, FPO, "secure checks");
  108. PUSH_FLAG(FrameProcedureOptions, AsynchronousExceptionHandling, FPO,
  109. "has async eh");
  110. PUSH_FLAG(FrameProcedureOptions, NoStackOrderingForSecurityChecks, FPO,
  111. "no stack order");
  112. PUSH_FLAG(FrameProcedureOptions, Inlined, FPO, "inlined");
  113. PUSH_FLAG(FrameProcedureOptions, StrictSecurityChecks, FPO,
  114. "strict secure checks");
  115. PUSH_FLAG(FrameProcedureOptions, SafeBuffers, FPO, "safe buffers");
  116. PUSH_FLAG(FrameProcedureOptions, ProfileGuidedOptimization, FPO, "pgo");
  117. PUSH_FLAG(FrameProcedureOptions, ValidProfileCounts, FPO,
  118. "has profile counts");
  119. PUSH_FLAG(FrameProcedureOptions, OptimizedForSpeed, FPO, "opt speed");
  120. PUSH_FLAG(FrameProcedureOptions, GuardCfg, FPO, "guard cfg");
  121. PUSH_FLAG(FrameProcedureOptions, GuardCfw, FPO, "guard cfw");
  122. return typesetItemList(Opts, 4, IndentLevel, " | ");
  123. }
  124. static std::string formatPublicSymFlags(uint32_t IndentLevel,
  125. PublicSymFlags Flags) {
  126. std::vector<std::string> Opts;
  127. if (Flags == PublicSymFlags::None)
  128. return "none";
  129. PUSH_FLAG(PublicSymFlags, Code, Flags, "code");
  130. PUSH_FLAG(PublicSymFlags, Function, Flags, "function");
  131. PUSH_FLAG(PublicSymFlags, Managed, Flags, "managed");
  132. PUSH_FLAG(PublicSymFlags, MSIL, Flags, "msil");
  133. return typesetItemList(Opts, 4, IndentLevel, " | ");
  134. }
  135. static std::string formatProcSymFlags(uint32_t IndentLevel,
  136. ProcSymFlags Flags) {
  137. std::vector<std::string> Opts;
  138. if (Flags == ProcSymFlags::None)
  139. return "none";
  140. PUSH_FLAG(ProcSymFlags, HasFP, Flags, "has fp");
  141. PUSH_FLAG(ProcSymFlags, HasIRET, Flags, "has iret");
  142. PUSH_FLAG(ProcSymFlags, HasFRET, Flags, "has fret");
  143. PUSH_FLAG(ProcSymFlags, IsNoReturn, Flags, "noreturn");
  144. PUSH_FLAG(ProcSymFlags, IsUnreachable, Flags, "unreachable");
  145. PUSH_FLAG(ProcSymFlags, HasCustomCallingConv, Flags, "custom calling conv");
  146. PUSH_FLAG(ProcSymFlags, IsNoInline, Flags, "noinline");
  147. PUSH_FLAG(ProcSymFlags, HasOptimizedDebugInfo, Flags, "opt debuginfo");
  148. return typesetItemList(Opts, 4, IndentLevel, " | ");
  149. }
  150. static std::string formatThunkOrdinal(ThunkOrdinal Ordinal) {
  151. switch (Ordinal) {
  152. RETURN_CASE(ThunkOrdinal, Standard, "thunk");
  153. RETURN_CASE(ThunkOrdinal, ThisAdjustor, "this adjustor");
  154. RETURN_CASE(ThunkOrdinal, Vcall, "vcall");
  155. RETURN_CASE(ThunkOrdinal, Pcode, "pcode");
  156. RETURN_CASE(ThunkOrdinal, UnknownLoad, "unknown load");
  157. RETURN_CASE(ThunkOrdinal, TrampIncremental, "tramp incremental");
  158. RETURN_CASE(ThunkOrdinal, BranchIsland, "branch island");
  159. }
  160. return formatUnknownEnum(Ordinal);
  161. }
  162. static std::string formatTrampolineType(TrampolineType Tramp) {
  163. switch (Tramp) {
  164. RETURN_CASE(TrampolineType, TrampIncremental, "tramp incremental");
  165. RETURN_CASE(TrampolineType, BranchIsland, "branch island");
  166. }
  167. return formatUnknownEnum(Tramp);
  168. }
  169. static std::string formatSourceLanguage(SourceLanguage Lang) {
  170. switch (Lang) {
  171. RETURN_CASE(SourceLanguage, C, "c");
  172. RETURN_CASE(SourceLanguage, Cpp, "c++");
  173. RETURN_CASE(SourceLanguage, Fortran, "fortran");
  174. RETURN_CASE(SourceLanguage, Masm, "masm");
  175. RETURN_CASE(SourceLanguage, Pascal, "pascal");
  176. RETURN_CASE(SourceLanguage, Basic, "basic");
  177. RETURN_CASE(SourceLanguage, Cobol, "cobol");
  178. RETURN_CASE(SourceLanguage, Link, "link");
  179. RETURN_CASE(SourceLanguage, VB, "vb");
  180. RETURN_CASE(SourceLanguage, Cvtres, "cvtres");
  181. RETURN_CASE(SourceLanguage, Cvtpgd, "cvtpgd");
  182. RETURN_CASE(SourceLanguage, CSharp, "c#");
  183. RETURN_CASE(SourceLanguage, ILAsm, "il asm");
  184. RETURN_CASE(SourceLanguage, Java, "java");
  185. RETURN_CASE(SourceLanguage, JScript, "javascript");
  186. RETURN_CASE(SourceLanguage, MSIL, "msil");
  187. RETURN_CASE(SourceLanguage, HLSL, "hlsl");
  188. RETURN_CASE(SourceLanguage, D, "d");
  189. RETURN_CASE(SourceLanguage, Swift, "swift");
  190. RETURN_CASE(SourceLanguage, Rust, "rust");
  191. }
  192. return formatUnknownEnum(Lang);
  193. }
  194. static std::string formatMachineType(CPUType Cpu) {
  195. switch (Cpu) {
  196. RETURN_CASE(CPUType, Intel8080, "intel 8080");
  197. RETURN_CASE(CPUType, Intel8086, "intel 8086");
  198. RETURN_CASE(CPUType, Intel80286, "intel 80286");
  199. RETURN_CASE(CPUType, Intel80386, "intel 80386");
  200. RETURN_CASE(CPUType, Intel80486, "intel 80486");
  201. RETURN_CASE(CPUType, Pentium, "intel pentium");
  202. RETURN_CASE(CPUType, PentiumPro, "intel pentium pro");
  203. RETURN_CASE(CPUType, Pentium3, "intel pentium 3");
  204. RETURN_CASE(CPUType, MIPS, "mips");
  205. RETURN_CASE(CPUType, MIPS16, "mips-16");
  206. RETURN_CASE(CPUType, MIPS32, "mips-32");
  207. RETURN_CASE(CPUType, MIPS64, "mips-64");
  208. RETURN_CASE(CPUType, MIPSI, "mips i");
  209. RETURN_CASE(CPUType, MIPSII, "mips ii");
  210. RETURN_CASE(CPUType, MIPSIII, "mips iii");
  211. RETURN_CASE(CPUType, MIPSIV, "mips iv");
  212. RETURN_CASE(CPUType, MIPSV, "mips v");
  213. RETURN_CASE(CPUType, M68000, "motorola 68000");
  214. RETURN_CASE(CPUType, M68010, "motorola 68010");
  215. RETURN_CASE(CPUType, M68020, "motorola 68020");
  216. RETURN_CASE(CPUType, M68030, "motorola 68030");
  217. RETURN_CASE(CPUType, M68040, "motorola 68040");
  218. RETURN_CASE(CPUType, Alpha, "alpha");
  219. RETURN_CASE(CPUType, Alpha21164, "alpha 21164");
  220. RETURN_CASE(CPUType, Alpha21164A, "alpha 21164a");
  221. RETURN_CASE(CPUType, Alpha21264, "alpha 21264");
  222. RETURN_CASE(CPUType, Alpha21364, "alpha 21364");
  223. RETURN_CASE(CPUType, PPC601, "powerpc 601");
  224. RETURN_CASE(CPUType, PPC603, "powerpc 603");
  225. RETURN_CASE(CPUType, PPC604, "powerpc 604");
  226. RETURN_CASE(CPUType, PPC620, "powerpc 620");
  227. RETURN_CASE(CPUType, PPCFP, "powerpc fp");
  228. RETURN_CASE(CPUType, PPCBE, "powerpc be");
  229. RETURN_CASE(CPUType, SH3, "sh3");
  230. RETURN_CASE(CPUType, SH3E, "sh3e");
  231. RETURN_CASE(CPUType, SH3DSP, "sh3 dsp");
  232. RETURN_CASE(CPUType, SH4, "sh4");
  233. RETURN_CASE(CPUType, SHMedia, "shmedia");
  234. RETURN_CASE(CPUType, ARM3, "arm 3");
  235. RETURN_CASE(CPUType, ARM4, "arm 4");
  236. RETURN_CASE(CPUType, ARM4T, "arm 4t");
  237. RETURN_CASE(CPUType, ARM5, "arm 5");
  238. RETURN_CASE(CPUType, ARM5T, "arm 5t");
  239. RETURN_CASE(CPUType, ARM6, "arm 6");
  240. RETURN_CASE(CPUType, ARM_XMAC, "arm xmac");
  241. RETURN_CASE(CPUType, ARM_WMMX, "arm wmmx");
  242. RETURN_CASE(CPUType, ARM7, "arm 7");
  243. RETURN_CASE(CPUType, ARM64, "arm64");
  244. RETURN_CASE(CPUType, ARM64EC, "arm64ec");
  245. RETURN_CASE(CPUType, ARM64X, "arm64x");
  246. RETURN_CASE(CPUType, HybridX86ARM64, "hybrid x86 arm64");
  247. RETURN_CASE(CPUType, Omni, "omni");
  248. RETURN_CASE(CPUType, Ia64, "intel itanium ia64");
  249. RETURN_CASE(CPUType, Ia64_2, "intel itanium ia64 2");
  250. RETURN_CASE(CPUType, CEE, "cee");
  251. RETURN_CASE(CPUType, AM33, "am33");
  252. RETURN_CASE(CPUType, M32R, "m32r");
  253. RETURN_CASE(CPUType, TriCore, "tri-core");
  254. RETURN_CASE(CPUType, X64, "intel x86-x64");
  255. RETURN_CASE(CPUType, EBC, "ebc");
  256. RETURN_CASE(CPUType, Thumb, "thumb");
  257. RETURN_CASE(CPUType, ARMNT, "arm nt");
  258. RETURN_CASE(CPUType, D3D11_Shader, "d3d11 shader");
  259. }
  260. return formatUnknownEnum(Cpu);
  261. }
  262. static std::string formatCookieKind(FrameCookieKind Kind) {
  263. switch (Kind) {
  264. RETURN_CASE(FrameCookieKind, Copy, "copy");
  265. RETURN_CASE(FrameCookieKind, XorStackPointer, "xor stack ptr");
  266. RETURN_CASE(FrameCookieKind, XorFramePointer, "xor frame ptr");
  267. RETURN_CASE(FrameCookieKind, XorR13, "xor rot13");
  268. }
  269. return formatUnknownEnum(Kind);
  270. }
  271. static std::string formatRegisterId(RegisterId Id, CPUType Cpu) {
  272. if (Cpu == CPUType::ARMNT) {
  273. switch (Id) {
  274. #define CV_REGISTERS_ARM
  275. #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
  276. #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
  277. #undef CV_REGISTER
  278. #undef CV_REGISTERS_ARM
  279. default:
  280. break;
  281. }
  282. } else if (Cpu == CPUType::ARM64) {
  283. switch (Id) {
  284. #define CV_REGISTERS_ARM64
  285. #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
  286. #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
  287. #undef CV_REGISTER
  288. #undef CV_REGISTERS_ARM64
  289. default:
  290. break;
  291. }
  292. } else {
  293. switch (Id) {
  294. #define CV_REGISTERS_X86
  295. #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
  296. #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
  297. #undef CV_REGISTER
  298. #undef CV_REGISTERS_X86
  299. default:
  300. break;
  301. }
  302. }
  303. return formatUnknownEnum(Id);
  304. }
  305. static std::string formatRegisterId(uint16_t Reg16, CPUType Cpu) {
  306. return formatRegisterId(RegisterId(Reg16), Cpu);
  307. }
  308. static std::string formatRegisterId(ulittle16_t &Reg16, CPUType Cpu) {
  309. return formatRegisterId(uint16_t(Reg16), Cpu);
  310. }
  311. static std::string formatRange(LocalVariableAddrRange Range) {
  312. return formatv("[{0},+{1})",
  313. formatSegmentOffset(Range.ISectStart, Range.OffsetStart),
  314. Range.Range)
  315. .str();
  316. }
  317. static std::string formatGaps(uint32_t IndentLevel,
  318. ArrayRef<LocalVariableAddrGap> Gaps) {
  319. std::vector<std::string> GapStrs;
  320. for (const auto &G : Gaps) {
  321. GapStrs.push_back(formatv("({0},{1})", G.GapStartOffset, G.Range).str());
  322. }
  323. return typesetItemList(GapStrs, 7, IndentLevel, ", ");
  324. }
  325. Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record) {
  326. return visitSymbolBegin(Record, 0);
  327. }
  328. Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record,
  329. uint32_t Offset) {
  330. // formatLine puts the newline at the beginning, so we use formatLine here
  331. // to start a new line, and then individual visit methods use format to
  332. // append to the existing line.
  333. P.formatLine("{0} | {1} [size = {2}]",
  334. fmt_align(Offset, AlignStyle::Right, 6),
  335. formatSymbolKind(Record.kind()), Record.length());
  336. P.Indent();
  337. return Error::success();
  338. }
  339. Error MinimalSymbolDumper::visitSymbolEnd(CVSymbol &Record) {
  340. if (RecordBytes) {
  341. AutoIndent Indent(P, 7);
  342. P.formatBinary("bytes", Record.content(), 0);
  343. }
  344. P.Unindent();
  345. return Error::success();
  346. }
  347. std::string MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI,
  348. bool IsType) const {
  349. if (TI.isSimple() || TI.isDecoratedItemId())
  350. return formatv("{0}", TI).str();
  351. auto &Container = IsType ? Types : Ids;
  352. StringRef Name = Container.getTypeName(TI);
  353. if (Name.size() > 32) {
  354. Name = Name.take_front(32);
  355. return std::string(formatv("{0} ({1}...)", TI, Name));
  356. } else
  357. return std::string(formatv("{0} ({1})", TI, Name));
  358. }
  359. std::string MinimalSymbolDumper::idIndex(codeview::TypeIndex TI) const {
  360. return typeOrIdIndex(TI, false);
  361. }
  362. std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const {
  363. return typeOrIdIndex(TI, true);
  364. }
  365. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
  366. P.format(" `{0}`", Block.Name);
  367. AutoIndent Indent(P, 7);
  368. P.formatLine("parent = {0}, end = {1}", Block.Parent, Block.End);
  369. P.formatLine("code size = {0}, addr = {1}", Block.CodeSize,
  370. formatSegmentOffset(Block.Segment, Block.CodeOffset));
  371. return Error::success();
  372. }
  373. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
  374. P.format(" `{0}`", Thunk.Name);
  375. AutoIndent Indent(P, 7);
  376. P.formatLine("parent = {0}, end = {1}, next = {2}", Thunk.Parent, Thunk.End,
  377. Thunk.Next);
  378. P.formatLine("kind = {0}, size = {1}, addr = {2}",
  379. formatThunkOrdinal(Thunk.Thunk), Thunk.Length,
  380. formatSegmentOffset(Thunk.Segment, Thunk.Offset));
  381. return Error::success();
  382. }
  383. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  384. TrampolineSym &Tramp) {
  385. AutoIndent Indent(P, 7);
  386. P.formatLine("type = {0}, size = {1}, source = {2}, target = {3}",
  387. formatTrampolineType(Tramp.Type), Tramp.Size,
  388. formatSegmentOffset(Tramp.ThunkSection, Tramp.ThunkOffset),
  389. formatSegmentOffset(Tramp.TargetSection, Tramp.ThunkOffset));
  390. return Error::success();
  391. }
  392. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  393. SectionSym &Section) {
  394. P.format(" `{0}`", Section.Name);
  395. AutoIndent Indent(P, 7);
  396. P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}",
  397. Section.Length, Section.Alignment, Section.Rva,
  398. Section.SectionNumber);
  399. P.printLine("characteristics =");
  400. AutoIndent Indent2(P, 2);
  401. P.printLine(formatSectionCharacteristics(P.getIndentLevel(),
  402. Section.Characteristics, 1, "",
  403. CharacteristicStyle::Descriptive));
  404. return Error::success();
  405. }
  406. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CoffGroupSym &CG) {
  407. P.format(" `{0}`", CG.Name);
  408. AutoIndent Indent(P, 7);
  409. P.formatLine("length = {0}, addr = {1}", CG.Size,
  410. formatSegmentOffset(CG.Segment, CG.Offset));
  411. P.printLine("characteristics =");
  412. AutoIndent Indent2(P, 2);
  413. P.printLine(formatSectionCharacteristics(P.getIndentLevel(),
  414. CG.Characteristics, 1, "",
  415. CharacteristicStyle::Descriptive));
  416. return Error::success();
  417. }
  418. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  419. BPRelativeSym &BPRel) {
  420. P.format(" `{0}`", BPRel.Name);
  421. AutoIndent Indent(P, 7);
  422. P.formatLine("type = {0}, offset = {1}", typeIndex(BPRel.Type), BPRel.Offset);
  423. return Error::success();
  424. }
  425. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  426. BuildInfoSym &BuildInfo) {
  427. P.format(" BuildId = `{0}`", BuildInfo.BuildId);
  428. return Error::success();
  429. }
  430. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  431. CallSiteInfoSym &CSI) {
  432. AutoIndent Indent(P, 7);
  433. P.formatLine("type = {0}, addr = {1}", typeIndex(CSI.Type),
  434. formatSegmentOffset(CSI.Segment, CSI.CodeOffset));
  435. return Error::success();
  436. }
  437. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  438. EnvBlockSym &EnvBlock) {
  439. AutoIndent Indent(P, 7);
  440. for (const auto &Entry : EnvBlock.Fields) {
  441. P.formatLine("- {0}", Entry);
  442. }
  443. return Error::success();
  444. }
  445. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FileStaticSym &FS) {
  446. P.format(" `{0}`", FS.Name);
  447. AutoIndent Indent(P, 7);
  448. if (SymGroup) {
  449. Expected<StringRef> FileName =
  450. SymGroup->getNameFromStringTable(FS.ModFilenameOffset);
  451. if (FileName) {
  452. P.formatLine("type = {0}, file name = {1} ({2}), flags = {3}",
  453. typeIndex(FS.Index), FS.ModFilenameOffset, *FileName,
  454. formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags));
  455. }
  456. return Error::success();
  457. }
  458. P.formatLine("type = {0}, file name offset = {1}, flags = {2}",
  459. typeIndex(FS.Index), FS.ModFilenameOffset,
  460. formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags));
  461. return Error::success();
  462. }
  463. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
  464. P.format(" `{0}`", Export.Name);
  465. AutoIndent Indent(P, 7);
  466. P.formatLine("ordinal = {0}, flags = {1}", Export.Ordinal,
  467. formatExportFlags(P.getIndentLevel() + 9, Export.Flags));
  468. return Error::success();
  469. }
  470. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  471. Compile2Sym &Compile2) {
  472. AutoIndent Indent(P, 7);
  473. SourceLanguage Lang = static_cast<SourceLanguage>(
  474. Compile2.Flags & CompileSym2Flags::SourceLanguageMask);
  475. CompilationCPU = Compile2.Machine;
  476. P.formatLine("machine = {0}, ver = {1}, language = {2}",
  477. formatMachineType(Compile2.Machine), Compile2.Version,
  478. formatSourceLanguage(Lang));
  479. P.formatLine("frontend = {0}.{1}.{2}, backend = {3}.{4}.{5}",
  480. Compile2.VersionFrontendMajor, Compile2.VersionFrontendMinor,
  481. Compile2.VersionFrontendBuild, Compile2.VersionBackendMajor,
  482. Compile2.VersionBackendMinor, Compile2.VersionBackendBuild);
  483. P.formatLine("flags = {0}",
  484. formatCompileSym2Flags(P.getIndentLevel() + 9, Compile2.Flags));
  485. P.formatLine(
  486. "extra strings = {0}",
  487. typesetStringList(P.getIndentLevel() + 9 + 2, Compile2.ExtraStrings));
  488. return Error::success();
  489. }
  490. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  491. Compile3Sym &Compile3) {
  492. AutoIndent Indent(P, 7);
  493. SourceLanguage Lang = static_cast<SourceLanguage>(
  494. Compile3.Flags & CompileSym3Flags::SourceLanguageMask);
  495. CompilationCPU = Compile3.Machine;
  496. P.formatLine("machine = {0}, Ver = {1}, language = {2}",
  497. formatMachineType(Compile3.Machine), Compile3.Version,
  498. formatSourceLanguage(Lang));
  499. P.formatLine("frontend = {0}.{1}.{2}.{3}, backend = {4}.{5}.{6}.{7}",
  500. Compile3.VersionFrontendMajor, Compile3.VersionFrontendMinor,
  501. Compile3.VersionFrontendBuild, Compile3.VersionFrontendQFE,
  502. Compile3.VersionBackendMajor, Compile3.VersionBackendMinor,
  503. Compile3.VersionBackendBuild, Compile3.VersionBackendQFE);
  504. P.formatLine("flags = {0}",
  505. formatCompileSym3Flags(P.getIndentLevel() + 9, Compile3.Flags));
  506. return Error::success();
  507. }
  508. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  509. ConstantSym &Constant) {
  510. P.format(" `{0}`", Constant.Name);
  511. AutoIndent Indent(P, 7);
  512. P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type),
  513. toString(Constant.Value, 10));
  514. return Error::success();
  515. }
  516. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
  517. P.format(" `{0}`", Data.Name);
  518. AutoIndent Indent(P, 7);
  519. P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type),
  520. formatSegmentOffset(Data.Segment, Data.DataOffset));
  521. return Error::success();
  522. }
  523. Error MinimalSymbolDumper::visitKnownRecord(
  524. CVSymbol &CVR, DefRangeFramePointerRelFullScopeSym &Def) {
  525. P.format(" offset = {0}", Def.Offset);
  526. return Error::success();
  527. }
  528. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  529. DefRangeFramePointerRelSym &Def) {
  530. AutoIndent Indent(P, 7);
  531. P.formatLine("offset = {0}, range = {1}", Def.Hdr.Offset,
  532. formatRange(Def.Range));
  533. P.formatLine("gaps = [{0}]", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
  534. return Error::success();
  535. }
  536. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  537. DefRangeRegisterRelSym &Def) {
  538. AutoIndent Indent(P, 7);
  539. P.formatLine("register = {0}, offset = {1}, offset in parent = {2}, has "
  540. "spilled udt = {3}",
  541. formatRegisterId(Def.Hdr.Register, CompilationCPU),
  542. int32_t(Def.Hdr.BasePointerOffset), Def.offsetInParent(),
  543. Def.hasSpilledUDTMember());
  544. P.formatLine("range = {0}, gaps = [{1}]", formatRange(Def.Range),
  545. formatGaps(P.getIndentLevel() + 9, Def.Gaps));
  546. return Error::success();
  547. }
  548. Error MinimalSymbolDumper::visitKnownRecord(
  549. CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
  550. AutoIndent Indent(P, 7);
  551. P.formatLine("register = {0}, may have no name = {1}, range start = "
  552. "{2}, length = {3}",
  553. formatRegisterId(DefRangeRegister.Hdr.Register, CompilationCPU),
  554. bool(DefRangeRegister.Hdr.MayHaveNoName),
  555. formatSegmentOffset(DefRangeRegister.Range.ISectStart,
  556. DefRangeRegister.Range.OffsetStart),
  557. DefRangeRegister.Range.Range);
  558. P.formatLine("gaps = [{0}]",
  559. formatGaps(P.getIndentLevel() + 9, DefRangeRegister.Gaps));
  560. return Error::success();
  561. }
  562. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  563. DefRangeSubfieldRegisterSym &Def) {
  564. AutoIndent Indent(P, 7);
  565. bool NoName = !!(Def.Hdr.MayHaveNoName == 0);
  566. P.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}",
  567. formatRegisterId(Def.Hdr.Register, CompilationCPU), NoName,
  568. uint32_t(Def.Hdr.OffsetInParent));
  569. P.formatLine("range = {0}, gaps = [{1}]", formatRange(Def.Range),
  570. formatGaps(P.getIndentLevel() + 9, Def.Gaps));
  571. return Error::success();
  572. }
  573. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  574. DefRangeSubfieldSym &Def) {
  575. AutoIndent Indent(P, 7);
  576. P.formatLine("program = {0}, offset in parent = {1}, range = {2}",
  577. Def.Program, Def.OffsetInParent, formatRange(Def.Range));
  578. P.formatLine("gaps = [{0}]", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
  579. return Error::success();
  580. }
  581. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DefRangeSym &Def) {
  582. AutoIndent Indent(P, 7);
  583. P.formatLine("program = {0}, range = {1}", Def.Program,
  584. formatRange(Def.Range));
  585. P.formatLine("gaps = [{0}]", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
  586. return Error::success();
  587. }
  588. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameCookieSym &FC) {
  589. AutoIndent Indent(P, 7);
  590. P.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}",
  591. FC.CodeOffset, formatRegisterId(FC.Register, CompilationCPU),
  592. formatCookieKind(FC.CookieKind), FC.Flags);
  593. return Error::success();
  594. }
  595. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameProcSym &FP) {
  596. AutoIndent Indent(P, 7);
  597. P.formatLine("size = {0}, padding size = {1}, offset to padding = {2}",
  598. FP.TotalFrameBytes, FP.PaddingFrameBytes, FP.OffsetToPadding);
  599. P.formatLine("bytes of callee saved registers = {0}, exception handler addr "
  600. "= {1}",
  601. FP.BytesOfCalleeSavedRegisters,
  602. formatSegmentOffset(FP.SectionIdOfExceptionHandler,
  603. FP.OffsetOfExceptionHandler));
  604. P.formatLine(
  605. "local fp reg = {0}, param fp reg = {1}",
  606. formatRegisterId(FP.getLocalFramePtrReg(CompilationCPU), CompilationCPU),
  607. formatRegisterId(FP.getParamFramePtrReg(CompilationCPU), CompilationCPU));
  608. P.formatLine("flags = {0}",
  609. formatFrameProcedureOptions(P.getIndentLevel() + 9, FP.Flags));
  610. return Error::success();
  611. }
  612. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  613. HeapAllocationSiteSym &HAS) {
  614. AutoIndent Indent(P, 7);
  615. P.formatLine("type = {0}, addr = {1} call size = {2}", typeIndex(HAS.Type),
  616. formatSegmentOffset(HAS.Segment, HAS.CodeOffset),
  617. HAS.CallInstructionSize);
  618. return Error::success();
  619. }
  620. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, InlineSiteSym &IS) {
  621. AutoIndent Indent(P, 7);
  622. P.formatLine("inlinee = {0}, parent = {1}, end = {2}", idIndex(IS.Inlinee),
  623. IS.Parent, IS.End);
  624. // Break down the annotation byte code and calculate code and line offsets.
  625. // FIXME: It would be helpful if we could look up the initial file and inlinee
  626. // lines offset using the inlinee index above.
  627. uint32_t CodeOffset = 0;
  628. int32_t LineOffset = 0;
  629. for (auto &Annot : IS.annotations()) {
  630. P.formatLine(" {0}", fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));
  631. auto formatCodeOffset = [&](uint32_t Delta) {
  632. CodeOffset += Delta;
  633. P.format(" code 0x{0} (+0x{1})", utohexstr(CodeOffset), utohexstr(Delta));
  634. };
  635. auto formatCodeLength = [&](uint32_t Length) {
  636. // Notably, changing the code length does not affect the code offset.
  637. P.format(" code end 0x{0} (+0x{1})", utohexstr(CodeOffset + Length),
  638. utohexstr(Length));
  639. };
  640. auto formatLineOffset = [&](int32_t Delta) {
  641. LineOffset += Delta;
  642. char Sign = Delta > 0 ? '+' : '-';
  643. P.format(" line {0} ({1}{2})", LineOffset, Sign, std::abs(Delta));
  644. };
  645. // Use the opcode to interpret the integer values.
  646. switch (Annot.OpCode) {
  647. case BinaryAnnotationsOpCode::Invalid:
  648. break;
  649. case BinaryAnnotationsOpCode::CodeOffset:
  650. case BinaryAnnotationsOpCode::ChangeCodeOffset:
  651. formatCodeOffset(Annot.U1);
  652. break;
  653. case BinaryAnnotationsOpCode::ChangeLineOffset:
  654. formatLineOffset(Annot.S1);
  655. break;
  656. case BinaryAnnotationsOpCode::ChangeCodeLength:
  657. formatCodeLength(Annot.U1);
  658. // Apparently this annotation updates the code offset. It's hard to make
  659. // MSVC produce this opcode, but clang uses it, and debuggers seem to use
  660. // this interpretation.
  661. CodeOffset += Annot.U1;
  662. break;
  663. case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
  664. formatCodeOffset(Annot.U1);
  665. formatLineOffset(Annot.S1);
  666. break;
  667. case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
  668. formatCodeOffset(Annot.U2);
  669. formatCodeLength(Annot.U1);
  670. break;
  671. case BinaryAnnotationsOpCode::ChangeFile: {
  672. uint32_t FileOffset = Annot.U1;
  673. StringRef Filename = "<unknown>";
  674. if (SymGroup) {
  675. if (Expected<StringRef> MaybeFile =
  676. SymGroup->getNameFromStringTable(FileOffset))
  677. Filename = *MaybeFile;
  678. else
  679. return MaybeFile.takeError();
  680. }
  681. P.format(" setfile {0} 0x{1}", utohexstr(FileOffset));
  682. break;
  683. }
  684. // The rest of these are hard to convince MSVC to emit, so they are not as
  685. // well understood.
  686. case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
  687. formatCodeOffset(Annot.U1);
  688. break;
  689. case BinaryAnnotationsOpCode::ChangeLineEndDelta:
  690. case BinaryAnnotationsOpCode::ChangeRangeKind:
  691. case BinaryAnnotationsOpCode::ChangeColumnStart:
  692. case BinaryAnnotationsOpCode::ChangeColumnEnd:
  693. P.format(" {0} {1}", Annot.Name, Annot.U1);
  694. break;
  695. case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
  696. P.format(" {0} {1}", Annot.Name, Annot.S1);
  697. break;
  698. }
  699. }
  700. return Error::success();
  701. }
  702. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  703. RegisterSym &Register) {
  704. P.format(" `{0}`", Register.Name);
  705. AutoIndent Indent(P, 7);
  706. P.formatLine("register = {0}, type = {1}",
  707. formatRegisterId(Register.Register, CompilationCPU),
  708. typeIndex(Register.Index));
  709. return Error::success();
  710. }
  711. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  712. PublicSym32 &Public) {
  713. P.format(" `{0}`", Public.Name);
  714. AutoIndent Indent(P, 7);
  715. P.formatLine("flags = {0}, addr = {1}",
  716. formatPublicSymFlags(P.getIndentLevel() + 9, Public.Flags),
  717. formatSegmentOffset(Public.Segment, Public.Offset));
  718. return Error::success();
  719. }
  720. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcRefSym &PR) {
  721. P.format(" `{0}`", PR.Name);
  722. AutoIndent Indent(P, 7);
  723. P.formatLine("module = {0}, sum name = {1}, offset = {2}", PR.Module,
  724. PR.SumName, PR.SymOffset);
  725. return Error::success();
  726. }
  727. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
  728. P.format(" `{0}` (addr = {1})", Label.Name,
  729. formatSegmentOffset(Label.Segment, Label.CodeOffset));
  730. AutoIndent Indent(P, 7);
  731. P.formatLine("flags = {0}",
  732. formatProcSymFlags(P.getIndentLevel() + 9, Label.Flags));
  733. return Error::success();
  734. }
  735. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
  736. P.format(" `{0}`", Local.Name);
  737. AutoIndent Indent(P, 7);
  738. std::string FlagStr =
  739. formatLocalSymFlags(P.getIndentLevel() + 9, Local.Flags);
  740. P.formatLine("type={0}, flags = {1}", typeIndex(Local.Type), FlagStr);
  741. return Error::success();
  742. }
  743. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  744. ObjNameSym &ObjName) {
  745. P.format(" sig={0}, `{1}`", ObjName.Signature, ObjName.Name);
  746. return Error::success();
  747. }
  748. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
  749. P.format(" `{0}`", Proc.Name);
  750. AutoIndent Indent(P, 7);
  751. P.formatLine("parent = {0}, end = {1}, addr = {2}, code size = {3}",
  752. Proc.Parent, Proc.End,
  753. formatSegmentOffset(Proc.Segment, Proc.CodeOffset),
  754. Proc.CodeSize);
  755. bool IsType = true;
  756. switch (Proc.getKind()) {
  757. case SymbolRecordKind::GlobalProcIdSym:
  758. case SymbolRecordKind::ProcIdSym:
  759. case SymbolRecordKind::DPCProcIdSym:
  760. IsType = false;
  761. break;
  762. default:
  763. break;
  764. }
  765. P.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}",
  766. typeOrIdIndex(Proc.FunctionType, IsType), Proc.DbgStart,
  767. Proc.DbgEnd,
  768. formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags));
  769. return Error::success();
  770. }
  771. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  772. ScopeEndSym &ScopeEnd) {
  773. return Error::success();
  774. }
  775. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
  776. AutoIndent Indent(P, 7);
  777. for (const auto &I : Caller.Indices) {
  778. P.formatLine("callee: {0}", idIndex(I));
  779. }
  780. return Error::success();
  781. }
  782. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  783. RegRelativeSym &RegRel) {
  784. P.format(" `{0}`", RegRel.Name);
  785. AutoIndent Indent(P, 7);
  786. P.formatLine(
  787. "type = {0}, register = {1}, offset = {2}", typeIndex(RegRel.Type),
  788. formatRegisterId(RegRel.Register, CompilationCPU), RegRel.Offset);
  789. return Error::success();
  790. }
  791. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  792. ThreadLocalDataSym &Data) {
  793. P.format(" `{0}`", Data.Name);
  794. AutoIndent Indent(P, 7);
  795. P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type),
  796. formatSegmentOffset(Data.Segment, Data.DataOffset));
  797. return Error::success();
  798. }
  799. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
  800. P.format(" `{0}`", UDT.Name);
  801. AutoIndent Indent(P, 7);
  802. P.formatLine("original type = {0}", UDT.Type);
  803. return Error::success();
  804. }
  805. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  806. UsingNamespaceSym &UN) {
  807. P.format(" `{0}`", UN.Name);
  808. return Error::success();
  809. }
  810. Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
  811. AnnotationSym &Annot) {
  812. AutoIndent Indent(P, 7);
  813. P.formatLine("addr = {0}", formatSegmentOffset(Annot.Segment, Annot.CodeOffset));
  814. P.formatLine("strings = {0}", typesetStringList(P.getIndentLevel() + 9 + 2,
  815. Annot.Strings));
  816. return Error::success();
  817. }