1aaad5744SZachary Turner //===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===//
2aaad5744SZachary Turner //
3aaad5744SZachary Turner //                     The LLVM Compiler Infrastructure
4aaad5744SZachary Turner //
5aaad5744SZachary Turner // This file is distributed under the University of Illinois Open Source
6aaad5744SZachary Turner // License. See LICENSE.TXT for details.
7aaad5744SZachary Turner //
8aaad5744SZachary Turner //===----------------------------------------------------------------------===//
9aaad5744SZachary Turner 
10aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
11aaad5744SZachary Turner #include "llvm/ADT/SmallString.h"
12aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
13591312c5SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
1493839cb4SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h"
150d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
16aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
17aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
180d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
190d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
20aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/TypeIndex.h"
210d840744SZachary Turner #include "llvm/Support/Error.h"
22aaad5744SZachary Turner #include "llvm/Support/ScopedPrinter.h"
23aaad5744SZachary Turner 
24aaad5744SZachary Turner #include <system_error>
25aaad5744SZachary Turner 
26aaad5744SZachary Turner using namespace llvm;
27aaad5744SZachary Turner using namespace llvm::codeview;
28aaad5744SZachary Turner 
29aaad5744SZachary Turner namespace {
30aaad5744SZachary Turner /// Use this private dumper implementation to keep implementation details about
31aaad5744SZachary Turner /// the visitor out of SymbolDumper.h.
320d840744SZachary Turner class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
33aaad5744SZachary Turner public:
34526f4f2aSZachary Turner   CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,
353e78e2d4SZachary Turner                      ScopedPrinter &W, bool PrintRecordBytes)
36526f4f2aSZachary Turner       : Types(Types), ObjDelegate(ObjDelegate), W(W),
370d840744SZachary Turner         PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
38aaad5744SZachary Turner 
39aaad5744SZachary Turner /// CVSymbolVisitor overrides.
40aaad5744SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
410d840744SZachary Turner   Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
42aaad5744SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
43d427383cSZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
44aaad5744SZachary Turner 
450d840744SZachary Turner   Error visitSymbolBegin(CVSymbol &Record) override;
460d840744SZachary Turner   Error visitSymbolEnd(CVSymbol &Record) override;
470d840744SZachary Turner   Error visitUnknownSymbol(CVSymbol &Record) override;
48aaad5744SZachary Turner 
49aaad5744SZachary Turner private:
50aaad5744SZachary Turner   void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
51aaad5744SZachary Turner                                    uint32_t RelocationOffset);
52aaad5744SZachary Turner   void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
53629cb7d8SZachary Turner   void printTypeIndex(StringRef FieldName, TypeIndex TI);
54aaad5744SZachary Turner 
55526f4f2aSZachary Turner   TypeCollection &Types;
56aaad5744SZachary Turner   SymbolDumpDelegate *ObjDelegate;
57aaad5744SZachary Turner   ScopedPrinter &W;
58aaad5744SZachary Turner 
59aaad5744SZachary Turner   bool PrintRecordBytes;
60aaad5744SZachary Turner   bool InFunctionScope;
61aaad5744SZachary Turner };
62aaad5744SZachary Turner }
63aaad5744SZachary Turner 
648d8888ffSReid Kleckner static StringRef getSymbolKindName(SymbolKind Kind) {
658d8888ffSReid Kleckner   switch (Kind) {
668d8888ffSReid Kleckner #define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
678d8888ffSReid Kleckner   case EnumName:                                                               \
688d8888ffSReid Kleckner     return #Name;
698d8888ffSReid Kleckner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
708d8888ffSReid Kleckner   default:
718d8888ffSReid Kleckner     break;
728d8888ffSReid Kleckner   }
738d8888ffSReid Kleckner   return "UnknownSym";
748d8888ffSReid Kleckner }
758d8888ffSReid Kleckner 
76aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrRange(
77aaad5744SZachary Turner     const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
78aaad5744SZachary Turner   DictScope S(W, "LocalVariableAddrRange");
79aaad5744SZachary Turner   if (ObjDelegate)
80aaad5744SZachary Turner     ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
81aaad5744SZachary Turner                                      Range.OffsetStart);
82aaad5744SZachary Turner   W.printHex("ISectStart", Range.ISectStart);
83aaad5744SZachary Turner   W.printHex("Range", Range.Range);
84aaad5744SZachary Turner }
85aaad5744SZachary Turner 
86aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrGap(
87aaad5744SZachary Turner     ArrayRef<LocalVariableAddrGap> Gaps) {
88aaad5744SZachary Turner   for (auto &Gap : Gaps) {
89aaad5744SZachary Turner     ListScope S(W, "LocalVariableAddrGap");
90aaad5744SZachary Turner     W.printHex("GapStartOffset", Gap.GapStartOffset);
91aaad5744SZachary Turner     W.printHex("Range", Gap.Range);
92aaad5744SZachary Turner   }
93aaad5744SZachary Turner }
94aaad5744SZachary Turner 
95629cb7d8SZachary Turner void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
96526f4f2aSZachary Turner   codeview::printTypeIndex(W, FieldName, TI, Types);
97629cb7d8SZachary Turner }
98629cb7d8SZachary Turner 
990d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
1008d8888ffSReid Kleckner   W.startLine() << getSymbolKindName(CVR.Type);
1018d8888ffSReid Kleckner   W.getOStream() << " {\n";
1028d8888ffSReid Kleckner   W.indent();
1038d8888ffSReid Kleckner   W.printEnum("Kind", unsigned(CVR.Type), getSymbolTypeNames());
1040d840744SZachary Turner   return Error::success();
105aaad5744SZachary Turner }
106aaad5744SZachary Turner 
1070d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {
1080d840744SZachary Turner   if (PrintRecordBytes && ObjDelegate)
1090d840744SZachary Turner     ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());
1108d8888ffSReid Kleckner 
1118d8888ffSReid Kleckner   W.unindent();
1128d8888ffSReid Kleckner   W.startLine() << "}\n";
1130d840744SZachary Turner   return Error::success();
1140d840744SZachary Turner }
1150d840744SZachary Turner 
1160d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
117aaad5744SZachary Turner   StringRef LinkageName;
11846225b19SZachary Turner   W.printHex("PtrParent", Block.Parent);
11946225b19SZachary Turner   W.printHex("PtrEnd", Block.End);
12046225b19SZachary Turner   W.printHex("CodeSize", Block.CodeSize);
121aaad5744SZachary Turner   if (ObjDelegate) {
122aaad5744SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
12346225b19SZachary Turner                                      Block.CodeOffset, &LinkageName);
124aaad5744SZachary Turner   }
12546225b19SZachary Turner   W.printHex("Segment", Block.Segment);
126aaad5744SZachary Turner   W.printString("BlockName", Block.Name);
127aaad5744SZachary Turner   W.printString("LinkageName", LinkageName);
1280d840744SZachary Turner   return Error::success();
129aaad5744SZachary Turner }
130aaad5744SZachary Turner 
1310d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
13294ece8fbSBrock Wyma   W.printString("Name", Thunk.Name);
13346225b19SZachary Turner   W.printNumber("Parent", Thunk.Parent);
13446225b19SZachary Turner   W.printNumber("End", Thunk.End);
13546225b19SZachary Turner   W.printNumber("Next", Thunk.Next);
13646225b19SZachary Turner   W.printNumber("Off", Thunk.Offset);
13746225b19SZachary Turner   W.printNumber("Seg", Thunk.Segment);
13846225b19SZachary Turner   W.printNumber("Len", Thunk.Length);
13946225b19SZachary Turner   W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());
1400d840744SZachary Turner   return Error::success();
1414caa1bf0SZachary Turner }
1424caa1bf0SZachary Turner 
1430d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
1444caa1bf0SZachary Turner                                            TrampolineSym &Tramp) {
14546225b19SZachary Turner   W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());
14646225b19SZachary Turner   W.printNumber("Size", Tramp.Size);
14746225b19SZachary Turner   W.printNumber("ThunkOff", Tramp.ThunkOffset);
14846225b19SZachary Turner   W.printNumber("TargetOff", Tramp.TargetOffset);
14946225b19SZachary Turner   W.printNumber("ThunkSection", Tramp.ThunkSection);
15046225b19SZachary Turner   W.printNumber("TargetSection", Tramp.TargetSection);
1510d840744SZachary Turner   return Error::success();
1524caa1bf0SZachary Turner }
1534caa1bf0SZachary Turner 
1540d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {
15546225b19SZachary Turner   W.printNumber("SectionNumber", Section.SectionNumber);
15646225b19SZachary Turner   W.printNumber("Alignment", Section.Alignment);
15746225b19SZachary Turner   W.printNumber("Rva", Section.Rva);
15846225b19SZachary Turner   W.printNumber("Length", Section.Length);
15946225b19SZachary Turner   W.printFlags("Characteristics", Section.Characteristics,
16093839cb4SZachary Turner                getImageSectionCharacteristicNames(),
16193839cb4SZachary Turner                COFF::SectionCharacteristics(0x00F00000));
16293839cb4SZachary Turner 
1634caa1bf0SZachary Turner   W.printString("Name", Section.Name);
1640d840744SZachary Turner   return Error::success();
1654caa1bf0SZachary Turner }
1664caa1bf0SZachary Turner 
1670d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
1684caa1bf0SZachary Turner                                            CoffGroupSym &CoffGroup) {
16946225b19SZachary Turner   W.printNumber("Size", CoffGroup.Size);
17046225b19SZachary Turner   W.printFlags("Characteristics", CoffGroup.Characteristics,
17193839cb4SZachary Turner                getImageSectionCharacteristicNames(),
17293839cb4SZachary Turner                COFF::SectionCharacteristics(0x00F00000));
17346225b19SZachary Turner   W.printNumber("Offset", CoffGroup.Offset);
17446225b19SZachary Turner   W.printNumber("Segment", CoffGroup.Segment);
1754caa1bf0SZachary Turner   W.printString("Name", CoffGroup.Name);
1760d840744SZachary Turner   return Error::success();
1774caa1bf0SZachary Turner }
1784caa1bf0SZachary Turner 
1790d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
180aaad5744SZachary Turner                                            BPRelativeSym &BPRel) {
18146225b19SZachary Turner   W.printNumber("Offset", BPRel.Offset);
182629cb7d8SZachary Turner   printTypeIndex("Type", BPRel.Type);
183aaad5744SZachary Turner   W.printString("VarName", BPRel.Name);
1840d840744SZachary Turner   return Error::success();
185aaad5744SZachary Turner }
186aaad5744SZachary Turner 
1870d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
188aaad5744SZachary Turner                                            BuildInfoSym &BuildInfo) {
189af88a910SReid Kleckner   printTypeIndex("BuildId", BuildInfo.BuildId);
1900d840744SZachary Turner   return Error::success();
191aaad5744SZachary Turner }
192aaad5744SZachary Turner 
1930d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
194aaad5744SZachary Turner                                            CallSiteInfoSym &CallSiteInfo) {
195aaad5744SZachary Turner   StringRef LinkageName;
196aaad5744SZachary Turner   if (ObjDelegate) {
19746225b19SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset",
19846225b19SZachary Turner                                      CallSiteInfo.getRelocationOffset(),
19946225b19SZachary Turner                                      CallSiteInfo.CodeOffset, &LinkageName);
200aaad5744SZachary Turner   }
20146225b19SZachary Turner   W.printHex("Segment", CallSiteInfo.Segment);
202629cb7d8SZachary Turner   printTypeIndex("Type", CallSiteInfo.Type);
203aaad5744SZachary Turner   if (!LinkageName.empty())
204aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
2050d840744SZachary Turner   return Error::success();
206aaad5744SZachary Turner }
207aaad5744SZachary Turner 
2080d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
2094caa1bf0SZachary Turner                                            EnvBlockSym &EnvBlock) {
2104caa1bf0SZachary Turner   ListScope L(W, "Entries");
2114caa1bf0SZachary Turner   for (auto Entry : EnvBlock.Fields) {
2124caa1bf0SZachary Turner     W.printString(Entry);
2134caa1bf0SZachary Turner   }
2140d840744SZachary Turner   return Error::success();
2154caa1bf0SZachary Turner }
2164caa1bf0SZachary Turner 
2170d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
2184caa1bf0SZachary Turner                                            FileStaticSym &FileStatic) {
21963055455SZachary Turner   printTypeIndex("Index", FileStatic.Index);
22046225b19SZachary Turner   W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
22146225b19SZachary Turner   W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
2224caa1bf0SZachary Turner   W.printString("Name", FileStatic.Name);
2230d840744SZachary Turner   return Error::success();
2244caa1bf0SZachary Turner }
2254caa1bf0SZachary Turner 
2260d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
22746225b19SZachary Turner   W.printNumber("Ordinal", Export.Ordinal);
22846225b19SZachary Turner   W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());
2299f054d42SZachary Turner   W.printString("Name", Export.Name);
2300d840744SZachary Turner   return Error::success();
2319f054d42SZachary Turner }
2329f054d42SZachary Turner 
2330d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
2344caa1bf0SZachary Turner                                            Compile2Sym &Compile2) {
23546225b19SZachary Turner   W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());
23646225b19SZachary Turner   W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());
23746225b19SZachary Turner   W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
2384caa1bf0SZachary Turner   std::string FrontendVersion;
2394caa1bf0SZachary Turner   {
2404caa1bf0SZachary Turner     raw_string_ostream Out(FrontendVersion);
24146225b19SZachary Turner     Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor
24246225b19SZachary Turner         << '.' << Compile2.VersionFrontendBuild;
2434caa1bf0SZachary Turner   }
2444caa1bf0SZachary Turner   std::string BackendVersion;
2454caa1bf0SZachary Turner   {
2464caa1bf0SZachary Turner     raw_string_ostream Out(BackendVersion);
24746225b19SZachary Turner     Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor
24846225b19SZachary Turner         << '.' << Compile2.VersionBackendBuild;
2494caa1bf0SZachary Turner   }
2504caa1bf0SZachary Turner   W.printString("FrontendVersion", FrontendVersion);
2514caa1bf0SZachary Turner   W.printString("BackendVersion", BackendVersion);
2524caa1bf0SZachary Turner   W.printString("VersionName", Compile2.Version);
2530d840744SZachary Turner   return Error::success();
2544caa1bf0SZachary Turner }
2554caa1bf0SZachary Turner 
2560d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
257aaad5744SZachary Turner                                            Compile3Sym &Compile3) {
25846225b19SZachary Turner   W.printEnum("Language", Compile3.getLanguage(), getSourceLanguageNames());
25946225b19SZachary Turner   W.printFlags("Flags", Compile3.getFlags(), getCompileSym3FlagNames());
26046225b19SZachary Turner   W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
261aaad5744SZachary Turner   std::string FrontendVersion;
262aaad5744SZachary Turner   {
263aaad5744SZachary Turner     raw_string_ostream Out(FrontendVersion);
26446225b19SZachary Turner     Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor
26546225b19SZachary Turner         << '.' << Compile3.VersionFrontendBuild << '.'
26646225b19SZachary Turner         << Compile3.VersionFrontendQFE;
267aaad5744SZachary Turner   }
268aaad5744SZachary Turner   std::string BackendVersion;
269aaad5744SZachary Turner   {
270aaad5744SZachary Turner     raw_string_ostream Out(BackendVersion);
27146225b19SZachary Turner     Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor
27246225b19SZachary Turner         << '.' << Compile3.VersionBackendBuild << '.'
27346225b19SZachary Turner         << Compile3.VersionBackendQFE;
274aaad5744SZachary Turner   }
275aaad5744SZachary Turner   W.printString("FrontendVersion", FrontendVersion);
276aaad5744SZachary Turner   W.printString("BackendVersion", BackendVersion);
277aaad5744SZachary Turner   W.printString("VersionName", Compile3.Version);
2780d840744SZachary Turner   return Error::success();
279aaad5744SZachary Turner }
280aaad5744SZachary Turner 
2810d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
282aaad5744SZachary Turner                                            ConstantSym &Constant) {
283629cb7d8SZachary Turner   printTypeIndex("Type", Constant.Type);
284aaad5744SZachary Turner   W.printNumber("Value", Constant.Value);
285aaad5744SZachary Turner   W.printString("Name", Constant.Name);
2860d840744SZachary Turner   return Error::success();
287aaad5744SZachary Turner }
288aaad5744SZachary Turner 
2890d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
290aaad5744SZachary Turner   StringRef LinkageName;
291aaad5744SZachary Turner   if (ObjDelegate) {
292aaad5744SZachary Turner     ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
29346225b19SZachary Turner                                      Data.DataOffset, &LinkageName);
294aaad5744SZachary Turner   }
295629cb7d8SZachary Turner   printTypeIndex("Type", Data.Type);
296aaad5744SZachary Turner   W.printString("DisplayName", Data.Name);
297aaad5744SZachary Turner   if (!LinkageName.empty())
298aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
2990d840744SZachary Turner   return Error::success();
300aaad5744SZachary Turner }
301aaad5744SZachary Turner 
3020d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3030d840744SZachary Turner     CVSymbol &CVR,
304aaad5744SZachary Turner     DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
30546225b19SZachary Turner   W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
3060d840744SZachary Turner   return Error::success();
307aaad5744SZachary Turner }
308aaad5744SZachary Turner 
3090d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3100d840744SZachary Turner     CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
31146225b19SZachary Turner   W.printNumber("Offset", DefRangeFramePointerRel.Offset);
31246225b19SZachary Turner   printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
313aaad5744SZachary Turner                               DefRangeFramePointerRel.getRelocationOffset());
314aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
3150d840744SZachary Turner   return Error::success();
316aaad5744SZachary Turner }
317aaad5744SZachary Turner 
3180d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3190d840744SZachary Turner     CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
320ea89ff7cSHans Wennborg   W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register),
321ea89ff7cSHans Wennborg               getRegisterNames());
322aaad5744SZachary Turner   W.printBoolean("HasSpilledUDTMember",
323aaad5744SZachary Turner                  DefRangeRegisterRel.hasSpilledUDTMember());
324aaad5744SZachary Turner   W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
32546225b19SZachary Turner   W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);
32646225b19SZachary Turner   printLocalVariableAddrRange(DefRangeRegisterRel.Range,
327aaad5744SZachary Turner                               DefRangeRegisterRel.getRelocationOffset());
328aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
3290d840744SZachary Turner   return Error::success();
330aaad5744SZachary Turner }
331aaad5744SZachary Turner 
3320d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3330d840744SZachary Turner     CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
334ea89ff7cSHans Wennborg   W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
335ea89ff7cSHans Wennborg               getRegisterNames());
33646225b19SZachary Turner   W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
33746225b19SZachary Turner   printLocalVariableAddrRange(DefRangeRegister.Range,
338aaad5744SZachary Turner                               DefRangeRegister.getRelocationOffset());
339aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeRegister.Gaps);
3400d840744SZachary Turner   return Error::success();
341aaad5744SZachary Turner }
342aaad5744SZachary Turner 
3430d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3440d840744SZachary Turner     CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
345ea89ff7cSHans Wennborg   W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
346ea89ff7cSHans Wennborg               getRegisterNames());
34746225b19SZachary Turner   W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
34846225b19SZachary Turner   W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
34946225b19SZachary Turner   printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
350aaad5744SZachary Turner                               DefRangeSubfieldRegister.getRelocationOffset());
351aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
3520d840744SZachary Turner   return Error::success();
353aaad5744SZachary Turner }
354aaad5744SZachary Turner 
3550d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
3560d840744SZachary Turner     CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
357aaad5744SZachary Turner   if (ObjDelegate) {
358591312c5SZachary Turner     DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
3592d5c2cd3SZachary Turner     auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
3602d5c2cd3SZachary Turner     if (!ExpectedProgram) {
3612d5c2cd3SZachary Turner       consumeError(ExpectedProgram.takeError());
3620d840744SZachary Turner       return llvm::make_error<CodeViewError>(
3630d840744SZachary Turner           "String table offset outside of bounds of String Table!");
3642d5c2cd3SZachary Turner     }
3652d5c2cd3SZachary Turner     W.printString("Program", *ExpectedProgram);
366aaad5744SZachary Turner   }
36746225b19SZachary Turner   W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
36846225b19SZachary Turner   printLocalVariableAddrRange(DefRangeSubfield.Range,
369aaad5744SZachary Turner                               DefRangeSubfield.getRelocationOffset());
370aaad5744SZachary Turner   printLocalVariableAddrGap(DefRangeSubfield.Gaps);
3710d840744SZachary Turner   return Error::success();
372aaad5744SZachary Turner }
373aaad5744SZachary Turner 
3740d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
375aaad5744SZachary Turner                                            DefRangeSym &DefRange) {
376aaad5744SZachary Turner   if (ObjDelegate) {
377591312c5SZachary Turner     DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
3782d5c2cd3SZachary Turner     auto ExpectedProgram = Strings.getString(DefRange.Program);
3792d5c2cd3SZachary Turner     if (!ExpectedProgram) {
3802d5c2cd3SZachary Turner       consumeError(ExpectedProgram.takeError());
3810d840744SZachary Turner       return llvm::make_error<CodeViewError>(
3820d840744SZachary Turner           "String table offset outside of bounds of String Table!");
3832d5c2cd3SZachary Turner     }
3842d5c2cd3SZachary Turner     W.printString("Program", *ExpectedProgram);
385aaad5744SZachary Turner   }
38646225b19SZachary Turner   printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
387aaad5744SZachary Turner   printLocalVariableAddrGap(DefRange.Gaps);
3880d840744SZachary Turner   return Error::success();
389aaad5744SZachary Turner }
390aaad5744SZachary Turner 
3910d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
392aaad5744SZachary Turner                                            FrameCookieSym &FrameCookie) {
393aaad5744SZachary Turner   StringRef LinkageName;
394aaad5744SZachary Turner   if (ObjDelegate) {
39546225b19SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset",
39646225b19SZachary Turner                                      FrameCookie.getRelocationOffset(),
39746225b19SZachary Turner                                      FrameCookie.CodeOffset, &LinkageName);
398aaad5744SZachary Turner   }
399ea89ff7cSHans Wennborg   W.printEnum("Register", uint16_t(FrameCookie.Register), getRegisterNames());
40046225b19SZachary Turner   W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
40193839cb4SZachary Turner               getFrameCookieKindNames());
40246225b19SZachary Turner   W.printHex("Flags", FrameCookie.Flags);
4030d840744SZachary Turner   return Error::success();
404aaad5744SZachary Turner }
405aaad5744SZachary Turner 
4060d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
407aaad5744SZachary Turner                                            FrameProcSym &FrameProc) {
40846225b19SZachary Turner   W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
40946225b19SZachary Turner   W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
41046225b19SZachary Turner   W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
411aaad5744SZachary Turner   W.printHex("BytesOfCalleeSavedRegisters",
41246225b19SZachary Turner              FrameProc.BytesOfCalleeSavedRegisters);
41346225b19SZachary Turner   W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
414aaad5744SZachary Turner   W.printHex("SectionIdOfExceptionHandler",
41546225b19SZachary Turner              FrameProc.SectionIdOfExceptionHandler);
41646225b19SZachary Turner   W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
41746225b19SZachary Turner                getFrameProcSymFlagNames());
4180d840744SZachary Turner   return Error::success();
419aaad5744SZachary Turner }
420aaad5744SZachary Turner 
4210d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(
4220d840744SZachary Turner     CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
423aaad5744SZachary Turner   StringRef LinkageName;
424aaad5744SZachary Turner   if (ObjDelegate) {
42546225b19SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset",
42646225b19SZachary Turner                                      HeapAllocSite.getRelocationOffset(),
42746225b19SZachary Turner                                      HeapAllocSite.CodeOffset, &LinkageName);
428aaad5744SZachary Turner   }
42946225b19SZachary Turner   W.printHex("Segment", HeapAllocSite.Segment);
43046225b19SZachary Turner   W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
431629cb7d8SZachary Turner   printTypeIndex("Type", HeapAllocSite.Type);
432aaad5744SZachary Turner   if (!LinkageName.empty())
433aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
4340d840744SZachary Turner   return Error::success();
435aaad5744SZachary Turner }
436aaad5744SZachary Turner 
4370d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
438aaad5744SZachary Turner                                            InlineSiteSym &InlineSite) {
43946225b19SZachary Turner   W.printHex("PtrParent", InlineSite.Parent);
44046225b19SZachary Turner   W.printHex("PtrEnd", InlineSite.End);
441629cb7d8SZachary Turner   printTypeIndex("Inlinee", InlineSite.Inlinee);
442aaad5744SZachary Turner 
443aaad5744SZachary Turner   ListScope BinaryAnnotations(W, "BinaryAnnotations");
444aaad5744SZachary Turner   for (auto &Annotation : InlineSite.annotations()) {
445aaad5744SZachary Turner     switch (Annotation.OpCode) {
446aaad5744SZachary Turner     case BinaryAnnotationsOpCode::Invalid:
44742cb87f4SZachary Turner       W.printString("(Annotation Padding)");
44842cb87f4SZachary Turner       break;
449aaad5744SZachary Turner     case BinaryAnnotationsOpCode::CodeOffset:
450aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeOffset:
451aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeLength:
452aaad5744SZachary Turner       W.printHex(Annotation.Name, Annotation.U1);
453aaad5744SZachary Turner       break;
454aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
455aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeLineEndDelta:
456aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeRangeKind:
457aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeColumnStart:
458aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeColumnEnd:
459aaad5744SZachary Turner       W.printNumber(Annotation.Name, Annotation.U1);
460aaad5744SZachary Turner       break;
461aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeLineOffset:
462aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
463aaad5744SZachary Turner       W.printNumber(Annotation.Name, Annotation.S1);
464aaad5744SZachary Turner       break;
465aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeFile:
466aaad5744SZachary Turner       if (ObjDelegate) {
467aaad5744SZachary Turner         W.printHex("ChangeFile",
468aaad5744SZachary Turner                    ObjDelegate->getFileNameForFileOffset(Annotation.U1),
469aaad5744SZachary Turner                    Annotation.U1);
470aaad5744SZachary Turner       } else {
471aaad5744SZachary Turner         W.printHex("ChangeFile", Annotation.U1);
472aaad5744SZachary Turner       }
473aaad5744SZachary Turner 
474aaad5744SZachary Turner       break;
475aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
476aaad5744SZachary Turner       W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
477aaad5744SZachary Turner                     << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
478aaad5744SZachary Turner                     << "}\n";
479aaad5744SZachary Turner       break;
480aaad5744SZachary Turner     }
481aaad5744SZachary Turner     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
482aaad5744SZachary Turner       W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
483aaad5744SZachary Turner                     << W.hex(Annotation.U2)
484aaad5744SZachary Turner                     << ", Length: " << W.hex(Annotation.U1) << "}\n";
485aaad5744SZachary Turner       break;
486aaad5744SZachary Turner     }
487aaad5744SZachary Turner     }
488aaad5744SZachary Turner   }
4890d840744SZachary Turner   return Error::success();
490aaad5744SZachary Turner }
491aaad5744SZachary Turner 
4920d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
4934caa1bf0SZachary Turner                                            RegisterSym &Register) {
49463055455SZachary Turner   printTypeIndex("Type", Register.Index);
49546225b19SZachary Turner   W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames());
4964caa1bf0SZachary Turner   W.printString("Name", Register.Name);
4970d840744SZachary Turner   return Error::success();
4984caa1bf0SZachary Turner }
4994caa1bf0SZachary Turner 
5000d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
50118d90e17SReid Kleckner   W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());
50246225b19SZachary Turner   W.printNumber("Seg", Public.Segment);
50346225b19SZachary Turner   W.printNumber("Off", Public.Offset);
5049e33e6f8SZachary Turner   W.printString("Name", Public.Name);
5050d840744SZachary Turner   return Error::success();
5069e33e6f8SZachary Turner }
5079e33e6f8SZachary Turner 
5080d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
50946225b19SZachary Turner   W.printNumber("SumName", ProcRef.SumName);
51046225b19SZachary Turner   W.printNumber("SymOffset", ProcRef.SymOffset);
51146225b19SZachary Turner   W.printNumber("Mod", ProcRef.Module);
5129e33e6f8SZachary Turner   W.printString("Name", ProcRef.Name);
5130d840744SZachary Turner   return Error::success();
5149e33e6f8SZachary Turner }
5159e33e6f8SZachary Turner 
5160d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
517aaad5744SZachary Turner   StringRef LinkageName;
518aaad5744SZachary Turner   if (ObjDelegate) {
519aaad5744SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
52046225b19SZachary Turner                                      Label.CodeOffset, &LinkageName);
521aaad5744SZachary Turner   }
52246225b19SZachary Turner   W.printHex("Segment", Label.Segment);
52346225b19SZachary Turner   W.printHex("Flags", uint8_t(Label.Flags));
52446225b19SZachary Turner   W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
525aaad5744SZachary Turner   W.printString("DisplayName", Label.Name);
526aaad5744SZachary Turner   if (!LinkageName.empty())
527aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
5280d840744SZachary Turner   return Error::success();
529aaad5744SZachary Turner }
530aaad5744SZachary Turner 
5310d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
532629cb7d8SZachary Turner   printTypeIndex("Type", Local.Type);
53346225b19SZachary Turner   W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
534aaad5744SZachary Turner   W.printString("VarName", Local.Name);
5350d840744SZachary Turner   return Error::success();
536aaad5744SZachary Turner }
537aaad5744SZachary Turner 
5380d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
53946225b19SZachary Turner   W.printHex("Signature", ObjName.Signature);
540aaad5744SZachary Turner   W.printString("ObjectName", ObjName.Name);
5410d840744SZachary Turner   return Error::success();
542aaad5744SZachary Turner }
543aaad5744SZachary Turner 
5440d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
545aaad5744SZachary Turner   if (InFunctionScope)
5460d840744SZachary Turner     return llvm::make_error<CodeViewError>(
5470d840744SZachary Turner         "Visiting a ProcSym while inside function scope!");
548aaad5744SZachary Turner 
549aaad5744SZachary Turner   InFunctionScope = true;
550aaad5744SZachary Turner 
551aaad5744SZachary Turner   StringRef LinkageName;
55246225b19SZachary Turner   W.printHex("PtrParent", Proc.Parent);
55346225b19SZachary Turner   W.printHex("PtrEnd", Proc.End);
55446225b19SZachary Turner   W.printHex("PtrNext", Proc.Next);
55546225b19SZachary Turner   W.printHex("CodeSize", Proc.CodeSize);
55646225b19SZachary Turner   W.printHex("DbgStart", Proc.DbgStart);
55746225b19SZachary Turner   W.printHex("DbgEnd", Proc.DbgEnd);
558629cb7d8SZachary Turner   printTypeIndex("FunctionType", Proc.FunctionType);
559aaad5744SZachary Turner   if (ObjDelegate) {
560aaad5744SZachary Turner     ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
56146225b19SZachary Turner                                      Proc.CodeOffset, &LinkageName);
562aaad5744SZachary Turner   }
56346225b19SZachary Turner   W.printHex("Segment", Proc.Segment);
56446225b19SZachary Turner   W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
56593839cb4SZachary Turner                getProcSymFlagNames());
566aaad5744SZachary Turner   W.printString("DisplayName", Proc.Name);
567aaad5744SZachary Turner   if (!LinkageName.empty())
568aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
5690d840744SZachary Turner   return Error::success();
570aaad5744SZachary Turner }
571aaad5744SZachary Turner 
5720d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
573aaad5744SZachary Turner                                            ScopeEndSym &ScopeEnd) {
574aaad5744SZachary Turner   InFunctionScope = false;
5750d840744SZachary Turner   return Error::success();
576aaad5744SZachary Turner }
577aaad5744SZachary Turner 
5780d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
5790d840744SZachary Turner   ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
580aaad5744SZachary Turner   for (auto FuncID : Caller.Indices)
581629cb7d8SZachary Turner     printTypeIndex("FuncID", FuncID);
5820d840744SZachary Turner   return Error::success();
583aaad5744SZachary Turner }
584aaad5744SZachary Turner 
5850d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
586aaad5744SZachary Turner                                            RegRelativeSym &RegRel) {
58746225b19SZachary Turner   W.printHex("Offset", RegRel.Offset);
588629cb7d8SZachary Turner   printTypeIndex("Type", RegRel.Type);
58963055455SZachary Turner   W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames());
590aaad5744SZachary Turner   W.printString("VarName", RegRel.Name);
5910d840744SZachary Turner   return Error::success();
592aaad5744SZachary Turner }
593aaad5744SZachary Turner 
5940d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
595aaad5744SZachary Turner                                            ThreadLocalDataSym &Data) {
596aaad5744SZachary Turner   StringRef LinkageName;
597aaad5744SZachary Turner   if (ObjDelegate) {
598aaad5744SZachary Turner     ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
59946225b19SZachary Turner                                      Data.DataOffset, &LinkageName);
600aaad5744SZachary Turner   }
601629cb7d8SZachary Turner   printTypeIndex("Type", Data.Type);
602aaad5744SZachary Turner   W.printString("DisplayName", Data.Name);
603aaad5744SZachary Turner   if (!LinkageName.empty())
604aaad5744SZachary Turner     W.printString("LinkageName", LinkageName);
6050d840744SZachary Turner   return Error::success();
606aaad5744SZachary Turner }
607aaad5744SZachary Turner 
6080d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
609629cb7d8SZachary Turner   printTypeIndex("Type", UDT.Type);
610aaad5744SZachary Turner   W.printString("UDTName", UDT.Name);
6110d840744SZachary Turner   return Error::success();
612aaad5744SZachary Turner }
613aaad5744SZachary Turner 
614*ee8a7200SAlexandre Ganea Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
615*ee8a7200SAlexandre Ganea                                            UsingNamespaceSym &UN) {
616*ee8a7200SAlexandre Ganea   W.printString("Namespace", UN.Name);
617*ee8a7200SAlexandre Ganea   return Error::success();
618*ee8a7200SAlexandre Ganea }
619*ee8a7200SAlexandre Ganea 
6200d840744SZachary Turner Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
6210d840744SZachary Turner   W.printNumber("Length", CVR.length());
6220d840744SZachary Turner   return Error::success();
623aaad5744SZachary Turner }
624aaad5744SZachary Turner 
6250d840744SZachary Turner Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
6260d840744SZachary Turner   SymbolVisitorCallbackPipeline Pipeline;
627ebd3ae83SZachary Turner   SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
628526f4f2aSZachary Turner   CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes);
6290d840744SZachary Turner 
6300d840744SZachary Turner   Pipeline.addCallbackToPipeline(Deserializer);
6310d840744SZachary Turner   Pipeline.addCallbackToPipeline(Dumper);
6320d840744SZachary Turner   CVSymbolVisitor Visitor(Pipeline);
6330d840744SZachary Turner   return Visitor.visitSymbolRecord(Record);
634aaad5744SZachary Turner }
635aaad5744SZachary Turner 
6360d840744SZachary Turner Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
6370d840744SZachary Turner   SymbolVisitorCallbackPipeline Pipeline;
638ebd3ae83SZachary Turner   SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
639526f4f2aSZachary Turner   CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes);
6400d840744SZachary Turner 
6410d840744SZachary Turner   Pipeline.addCallbackToPipeline(Deserializer);
6420d840744SZachary Turner   Pipeline.addCallbackToPipeline(Dumper);
6430d840744SZachary Turner   CVSymbolVisitor Visitor(Pipeline);
6440d840744SZachary Turner   return Visitor.visitSymbolStream(Symbols);
645aaad5744SZachary Turner }
646