Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
35271 views
//===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/DebugInfo/CodeView/SymbolDumper.h"9#include "llvm/ADT/StringRef.h"10#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"11#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"12#include "llvm/DebugInfo/CodeView/EnumTables.h"13#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"14#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"15#include "llvm/DebugInfo/CodeView/SymbolRecord.h"16#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"17#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"18#include "llvm/DebugInfo/CodeView/TypeIndex.h"19#include "llvm/Support/Error.h"20#include "llvm/Support/ScopedPrinter.h"2122using namespace llvm;23using namespace llvm::codeview;2425namespace {26/// Use this private dumper implementation to keep implementation details about27/// the visitor out of SymbolDumper.h.28class CVSymbolDumperImpl : public SymbolVisitorCallbacks {29public:30CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,31ScopedPrinter &W, CPUType CPU, bool PrintRecordBytes)32: Types(Types), ObjDelegate(ObjDelegate), W(W), CompilationCPUType(CPU),33PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}3435/// CVSymbolVisitor overrides.36#define SYMBOL_RECORD(EnumName, EnumVal, Name) \37Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;38#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)39#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"4041Error visitSymbolBegin(CVSymbol &Record) override;42Error visitSymbolEnd(CVSymbol &Record) override;43Error visitUnknownSymbol(CVSymbol &Record) override;4445CPUType getCompilationCPUType() const { return CompilationCPUType; }4647private:48void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,49uint32_t RelocationOffset);50void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);51void printTypeIndex(StringRef FieldName, TypeIndex TI);5253TypeCollection &Types;54SymbolDumpDelegate *ObjDelegate;55ScopedPrinter &W;5657/// Save the machine or CPU type when dumping a compile symbols.58CPUType CompilationCPUType = CPUType::X64;5960bool PrintRecordBytes;61bool InFunctionScope;62};63}6465static StringRef getSymbolKindName(SymbolKind Kind) {66switch (Kind) {67#define SYMBOL_RECORD(EnumName, EnumVal, Name) \68case EnumName: \69return #Name;70#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"71default:72break;73}74return "UnknownSym";75}7677void CVSymbolDumperImpl::printLocalVariableAddrRange(78const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {79DictScope S(W, "LocalVariableAddrRange");80if (ObjDelegate)81ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,82Range.OffsetStart);83W.printHex("ISectStart", Range.ISectStart);84W.printHex("Range", Range.Range);85}8687void CVSymbolDumperImpl::printLocalVariableAddrGap(88ArrayRef<LocalVariableAddrGap> Gaps) {89for (auto &Gap : Gaps) {90ListScope S(W, "LocalVariableAddrGap");91W.printHex("GapStartOffset", Gap.GapStartOffset);92W.printHex("Range", Gap.Range);93}94}9596void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {97codeview::printTypeIndex(W, FieldName, TI, Types);98}99100Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {101W.startLine() << getSymbolKindName(CVR.kind());102W.getOStream() << " {\n";103W.indent();104W.printEnum("Kind", unsigned(CVR.kind()), getSymbolTypeNames());105return Error::success();106}107108Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {109if (PrintRecordBytes && ObjDelegate)110ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());111112W.unindent();113W.startLine() << "}\n";114return Error::success();115}116117Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {118StringRef LinkageName;119W.printHex("PtrParent", Block.Parent);120W.printHex("PtrEnd", Block.End);121W.printHex("CodeSize", Block.CodeSize);122if (ObjDelegate) {123ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),124Block.CodeOffset, &LinkageName);125}126W.printHex("Segment", Block.Segment);127W.printString("BlockName", Block.Name);128W.printString("LinkageName", LinkageName);129return Error::success();130}131132Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {133W.printString("Name", Thunk.Name);134W.printNumber("Parent", Thunk.Parent);135W.printNumber("End", Thunk.End);136W.printNumber("Next", Thunk.Next);137W.printNumber("Off", Thunk.Offset);138W.printNumber("Seg", Thunk.Segment);139W.printNumber("Len", Thunk.Length);140W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());141return Error::success();142}143144Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,145TrampolineSym &Tramp) {146W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());147W.printNumber("Size", Tramp.Size);148W.printNumber("ThunkOff", Tramp.ThunkOffset);149W.printNumber("TargetOff", Tramp.TargetOffset);150W.printNumber("ThunkSection", Tramp.ThunkSection);151W.printNumber("TargetSection", Tramp.TargetSection);152return Error::success();153}154155Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {156W.printNumber("SectionNumber", Section.SectionNumber);157W.printNumber("Alignment", Section.Alignment);158W.printNumber("Rva", Section.Rva);159W.printNumber("Length", Section.Length);160W.printFlags("Characteristics", Section.Characteristics,161getImageSectionCharacteristicNames(),162COFF::SectionCharacteristics(0x00F00000));163164W.printString("Name", Section.Name);165return Error::success();166}167168Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,169CoffGroupSym &CoffGroup) {170W.printNumber("Size", CoffGroup.Size);171W.printFlags("Characteristics", CoffGroup.Characteristics,172getImageSectionCharacteristicNames(),173COFF::SectionCharacteristics(0x00F00000));174W.printNumber("Offset", CoffGroup.Offset);175W.printNumber("Segment", CoffGroup.Segment);176W.printString("Name", CoffGroup.Name);177return Error::success();178}179180Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,181BPRelativeSym &BPRel) {182W.printNumber("Offset", BPRel.Offset);183printTypeIndex("Type", BPRel.Type);184W.printString("VarName", BPRel.Name);185return Error::success();186}187188Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,189BuildInfoSym &BuildInfo) {190printTypeIndex("BuildId", BuildInfo.BuildId);191return Error::success();192}193194Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,195CallSiteInfoSym &CallSiteInfo) {196StringRef LinkageName;197if (ObjDelegate) {198ObjDelegate->printRelocatedField("CodeOffset",199CallSiteInfo.getRelocationOffset(),200CallSiteInfo.CodeOffset, &LinkageName);201}202W.printHex("Segment", CallSiteInfo.Segment);203printTypeIndex("Type", CallSiteInfo.Type);204if (!LinkageName.empty())205W.printString("LinkageName", LinkageName);206return Error::success();207}208209Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,210EnvBlockSym &EnvBlock) {211ListScope L(W, "Entries");212for (auto Entry : EnvBlock.Fields) {213W.printString(Entry);214}215return Error::success();216}217218Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,219FileStaticSym &FileStatic) {220printTypeIndex("Index", FileStatic.Index);221W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);222W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());223W.printString("Name", FileStatic.Name);224return Error::success();225}226227Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {228W.printNumber("Ordinal", Export.Ordinal);229W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());230W.printString("Name", Export.Name);231return Error::success();232}233234Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,235Compile2Sym &Compile2) {236W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());237W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());238W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());239CompilationCPUType = Compile2.Machine;240std::string FrontendVersion;241{242raw_string_ostream Out(FrontendVersion);243Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor244<< '.' << Compile2.VersionFrontendBuild;245}246std::string BackendVersion;247{248raw_string_ostream Out(BackendVersion);249Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor250<< '.' << Compile2.VersionBackendBuild;251}252W.printString("FrontendVersion", FrontendVersion);253W.printString("BackendVersion", BackendVersion);254W.printString("VersionName", Compile2.Version);255return Error::success();256}257258Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,259Compile3Sym &Compile3) {260W.printEnum("Language", uint8_t(Compile3.getLanguage()), getSourceLanguageNames());261W.printFlags("Flags", uint32_t(Compile3.getFlags()),262getCompileSym3FlagNames());263W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());264CompilationCPUType = Compile3.Machine;265std::string FrontendVersion;266{267raw_string_ostream Out(FrontendVersion);268Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor269<< '.' << Compile3.VersionFrontendBuild << '.'270<< Compile3.VersionFrontendQFE;271}272std::string BackendVersion;273{274raw_string_ostream Out(BackendVersion);275Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor276<< '.' << Compile3.VersionBackendBuild << '.'277<< Compile3.VersionBackendQFE;278}279W.printString("FrontendVersion", FrontendVersion);280W.printString("BackendVersion", BackendVersion);281W.printString("VersionName", Compile3.Version);282return Error::success();283}284285Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,286ConstantSym &Constant) {287printTypeIndex("Type", Constant.Type);288W.printNumber("Value", Constant.Value);289W.printString("Name", Constant.Name);290return Error::success();291}292293Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {294StringRef LinkageName;295if (ObjDelegate) {296ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),297Data.DataOffset, &LinkageName);298}299printTypeIndex("Type", Data.Type);300W.printString("DisplayName", Data.Name);301if (!LinkageName.empty())302W.printString("LinkageName", LinkageName);303return Error::success();304}305306Error CVSymbolDumperImpl::visitKnownRecord(307CVSymbol &CVR,308DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {309W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);310return Error::success();311}312313Error CVSymbolDumperImpl::visitKnownRecord(314CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {315W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);316printLocalVariableAddrRange(DefRangeFramePointerRel.Range,317DefRangeFramePointerRel.getRelocationOffset());318printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);319return Error::success();320}321322Error CVSymbolDumperImpl::visitKnownRecord(323CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {324W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register),325getRegisterNames(CompilationCPUType));326W.printBoolean("HasSpilledUDTMember",327DefRangeRegisterRel.hasSpilledUDTMember());328W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());329W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);330printLocalVariableAddrRange(DefRangeRegisterRel.Range,331DefRangeRegisterRel.getRelocationOffset());332printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);333return Error::success();334}335336Error CVSymbolDumperImpl::visitKnownRecord(337CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {338W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),339getRegisterNames(CompilationCPUType));340W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);341printLocalVariableAddrRange(DefRangeRegister.Range,342DefRangeRegister.getRelocationOffset());343printLocalVariableAddrGap(DefRangeRegister.Gaps);344return Error::success();345}346347Error CVSymbolDumperImpl::visitKnownRecord(348CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {349W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),350getRegisterNames(CompilationCPUType));351W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);352W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);353printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,354DefRangeSubfieldRegister.getRelocationOffset());355printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);356return Error::success();357}358359Error CVSymbolDumperImpl::visitKnownRecord(360CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {361if (ObjDelegate) {362DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();363auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);364if (!ExpectedProgram) {365consumeError(ExpectedProgram.takeError());366return llvm::make_error<CodeViewError>(367"String table offset outside of bounds of String Table!");368}369W.printString("Program", *ExpectedProgram);370}371W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);372printLocalVariableAddrRange(DefRangeSubfield.Range,373DefRangeSubfield.getRelocationOffset());374printLocalVariableAddrGap(DefRangeSubfield.Gaps);375return Error::success();376}377378Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,379DefRangeSym &DefRange) {380if (ObjDelegate) {381DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();382auto ExpectedProgram = Strings.getString(DefRange.Program);383if (!ExpectedProgram) {384consumeError(ExpectedProgram.takeError());385return llvm::make_error<CodeViewError>(386"String table offset outside of bounds of String Table!");387}388W.printString("Program", *ExpectedProgram);389}390printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());391printLocalVariableAddrGap(DefRange.Gaps);392return Error::success();393}394395Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,396FrameCookieSym &FrameCookie) {397StringRef LinkageName;398if (ObjDelegate) {399ObjDelegate->printRelocatedField("CodeOffset",400FrameCookie.getRelocationOffset(),401FrameCookie.CodeOffset, &LinkageName);402}403W.printEnum("Register", uint16_t(FrameCookie.Register),404getRegisterNames(CompilationCPUType));405W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),406getFrameCookieKindNames());407W.printHex("Flags", FrameCookie.Flags);408return Error::success();409}410411Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,412FrameProcSym &FrameProc) {413W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);414W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);415W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);416W.printHex("BytesOfCalleeSavedRegisters",417FrameProc.BytesOfCalleeSavedRegisters);418W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);419W.printHex("SectionIdOfExceptionHandler",420FrameProc.SectionIdOfExceptionHandler);421W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),422getFrameProcSymFlagNames());423W.printEnum("LocalFramePtrReg",424uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)),425getRegisterNames(CompilationCPUType));426W.printEnum("ParamFramePtrReg",427uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)),428getRegisterNames(CompilationCPUType));429return Error::success();430}431432Error CVSymbolDumperImpl::visitKnownRecord(433CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {434StringRef LinkageName;435if (ObjDelegate) {436ObjDelegate->printRelocatedField("CodeOffset",437HeapAllocSite.getRelocationOffset(),438HeapAllocSite.CodeOffset, &LinkageName);439}440W.printHex("Segment", HeapAllocSite.Segment);441W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);442printTypeIndex("Type", HeapAllocSite.Type);443if (!LinkageName.empty())444W.printString("LinkageName", LinkageName);445return Error::success();446}447448Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,449InlineSiteSym &InlineSite) {450W.printHex("PtrParent", InlineSite.Parent);451W.printHex("PtrEnd", InlineSite.End);452printTypeIndex("Inlinee", InlineSite.Inlinee);453454ListScope BinaryAnnotations(W, "BinaryAnnotations");455for (auto &Annotation : InlineSite.annotations()) {456switch (Annotation.OpCode) {457case BinaryAnnotationsOpCode::Invalid:458W.printString("(Annotation Padding)");459break;460case BinaryAnnotationsOpCode::CodeOffset:461case BinaryAnnotationsOpCode::ChangeCodeOffset:462case BinaryAnnotationsOpCode::ChangeCodeLength:463W.printHex(Annotation.Name, Annotation.U1);464break;465case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:466case BinaryAnnotationsOpCode::ChangeLineEndDelta:467case BinaryAnnotationsOpCode::ChangeRangeKind:468case BinaryAnnotationsOpCode::ChangeColumnStart:469case BinaryAnnotationsOpCode::ChangeColumnEnd:470W.printNumber(Annotation.Name, Annotation.U1);471break;472case BinaryAnnotationsOpCode::ChangeLineOffset:473case BinaryAnnotationsOpCode::ChangeColumnEndDelta:474W.printNumber(Annotation.Name, Annotation.S1);475break;476case BinaryAnnotationsOpCode::ChangeFile:477if (ObjDelegate) {478W.printHex("ChangeFile",479ObjDelegate->getFileNameForFileOffset(Annotation.U1),480Annotation.U1);481} else {482W.printHex("ChangeFile", Annotation.U1);483}484485break;486case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {487W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "488<< W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1489<< "}\n";490break;491}492case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {493W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "494<< W.hex(Annotation.U2)495<< ", Length: " << W.hex(Annotation.U1) << "}\n";496break;497}498}499}500return Error::success();501}502503Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,504RegisterSym &Register) {505printTypeIndex("Type", Register.Index);506W.printEnum("Seg", uint16_t(Register.Register),507getRegisterNames(CompilationCPUType));508W.printString("Name", Register.Name);509return Error::success();510}511512Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {513W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());514W.printNumber("Seg", Public.Segment);515W.printNumber("Off", Public.Offset);516W.printString("Name", Public.Name);517return Error::success();518}519520Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {521W.printNumber("SumName", ProcRef.SumName);522W.printNumber("SymOffset", ProcRef.SymOffset);523W.printNumber("Mod", ProcRef.Module);524W.printString("Name", ProcRef.Name);525return Error::success();526}527528Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {529StringRef LinkageName;530if (ObjDelegate) {531ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),532Label.CodeOffset, &LinkageName);533}534W.printHex("Segment", Label.Segment);535W.printHex("Flags", uint8_t(Label.Flags));536W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());537W.printString("DisplayName", Label.Name);538if (!LinkageName.empty())539W.printString("LinkageName", LinkageName);540return Error::success();541}542543Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {544printTypeIndex("Type", Local.Type);545W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());546W.printString("VarName", Local.Name);547return Error::success();548}549550Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {551W.printHex("Signature", ObjName.Signature);552W.printString("ObjectName", ObjName.Name);553return Error::success();554}555556Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {557if (InFunctionScope)558return llvm::make_error<CodeViewError>(559"Visiting a ProcSym while inside function scope!");560561InFunctionScope = true;562563StringRef LinkageName;564W.printHex("PtrParent", Proc.Parent);565W.printHex("PtrEnd", Proc.End);566W.printHex("PtrNext", Proc.Next);567W.printHex("CodeSize", Proc.CodeSize);568W.printHex("DbgStart", Proc.DbgStart);569W.printHex("DbgEnd", Proc.DbgEnd);570printTypeIndex("FunctionType", Proc.FunctionType);571if (ObjDelegate) {572ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),573Proc.CodeOffset, &LinkageName);574}575W.printHex("Segment", Proc.Segment);576W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),577getProcSymFlagNames());578W.printString("DisplayName", Proc.Name);579if (!LinkageName.empty())580W.printString("LinkageName", LinkageName);581return Error::success();582}583584Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,585ScopeEndSym &ScopeEnd) {586InFunctionScope = false;587return Error::success();588}589590Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {591llvm::StringRef ScopeName;592switch (CVR.kind()) {593case S_CALLEES:594ScopeName = "Callees";595break;596case S_CALLERS:597ScopeName = "Callers";598break;599case S_INLINEES:600ScopeName = "Inlinees";601break;602default:603return llvm::make_error<CodeViewError>(604"Unknown CV Record type for a CallerSym object!");605}606ListScope S(W, ScopeName);607for (auto FuncID : Caller.Indices)608printTypeIndex("FuncID", FuncID);609return Error::success();610}611612Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,613RegRelativeSym &RegRel) {614W.printHex("Offset", RegRel.Offset);615printTypeIndex("Type", RegRel.Type);616W.printEnum("Register", uint16_t(RegRel.Register),617getRegisterNames(CompilationCPUType));618W.printString("VarName", RegRel.Name);619return Error::success();620}621622Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,623ThreadLocalDataSym &Data) {624StringRef LinkageName;625if (ObjDelegate) {626ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),627Data.DataOffset, &LinkageName);628}629printTypeIndex("Type", Data.Type);630W.printString("DisplayName", Data.Name);631if (!LinkageName.empty())632W.printString("LinkageName", LinkageName);633return Error::success();634}635636Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {637printTypeIndex("Type", UDT.Type);638W.printString("UDTName", UDT.Name);639return Error::success();640}641642Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,643UsingNamespaceSym &UN) {644W.printString("Namespace", UN.Name);645return Error::success();646}647648Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,649AnnotationSym &Annot) {650W.printHex("Offset", Annot.CodeOffset);651W.printHex("Segment", Annot.Segment);652653ListScope S(W, "Strings");654for (StringRef Str : Annot.Strings)655W.printString(Str);656657return Error::success();658}659660Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,661JumpTableSym &JumpTable) {662W.printHex("BaseOffset", JumpTable.BaseOffset);663W.printNumber("BaseSegment", JumpTable.BaseSegment);664W.printEnum("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),665getJumpTableEntrySizeNames());666W.printHex("BranchOffset", JumpTable.BranchOffset);667W.printHex("TableOffset", JumpTable.TableOffset);668W.printNumber("BranchSegment", JumpTable.BranchSegment);669W.printNumber("TableSegment", JumpTable.TableSegment);670W.printNumber("EntriesCount", JumpTable.EntriesCount);671return Error::success();672}673674Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {675W.printNumber("Length", CVR.length());676return Error::success();677}678679Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {680SymbolVisitorCallbackPipeline Pipeline;681SymbolDeserializer Deserializer(ObjDelegate.get(), Container);682CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,683PrintRecordBytes);684685Pipeline.addCallbackToPipeline(Deserializer);686Pipeline.addCallbackToPipeline(Dumper);687CVSymbolVisitor Visitor(Pipeline);688auto Err = Visitor.visitSymbolRecord(Record);689CompilationCPUType = Dumper.getCompilationCPUType();690return Err;691}692693Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {694SymbolVisitorCallbackPipeline Pipeline;695SymbolDeserializer Deserializer(ObjDelegate.get(), Container);696CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,697PrintRecordBytes);698699Pipeline.addCallbackToPipeline(Deserializer);700Pipeline.addCallbackToPipeline(Dumper);701CVSymbolVisitor Visitor(Pipeline);702auto Err = Visitor.visitSymbolStream(Symbols);703CompilationCPUType = Dumper.getCompilationCPUType();704return Err;705}706707708