1 //===- MinimalSymbolDumper.cpp -------------------------------- *- C++ --*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MinimalSymbolDumper.h"
12 #include "FormatUtil.h"
13 #include "InputFile.h"
14 #include "LinePrinter.h"
16 #include "llvm/DebugInfo/CodeView/CVRecord.h"
17 #include "llvm/DebugInfo/CodeView/CodeView.h"
18 #include "llvm/DebugInfo/CodeView/Formatters.h"
19 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
20 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
21 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
22 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
23 #include "llvm/Support/FormatVariadic.h"
26 using namespace llvm::codeview
;
27 using namespace llvm::pdb
;
29 static std::string
formatLocalSymFlags(uint32_t IndentLevel
,
30 LocalSymFlags Flags
) {
31 std::vector
<std::string
> Opts
;
32 if (Flags
== LocalSymFlags::None
)
35 PUSH_FLAG(LocalSymFlags
, IsParameter
, Flags
, "param");
36 PUSH_FLAG(LocalSymFlags
, IsAddressTaken
, Flags
, "address is taken");
37 PUSH_FLAG(LocalSymFlags
, IsCompilerGenerated
, Flags
, "compiler generated");
38 PUSH_FLAG(LocalSymFlags
, IsAggregate
, Flags
, "aggregate");
39 PUSH_FLAG(LocalSymFlags
, IsAggregated
, Flags
, "aggregated");
40 PUSH_FLAG(LocalSymFlags
, IsAliased
, Flags
, "aliased");
41 PUSH_FLAG(LocalSymFlags
, IsAlias
, Flags
, "alias");
42 PUSH_FLAG(LocalSymFlags
, IsReturnValue
, Flags
, "return val");
43 PUSH_FLAG(LocalSymFlags
, IsOptimizedOut
, Flags
, "optimized away");
44 PUSH_FLAG(LocalSymFlags
, IsEnregisteredGlobal
, Flags
, "enreg global");
45 PUSH_FLAG(LocalSymFlags
, IsEnregisteredStatic
, Flags
, "enreg static");
46 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
49 static std::string
formatExportFlags(uint32_t IndentLevel
, ExportFlags Flags
) {
50 std::vector
<std::string
> Opts
;
51 if (Flags
== ExportFlags::None
)
54 PUSH_FLAG(ExportFlags
, IsConstant
, Flags
, "constant");
55 PUSH_FLAG(ExportFlags
, IsData
, Flags
, "data");
56 PUSH_FLAG(ExportFlags
, IsPrivate
, Flags
, "private");
57 PUSH_FLAG(ExportFlags
, HasNoName
, Flags
, "no name");
58 PUSH_FLAG(ExportFlags
, HasExplicitOrdinal
, Flags
, "explicit ord");
59 PUSH_FLAG(ExportFlags
, IsForwarder
, Flags
, "forwarder");
61 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
64 static std::string
formatCompileSym2Flags(uint32_t IndentLevel
,
65 CompileSym2Flags Flags
) {
66 std::vector
<std::string
> Opts
;
67 Flags
&= ~CompileSym2Flags::SourceLanguageMask
;
68 if (Flags
== CompileSym2Flags::None
)
71 PUSH_FLAG(CompileSym2Flags
, EC
, Flags
, "edit and continue");
72 PUSH_FLAG(CompileSym2Flags
, NoDbgInfo
, Flags
, "no dbg info");
73 PUSH_FLAG(CompileSym2Flags
, LTCG
, Flags
, "ltcg");
74 PUSH_FLAG(CompileSym2Flags
, NoDataAlign
, Flags
, "no data align");
75 PUSH_FLAG(CompileSym2Flags
, ManagedPresent
, Flags
, "has managed code");
76 PUSH_FLAG(CompileSym2Flags
, SecurityChecks
, Flags
, "security checks");
77 PUSH_FLAG(CompileSym2Flags
, HotPatch
, Flags
, "hot patchable");
78 PUSH_FLAG(CompileSym2Flags
, CVTCIL
, Flags
, "cvtcil");
79 PUSH_FLAG(CompileSym2Flags
, MSILModule
, Flags
, "msil module");
80 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
83 static std::string
formatCompileSym3Flags(uint32_t IndentLevel
,
84 CompileSym3Flags Flags
) {
85 std::vector
<std::string
> Opts
;
86 Flags
&= ~CompileSym3Flags::SourceLanguageMask
;
88 if (Flags
== CompileSym3Flags::None
)
91 PUSH_FLAG(CompileSym3Flags
, EC
, Flags
, "edit and continue");
92 PUSH_FLAG(CompileSym3Flags
, NoDbgInfo
, Flags
, "no dbg info");
93 PUSH_FLAG(CompileSym3Flags
, LTCG
, Flags
, "ltcg");
94 PUSH_FLAG(CompileSym3Flags
, NoDataAlign
, Flags
, "no data align");
95 PUSH_FLAG(CompileSym3Flags
, ManagedPresent
, Flags
, "has managed code");
96 PUSH_FLAG(CompileSym3Flags
, SecurityChecks
, Flags
, "security checks");
97 PUSH_FLAG(CompileSym3Flags
, HotPatch
, Flags
, "hot patchable");
98 PUSH_FLAG(CompileSym3Flags
, CVTCIL
, Flags
, "cvtcil");
99 PUSH_FLAG(CompileSym3Flags
, MSILModule
, Flags
, "msil module");
100 PUSH_FLAG(CompileSym3Flags
, Sdl
, Flags
, "sdl");
101 PUSH_FLAG(CompileSym3Flags
, PGO
, Flags
, "pgo");
102 PUSH_FLAG(CompileSym3Flags
, Exp
, Flags
, "exp");
103 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
106 static std::string
formatFrameProcedureOptions(uint32_t IndentLevel
,
107 FrameProcedureOptions FPO
) {
108 std::vector
<std::string
> Opts
;
109 if (FPO
== FrameProcedureOptions::None
)
112 PUSH_FLAG(FrameProcedureOptions
, HasAlloca
, FPO
, "has alloca");
113 PUSH_FLAG(FrameProcedureOptions
, HasSetJmp
, FPO
, "has setjmp");
114 PUSH_FLAG(FrameProcedureOptions
, HasLongJmp
, FPO
, "has longjmp");
115 PUSH_FLAG(FrameProcedureOptions
, HasInlineAssembly
, FPO
, "has inline asm");
116 PUSH_FLAG(FrameProcedureOptions
, HasExceptionHandling
, FPO
, "has eh");
117 PUSH_FLAG(FrameProcedureOptions
, MarkedInline
, FPO
, "marked inline");
118 PUSH_FLAG(FrameProcedureOptions
, HasStructuredExceptionHandling
, FPO
,
120 PUSH_FLAG(FrameProcedureOptions
, Naked
, FPO
, "naked");
121 PUSH_FLAG(FrameProcedureOptions
, SecurityChecks
, FPO
, "secure checks");
122 PUSH_FLAG(FrameProcedureOptions
, AsynchronousExceptionHandling
, FPO
,
124 PUSH_FLAG(FrameProcedureOptions
, NoStackOrderingForSecurityChecks
, FPO
,
126 PUSH_FLAG(FrameProcedureOptions
, Inlined
, FPO
, "inlined");
127 PUSH_FLAG(FrameProcedureOptions
, StrictSecurityChecks
, FPO
,
128 "strict secure checks");
129 PUSH_FLAG(FrameProcedureOptions
, SafeBuffers
, FPO
, "safe buffers");
130 PUSH_FLAG(FrameProcedureOptions
, ProfileGuidedOptimization
, FPO
, "pgo");
131 PUSH_FLAG(FrameProcedureOptions
, ValidProfileCounts
, FPO
,
132 "has profile counts");
133 PUSH_FLAG(FrameProcedureOptions
, OptimizedForSpeed
, FPO
, "opt speed");
134 PUSH_FLAG(FrameProcedureOptions
, GuardCfg
, FPO
, "guard cfg");
135 PUSH_FLAG(FrameProcedureOptions
, GuardCfw
, FPO
, "guard cfw");
136 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
139 static std::string
formatPublicSymFlags(uint32_t IndentLevel
,
140 PublicSymFlags Flags
) {
141 std::vector
<std::string
> Opts
;
142 if (Flags
== PublicSymFlags::None
)
145 PUSH_FLAG(PublicSymFlags
, Code
, Flags
, "code");
146 PUSH_FLAG(PublicSymFlags
, Function
, Flags
, "function");
147 PUSH_FLAG(PublicSymFlags
, Managed
, Flags
, "managed");
148 PUSH_FLAG(PublicSymFlags
, MSIL
, Flags
, "msil");
149 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
152 static std::string
formatProcSymFlags(uint32_t IndentLevel
,
153 ProcSymFlags Flags
) {
154 std::vector
<std::string
> Opts
;
155 if (Flags
== ProcSymFlags::None
)
158 PUSH_FLAG(ProcSymFlags
, HasFP
, Flags
, "has fp");
159 PUSH_FLAG(ProcSymFlags
, HasIRET
, Flags
, "has iret");
160 PUSH_FLAG(ProcSymFlags
, HasFRET
, Flags
, "has fret");
161 PUSH_FLAG(ProcSymFlags
, IsNoReturn
, Flags
, "noreturn");
162 PUSH_FLAG(ProcSymFlags
, IsUnreachable
, Flags
, "unreachable");
163 PUSH_FLAG(ProcSymFlags
, HasCustomCallingConv
, Flags
, "custom calling conv");
164 PUSH_FLAG(ProcSymFlags
, IsNoInline
, Flags
, "noinline");
165 PUSH_FLAG(ProcSymFlags
, HasOptimizedDebugInfo
, Flags
, "opt debuginfo");
166 return typesetItemList(Opts
, 4, IndentLevel
, " | ");
169 static std::string
formatThunkOrdinal(ThunkOrdinal Ordinal
) {
171 RETURN_CASE(ThunkOrdinal
, Standard
, "thunk");
172 RETURN_CASE(ThunkOrdinal
, ThisAdjustor
, "this adjustor");
173 RETURN_CASE(ThunkOrdinal
, Vcall
, "vcall");
174 RETURN_CASE(ThunkOrdinal
, Pcode
, "pcode");
175 RETURN_CASE(ThunkOrdinal
, UnknownLoad
, "unknown load");
176 RETURN_CASE(ThunkOrdinal
, TrampIncremental
, "tramp incremental");
177 RETURN_CASE(ThunkOrdinal
, BranchIsland
, "branch island");
179 return formatUnknownEnum(Ordinal
);
182 static std::string
formatTrampolineType(TrampolineType Tramp
) {
184 RETURN_CASE(TrampolineType
, TrampIncremental
, "tramp incremental");
185 RETURN_CASE(TrampolineType
, BranchIsland
, "branch island");
187 return formatUnknownEnum(Tramp
);
190 static std::string
formatSourceLanguage(SourceLanguage Lang
) {
192 RETURN_CASE(SourceLanguage
, C
, "c");
193 RETURN_CASE(SourceLanguage
, Cpp
, "c++");
194 RETURN_CASE(SourceLanguage
, Fortran
, "fortran");
195 RETURN_CASE(SourceLanguage
, Masm
, "masm");
196 RETURN_CASE(SourceLanguage
, Pascal
, "pascal");
197 RETURN_CASE(SourceLanguage
, Basic
, "basic");
198 RETURN_CASE(SourceLanguage
, Cobol
, "cobol");
199 RETURN_CASE(SourceLanguage
, Link
, "link");
200 RETURN_CASE(SourceLanguage
, VB
, "vb");
201 RETURN_CASE(SourceLanguage
, Cvtres
, "cvtres");
202 RETURN_CASE(SourceLanguage
, Cvtpgd
, "cvtpgd");
203 RETURN_CASE(SourceLanguage
, CSharp
, "c#");
204 RETURN_CASE(SourceLanguage
, ILAsm
, "il asm");
205 RETURN_CASE(SourceLanguage
, Java
, "java");
206 RETURN_CASE(SourceLanguage
, JScript
, "javascript");
207 RETURN_CASE(SourceLanguage
, MSIL
, "msil");
208 RETURN_CASE(SourceLanguage
, HLSL
, "hlsl");
209 RETURN_CASE(SourceLanguage
, D
, "d");
211 return formatUnknownEnum(Lang
);
214 static std::string
formatMachineType(CPUType Cpu
) {
216 RETURN_CASE(CPUType
, Intel8080
, "intel 8080");
217 RETURN_CASE(CPUType
, Intel8086
, "intel 8086");
218 RETURN_CASE(CPUType
, Intel80286
, "intel 80286");
219 RETURN_CASE(CPUType
, Intel80386
, "intel 80386");
220 RETURN_CASE(CPUType
, Intel80486
, "intel 80486");
221 RETURN_CASE(CPUType
, Pentium
, "intel pentium");
222 RETURN_CASE(CPUType
, PentiumPro
, "intel pentium pro");
223 RETURN_CASE(CPUType
, Pentium3
, "intel pentium 3");
224 RETURN_CASE(CPUType
, MIPS
, "mips");
225 RETURN_CASE(CPUType
, MIPS16
, "mips-16");
226 RETURN_CASE(CPUType
, MIPS32
, "mips-32");
227 RETURN_CASE(CPUType
, MIPS64
, "mips-64");
228 RETURN_CASE(CPUType
, MIPSI
, "mips i");
229 RETURN_CASE(CPUType
, MIPSII
, "mips ii");
230 RETURN_CASE(CPUType
, MIPSIII
, "mips iii");
231 RETURN_CASE(CPUType
, MIPSIV
, "mips iv");
232 RETURN_CASE(CPUType
, MIPSV
, "mips v");
233 RETURN_CASE(CPUType
, M68000
, "motorola 68000");
234 RETURN_CASE(CPUType
, M68010
, "motorola 68010");
235 RETURN_CASE(CPUType
, M68020
, "motorola 68020");
236 RETURN_CASE(CPUType
, M68030
, "motorola 68030");
237 RETURN_CASE(CPUType
, M68040
, "motorola 68040");
238 RETURN_CASE(CPUType
, Alpha
, "alpha");
239 RETURN_CASE(CPUType
, Alpha21164
, "alpha 21164");
240 RETURN_CASE(CPUType
, Alpha21164A
, "alpha 21164a");
241 RETURN_CASE(CPUType
, Alpha21264
, "alpha 21264");
242 RETURN_CASE(CPUType
, Alpha21364
, "alpha 21364");
243 RETURN_CASE(CPUType
, PPC601
, "powerpc 601");
244 RETURN_CASE(CPUType
, PPC603
, "powerpc 603");
245 RETURN_CASE(CPUType
, PPC604
, "powerpc 604");
246 RETURN_CASE(CPUType
, PPC620
, "powerpc 620");
247 RETURN_CASE(CPUType
, PPCFP
, "powerpc fp");
248 RETURN_CASE(CPUType
, PPCBE
, "powerpc be");
249 RETURN_CASE(CPUType
, SH3
, "sh3");
250 RETURN_CASE(CPUType
, SH3E
, "sh3e");
251 RETURN_CASE(CPUType
, SH3DSP
, "sh3 dsp");
252 RETURN_CASE(CPUType
, SH4
, "sh4");
253 RETURN_CASE(CPUType
, SHMedia
, "shmedia");
254 RETURN_CASE(CPUType
, ARM3
, "arm 3");
255 RETURN_CASE(CPUType
, ARM4
, "arm 4");
256 RETURN_CASE(CPUType
, ARM4T
, "arm 4t");
257 RETURN_CASE(CPUType
, ARM5
, "arm 5");
258 RETURN_CASE(CPUType
, ARM5T
, "arm 5t");
259 RETURN_CASE(CPUType
, ARM6
, "arm 6");
260 RETURN_CASE(CPUType
, ARM_XMAC
, "arm xmac");
261 RETURN_CASE(CPUType
, ARM_WMMX
, "arm wmmx");
262 RETURN_CASE(CPUType
, ARM7
, "arm 7");
263 RETURN_CASE(CPUType
, ARM64
, "arm64");
264 RETURN_CASE(CPUType
, Omni
, "omni");
265 RETURN_CASE(CPUType
, Ia64
, "intel itanium ia64");
266 RETURN_CASE(CPUType
, Ia64_2
, "intel itanium ia64 2");
267 RETURN_CASE(CPUType
, CEE
, "cee");
268 RETURN_CASE(CPUType
, AM33
, "am33");
269 RETURN_CASE(CPUType
, M32R
, "m32r");
270 RETURN_CASE(CPUType
, TriCore
, "tri-core");
271 RETURN_CASE(CPUType
, X64
, "intel x86-x64");
272 RETURN_CASE(CPUType
, EBC
, "ebc");
273 RETURN_CASE(CPUType
, Thumb
, "thumb");
274 RETURN_CASE(CPUType
, ARMNT
, "arm nt");
275 RETURN_CASE(CPUType
, D3D11_Shader
, "d3d11 shader");
277 return formatUnknownEnum(Cpu
);
280 static std::string
formatCookieKind(FrameCookieKind Kind
) {
282 RETURN_CASE(FrameCookieKind
, Copy
, "copy");
283 RETURN_CASE(FrameCookieKind
, XorStackPointer
, "xor stack ptr");
284 RETURN_CASE(FrameCookieKind
, XorFramePointer
, "xor frame ptr");
285 RETURN_CASE(FrameCookieKind
, XorR13
, "xor rot13");
287 return formatUnknownEnum(Kind
);
290 static std::string
formatRegisterId(RegisterId Id
) {
292 #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
293 #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
296 return formatUnknownEnum(Id
);
299 static std::string
formatRegisterId(uint16_t Reg16
) {
300 return formatRegisterId(RegisterId(Reg16
));
303 static std::string
formatRegisterId(ulittle16_t
&Reg16
) {
304 return formatRegisterId(uint16_t(Reg16
));
307 static std::string
formatRange(LocalVariableAddrRange Range
) {
308 return formatv("[{0},+{1})",
309 formatSegmentOffset(Range
.ISectStart
, Range
.OffsetStart
),
314 static std::string
formatGaps(uint32_t IndentLevel
,
315 ArrayRef
<LocalVariableAddrGap
> Gaps
) {
316 std::vector
<std::string
> GapStrs
;
317 for (const auto &G
: Gaps
) {
318 GapStrs
.push_back(formatv("({0},{1})", G
.GapStartOffset
, G
.Range
).str());
320 return typesetItemList(GapStrs
, 7, IndentLevel
, ", ");
323 Error
MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol
&Record
) {
324 return visitSymbolBegin(Record
, 0);
327 Error
MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol
&Record
,
329 // formatLine puts the newline at the beginning, so we use formatLine here
330 // to start a new line, and then individual visit methods use format to
331 // append to the existing line.
332 P
.formatLine("{0} | {1} [size = {2}]",
333 fmt_align(Offset
, AlignStyle::Right
, 6),
334 formatSymbolKind(Record
.Type
), Record
.length());
336 return Error::success();
339 Error
MinimalSymbolDumper::visitSymbolEnd(CVSymbol
&Record
) {
341 AutoIndent
Indent(P
, 7);
342 P
.formatBinary("bytes", Record
.content(), 0);
345 return Error::success();
348 std::string
MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI
,
350 if (TI
.isSimple() || TI
.isDecoratedItemId())
351 return formatv("{0}", TI
).str();
352 auto &Container
= IsType
? Types
: Ids
;
353 StringRef Name
= Container
.getTypeName(TI
);
354 if (Name
.size() > 32) {
355 Name
= Name
.take_front(32);
356 return formatv("{0} ({1}...)", TI
, Name
);
358 return formatv("{0} ({1})", TI
, Name
);
361 std::string
MinimalSymbolDumper::idIndex(codeview::TypeIndex TI
) const {
362 return typeOrIdIndex(TI
, false);
365 std::string
MinimalSymbolDumper::typeIndex(TypeIndex TI
) const {
366 return typeOrIdIndex(TI
, true);
369 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, BlockSym
&Block
) {
370 P
.format(" `{0}`", Block
.Name
);
371 AutoIndent
Indent(P
, 7);
372 P
.formatLine("parent = {0}, end = {1}", Block
.Parent
, Block
.End
);
373 P
.formatLine("code size = {0}, addr = {1}", Block
.CodeSize
,
374 formatSegmentOffset(Block
.Segment
, Block
.CodeOffset
));
375 return Error::success();
378 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, Thunk32Sym
&Thunk
) {
379 P
.format(" `{0}`", Thunk
.Name
);
380 AutoIndent
Indent(P
, 7);
381 P
.formatLine("parent = {0}, end = {1}, next = {2}", Thunk
.Parent
, Thunk
.End
,
383 P
.formatLine("kind = {0}, size = {1}, addr = {2}",
384 formatThunkOrdinal(Thunk
.Thunk
), Thunk
.Length
,
385 formatSegmentOffset(Thunk
.Segment
, Thunk
.Offset
));
387 return Error::success();
390 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
391 TrampolineSym
&Tramp
) {
392 AutoIndent
Indent(P
, 7);
393 P
.formatLine("type = {0}, size = {1}, source = {2}, target = {3}",
394 formatTrampolineType(Tramp
.Type
), Tramp
.Size
,
395 formatSegmentOffset(Tramp
.ThunkSection
, Tramp
.ThunkOffset
),
396 formatSegmentOffset(Tramp
.TargetSection
, Tramp
.ThunkOffset
));
398 return Error::success();
401 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
402 SectionSym
&Section
) {
403 P
.format(" `{0}`", Section
.Name
);
404 AutoIndent
Indent(P
, 7);
405 P
.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}",
406 Section
.Length
, Section
.Alignment
, Section
.Rva
,
407 Section
.SectionNumber
);
408 P
.printLine("characteristics =");
409 AutoIndent
Indent2(P
, 2);
410 P
.printLine(formatSectionCharacteristics(P
.getIndentLevel(),
411 Section
.Characteristics
, 1, "",
412 CharacteristicStyle::Descriptive
));
413 return Error::success();
416 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, CoffGroupSym
&CG
) {
417 P
.format(" `{0}`", CG
.Name
);
418 AutoIndent
Indent(P
, 7);
419 P
.formatLine("length = {0}, addr = {1}", CG
.Size
,
420 formatSegmentOffset(CG
.Segment
, CG
.Offset
));
421 P
.printLine("characteristics =");
422 AutoIndent
Indent2(P
, 2);
423 P
.printLine(formatSectionCharacteristics(P
.getIndentLevel(),
424 CG
.Characteristics
, 1, "",
425 CharacteristicStyle::Descriptive
));
426 return Error::success();
429 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
430 BPRelativeSym
&BPRel
) {
431 P
.format(" `{0}`", BPRel
.Name
);
432 AutoIndent
Indent(P
, 7);
433 P
.formatLine("type = {0}, offset = {1}", typeIndex(BPRel
.Type
), BPRel
.Offset
);
434 return Error::success();
437 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
438 BuildInfoSym
&BuildInfo
) {
439 P
.format(" BuildId = `{0}`", BuildInfo
.BuildId
);
440 return Error::success();
443 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
444 CallSiteInfoSym
&CSI
) {
445 AutoIndent
Indent(P
, 7);
446 P
.formatLine("type = {0}, addr = {1}", typeIndex(CSI
.Type
),
447 formatSegmentOffset(CSI
.Segment
, CSI
.CodeOffset
));
448 return Error::success();
451 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
452 EnvBlockSym
&EnvBlock
) {
453 AutoIndent
Indent(P
, 7);
454 for (const auto &Entry
: EnvBlock
.Fields
) {
455 P
.formatLine("- {0}", Entry
);
457 return Error::success();
460 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, FileStaticSym
&FS
) {
461 P
.format(" `{0}`", FS
.Name
);
462 AutoIndent
Indent(P
, 7);
464 Expected
<StringRef
> FileName
=
465 SymGroup
->getNameFromStringTable(FS
.ModFilenameOffset
);
467 P
.formatLine("type = {0}, file name = {1} ({2}), flags = {3}",
468 typeIndex(FS
.Index
), FS
.ModFilenameOffset
, *FileName
,
469 formatLocalSymFlags(P
.getIndentLevel() + 9, FS
.Flags
));
471 return Error::success();
474 P
.formatLine("type = {0}, file name offset = {1}, flags = {2}",
475 typeIndex(FS
.Index
), FS
.ModFilenameOffset
,
476 formatLocalSymFlags(P
.getIndentLevel() + 9, FS
.Flags
));
477 return Error::success();
480 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, ExportSym
&Export
) {
481 P
.format(" `{0}`", Export
.Name
);
482 AutoIndent
Indent(P
, 7);
483 P
.formatLine("ordinal = {0}, flags = {1}", Export
.Ordinal
,
484 formatExportFlags(P
.getIndentLevel() + 9, Export
.Flags
));
485 return Error::success();
488 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
489 Compile2Sym
&Compile2
) {
490 AutoIndent
Indent(P
, 7);
491 SourceLanguage Lang
= static_cast<SourceLanguage
>(
492 Compile2
.Flags
& CompileSym2Flags::SourceLanguageMask
);
493 CompilationCPU
= Compile2
.Machine
;
494 P
.formatLine("machine = {0}, ver = {1}, language = {2}",
495 formatMachineType(Compile2
.Machine
), Compile2
.Version
,
496 formatSourceLanguage(Lang
));
497 P
.formatLine("frontend = {0}.{1}.{2}, backend = {3}.{4}.{5}",
498 Compile2
.VersionFrontendMajor
, Compile2
.VersionFrontendMinor
,
499 Compile2
.VersionFrontendBuild
, Compile2
.VersionBackendMajor
,
500 Compile2
.VersionBackendMinor
, Compile2
.VersionBackendBuild
);
501 P
.formatLine("flags = {0}",
502 formatCompileSym2Flags(P
.getIndentLevel() + 9, Compile2
.Flags
));
504 "extra strings = {0}",
505 typesetStringList(P
.getIndentLevel() + 9 + 2, Compile2
.ExtraStrings
));
506 return Error::success();
509 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
510 Compile3Sym
&Compile3
) {
511 AutoIndent
Indent(P
, 7);
512 SourceLanguage Lang
= static_cast<SourceLanguage
>(
513 Compile3
.Flags
& CompileSym3Flags::SourceLanguageMask
);
514 CompilationCPU
= Compile3
.Machine
;
515 P
.formatLine("machine = {0}, Ver = {1}, language = {2}",
516 formatMachineType(Compile3
.Machine
), Compile3
.Version
,
517 formatSourceLanguage(Lang
));
518 P
.formatLine("frontend = {0}.{1}.{2}.{3}, backend = {4}.{5}.{6}.{7}",
519 Compile3
.VersionFrontendMajor
, Compile3
.VersionFrontendMinor
,
520 Compile3
.VersionFrontendBuild
, Compile3
.VersionFrontendQFE
,
521 Compile3
.VersionBackendMajor
, Compile3
.VersionBackendMinor
,
522 Compile3
.VersionBackendBuild
, Compile3
.VersionBackendQFE
);
523 P
.formatLine("flags = {0}",
524 formatCompileSym3Flags(P
.getIndentLevel() + 9, Compile3
.Flags
));
525 return Error::success();
528 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
529 ConstantSym
&Constant
) {
530 P
.format(" `{0}`", Constant
.Name
);
531 AutoIndent
Indent(P
, 7);
532 P
.formatLine("type = {0}, value = {1}", typeIndex(Constant
.Type
),
533 Constant
.Value
.toString(10));
534 return Error::success();
537 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, DataSym
&Data
) {
538 P
.format(" `{0}`", Data
.Name
);
539 AutoIndent
Indent(P
, 7);
540 P
.formatLine("type = {0}, addr = {1}", typeIndex(Data
.Type
),
541 formatSegmentOffset(Data
.Segment
, Data
.DataOffset
));
542 return Error::success();
545 Error
MinimalSymbolDumper::visitKnownRecord(
546 CVSymbol
&CVR
, DefRangeFramePointerRelFullScopeSym
&Def
) {
547 P
.format(" offset = {0}", Def
.Offset
);
548 return Error::success();
551 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
552 DefRangeFramePointerRelSym
&Def
) {
553 AutoIndent
Indent(P
, 7);
554 P
.formatLine("offset = {0}, range = {1}", Def
.Offset
, formatRange(Def
.Range
));
555 P
.formatLine("gaps = {2}", Def
.Offset
,
556 formatGaps(P
.getIndentLevel() + 9, Def
.Gaps
));
557 return Error::success();
560 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
561 DefRangeRegisterRelSym
&Def
) {
562 AutoIndent
Indent(P
, 7);
563 P
.formatLine("register = {0}, offset = {1}, offset in parent = {2}, has "
565 formatRegisterId(Def
.Hdr
.Register
),
566 int32_t(Def
.Hdr
.BasePointerOffset
), Def
.offsetInParent(),
567 Def
.hasSpilledUDTMember());
568 P
.formatLine("range = {0}, gaps = {1}", formatRange(Def
.Range
),
569 formatGaps(P
.getIndentLevel() + 9, Def
.Gaps
));
570 return Error::success();
573 Error
MinimalSymbolDumper::visitKnownRecord(
574 CVSymbol
&CVR
, DefRangeRegisterSym
&DefRangeRegister
) {
575 AutoIndent
Indent(P
, 7);
576 P
.formatLine("register = {0}, may have no name = {1}, range start = "
578 formatRegisterId(DefRangeRegister
.Hdr
.Register
),
579 bool(DefRangeRegister
.Hdr
.MayHaveNoName
),
580 formatSegmentOffset(DefRangeRegister
.Range
.ISectStart
,
581 DefRangeRegister
.Range
.OffsetStart
),
582 DefRangeRegister
.Range
.Range
);
583 P
.formatLine("gaps = [{0}]",
584 formatGaps(P
.getIndentLevel() + 9, DefRangeRegister
.Gaps
));
585 return Error::success();
588 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
589 DefRangeSubfieldRegisterSym
&Def
) {
590 AutoIndent
Indent(P
, 7);
591 bool NoName
= !!(Def
.Hdr
.MayHaveNoName
== 0);
592 P
.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}",
593 formatRegisterId(Def
.Hdr
.Register
), NoName
,
594 uint32_t(Def
.Hdr
.OffsetInParent
));
595 P
.formatLine("range = {0}, gaps = {1}", formatRange(Def
.Range
),
596 formatGaps(P
.getIndentLevel() + 9, Def
.Gaps
));
597 return Error::success();
600 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
601 DefRangeSubfieldSym
&Def
) {
602 AutoIndent
Indent(P
, 7);
603 P
.formatLine("program = {0}, offset in parent = {1}, range = {2}",
604 Def
.Program
, Def
.OffsetInParent
, formatRange(Def
.Range
));
605 P
.formatLine("gaps = {0}", formatGaps(P
.getIndentLevel() + 9, Def
.Gaps
));
606 return Error::success();
609 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, DefRangeSym
&Def
) {
610 AutoIndent
Indent(P
, 7);
611 P
.formatLine("program = {0}, range = {1}", Def
.Program
,
612 formatRange(Def
.Range
));
613 P
.formatLine("gaps = {0}", formatGaps(P
.getIndentLevel() + 9, Def
.Gaps
));
614 return Error::success();
617 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, FrameCookieSym
&FC
) {
618 AutoIndent
Indent(P
, 7);
619 P
.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}",
620 FC
.CodeOffset
, formatRegisterId(FC
.Register
),
621 formatCookieKind(FC
.CookieKind
), FC
.Flags
);
622 return Error::success();
625 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, FrameProcSym
&FP
) {
626 AutoIndent
Indent(P
, 7);
627 P
.formatLine("size = {0}, padding size = {1}, offset to padding = {2}",
628 FP
.TotalFrameBytes
, FP
.PaddingFrameBytes
, FP
.OffsetToPadding
);
629 P
.formatLine("bytes of callee saved registers = {0}, exception handler addr "
631 FP
.BytesOfCalleeSavedRegisters
,
632 formatSegmentOffset(FP
.SectionIdOfExceptionHandler
,
633 FP
.OffsetOfExceptionHandler
));
634 P
.formatLine("local fp reg = {0}, param fp reg = {1}",
635 formatRegisterId(FP
.getLocalFramePtrReg(CompilationCPU
)),
636 formatRegisterId(FP
.getParamFramePtrReg(CompilationCPU
)));
637 P
.formatLine("flags = {0}",
638 formatFrameProcedureOptions(P
.getIndentLevel() + 9, FP
.Flags
));
639 return Error::success();
642 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
643 HeapAllocationSiteSym
&HAS
) {
644 AutoIndent
Indent(P
, 7);
645 P
.formatLine("type = {0}, addr = {1} call size = {2}", typeIndex(HAS
.Type
),
646 formatSegmentOffset(HAS
.Segment
, HAS
.CodeOffset
),
647 HAS
.CallInstructionSize
);
648 return Error::success();
651 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, InlineSiteSym
&IS
) {
652 AutoIndent
Indent(P
, 7);
653 auto Bytes
= makeArrayRef(IS
.AnnotationData
);
654 StringRef
Annotations(reinterpret_cast<const char *>(Bytes
.begin()),
657 P
.formatLine("inlinee = {0}, parent = {1}, end = {2}", idIndex(IS
.Inlinee
),
659 P
.formatLine("annotations = {0}", toHex(Annotations
));
660 return Error::success();
663 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
664 RegisterSym
&Register
) {
665 P
.format(" `{0}`", Register
.Name
);
666 AutoIndent
Indent(P
, 7);
667 P
.formatLine("register = {0}, type = {1}",
668 formatRegisterId(Register
.Register
), typeIndex(Register
.Index
));
669 return Error::success();
672 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
673 PublicSym32
&Public
) {
674 P
.format(" `{0}`", Public
.Name
);
675 AutoIndent
Indent(P
, 7);
676 P
.formatLine("flags = {0}, addr = {1}",
677 formatPublicSymFlags(P
.getIndentLevel() + 9, Public
.Flags
),
678 formatSegmentOffset(Public
.Segment
, Public
.Offset
));
679 return Error::success();
682 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, ProcRefSym
&PR
) {
683 P
.format(" `{0}`", PR
.Name
);
684 AutoIndent
Indent(P
, 7);
685 P
.formatLine("module = {0}, sum name = {1}, offset = {2}", PR
.Module
,
686 PR
.SumName
, PR
.SymOffset
);
687 return Error::success();
690 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, LabelSym
&Label
) {
691 P
.format(" `{0}` (addr = {1})", Label
.Name
,
692 formatSegmentOffset(Label
.Segment
, Label
.CodeOffset
));
693 AutoIndent
Indent(P
, 7);
694 P
.formatLine("flags = {0}",
695 formatProcSymFlags(P
.getIndentLevel() + 9, Label
.Flags
));
696 return Error::success();
699 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, LocalSym
&Local
) {
700 P
.format(" `{0}`", Local
.Name
);
701 AutoIndent
Indent(P
, 7);
703 std::string FlagStr
=
704 formatLocalSymFlags(P
.getIndentLevel() + 9, Local
.Flags
);
705 P
.formatLine("type={0}, flags = {1}", typeIndex(Local
.Type
), FlagStr
);
706 return Error::success();
709 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
710 ObjNameSym
&ObjName
) {
711 P
.format(" sig={0}, `{1}`", ObjName
.Signature
, ObjName
.Name
);
712 return Error::success();
715 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, ProcSym
&Proc
) {
716 P
.format(" `{0}`", Proc
.Name
);
717 AutoIndent
Indent(P
, 7);
718 P
.formatLine("parent = {0}, end = {1}, addr = {2}, code size = {3}",
719 Proc
.Parent
, Proc
.End
,
720 formatSegmentOffset(Proc
.Segment
, Proc
.CodeOffset
),
723 switch (Proc
.getKind()) {
724 case SymbolRecordKind::GlobalProcIdSym
:
725 case SymbolRecordKind::ProcIdSym
:
726 case SymbolRecordKind::DPCProcIdSym
:
732 P
.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}",
733 typeOrIdIndex(Proc
.FunctionType
, IsType
), Proc
.DbgStart
,
735 formatProcSymFlags(P
.getIndentLevel() + 9, Proc
.Flags
));
736 return Error::success();
739 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
740 ScopeEndSym
&ScopeEnd
) {
741 return Error::success();
744 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, CallerSym
&Caller
) {
745 AutoIndent
Indent(P
, 7);
746 for (const auto &I
: Caller
.Indices
) {
747 P
.formatLine("callee: {0}", idIndex(I
));
749 return Error::success();
752 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
753 RegRelativeSym
&RegRel
) {
754 P
.format(" `{0}`", RegRel
.Name
);
755 AutoIndent
Indent(P
, 7);
756 P
.formatLine("type = {0}, register = {1}, offset = {2}",
757 typeIndex(RegRel
.Type
), formatRegisterId(RegRel
.Register
),
759 return Error::success();
762 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
763 ThreadLocalDataSym
&Data
) {
764 P
.format(" `{0}`", Data
.Name
);
765 AutoIndent
Indent(P
, 7);
766 P
.formatLine("type = {0}, addr = {1}", typeIndex(Data
.Type
),
767 formatSegmentOffset(Data
.Segment
, Data
.DataOffset
));
768 return Error::success();
771 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
, UDTSym
&UDT
) {
772 P
.format(" `{0}`", UDT
.Name
);
773 AutoIndent
Indent(P
, 7);
774 P
.formatLine("original type = {0}", UDT
.Type
);
775 return Error::success();
778 Error
MinimalSymbolDumper::visitKnownRecord(CVSymbol
&CVR
,
779 UsingNamespaceSym
&UN
) {
780 P
.format(" `{0}`", UN
.Name
);
781 return Error::success();