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