SymbolDumper.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. //===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- 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/CodeView/SymbolDumper.h"
  9. #include "llvm/ADT/StringRef.h"
  10. #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
  11. #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
  12. #include "llvm/DebugInfo/CodeView/EnumTables.h"
  13. #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
  14. #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
  15. #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
  16. #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
  17. #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
  18. #include "llvm/DebugInfo/CodeView/TypeIndex.h"
  19. #include "llvm/Support/Error.h"
  20. #include "llvm/Support/ScopedPrinter.h"
  21. using namespace llvm;
  22. using namespace llvm::codeview;
  23. namespace {
  24. /// Use this private dumper implementation to keep implementation details about
  25. /// the visitor out of SymbolDumper.h.
  26. class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
  27. public:
  28. CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,
  29. ScopedPrinter &W, CPUType CPU, bool PrintRecordBytes)
  30. : Types(Types), ObjDelegate(ObjDelegate), W(W), CompilationCPUType(CPU),
  31. PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
  32. /// CVSymbolVisitor overrides.
  33. #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
  34. Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
  35. #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  36. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  37. Error visitSymbolBegin(CVSymbol &Record) override;
  38. Error visitSymbolEnd(CVSymbol &Record) override;
  39. Error visitUnknownSymbol(CVSymbol &Record) override;
  40. CPUType getCompilationCPUType() const { return CompilationCPUType; }
  41. private:
  42. void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
  43. uint32_t RelocationOffset);
  44. void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
  45. void printTypeIndex(StringRef FieldName, TypeIndex TI);
  46. TypeCollection &Types;
  47. SymbolDumpDelegate *ObjDelegate;
  48. ScopedPrinter &W;
  49. /// Save the machine or CPU type when dumping a compile symbols.
  50. CPUType CompilationCPUType = CPUType::X64;
  51. bool PrintRecordBytes;
  52. bool InFunctionScope;
  53. };
  54. }
  55. static StringRef getSymbolKindName(SymbolKind Kind) {
  56. switch (Kind) {
  57. #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
  58. case EnumName: \
  59. return #Name;
  60. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  61. default:
  62. break;
  63. }
  64. return "UnknownSym";
  65. }
  66. void CVSymbolDumperImpl::printLocalVariableAddrRange(
  67. const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
  68. DictScope S(W, "LocalVariableAddrRange");
  69. if (ObjDelegate)
  70. ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
  71. Range.OffsetStart);
  72. W.printHex("ISectStart", Range.ISectStart);
  73. W.printHex("Range", Range.Range);
  74. }
  75. void CVSymbolDumperImpl::printLocalVariableAddrGap(
  76. ArrayRef<LocalVariableAddrGap> Gaps) {
  77. for (auto &Gap : Gaps) {
  78. ListScope S(W, "LocalVariableAddrGap");
  79. W.printHex("GapStartOffset", Gap.GapStartOffset);
  80. W.printHex("Range", Gap.Range);
  81. }
  82. }
  83. void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
  84. codeview::printTypeIndex(W, FieldName, TI, Types);
  85. }
  86. Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
  87. W.startLine() << getSymbolKindName(CVR.kind());
  88. W.getOStream() << " {\n";
  89. W.indent();
  90. W.printEnum("Kind", unsigned(CVR.kind()), getSymbolTypeNames());
  91. return Error::success();
  92. }
  93. Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {
  94. if (PrintRecordBytes && ObjDelegate)
  95. ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());
  96. W.unindent();
  97. W.startLine() << "}\n";
  98. return Error::success();
  99. }
  100. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
  101. StringRef LinkageName;
  102. W.printHex("PtrParent", Block.Parent);
  103. W.printHex("PtrEnd", Block.End);
  104. W.printHex("CodeSize", Block.CodeSize);
  105. if (ObjDelegate) {
  106. ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
  107. Block.CodeOffset, &LinkageName);
  108. }
  109. W.printHex("Segment", Block.Segment);
  110. W.printString("BlockName", Block.Name);
  111. W.printString("LinkageName", LinkageName);
  112. return Error::success();
  113. }
  114. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
  115. W.printString("Name", Thunk.Name);
  116. W.printNumber("Parent", Thunk.Parent);
  117. W.printNumber("End", Thunk.End);
  118. W.printNumber("Next", Thunk.Next);
  119. W.printNumber("Off", Thunk.Offset);
  120. W.printNumber("Seg", Thunk.Segment);
  121. W.printNumber("Len", Thunk.Length);
  122. W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());
  123. return Error::success();
  124. }
  125. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  126. TrampolineSym &Tramp) {
  127. W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());
  128. W.printNumber("Size", Tramp.Size);
  129. W.printNumber("ThunkOff", Tramp.ThunkOffset);
  130. W.printNumber("TargetOff", Tramp.TargetOffset);
  131. W.printNumber("ThunkSection", Tramp.ThunkSection);
  132. W.printNumber("TargetSection", Tramp.TargetSection);
  133. return Error::success();
  134. }
  135. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {
  136. W.printNumber("SectionNumber", Section.SectionNumber);
  137. W.printNumber("Alignment", Section.Alignment);
  138. W.printNumber("Rva", Section.Rva);
  139. W.printNumber("Length", Section.Length);
  140. W.printFlags("Characteristics", Section.Characteristics,
  141. getImageSectionCharacteristicNames(),
  142. COFF::SectionCharacteristics(0x00F00000));
  143. W.printString("Name", Section.Name);
  144. return Error::success();
  145. }
  146. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  147. CoffGroupSym &CoffGroup) {
  148. W.printNumber("Size", CoffGroup.Size);
  149. W.printFlags("Characteristics", CoffGroup.Characteristics,
  150. getImageSectionCharacteristicNames(),
  151. COFF::SectionCharacteristics(0x00F00000));
  152. W.printNumber("Offset", CoffGroup.Offset);
  153. W.printNumber("Segment", CoffGroup.Segment);
  154. W.printString("Name", CoffGroup.Name);
  155. return Error::success();
  156. }
  157. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  158. BPRelativeSym &BPRel) {
  159. W.printNumber("Offset", BPRel.Offset);
  160. printTypeIndex("Type", BPRel.Type);
  161. W.printString("VarName", BPRel.Name);
  162. return Error::success();
  163. }
  164. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  165. BuildInfoSym &BuildInfo) {
  166. printTypeIndex("BuildId", BuildInfo.BuildId);
  167. return Error::success();
  168. }
  169. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  170. CallSiteInfoSym &CallSiteInfo) {
  171. StringRef LinkageName;
  172. if (ObjDelegate) {
  173. ObjDelegate->printRelocatedField("CodeOffset",
  174. CallSiteInfo.getRelocationOffset(),
  175. CallSiteInfo.CodeOffset, &LinkageName);
  176. }
  177. W.printHex("Segment", CallSiteInfo.Segment);
  178. printTypeIndex("Type", CallSiteInfo.Type);
  179. if (!LinkageName.empty())
  180. W.printString("LinkageName", LinkageName);
  181. return Error::success();
  182. }
  183. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  184. EnvBlockSym &EnvBlock) {
  185. ListScope L(W, "Entries");
  186. for (auto Entry : EnvBlock.Fields) {
  187. W.printString(Entry);
  188. }
  189. return Error::success();
  190. }
  191. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  192. FileStaticSym &FileStatic) {
  193. printTypeIndex("Index", FileStatic.Index);
  194. W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
  195. W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
  196. W.printString("Name", FileStatic.Name);
  197. return Error::success();
  198. }
  199. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
  200. W.printNumber("Ordinal", Export.Ordinal);
  201. W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());
  202. W.printString("Name", Export.Name);
  203. return Error::success();
  204. }
  205. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  206. Compile2Sym &Compile2) {
  207. W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());
  208. W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());
  209. W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
  210. CompilationCPUType = Compile2.Machine;
  211. std::string FrontendVersion;
  212. {
  213. raw_string_ostream Out(FrontendVersion);
  214. Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor
  215. << '.' << Compile2.VersionFrontendBuild;
  216. }
  217. std::string BackendVersion;
  218. {
  219. raw_string_ostream Out(BackendVersion);
  220. Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor
  221. << '.' << Compile2.VersionBackendBuild;
  222. }
  223. W.printString("FrontendVersion", FrontendVersion);
  224. W.printString("BackendVersion", BackendVersion);
  225. W.printString("VersionName", Compile2.Version);
  226. return Error::success();
  227. }
  228. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  229. Compile3Sym &Compile3) {
  230. W.printEnum("Language", uint8_t(Compile3.getLanguage()), getSourceLanguageNames());
  231. W.printFlags("Flags", uint32_t(Compile3.getFlags()),
  232. getCompileSym3FlagNames());
  233. W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
  234. CompilationCPUType = Compile3.Machine;
  235. std::string FrontendVersion;
  236. {
  237. raw_string_ostream Out(FrontendVersion);
  238. Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor
  239. << '.' << Compile3.VersionFrontendBuild << '.'
  240. << Compile3.VersionFrontendQFE;
  241. }
  242. std::string BackendVersion;
  243. {
  244. raw_string_ostream Out(BackendVersion);
  245. Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor
  246. << '.' << Compile3.VersionBackendBuild << '.'
  247. << Compile3.VersionBackendQFE;
  248. }
  249. W.printString("FrontendVersion", FrontendVersion);
  250. W.printString("BackendVersion", BackendVersion);
  251. W.printString("VersionName", Compile3.Version);
  252. return Error::success();
  253. }
  254. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  255. ConstantSym &Constant) {
  256. printTypeIndex("Type", Constant.Type);
  257. W.printNumber("Value", Constant.Value);
  258. W.printString("Name", Constant.Name);
  259. return Error::success();
  260. }
  261. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
  262. StringRef LinkageName;
  263. if (ObjDelegate) {
  264. ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
  265. Data.DataOffset, &LinkageName);
  266. }
  267. printTypeIndex("Type", Data.Type);
  268. W.printString("DisplayName", Data.Name);
  269. if (!LinkageName.empty())
  270. W.printString("LinkageName", LinkageName);
  271. return Error::success();
  272. }
  273. Error CVSymbolDumperImpl::visitKnownRecord(
  274. CVSymbol &CVR,
  275. DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
  276. W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
  277. return Error::success();
  278. }
  279. Error CVSymbolDumperImpl::visitKnownRecord(
  280. CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
  281. W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
  282. printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
  283. DefRangeFramePointerRel.getRelocationOffset());
  284. printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
  285. return Error::success();
  286. }
  287. Error CVSymbolDumperImpl::visitKnownRecord(
  288. CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
  289. W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register),
  290. getRegisterNames(CompilationCPUType));
  291. W.printBoolean("HasSpilledUDTMember",
  292. DefRangeRegisterRel.hasSpilledUDTMember());
  293. W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
  294. W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);
  295. printLocalVariableAddrRange(DefRangeRegisterRel.Range,
  296. DefRangeRegisterRel.getRelocationOffset());
  297. printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
  298. return Error::success();
  299. }
  300. Error CVSymbolDumperImpl::visitKnownRecord(
  301. CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
  302. W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
  303. getRegisterNames(CompilationCPUType));
  304. W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
  305. printLocalVariableAddrRange(DefRangeRegister.Range,
  306. DefRangeRegister.getRelocationOffset());
  307. printLocalVariableAddrGap(DefRangeRegister.Gaps);
  308. return Error::success();
  309. }
  310. Error CVSymbolDumperImpl::visitKnownRecord(
  311. CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
  312. W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
  313. getRegisterNames(CompilationCPUType));
  314. W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
  315. W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
  316. printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
  317. DefRangeSubfieldRegister.getRelocationOffset());
  318. printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
  319. return Error::success();
  320. }
  321. Error CVSymbolDumperImpl::visitKnownRecord(
  322. CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
  323. if (ObjDelegate) {
  324. DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
  325. auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
  326. if (!ExpectedProgram) {
  327. consumeError(ExpectedProgram.takeError());
  328. return llvm::make_error<CodeViewError>(
  329. "String table offset outside of bounds of String Table!");
  330. }
  331. W.printString("Program", *ExpectedProgram);
  332. }
  333. W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
  334. printLocalVariableAddrRange(DefRangeSubfield.Range,
  335. DefRangeSubfield.getRelocationOffset());
  336. printLocalVariableAddrGap(DefRangeSubfield.Gaps);
  337. return Error::success();
  338. }
  339. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  340. DefRangeSym &DefRange) {
  341. if (ObjDelegate) {
  342. DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
  343. auto ExpectedProgram = Strings.getString(DefRange.Program);
  344. if (!ExpectedProgram) {
  345. consumeError(ExpectedProgram.takeError());
  346. return llvm::make_error<CodeViewError>(
  347. "String table offset outside of bounds of String Table!");
  348. }
  349. W.printString("Program", *ExpectedProgram);
  350. }
  351. printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
  352. printLocalVariableAddrGap(DefRange.Gaps);
  353. return Error::success();
  354. }
  355. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  356. FrameCookieSym &FrameCookie) {
  357. StringRef LinkageName;
  358. if (ObjDelegate) {
  359. ObjDelegate->printRelocatedField("CodeOffset",
  360. FrameCookie.getRelocationOffset(),
  361. FrameCookie.CodeOffset, &LinkageName);
  362. }
  363. W.printEnum("Register", uint16_t(FrameCookie.Register),
  364. getRegisterNames(CompilationCPUType));
  365. W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
  366. getFrameCookieKindNames());
  367. W.printHex("Flags", FrameCookie.Flags);
  368. return Error::success();
  369. }
  370. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  371. FrameProcSym &FrameProc) {
  372. W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
  373. W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
  374. W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
  375. W.printHex("BytesOfCalleeSavedRegisters",
  376. FrameProc.BytesOfCalleeSavedRegisters);
  377. W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
  378. W.printHex("SectionIdOfExceptionHandler",
  379. FrameProc.SectionIdOfExceptionHandler);
  380. W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
  381. getFrameProcSymFlagNames());
  382. W.printEnum("LocalFramePtrReg",
  383. uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)),
  384. getRegisterNames(CompilationCPUType));
  385. W.printEnum("ParamFramePtrReg",
  386. uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)),
  387. getRegisterNames(CompilationCPUType));
  388. return Error::success();
  389. }
  390. Error CVSymbolDumperImpl::visitKnownRecord(
  391. CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
  392. StringRef LinkageName;
  393. if (ObjDelegate) {
  394. ObjDelegate->printRelocatedField("CodeOffset",
  395. HeapAllocSite.getRelocationOffset(),
  396. HeapAllocSite.CodeOffset, &LinkageName);
  397. }
  398. W.printHex("Segment", HeapAllocSite.Segment);
  399. W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
  400. printTypeIndex("Type", HeapAllocSite.Type);
  401. if (!LinkageName.empty())
  402. W.printString("LinkageName", LinkageName);
  403. return Error::success();
  404. }
  405. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  406. InlineSiteSym &InlineSite) {
  407. W.printHex("PtrParent", InlineSite.Parent);
  408. W.printHex("PtrEnd", InlineSite.End);
  409. printTypeIndex("Inlinee", InlineSite.Inlinee);
  410. ListScope BinaryAnnotations(W, "BinaryAnnotations");
  411. for (auto &Annotation : InlineSite.annotations()) {
  412. switch (Annotation.OpCode) {
  413. case BinaryAnnotationsOpCode::Invalid:
  414. W.printString("(Annotation Padding)");
  415. break;
  416. case BinaryAnnotationsOpCode::CodeOffset:
  417. case BinaryAnnotationsOpCode::ChangeCodeOffset:
  418. case BinaryAnnotationsOpCode::ChangeCodeLength:
  419. W.printHex(Annotation.Name, Annotation.U1);
  420. break;
  421. case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
  422. case BinaryAnnotationsOpCode::ChangeLineEndDelta:
  423. case BinaryAnnotationsOpCode::ChangeRangeKind:
  424. case BinaryAnnotationsOpCode::ChangeColumnStart:
  425. case BinaryAnnotationsOpCode::ChangeColumnEnd:
  426. W.printNumber(Annotation.Name, Annotation.U1);
  427. break;
  428. case BinaryAnnotationsOpCode::ChangeLineOffset:
  429. case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
  430. W.printNumber(Annotation.Name, Annotation.S1);
  431. break;
  432. case BinaryAnnotationsOpCode::ChangeFile:
  433. if (ObjDelegate) {
  434. W.printHex("ChangeFile",
  435. ObjDelegate->getFileNameForFileOffset(Annotation.U1),
  436. Annotation.U1);
  437. } else {
  438. W.printHex("ChangeFile", Annotation.U1);
  439. }
  440. break;
  441. case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
  442. W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
  443. << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
  444. << "}\n";
  445. break;
  446. }
  447. case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
  448. W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
  449. << W.hex(Annotation.U2)
  450. << ", Length: " << W.hex(Annotation.U1) << "}\n";
  451. break;
  452. }
  453. }
  454. }
  455. return Error::success();
  456. }
  457. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  458. RegisterSym &Register) {
  459. printTypeIndex("Type", Register.Index);
  460. W.printEnum("Seg", uint16_t(Register.Register),
  461. getRegisterNames(CompilationCPUType));
  462. W.printString("Name", Register.Name);
  463. return Error::success();
  464. }
  465. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
  466. W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());
  467. W.printNumber("Seg", Public.Segment);
  468. W.printNumber("Off", Public.Offset);
  469. W.printString("Name", Public.Name);
  470. return Error::success();
  471. }
  472. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
  473. W.printNumber("SumName", ProcRef.SumName);
  474. W.printNumber("SymOffset", ProcRef.SymOffset);
  475. W.printNumber("Mod", ProcRef.Module);
  476. W.printString("Name", ProcRef.Name);
  477. return Error::success();
  478. }
  479. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
  480. StringRef LinkageName;
  481. if (ObjDelegate) {
  482. ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
  483. Label.CodeOffset, &LinkageName);
  484. }
  485. W.printHex("Segment", Label.Segment);
  486. W.printHex("Flags", uint8_t(Label.Flags));
  487. W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
  488. W.printString("DisplayName", Label.Name);
  489. if (!LinkageName.empty())
  490. W.printString("LinkageName", LinkageName);
  491. return Error::success();
  492. }
  493. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
  494. printTypeIndex("Type", Local.Type);
  495. W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
  496. W.printString("VarName", Local.Name);
  497. return Error::success();
  498. }
  499. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
  500. W.printHex("Signature", ObjName.Signature);
  501. W.printString("ObjectName", ObjName.Name);
  502. return Error::success();
  503. }
  504. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
  505. if (InFunctionScope)
  506. return llvm::make_error<CodeViewError>(
  507. "Visiting a ProcSym while inside function scope!");
  508. InFunctionScope = true;
  509. StringRef LinkageName;
  510. W.printHex("PtrParent", Proc.Parent);
  511. W.printHex("PtrEnd", Proc.End);
  512. W.printHex("PtrNext", Proc.Next);
  513. W.printHex("CodeSize", Proc.CodeSize);
  514. W.printHex("DbgStart", Proc.DbgStart);
  515. W.printHex("DbgEnd", Proc.DbgEnd);
  516. printTypeIndex("FunctionType", Proc.FunctionType);
  517. if (ObjDelegate) {
  518. ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
  519. Proc.CodeOffset, &LinkageName);
  520. }
  521. W.printHex("Segment", Proc.Segment);
  522. W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
  523. getProcSymFlagNames());
  524. W.printString("DisplayName", Proc.Name);
  525. if (!LinkageName.empty())
  526. W.printString("LinkageName", LinkageName);
  527. return Error::success();
  528. }
  529. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  530. ScopeEndSym &ScopeEnd) {
  531. InFunctionScope = false;
  532. return Error::success();
  533. }
  534. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
  535. ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
  536. for (auto FuncID : Caller.Indices)
  537. printTypeIndex("FuncID", FuncID);
  538. return Error::success();
  539. }
  540. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  541. RegRelativeSym &RegRel) {
  542. W.printHex("Offset", RegRel.Offset);
  543. printTypeIndex("Type", RegRel.Type);
  544. W.printEnum("Register", uint16_t(RegRel.Register),
  545. getRegisterNames(CompilationCPUType));
  546. W.printString("VarName", RegRel.Name);
  547. return Error::success();
  548. }
  549. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  550. ThreadLocalDataSym &Data) {
  551. StringRef LinkageName;
  552. if (ObjDelegate) {
  553. ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
  554. Data.DataOffset, &LinkageName);
  555. }
  556. printTypeIndex("Type", Data.Type);
  557. W.printString("DisplayName", Data.Name);
  558. if (!LinkageName.empty())
  559. W.printString("LinkageName", LinkageName);
  560. return Error::success();
  561. }
  562. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
  563. printTypeIndex("Type", UDT.Type);
  564. W.printString("UDTName", UDT.Name);
  565. return Error::success();
  566. }
  567. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  568. UsingNamespaceSym &UN) {
  569. W.printString("Namespace", UN.Name);
  570. return Error::success();
  571. }
  572. Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
  573. AnnotationSym &Annot) {
  574. W.printHex("Offset", Annot.CodeOffset);
  575. W.printHex("Segment", Annot.Segment);
  576. ListScope S(W, "Strings");
  577. for (StringRef Str : Annot.Strings)
  578. W.printString(Str);
  579. return Error::success();
  580. }
  581. Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
  582. W.printNumber("Length", CVR.length());
  583. return Error::success();
  584. }
  585. Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
  586. SymbolVisitorCallbackPipeline Pipeline;
  587. SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
  588. CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
  589. PrintRecordBytes);
  590. Pipeline.addCallbackToPipeline(Deserializer);
  591. Pipeline.addCallbackToPipeline(Dumper);
  592. CVSymbolVisitor Visitor(Pipeline);
  593. auto Err = Visitor.visitSymbolRecord(Record);
  594. CompilationCPUType = Dumper.getCompilationCPUType();
  595. return Err;
  596. }
  597. Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
  598. SymbolVisitorCallbackPipeline Pipeline;
  599. SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
  600. CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
  601. PrintRecordBytes);
  602. Pipeline.addCallbackToPipeline(Deserializer);
  603. Pipeline.addCallbackToPipeline(Dumper);
  604. CVSymbolVisitor Visitor(Pipeline);
  605. auto Err = Visitor.visitSymbolStream(Symbols);
  606. CompilationCPUType = Dumper.getCompilationCPUType();
  607. return Err;
  608. }