SymbolDumper.cpp 26 KB

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