LLVM 22.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, DefRangeRegisterSym &DefRangeRegister) {
339 W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
340 getRegisterNames(CompilationCPUType));
341 W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
342 printLocalVariableAddrRange(DefRangeRegister.Range,
343 DefRangeRegister.getRelocationOffset());
344 printLocalVariableAddrGap(DefRangeRegister.Gaps);
345 return Error::success();
346}
347
348Error CVSymbolDumperImpl::visitKnownRecord(
349 CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
350 W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
351 getRegisterNames(CompilationCPUType));
352 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
353 W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
354 printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
355 DefRangeSubfieldRegister.getRelocationOffset());
356 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
357 return Error::success();
358}
359
360Error CVSymbolDumperImpl::visitKnownRecord(
361 CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
362 if (ObjDelegate) {
363 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
364 auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
365 if (!ExpectedProgram) {
366 consumeError(ExpectedProgram.takeError());
368 "String table offset outside of bounds of String Table!");
369 }
370 W.printString("Program", *ExpectedProgram);
371 }
372 W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
373 printLocalVariableAddrRange(DefRangeSubfield.Range,
374 DefRangeSubfield.getRelocationOffset());
375 printLocalVariableAddrGap(DefRangeSubfield.Gaps);
376 return Error::success();
377}
378
379Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
380 DefRangeSym &DefRange) {
381 if (ObjDelegate) {
382 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
383 auto ExpectedProgram = Strings.getString(DefRange.Program);
384 if (!ExpectedProgram) {
385 consumeError(ExpectedProgram.takeError());
387 "String table offset outside of bounds of String Table!");
388 }
389 W.printString("Program", *ExpectedProgram);
390 }
391 printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
392 printLocalVariableAddrGap(DefRange.Gaps);
393 return Error::success();
394}
395
396Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
397 FrameCookieSym &FrameCookie) {
398 StringRef LinkageName;
399 if (ObjDelegate) {
400 ObjDelegate->printRelocatedField("CodeOffset",
401 FrameCookie.getRelocationOffset(),
402 FrameCookie.CodeOffset, &LinkageName);
403 }
404 W.printEnum("Register", uint16_t(FrameCookie.Register),
405 getRegisterNames(CompilationCPUType));
406 W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
408 W.printHex("Flags", FrameCookie.Flags);
409 return Error::success();
410}
411
412Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
413 FrameProcSym &FrameProc) {
414 W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
415 W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
416 W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
417 W.printHex("BytesOfCalleeSavedRegisters",
419 W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
420 W.printHex("SectionIdOfExceptionHandler",
422 W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
424 W.printEnum("LocalFramePtrReg",
425 uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)),
426 getRegisterNames(CompilationCPUType));
427 W.printEnum("ParamFramePtrReg",
428 uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)),
429 getRegisterNames(CompilationCPUType));
430 return Error::success();
431}
432
433Error CVSymbolDumperImpl::visitKnownRecord(
434 CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
435 StringRef LinkageName;
436 if (ObjDelegate) {
437 ObjDelegate->printRelocatedField("CodeOffset",
438 HeapAllocSite.getRelocationOffset(),
439 HeapAllocSite.CodeOffset, &LinkageName);
440 }
441 W.printHex("Segment", HeapAllocSite.Segment);
442 W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
443 printTypeIndex("Type", HeapAllocSite.Type);
444 if (!LinkageName.empty())
445 W.printString("LinkageName", LinkageName);
446 return Error::success();
447}
448
449Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
450 InlineSiteSym &InlineSite) {
451 W.printHex("PtrParent", InlineSite.Parent);
452 W.printHex("PtrEnd", InlineSite.End);
453 printTypeIndex("Inlinee", InlineSite.Inlinee);
454
455 ListScope BinaryAnnotations(W, "BinaryAnnotations");
456 for (auto &Annotation : InlineSite.annotations()) {
457 switch (Annotation.OpCode) {
458 case BinaryAnnotationsOpCode::Invalid:
459 W.printString("(Annotation Padding)");
460 break;
461 case BinaryAnnotationsOpCode::CodeOffset:
462 case BinaryAnnotationsOpCode::ChangeCodeOffset:
463 case BinaryAnnotationsOpCode::ChangeCodeLength:
464 W.printHex(Annotation.Name, Annotation.U1);
465 break;
466 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
467 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
468 case BinaryAnnotationsOpCode::ChangeRangeKind:
469 case BinaryAnnotationsOpCode::ChangeColumnStart:
470 case BinaryAnnotationsOpCode::ChangeColumnEnd:
472 break;
473 case BinaryAnnotationsOpCode::ChangeLineOffset:
474 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
476 break;
477 case BinaryAnnotationsOpCode::ChangeFile:
478 if (ObjDelegate) {
479 W.printHex("ChangeFile",
480 ObjDelegate->getFileNameForFileOffset(Annotation.U1),
481 Annotation.U1);
482 } else {
483 W.printHex("ChangeFile", Annotation.U1);
484 }
485
486 break;
487 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
488 W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
489 << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
490 << "}\n";
491 break;
492 }
493 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
494 W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
495 << W.hex(Annotation.U2)
496 << ", Length: " << W.hex(Annotation.U1) << "}\n";
497 break;
498 }
499 }
500 }
501 return Error::success();
502}
503
504Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
505 RegisterSym &Register) {
506 printTypeIndex("Type", Register.Index);
507 W.printEnum("Seg", uint16_t(Register.Register),
508 getRegisterNames(CompilationCPUType));
509 W.printString("Name", Register.Name);
510 return Error::success();
511}
512
513Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
514 W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());
515 W.printNumber("Seg", Public.Segment);
516 W.printNumber("Off", Public.Offset);
517 W.printString("Name", Public.Name);
518 return Error::success();
519}
520
521Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
522 W.printNumber("SumName", ProcRef.SumName);
523 W.printNumber("SymOffset", ProcRef.SymOffset);
524 W.printNumber("Mod", ProcRef.Module);
525 W.printString("Name", ProcRef.Name);
526 return Error::success();
527}
528
529Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
530 StringRef LinkageName;
531 if (ObjDelegate) {
532 ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
533 Label.CodeOffset, &LinkageName);
534 }
535 W.printHex("Segment", Label.Segment);
536 W.printHex("Flags", uint8_t(Label.Flags));
537 W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
538 W.printString("DisplayName", Label.Name);
539 if (!LinkageName.empty())
540 W.printString("LinkageName", LinkageName);
541 return Error::success();
542}
543
544Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
545 printTypeIndex("Type", Local.Type);
546 W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
547 W.printString("VarName", Local.Name);
548 return Error::success();
549}
550
551Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
552 W.printHex("Signature", ObjName.Signature);
553 W.printString("ObjectName", ObjName.Name);
554 return Error::success();
555}
556
557Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
558 if (InFunctionScope)
560 "Visiting a ProcSym while inside function scope!");
561
562 InFunctionScope = true;
563
564 StringRef LinkageName;
565 W.printHex("PtrParent", Proc.Parent);
566 W.printHex("PtrEnd", Proc.End);
567 W.printHex("PtrNext", Proc.Next);
568 W.printHex("CodeSize", Proc.CodeSize);
569 W.printHex("DbgStart", Proc.DbgStart);
570 W.printHex("DbgEnd", Proc.DbgEnd);
571 printTypeIndex("FunctionType", Proc.FunctionType);
572 if (ObjDelegate) {
573 ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
574 Proc.CodeOffset, &LinkageName);
575 }
576 W.printHex("Segment", Proc.Segment);
577 W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
579 W.printString("DisplayName", Proc.Name);
580 if (!LinkageName.empty())
581 W.printString("LinkageName", LinkageName);
582 return Error::success();
583}
584
585Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
586 ScopeEndSym &ScopeEnd) {
587 InFunctionScope = false;
588 return Error::success();
589}
590
591Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
592 llvm::StringRef ScopeName;
593 switch (CVR.kind()) {
594 case S_CALLEES:
595 ScopeName = "Callees";
596 break;
597 case S_CALLERS:
598 ScopeName = "Callers";
599 break;
600 case S_INLINEES:
601 ScopeName = "Inlinees";
602 break;
603 default:
605 "Unknown CV Record type for a CallerSym object!");
606 }
607 ListScope S(W, ScopeName);
608 for (auto FuncID : Caller.Indices)
609 printTypeIndex("FuncID", FuncID);
610 return Error::success();
611}
612
613Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
614 RegRelativeSym &RegRel) {
615 W.printHex("Offset", RegRel.Offset);
616 printTypeIndex("Type", RegRel.Type);
617 W.printEnum("Register", uint16_t(RegRel.Register),
618 getRegisterNames(CompilationCPUType));
619 W.printString("VarName", RegRel.Name);
620 return Error::success();
621}
622
623Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
624 ThreadLocalDataSym &Data) {
625 StringRef LinkageName;
626 if (ObjDelegate) {
627 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
628 Data.DataOffset, &LinkageName);
629 }
630 printTypeIndex("Type", Data.Type);
631 W.printString("DisplayName", Data.Name);
632 if (!LinkageName.empty())
633 W.printString("LinkageName", LinkageName);
634 return Error::success();
635}
636
637Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
638 printTypeIndex("Type", UDT.Type);
639 W.printString("UDTName", UDT.Name);
640 return Error::success();
641}
642
643Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
644 UsingNamespaceSym &UN) {
645 W.printString("Namespace", UN.Name);
646 return Error::success();
647}
648
649Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
650 AnnotationSym &Annot) {
651 W.printHex("Offset", Annot.CodeOffset);
652 W.printHex("Segment", Annot.Segment);
653
654 ListScope S(W, "Strings");
655 for (StringRef Str : Annot.Strings)
656 W.printString(Str);
657
658 return Error::success();
659}
660
661Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
662 JumpTableSym &JumpTable) {
663 W.printHex("BaseOffset", JumpTable.BaseOffset);
664 W.printNumber("BaseSegment", JumpTable.BaseSegment);
665 W.printEnum("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),
667 W.printHex("BranchOffset", JumpTable.BranchOffset);
668 W.printHex("TableOffset", JumpTable.TableOffset);
669 W.printNumber("BranchSegment", JumpTable.BranchSegment);
670 W.printNumber("TableSegment", JumpTable.TableSegment);
671 W.printNumber("EntriesCount", JumpTable.EntriesCount);
672 return Error::success();
673}
674
675Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
676 HotPatchFuncSym &HotPatchFunc) {
677 printTypeIndex("Function", HotPatchFunc.Function);
678 W.printString("Name", HotPatchFunc.Name);
679 return Error::success();
680}
681
682Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
683 W.printNumber("Length", CVR.length());
684 return Error::success();
685}
686
689 SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
690 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
691 PrintRecordBytes);
692
693 Pipeline.addCallbackToPipeline(Deserializer);
694 Pipeline.addCallbackToPipeline(Dumper);
695 CVSymbolVisitor Visitor(Pipeline);
696 auto Err = Visitor.visitSymbolRecord(Record);
697 CompilationCPUType = Dumper.getCompilationCPUType();
698 return Err;
699}
700
703 SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
704 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
705 PrintRecordBytes);
706
707 Pipeline.addCallbackToPipeline(Deserializer);
708 Pipeline.addCallbackToPipeline(Dumper);
709 CVSymbolVisitor Visitor(Pipeline);
710 auto Err = Visitor.visitSymbolStream(Symbols);
711 CompilationCPUType = Dumper.getCompilationCPUType();
712 return Err;
713}
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
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:77
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:49
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.
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