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