33 :
Types(
Types), ObjDelegate(ObjDelegate),
W(
W), CompilationCPUType(CPU),
34 PrintRecordBytes(PrintRecordBytes), InFunctionScope(
false) {}
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"
46 CPUType getCompilationCPUType()
const {
return CompilationCPUType; }
61 bool PrintRecordBytes;
68#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
71#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
78void CVSymbolDumperImpl::printLocalVariableAddrRange(
82 ObjDelegate->printRelocatedField(
"OffsetStart", RelocationOffset,
84 W.printHex(
"ISectStart",
Range.ISectStart);
85 W.printHex(
"Range",
Range.Range);
88void CVSymbolDumperImpl::printLocalVariableAddrGap(
90 for (
auto &Gap : Gaps) {
92 W.printHex(
"GapStartOffset", Gap.GapStartOffset);
93 W.printHex(
"Range", Gap.Range);
103 W.getOStream() <<
" {\n";
110 if (PrintRecordBytes && ObjDelegate)
111 ObjDelegate->printBinaryBlockWithRelocs(
"SymData", CVR.
content());
114 W.startLine() <<
"}\n";
120 W.printHex(
"PtrParent",
Block.Parent);
121 W.printHex(
"PtrEnd",
Block.End);
122 W.printHex(
"CodeSize",
Block.CodeSize);
124 ObjDelegate->printRelocatedField(
"CodeOffset",
Block.getRelocationOffset(),
127 W.printHex(
"Segment",
Block.Segment);
128 W.printString(
"BlockName",
Block.Name);
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);
148 W.printNumber(
"Size", Tramp.
Size);
157 W.printNumber(
"SectionNumber",
Section.SectionNumber);
158 W.printNumber(
"Alignment",
Section.Alignment);
160 W.printNumber(
"Length",
Section.Length);
161 W.printFlags(
"Characteristics",
Section.Characteristics,
165 W.printString(
"Name",
Section.Name);
172 W.printFlags(
"Characteristics",
CoffGroup.Characteristics,
183 W.printNumber(
"Offset", BPRel.
Offset);
185 W.printString(
"VarName", BPRel.
Name);
199 ObjDelegate->printRelocatedField(
"CodeOffset",
203 W.printHex(
"Segment", CallSiteInfo.
Segment);
213 for (
auto Entry : EnvBlock.
Fields) {
214 W.printString(Entry);
222 W.printNumber(
"ModFilenameOffset",
FileStatic.ModFilenameOffset);
229 W.printNumber(
"Ordinal",
Export.Ordinal);
231 W.printString(
"Name",
Export.Name);
240 CompilationCPUType = Compile2.
Machine;
241 std::string FrontendVersion;
247 std::string BackendVersion;
253 W.printString(
"FrontendVersion", FrontendVersion);
254 W.printString(
"BackendVersion", BackendVersion);
255 W.printString(
"VersionName", Compile2.
Version);
265 CompilationCPUType = Compile3.
Machine;
266 std::string FrontendVersion;
273 std::string BackendVersion;
280 W.printString(
"FrontendVersion", FrontendVersion);
281 W.printString(
"BackendVersion", BackendVersion);
282 W.printString(
"VersionName", Compile3.
Version);
297 ObjDelegate->printRelocatedField(
"DataOffset", Data.getRelocationOffset(),
301 W.printString(
"DisplayName", Data.Name);
307Error CVSymbolDumperImpl::visitKnownRecord(
310 W.printNumber(
"Offset", DefRangeFramePointerRelFullScope.
Offset);
314Error CVSymbolDumperImpl::visitKnownRecord(
316 W.printNumber(
"Offset", DefRangeFramePointerRel.
Hdr.
Offset);
317 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
319 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
323Error CVSymbolDumperImpl::visitKnownRecord(
327 W.printBoolean(
"HasSpilledUDTMember",
331 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
333 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
337Error CVSymbolDumperImpl::visitKnownRecord(
342 printLocalVariableAddrRange(DefRangeRegister.
Range,
344 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
348Error CVSymbolDumperImpl::visitKnownRecord(
354 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
356 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
360Error CVSymbolDumperImpl::visitKnownRecord(
364 auto ExpectedProgram = Strings.getString(DefRangeSubfield.
Program);
365 if (!ExpectedProgram) {
367 return llvm::make_error<CodeViewError>(
368 "String table offset outside of bounds of String Table!");
370 W.printString(
"Program", *ExpectedProgram);
373 printLocalVariableAddrRange(DefRangeSubfield.
Range,
375 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
383 auto ExpectedProgram = Strings.getString(DefRange.
Program);
384 if (!ExpectedProgram) {
386 return llvm::make_error<CodeViewError>(
387 "String table offset outside of bounds of String Table!");
389 W.printString(
"Program", *ExpectedProgram);
392 printLocalVariableAddrGap(DefRange.
Gaps);
400 ObjDelegate->printRelocatedField(
"CodeOffset",
408 W.printHex(
"Flags", FrameCookie.
Flags);
417 W.printHex(
"BytesOfCalleeSavedRegisters",
420 W.printHex(
"SectionIdOfExceptionHandler",
424 W.printEnum(
"LocalFramePtrReg",
427 W.printEnum(
"ParamFramePtrReg",
433Error CVSymbolDumperImpl::visitKnownRecord(
437 ObjDelegate->printRelocatedField(
"CodeOffset",
441 W.printHex(
"Segment", HeapAllocSite.
Segment);
455 ListScope BinaryAnnotations(W,
"BinaryAnnotations");
456 for (
auto &Annotation :
InlineSite.annotations()) {
458 case BinaryAnnotationsOpCode::Invalid:
459 W.printString(
"(Annotation Padding)");
461 case BinaryAnnotationsOpCode::CodeOffset:
462 case BinaryAnnotationsOpCode::ChangeCodeOffset:
463 case BinaryAnnotationsOpCode::ChangeCodeLength:
466 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
467 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
468 case BinaryAnnotationsOpCode::ChangeRangeKind:
469 case BinaryAnnotationsOpCode::ChangeColumnStart:
470 case BinaryAnnotationsOpCode::ChangeColumnEnd:
473 case BinaryAnnotationsOpCode::ChangeLineOffset:
474 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
477 case BinaryAnnotationsOpCode::ChangeFile:
479 W.printHex(
"ChangeFile",
480 ObjDelegate->getFileNameForFileOffset(
Annotation.U1),
487 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
488 W.startLine() <<
"ChangeCodeOffsetAndLineOffset: {CodeOffset: "
493 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
494 W.startLine() <<
"ChangeCodeLengthAndCodeOffset: {CodeOffset: "
515 W.printNumber(
"Seg",
Public.Segment);
516 W.printNumber(
"Off",
Public.Offset);
517 W.printString(
"Name",
Public.Name);
522 W.printNumber(
"SumName", ProcRef.
SumName);
523 W.printNumber(
"SymOffset", ProcRef.
SymOffset);
524 W.printNumber(
"Mod", ProcRef.
Module);
525 W.printString(
"Name", ProcRef.
Name);
532 ObjDelegate->printRelocatedField(
"CodeOffset",
Label.getRelocationOffset(),
535 W.printHex(
"Segment",
Label.Segment);
536 W.printHex(
"Flags", uint8_t(
Label.Flags));
538 W.printString(
"DisplayName",
Label.Name);
547 W.printString(
"VarName",
Local.Name);
553 W.printString(
"ObjectName", ObjName.
Name);
559 return llvm::make_error<CodeViewError>(
560 "Visiting a ProcSym while inside function scope!");
562 InFunctionScope =
true;
565 W.printHex(
"PtrParent", Proc.
Parent);
566 W.printHex(
"PtrEnd", Proc.
End);
567 W.printHex(
"PtrNext", Proc.
Next);
570 W.printHex(
"DbgEnd", Proc.
DbgEnd);
576 W.printHex(
"Segment", Proc.
Segment);
577 W.printFlags(
"Flags",
static_cast<uint8_t
>(Proc.
Flags),
579 W.printString(
"DisplayName", Proc.
Name);
587 InFunctionScope =
false;
593 switch (CVR.
kind()) {
595 ScopeName =
"Callees";
598 ScopeName =
"Callers";
601 ScopeName =
"Inlinees";
604 return llvm::make_error<CodeViewError>(
605 "Unknown CV Record type for a CallerSym object!");
608 for (
auto FuncID :
Caller.Indices)
615 W.printHex(
"Offset",
RegRel.Offset);
619 W.printString(
"VarName",
RegRel.Name);
627 ObjDelegate->printRelocatedField(
"DataOffset", Data.getRelocationOffset(),
631 W.printString(
"DisplayName", Data.Name);
639 W.printString(
"UDTName",
UDT.Name);
645 W.printString(
"Namespace", UN.
Name);
652 W.printHex(
"Segment", Annot.
Segment);
663 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
664 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
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);
676 W.printNumber(
"Length", CVR.
length());
683 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
690 CompilationCPUType = Dumper.getCompilationCPUType();
697 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
704 CompilationCPUType = Dumper.getCompilationCPUType();
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static StringRef getSymbolKindName(SymbolKind Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Wrapper class representing virtual and physical registers.
constexpr Register(unsigned Val=0)
StringRef - Represent a constant reference to a string, i.e.
Value(Type *Ty, unsigned scid)
std::vector< StringRef > Strings
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
ArrayRef< uint8_t > content() const
Error dump(CVRecord< SymbolKind > &Record)
Dumps one type record.
Error visitSymbolRecord(CVSymbol &Record)
Error visitSymbolStream(const CVSymbolArray &Symbols)
uint32_t getRelocationOffset() const
uint8_t getLanguage() const
uint32_t getFlags() const
uint16_t VersionBackendMajor
uint16_t VersionFrontendMajor
uint16_t VersionBackendMinor
uint16_t VersionFrontendMinor
uint16_t VersionBackendBuild
uint16_t VersionFrontendBuild
CompileSym3Flags getFlags() const
uint16_t VersionBackendBuild
uint16_t VersionBackendQFE
SourceLanguage getLanguage() const
uint16_t VersionFrontendMajor
uint16_t VersionBackendMajor
uint16_t VersionBackendMinor
uint16_t VersionFrontendBuild
uint16_t VersionFrontendMinor
uint16_t VersionFrontendQFE
Represents a read-only view of a CodeView string table.
DefRangeFramePointerRelHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeRegisterRelHeader Hdr
bool hasSpilledUDTMember() const
uint32_t getRelocationOffset() const
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
DefRangeRegisterHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
LocalVariableAddrRange Range
std::vector< StringRef > Fields
FrameCookieKind CookieKind
uint32_t getRelocationOffset() const
uint32_t BytesOfCalleeSavedRegisters
uint16_t SectionIdOfExceptionHandler
uint32_t PaddingFrameBytes
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.
uint32_t OffsetOfExceptionHandler
FrameProcedureOptions Flags
uint16_t CallInstructionSize
uint32_t getRelocationOffset() const
uint32_t getRelocationOffset() const
void addCallbackToPipeline(SymbolVisitorCallbacks &Callbacks)
virtual Error visitSymbolEnd(CVSymbol &Record)
virtual Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset)
Paired begin/end actions for all symbols.
virtual Error visitUnknownSymbol(CVSymbol &Record)
Action to take on unknown symbols. By default, they are ignored.
A raw_ostream that writes to an std::string.
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
ArrayRef< EnumEntry< uint32_t > > getCompileSym2FlagNames()
ArrayRef< EnumEntry< COFF::SectionCharacteristics > > getImageSectionCharacteristicNames()
ArrayRef< EnumEntry< uint16_t > > getExportSymFlagNames()
ArrayRef< EnumEntry< uint16_t > > getJumpTableEntrySizeNames()
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
ArrayRef< EnumEntry< uint8_t > > getThunkOrdinalNames()
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
ArrayRef< EnumEntry< SourceLanguage > > getSourceLanguageNames()
ArrayRef< EnumEntry< uint32_t > > getFrameProcSymFlagNames()
ArrayRef< EnumEntry< uint16_t > > getTrampolineNames()
ArrayRef< EnumEntry< uint32_t > > getPublicSymFlagNames()
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
ArrayRef< EnumEntry< uint8_t > > getFrameCookieKindNames()
void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
This is an optimization pass for GlobalISel generic memory operations.
std::tuple< uint64_t, uint32_t > InlineSite
@ Export
Export information to summary.
void consumeError(Error Err)
Consume a Error without doing anything.