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