1aaad5744SZachary Turner //===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===// 2aaad5744SZachary Turner // 3aaad5744SZachary Turner // The LLVM Compiler Infrastructure 4aaad5744SZachary Turner // 5aaad5744SZachary Turner // This file is distributed under the University of Illinois Open Source 6aaad5744SZachary Turner // License. See LICENSE.TXT for details. 7aaad5744SZachary Turner // 8aaad5744SZachary Turner //===----------------------------------------------------------------------===// 9aaad5744SZachary Turner 10aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumper.h" 11aaad5744SZachary Turner #include "llvm/ADT/DenseMap.h" 12aaad5744SZachary Turner #include "llvm/ADT/SmallString.h" 13aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" 14*a9054dddSZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeDumper.h" 1593839cb4SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h" 160d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 17aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" 18aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 190d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" 200d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" 21aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/TypeIndex.h" 220d840744SZachary Turner #include "llvm/Support/Error.h" 23aaad5744SZachary Turner #include "llvm/Support/ScopedPrinter.h" 24aaad5744SZachary Turner 25aaad5744SZachary Turner #include <system_error> 26aaad5744SZachary Turner 27aaad5744SZachary Turner using namespace llvm; 28aaad5744SZachary Turner using namespace llvm::codeview; 29aaad5744SZachary Turner 30aaad5744SZachary Turner namespace { 31aaad5744SZachary Turner /// Use this private dumper implementation to keep implementation details about 32aaad5744SZachary Turner /// the visitor out of SymbolDumper.h. 330d840744SZachary Turner class CVSymbolDumperImpl : public SymbolVisitorCallbacks { 34aaad5744SZachary Turner public: 353e78e2d4SZachary Turner CVSymbolDumperImpl(CVTypeDumper &CVTD, SymbolDumpDelegate *ObjDelegate, 363e78e2d4SZachary Turner ScopedPrinter &W, bool PrintRecordBytes) 370d840744SZachary Turner : CVTD(CVTD), ObjDelegate(ObjDelegate), W(W), 380d840744SZachary Turner PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {} 39aaad5744SZachary Turner 40aaad5744SZachary Turner /// CVSymbolVisitor overrides. 41aaad5744SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 420d840744SZachary Turner Error visitKnownRecord(CVSymbol &CVR, Name &Record) override; 43aaad5744SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 44aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" 45aaad5744SZachary Turner 460d840744SZachary Turner Error visitSymbolBegin(CVSymbol &Record) override; 470d840744SZachary Turner Error visitSymbolEnd(CVSymbol &Record) override; 480d840744SZachary Turner Error visitUnknownSymbol(CVSymbol &Record) override; 49aaad5744SZachary Turner 50aaad5744SZachary Turner private: 51aaad5744SZachary Turner void printLocalVariableAddrRange(const LocalVariableAddrRange &Range, 52aaad5744SZachary Turner uint32_t RelocationOffset); 53aaad5744SZachary Turner void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps); 54aaad5744SZachary Turner 55aaad5744SZachary Turner CVTypeDumper &CVTD; 56aaad5744SZachary Turner SymbolDumpDelegate *ObjDelegate; 57aaad5744SZachary Turner ScopedPrinter &W; 58aaad5744SZachary Turner 59aaad5744SZachary Turner bool PrintRecordBytes; 60aaad5744SZachary Turner bool InFunctionScope; 61aaad5744SZachary Turner }; 62aaad5744SZachary Turner } 63aaad5744SZachary Turner 64aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrRange( 65aaad5744SZachary Turner const LocalVariableAddrRange &Range, uint32_t RelocationOffset) { 66aaad5744SZachary Turner DictScope S(W, "LocalVariableAddrRange"); 67aaad5744SZachary Turner if (ObjDelegate) 68aaad5744SZachary Turner ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset, 69aaad5744SZachary Turner Range.OffsetStart); 70aaad5744SZachary Turner W.printHex("ISectStart", Range.ISectStart); 71aaad5744SZachary Turner W.printHex("Range", Range.Range); 72aaad5744SZachary Turner } 73aaad5744SZachary Turner 74aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrGap( 75aaad5744SZachary Turner ArrayRef<LocalVariableAddrGap> Gaps) { 76aaad5744SZachary Turner for (auto &Gap : Gaps) { 77aaad5744SZachary Turner ListScope S(W, "LocalVariableAddrGap"); 78aaad5744SZachary Turner W.printHex("GapStartOffset", Gap.GapStartOffset); 79aaad5744SZachary Turner W.printHex("Range", Gap.Range); 80aaad5744SZachary Turner } 81aaad5744SZachary Turner } 82aaad5744SZachary Turner 830d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) { 840d840744SZachary Turner return Error::success(); 85aaad5744SZachary Turner } 86aaad5744SZachary Turner 870d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) { 880d840744SZachary Turner if (PrintRecordBytes && ObjDelegate) 890d840744SZachary Turner ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content()); 900d840744SZachary Turner return Error::success(); 910d840744SZachary Turner } 920d840744SZachary Turner 930d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 94aaad5744SZachary Turner DictScope S(W, "BlockStart"); 95aaad5744SZachary Turner 96aaad5744SZachary Turner StringRef LinkageName; 9746225b19SZachary Turner W.printHex("PtrParent", Block.Parent); 9846225b19SZachary Turner W.printHex("PtrEnd", Block.End); 9946225b19SZachary Turner W.printHex("CodeSize", Block.CodeSize); 100aaad5744SZachary Turner if (ObjDelegate) { 101aaad5744SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(), 10246225b19SZachary Turner Block.CodeOffset, &LinkageName); 103aaad5744SZachary Turner } 10446225b19SZachary Turner W.printHex("Segment", Block.Segment); 105aaad5744SZachary Turner W.printString("BlockName", Block.Name); 106aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 1070d840744SZachary Turner return Error::success(); 108aaad5744SZachary Turner } 109aaad5744SZachary Turner 1100d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 1114caa1bf0SZachary Turner DictScope S(W, "Thunk32"); 11246225b19SZachary Turner W.printNumber("Parent", Thunk.Parent); 11346225b19SZachary Turner W.printNumber("End", Thunk.End); 11446225b19SZachary Turner W.printNumber("Next", Thunk.Next); 11546225b19SZachary Turner W.printNumber("Off", Thunk.Offset); 11646225b19SZachary Turner W.printNumber("Seg", Thunk.Segment); 11746225b19SZachary Turner W.printNumber("Len", Thunk.Length); 11846225b19SZachary Turner W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames()); 1190d840744SZachary Turner return Error::success(); 1204caa1bf0SZachary Turner } 1214caa1bf0SZachary Turner 1220d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 1234caa1bf0SZachary Turner TrampolineSym &Tramp) { 1244caa1bf0SZachary Turner DictScope S(W, "Trampoline"); 12546225b19SZachary Turner W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames()); 12646225b19SZachary Turner W.printNumber("Size", Tramp.Size); 12746225b19SZachary Turner W.printNumber("ThunkOff", Tramp.ThunkOffset); 12846225b19SZachary Turner W.printNumber("TargetOff", Tramp.TargetOffset); 12946225b19SZachary Turner W.printNumber("ThunkSection", Tramp.ThunkSection); 13046225b19SZachary Turner W.printNumber("TargetSection", Tramp.TargetSection); 1310d840744SZachary Turner return Error::success(); 1324caa1bf0SZachary Turner } 1334caa1bf0SZachary Turner 1340d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) { 1354caa1bf0SZachary Turner DictScope S(W, "Section"); 13646225b19SZachary Turner W.printNumber("SectionNumber", Section.SectionNumber); 13746225b19SZachary Turner W.printNumber("Alignment", Section.Alignment); 13846225b19SZachary Turner W.printNumber("Rva", Section.Rva); 13946225b19SZachary Turner W.printNumber("Length", Section.Length); 14046225b19SZachary Turner W.printFlags("Characteristics", Section.Characteristics, 14193839cb4SZachary Turner getImageSectionCharacteristicNames(), 14293839cb4SZachary Turner COFF::SectionCharacteristics(0x00F00000)); 14393839cb4SZachary Turner 1444caa1bf0SZachary Turner W.printString("Name", Section.Name); 1450d840744SZachary Turner return Error::success(); 1464caa1bf0SZachary Turner } 1474caa1bf0SZachary Turner 1480d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 1494caa1bf0SZachary Turner CoffGroupSym &CoffGroup) { 1504caa1bf0SZachary Turner DictScope S(W, "COFF Group"); 15146225b19SZachary Turner W.printNumber("Size", CoffGroup.Size); 15246225b19SZachary Turner W.printFlags("Characteristics", CoffGroup.Characteristics, 15393839cb4SZachary Turner getImageSectionCharacteristicNames(), 15493839cb4SZachary Turner COFF::SectionCharacteristics(0x00F00000)); 15546225b19SZachary Turner W.printNumber("Offset", CoffGroup.Offset); 15646225b19SZachary Turner W.printNumber("Segment", CoffGroup.Segment); 1574caa1bf0SZachary Turner W.printString("Name", CoffGroup.Name); 1580d840744SZachary Turner return Error::success(); 1594caa1bf0SZachary Turner } 1604caa1bf0SZachary Turner 1610d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 162aaad5744SZachary Turner BPRelativeSym &BPRel) { 163aaad5744SZachary Turner DictScope S(W, "BPRelativeSym"); 164aaad5744SZachary Turner 16546225b19SZachary Turner W.printNumber("Offset", BPRel.Offset); 16646225b19SZachary Turner CVTD.printTypeIndex("Type", BPRel.Type); 167aaad5744SZachary Turner W.printString("VarName", BPRel.Name); 1680d840744SZachary Turner return Error::success(); 169aaad5744SZachary Turner } 170aaad5744SZachary Turner 1710d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 172aaad5744SZachary Turner BuildInfoSym &BuildInfo) { 173aaad5744SZachary Turner DictScope S(W, "BuildInfo"); 174aaad5744SZachary Turner 17546225b19SZachary Turner W.printNumber("BuildId", BuildInfo.BuildId); 1760d840744SZachary Turner return Error::success(); 177aaad5744SZachary Turner } 178aaad5744SZachary Turner 1790d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 180aaad5744SZachary Turner CallSiteInfoSym &CallSiteInfo) { 181aaad5744SZachary Turner DictScope S(W, "CallSiteInfo"); 182aaad5744SZachary Turner 183aaad5744SZachary Turner StringRef LinkageName; 184aaad5744SZachary Turner if (ObjDelegate) { 18546225b19SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", 18646225b19SZachary Turner CallSiteInfo.getRelocationOffset(), 18746225b19SZachary Turner CallSiteInfo.CodeOffset, &LinkageName); 188aaad5744SZachary Turner } 18946225b19SZachary Turner W.printHex("Segment", CallSiteInfo.Segment); 19046225b19SZachary Turner CVTD.printTypeIndex("Type", CallSiteInfo.Type); 191aaad5744SZachary Turner if (!LinkageName.empty()) 192aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 1930d840744SZachary Turner return Error::success(); 194aaad5744SZachary Turner } 195aaad5744SZachary Turner 1960d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 1974caa1bf0SZachary Turner EnvBlockSym &EnvBlock) { 1984caa1bf0SZachary Turner DictScope S(W, "EnvBlock"); 1994caa1bf0SZachary Turner 2004caa1bf0SZachary Turner ListScope L(W, "Entries"); 2014caa1bf0SZachary Turner for (auto Entry : EnvBlock.Fields) { 2024caa1bf0SZachary Turner W.printString(Entry); 2034caa1bf0SZachary Turner } 2040d840744SZachary Turner return Error::success(); 2054caa1bf0SZachary Turner } 2064caa1bf0SZachary Turner 2070d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 2084caa1bf0SZachary Turner FileStaticSym &FileStatic) { 2094caa1bf0SZachary Turner DictScope S(W, "FileStatic"); 21046225b19SZachary Turner W.printNumber("Index", FileStatic.Index); 21146225b19SZachary Turner W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset); 21246225b19SZachary Turner W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames()); 2134caa1bf0SZachary Turner W.printString("Name", FileStatic.Name); 2140d840744SZachary Turner return Error::success(); 2154caa1bf0SZachary Turner } 2164caa1bf0SZachary Turner 2170d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) { 2189f054d42SZachary Turner DictScope S(W, "Export"); 21946225b19SZachary Turner W.printNumber("Ordinal", Export.Ordinal); 22046225b19SZachary Turner W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames()); 2219f054d42SZachary Turner W.printString("Name", Export.Name); 2220d840744SZachary Turner return Error::success(); 2239f054d42SZachary Turner } 2249f054d42SZachary Turner 2250d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 2264caa1bf0SZachary Turner Compile2Sym &Compile2) { 2274caa1bf0SZachary Turner DictScope S(W, "CompilerFlags2"); 2284caa1bf0SZachary Turner 22946225b19SZachary Turner W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames()); 23046225b19SZachary Turner W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames()); 23146225b19SZachary Turner W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames()); 2324caa1bf0SZachary Turner std::string FrontendVersion; 2334caa1bf0SZachary Turner { 2344caa1bf0SZachary Turner raw_string_ostream Out(FrontendVersion); 23546225b19SZachary Turner Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor 23646225b19SZachary Turner << '.' << Compile2.VersionFrontendBuild; 2374caa1bf0SZachary Turner } 2384caa1bf0SZachary Turner std::string BackendVersion; 2394caa1bf0SZachary Turner { 2404caa1bf0SZachary Turner raw_string_ostream Out(BackendVersion); 24146225b19SZachary Turner Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor 24246225b19SZachary Turner << '.' << Compile2.VersionBackendBuild; 2434caa1bf0SZachary Turner } 2444caa1bf0SZachary Turner W.printString("FrontendVersion", FrontendVersion); 2454caa1bf0SZachary Turner W.printString("BackendVersion", BackendVersion); 2464caa1bf0SZachary Turner W.printString("VersionName", Compile2.Version); 2470d840744SZachary Turner return Error::success(); 2484caa1bf0SZachary Turner } 2494caa1bf0SZachary Turner 2500d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 251aaad5744SZachary Turner Compile3Sym &Compile3) { 2524caa1bf0SZachary Turner DictScope S(W, "CompilerFlags3"); 253aaad5744SZachary Turner 25446225b19SZachary Turner W.printEnum("Language", Compile3.getLanguage(), getSourceLanguageNames()); 25546225b19SZachary Turner W.printFlags("Flags", Compile3.getFlags(), getCompileSym3FlagNames()); 25646225b19SZachary Turner W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames()); 257aaad5744SZachary Turner std::string FrontendVersion; 258aaad5744SZachary Turner { 259aaad5744SZachary Turner raw_string_ostream Out(FrontendVersion); 26046225b19SZachary Turner Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor 26146225b19SZachary Turner << '.' << Compile3.VersionFrontendBuild << '.' 26246225b19SZachary Turner << Compile3.VersionFrontendQFE; 263aaad5744SZachary Turner } 264aaad5744SZachary Turner std::string BackendVersion; 265aaad5744SZachary Turner { 266aaad5744SZachary Turner raw_string_ostream Out(BackendVersion); 26746225b19SZachary Turner Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor 26846225b19SZachary Turner << '.' << Compile3.VersionBackendBuild << '.' 26946225b19SZachary Turner << Compile3.VersionBackendQFE; 270aaad5744SZachary Turner } 271aaad5744SZachary Turner W.printString("FrontendVersion", FrontendVersion); 272aaad5744SZachary Turner W.printString("BackendVersion", BackendVersion); 273aaad5744SZachary Turner W.printString("VersionName", Compile3.Version); 2740d840744SZachary Turner return Error::success(); 275aaad5744SZachary Turner } 276aaad5744SZachary Turner 2770d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 278aaad5744SZachary Turner ConstantSym &Constant) { 279aaad5744SZachary Turner DictScope S(W, "Constant"); 280aaad5744SZachary Turner 28146225b19SZachary Turner CVTD.printTypeIndex("Type", Constant.Type); 282aaad5744SZachary Turner W.printNumber("Value", Constant.Value); 283aaad5744SZachary Turner W.printString("Name", Constant.Name); 2840d840744SZachary Turner return Error::success(); 285aaad5744SZachary Turner } 286aaad5744SZachary Turner 2870d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { 288aaad5744SZachary Turner DictScope S(W, "DataSym"); 289aaad5744SZachary Turner 2900d840744SZachary Turner W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames()); 291aaad5744SZachary Turner StringRef LinkageName; 292aaad5744SZachary Turner if (ObjDelegate) { 293aaad5744SZachary Turner ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 29446225b19SZachary Turner Data.DataOffset, &LinkageName); 295aaad5744SZachary Turner } 29646225b19SZachary Turner CVTD.printTypeIndex("Type", Data.Type); 297aaad5744SZachary Turner W.printString("DisplayName", Data.Name); 298aaad5744SZachary Turner if (!LinkageName.empty()) 299aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 3000d840744SZachary Turner return Error::success(); 301aaad5744SZachary Turner } 302aaad5744SZachary Turner 3030d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3040d840744SZachary Turner CVSymbol &CVR, 305aaad5744SZachary Turner DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) { 306aaad5744SZachary Turner DictScope S(W, "DefRangeFramePointerRelFullScope"); 30746225b19SZachary Turner W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset); 3080d840744SZachary Turner return Error::success(); 309aaad5744SZachary Turner } 310aaad5744SZachary Turner 3110d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3120d840744SZachary Turner CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { 313aaad5744SZachary Turner DictScope S(W, "DefRangeFramePointerRel"); 314aaad5744SZachary Turner 31546225b19SZachary Turner W.printNumber("Offset", DefRangeFramePointerRel.Offset); 31646225b19SZachary Turner printLocalVariableAddrRange(DefRangeFramePointerRel.Range, 317aaad5744SZachary Turner DefRangeFramePointerRel.getRelocationOffset()); 318aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps); 3190d840744SZachary Turner return Error::success(); 320aaad5744SZachary Turner } 321aaad5744SZachary Turner 3220d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3230d840744SZachary Turner CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) { 324aaad5744SZachary Turner DictScope S(W, "DefRangeRegisterRel"); 325aaad5744SZachary Turner 32646225b19SZachary Turner W.printNumber("BaseRegister", DefRangeRegisterRel.Hdr.Register); 327aaad5744SZachary Turner W.printBoolean("HasSpilledUDTMember", 328aaad5744SZachary Turner DefRangeRegisterRel.hasSpilledUDTMember()); 329aaad5744SZachary Turner W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent()); 33046225b19SZachary Turner W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset); 33146225b19SZachary Turner printLocalVariableAddrRange(DefRangeRegisterRel.Range, 332aaad5744SZachary Turner DefRangeRegisterRel.getRelocationOffset()); 333aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeRegisterRel.Gaps); 3340d840744SZachary Turner return Error::success(); 335aaad5744SZachary Turner } 336aaad5744SZachary Turner 3370d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3380d840744SZachary Turner CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { 339aaad5744SZachary Turner DictScope S(W, "DefRangeRegister"); 340aaad5744SZachary Turner 34146225b19SZachary Turner W.printNumber("Register", DefRangeRegister.Hdr.Register); 34246225b19SZachary Turner W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName); 34346225b19SZachary Turner printLocalVariableAddrRange(DefRangeRegister.Range, 344aaad5744SZachary Turner DefRangeRegister.getRelocationOffset()); 345aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeRegister.Gaps); 3460d840744SZachary Turner return Error::success(); 347aaad5744SZachary Turner } 348aaad5744SZachary Turner 3490d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3500d840744SZachary Turner CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { 351aaad5744SZachary Turner DictScope S(W, "DefRangeSubfieldRegister"); 352aaad5744SZachary Turner 35346225b19SZachary Turner W.printNumber("Register", DefRangeSubfieldRegister.Hdr.Register); 35446225b19SZachary Turner W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName); 35546225b19SZachary Turner W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent); 35646225b19SZachary Turner printLocalVariableAddrRange(DefRangeSubfieldRegister.Range, 357aaad5744SZachary Turner DefRangeSubfieldRegister.getRelocationOffset()); 358aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps); 3590d840744SZachary Turner return Error::success(); 360aaad5744SZachary Turner } 361aaad5744SZachary Turner 3620d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3630d840744SZachary Turner CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) { 364aaad5744SZachary Turner DictScope S(W, "DefRangeSubfield"); 365aaad5744SZachary Turner 366aaad5744SZachary Turner if (ObjDelegate) { 367aaad5744SZachary Turner StringRef StringTable = ObjDelegate->getStringTable(); 36846225b19SZachary Turner auto ProgramStringTableOffset = DefRangeSubfield.Program; 369c6cb2ec3SDavid Majnemer if (ProgramStringTableOffset >= StringTable.size()) 3700d840744SZachary Turner return llvm::make_error<CodeViewError>( 3710d840744SZachary Turner "String table offset outside of bounds of String Table!"); 372c6cb2ec3SDavid Majnemer StringRef Program = 373c6cb2ec3SDavid Majnemer StringTable.drop_front(ProgramStringTableOffset).split('\0').first; 374c6cb2ec3SDavid Majnemer W.printString("Program", Program); 375aaad5744SZachary Turner } 37646225b19SZachary Turner W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent); 37746225b19SZachary Turner printLocalVariableAddrRange(DefRangeSubfield.Range, 378aaad5744SZachary Turner DefRangeSubfield.getRelocationOffset()); 379aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeSubfield.Gaps); 3800d840744SZachary Turner return Error::success(); 381aaad5744SZachary Turner } 382aaad5744SZachary Turner 3830d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 384aaad5744SZachary Turner DefRangeSym &DefRange) { 385aaad5744SZachary Turner DictScope S(W, "DefRange"); 386aaad5744SZachary Turner 387aaad5744SZachary Turner if (ObjDelegate) { 388aaad5744SZachary Turner StringRef StringTable = ObjDelegate->getStringTable(); 38946225b19SZachary Turner auto ProgramStringTableOffset = DefRange.Program; 390b343310bSDavid Majnemer if (ProgramStringTableOffset >= StringTable.size()) 3910d840744SZachary Turner return llvm::make_error<CodeViewError>( 3920d840744SZachary Turner "String table offset outside of bounds of String Table!"); 393b343310bSDavid Majnemer StringRef Program = 394b343310bSDavid Majnemer StringTable.drop_front(ProgramStringTableOffset).split('\0').first; 395b343310bSDavid Majnemer W.printString("Program", Program); 396aaad5744SZachary Turner } 39746225b19SZachary Turner printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset()); 398aaad5744SZachary Turner printLocalVariableAddrGap(DefRange.Gaps); 3990d840744SZachary Turner return Error::success(); 400aaad5744SZachary Turner } 401aaad5744SZachary Turner 4020d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 403aaad5744SZachary Turner FrameCookieSym &FrameCookie) { 404aaad5744SZachary Turner DictScope S(W, "FrameCookie"); 405aaad5744SZachary Turner 406aaad5744SZachary Turner StringRef LinkageName; 407aaad5744SZachary Turner if (ObjDelegate) { 40846225b19SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", 40946225b19SZachary Turner FrameCookie.getRelocationOffset(), 41046225b19SZachary Turner FrameCookie.CodeOffset, &LinkageName); 411aaad5744SZachary Turner } 41246225b19SZachary Turner W.printHex("Register", FrameCookie.Register); 41346225b19SZachary Turner W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind), 41493839cb4SZachary Turner getFrameCookieKindNames()); 41546225b19SZachary Turner W.printHex("Flags", FrameCookie.Flags); 4160d840744SZachary Turner return Error::success(); 417aaad5744SZachary Turner } 418aaad5744SZachary Turner 4190d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 420aaad5744SZachary Turner FrameProcSym &FrameProc) { 421aaad5744SZachary Turner DictScope S(W, "FrameProc"); 422aaad5744SZachary Turner 42346225b19SZachary Turner W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes); 42446225b19SZachary Turner W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes); 42546225b19SZachary Turner W.printHex("OffsetToPadding", FrameProc.OffsetToPadding); 426aaad5744SZachary Turner W.printHex("BytesOfCalleeSavedRegisters", 42746225b19SZachary Turner FrameProc.BytesOfCalleeSavedRegisters); 42846225b19SZachary Turner W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler); 429aaad5744SZachary Turner W.printHex("SectionIdOfExceptionHandler", 43046225b19SZachary Turner FrameProc.SectionIdOfExceptionHandler); 43146225b19SZachary Turner W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags), 43246225b19SZachary Turner getFrameProcSymFlagNames()); 4330d840744SZachary Turner return Error::success(); 434aaad5744SZachary Turner } 435aaad5744SZachary Turner 4360d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 4370d840744SZachary Turner CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) { 438aaad5744SZachary Turner DictScope S(W, "HeapAllocationSite"); 439aaad5744SZachary Turner 440aaad5744SZachary Turner StringRef LinkageName; 441aaad5744SZachary Turner if (ObjDelegate) { 44246225b19SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", 44346225b19SZachary Turner HeapAllocSite.getRelocationOffset(), 44446225b19SZachary Turner HeapAllocSite.CodeOffset, &LinkageName); 445aaad5744SZachary Turner } 44646225b19SZachary Turner W.printHex("Segment", HeapAllocSite.Segment); 44746225b19SZachary Turner W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize); 44846225b19SZachary Turner CVTD.printTypeIndex("Type", HeapAllocSite.Type); 449aaad5744SZachary Turner if (!LinkageName.empty()) 450aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 4510d840744SZachary Turner return Error::success(); 452aaad5744SZachary Turner } 453aaad5744SZachary Turner 4540d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 455aaad5744SZachary Turner InlineSiteSym &InlineSite) { 456aaad5744SZachary Turner DictScope S(W, "InlineSite"); 457aaad5744SZachary Turner 45846225b19SZachary Turner W.printHex("PtrParent", InlineSite.Parent); 45946225b19SZachary Turner W.printHex("PtrEnd", InlineSite.End); 46046225b19SZachary Turner CVTD.printTypeIndex("Inlinee", InlineSite.Inlinee); 461aaad5744SZachary Turner 462aaad5744SZachary Turner ListScope BinaryAnnotations(W, "BinaryAnnotations"); 463aaad5744SZachary Turner for (auto &Annotation : InlineSite.annotations()) { 464aaad5744SZachary Turner switch (Annotation.OpCode) { 465aaad5744SZachary Turner case BinaryAnnotationsOpCode::Invalid: 4660d840744SZachary Turner return llvm::make_error<CodeViewError>( 4670d840744SZachary Turner "Invalid binary annotation opcode!"); 468aaad5744SZachary Turner case BinaryAnnotationsOpCode::CodeOffset: 469aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeOffset: 470aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeLength: 471aaad5744SZachary Turner W.printHex(Annotation.Name, Annotation.U1); 472aaad5744SZachary Turner break; 473aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 474aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeLineEndDelta: 475aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeRangeKind: 476aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeColumnStart: 477aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeColumnEnd: 478aaad5744SZachary Turner W.printNumber(Annotation.Name, Annotation.U1); 479aaad5744SZachary Turner break; 480aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeLineOffset: 481aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 482aaad5744SZachary Turner W.printNumber(Annotation.Name, Annotation.S1); 483aaad5744SZachary Turner break; 484aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeFile: 485aaad5744SZachary Turner if (ObjDelegate) { 486aaad5744SZachary Turner W.printHex("ChangeFile", 487aaad5744SZachary Turner ObjDelegate->getFileNameForFileOffset(Annotation.U1), 488aaad5744SZachary Turner Annotation.U1); 489aaad5744SZachary Turner } else { 490aaad5744SZachary Turner W.printHex("ChangeFile", Annotation.U1); 491aaad5744SZachary Turner } 492aaad5744SZachary Turner 493aaad5744SZachary Turner break; 494aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: { 495aaad5744SZachary Turner W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: " 496aaad5744SZachary Turner << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1 497aaad5744SZachary Turner << "}\n"; 498aaad5744SZachary Turner break; 499aaad5744SZachary Turner } 500aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: { 501aaad5744SZachary Turner W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: " 502aaad5744SZachary Turner << W.hex(Annotation.U2) 503aaad5744SZachary Turner << ", Length: " << W.hex(Annotation.U1) << "}\n"; 504aaad5744SZachary Turner break; 505aaad5744SZachary Turner } 506aaad5744SZachary Turner } 507aaad5744SZachary Turner } 5080d840744SZachary Turner return Error::success(); 509aaad5744SZachary Turner } 510aaad5744SZachary Turner 5110d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 5124caa1bf0SZachary Turner RegisterSym &Register) { 5134caa1bf0SZachary Turner DictScope S(W, "RegisterSym"); 51446225b19SZachary Turner W.printNumber("Type", Register.Index); 51546225b19SZachary Turner W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); 5164caa1bf0SZachary Turner W.printString("Name", Register.Name); 5170d840744SZachary Turner return Error::success(); 5184caa1bf0SZachary Turner } 5194caa1bf0SZachary Turner 5200d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) { 5219e33e6f8SZachary Turner DictScope S(W, "PublicSym"); 52246225b19SZachary Turner W.printNumber("Type", Public.Index); 52346225b19SZachary Turner W.printNumber("Seg", Public.Segment); 52446225b19SZachary Turner W.printNumber("Off", Public.Offset); 5259e33e6f8SZachary Turner W.printString("Name", Public.Name); 5260d840744SZachary Turner return Error::success(); 5279e33e6f8SZachary Turner } 5289e33e6f8SZachary Turner 5290d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) { 5309e33e6f8SZachary Turner DictScope S(W, "ProcRef"); 53146225b19SZachary Turner W.printNumber("SumName", ProcRef.SumName); 53246225b19SZachary Turner W.printNumber("SymOffset", ProcRef.SymOffset); 53346225b19SZachary Turner W.printNumber("Mod", ProcRef.Module); 5349e33e6f8SZachary Turner W.printString("Name", ProcRef.Name); 5350d840744SZachary Turner return Error::success(); 5369e33e6f8SZachary Turner } 5379e33e6f8SZachary Turner 5380d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 539aaad5744SZachary Turner DictScope S(W, "Label"); 540aaad5744SZachary Turner 541aaad5744SZachary Turner StringRef LinkageName; 542aaad5744SZachary Turner if (ObjDelegate) { 543aaad5744SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(), 54446225b19SZachary Turner Label.CodeOffset, &LinkageName); 545aaad5744SZachary Turner } 54646225b19SZachary Turner W.printHex("Segment", Label.Segment); 54746225b19SZachary Turner W.printHex("Flags", uint8_t(Label.Flags)); 54846225b19SZachary Turner W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames()); 549aaad5744SZachary Turner W.printString("DisplayName", Label.Name); 550aaad5744SZachary Turner if (!LinkageName.empty()) 551aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 5520d840744SZachary Turner return Error::success(); 553aaad5744SZachary Turner } 554aaad5744SZachary Turner 5550d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 556aaad5744SZachary Turner DictScope S(W, "Local"); 557aaad5744SZachary Turner 55846225b19SZachary Turner CVTD.printTypeIndex("Type", Local.Type); 55946225b19SZachary Turner W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames()); 560aaad5744SZachary Turner W.printString("VarName", Local.Name); 5610d840744SZachary Turner return Error::success(); 562aaad5744SZachary Turner } 563aaad5744SZachary Turner 5640d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) { 565aaad5744SZachary Turner DictScope S(W, "ObjectName"); 566aaad5744SZachary Turner 56746225b19SZachary Turner W.printHex("Signature", ObjName.Signature); 568aaad5744SZachary Turner W.printString("ObjectName", ObjName.Name); 5690d840744SZachary Turner return Error::success(); 570aaad5744SZachary Turner } 571aaad5744SZachary Turner 5720d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 573aaad5744SZachary Turner DictScope S(W, "ProcStart"); 574aaad5744SZachary Turner 575aaad5744SZachary Turner if (InFunctionScope) 5760d840744SZachary Turner return llvm::make_error<CodeViewError>( 5770d840744SZachary Turner "Visiting a ProcSym while inside function scope!"); 578aaad5744SZachary Turner 579aaad5744SZachary Turner InFunctionScope = true; 580aaad5744SZachary Turner 581aaad5744SZachary Turner StringRef LinkageName; 5820d840744SZachary Turner W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames()); 58346225b19SZachary Turner W.printHex("PtrParent", Proc.Parent); 58446225b19SZachary Turner W.printHex("PtrEnd", Proc.End); 58546225b19SZachary Turner W.printHex("PtrNext", Proc.Next); 58646225b19SZachary Turner W.printHex("CodeSize", Proc.CodeSize); 58746225b19SZachary Turner W.printHex("DbgStart", Proc.DbgStart); 58846225b19SZachary Turner W.printHex("DbgEnd", Proc.DbgEnd); 58946225b19SZachary Turner CVTD.printTypeIndex("FunctionType", Proc.FunctionType); 590aaad5744SZachary Turner if (ObjDelegate) { 591aaad5744SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(), 59246225b19SZachary Turner Proc.CodeOffset, &LinkageName); 593aaad5744SZachary Turner } 59446225b19SZachary Turner W.printHex("Segment", Proc.Segment); 59546225b19SZachary Turner W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags), 59693839cb4SZachary Turner getProcSymFlagNames()); 597aaad5744SZachary Turner W.printString("DisplayName", Proc.Name); 598aaad5744SZachary Turner if (!LinkageName.empty()) 599aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 6000d840744SZachary Turner return Error::success(); 601aaad5744SZachary Turner } 602aaad5744SZachary Turner 6030d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 604aaad5744SZachary Turner ScopeEndSym &ScopeEnd) { 6050d840744SZachary Turner if (CVR.kind() == SymbolKind::S_END) 606cac29ae0SZachary Turner DictScope S(W, "BlockEnd"); 6070d840744SZachary Turner else if (CVR.kind() == SymbolKind::S_PROC_ID_END) 608cac29ae0SZachary Turner DictScope S(W, "ProcEnd"); 6090d840744SZachary Turner else if (CVR.kind() == SymbolKind::S_INLINESITE_END) 610aaad5744SZachary Turner DictScope S(W, "InlineSiteEnd"); 611aaad5744SZachary Turner 612aaad5744SZachary Turner InFunctionScope = false; 6130d840744SZachary Turner return Error::success(); 614aaad5744SZachary Turner } 615aaad5744SZachary Turner 6160d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 6170d840744SZachary Turner ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers"); 618aaad5744SZachary Turner for (auto FuncID : Caller.Indices) 619aaad5744SZachary Turner CVTD.printTypeIndex("FuncID", FuncID); 6200d840744SZachary Turner return Error::success(); 621aaad5744SZachary Turner } 622aaad5744SZachary Turner 6230d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 624aaad5744SZachary Turner RegRelativeSym &RegRel) { 625aaad5744SZachary Turner DictScope S(W, "RegRelativeSym"); 626aaad5744SZachary Turner 62746225b19SZachary Turner W.printHex("Offset", RegRel.Offset); 62846225b19SZachary Turner CVTD.printTypeIndex("Type", RegRel.Type); 62946225b19SZachary Turner W.printHex("Register", RegRel.Register); 630aaad5744SZachary Turner W.printString("VarName", RegRel.Name); 6310d840744SZachary Turner return Error::success(); 632aaad5744SZachary Turner } 633aaad5744SZachary Turner 6340d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 635aaad5744SZachary Turner ThreadLocalDataSym &Data) { 636aaad5744SZachary Turner DictScope S(W, "ThreadLocalDataSym"); 637aaad5744SZachary Turner 638aaad5744SZachary Turner StringRef LinkageName; 639aaad5744SZachary Turner if (ObjDelegate) { 640aaad5744SZachary Turner ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 64146225b19SZachary Turner Data.DataOffset, &LinkageName); 642aaad5744SZachary Turner } 64346225b19SZachary Turner CVTD.printTypeIndex("Type", Data.Type); 644aaad5744SZachary Turner W.printString("DisplayName", Data.Name); 645aaad5744SZachary Turner if (!LinkageName.empty()) 646aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 6470d840744SZachary Turner return Error::success(); 648aaad5744SZachary Turner } 649aaad5744SZachary Turner 6500d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 651aaad5744SZachary Turner DictScope S(W, "UDT"); 65246225b19SZachary Turner CVTD.printTypeIndex("Type", UDT.Type); 653aaad5744SZachary Turner W.printString("UDTName", UDT.Name); 6540d840744SZachary Turner return Error::success(); 655aaad5744SZachary Turner } 656aaad5744SZachary Turner 6570d840744SZachary Turner Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) { 658aaad5744SZachary Turner DictScope S(W, "UnknownSym"); 6590d840744SZachary Turner W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames()); 6600d840744SZachary Turner W.printNumber("Length", CVR.length()); 6610d840744SZachary Turner return Error::success(); 662aaad5744SZachary Turner } 663aaad5744SZachary Turner 6640d840744SZachary Turner Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) { 6650d840744SZachary Turner SymbolVisitorCallbackPipeline Pipeline; 6660d840744SZachary Turner SymbolDeserializer Deserializer(ObjDelegate.get()); 6673e78e2d4SZachary Turner CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes); 6680d840744SZachary Turner 6690d840744SZachary Turner Pipeline.addCallbackToPipeline(Deserializer); 6700d840744SZachary Turner Pipeline.addCallbackToPipeline(Dumper); 6710d840744SZachary Turner CVSymbolVisitor Visitor(Pipeline); 6720d840744SZachary Turner return Visitor.visitSymbolRecord(Record); 673aaad5744SZachary Turner } 674aaad5744SZachary Turner 6750d840744SZachary Turner Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) { 6760d840744SZachary Turner SymbolVisitorCallbackPipeline Pipeline; 6770d840744SZachary Turner SymbolDeserializer Deserializer(ObjDelegate.get()); 6783e78e2d4SZachary Turner CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes); 6790d840744SZachary Turner 6800d840744SZachary Turner Pipeline.addCallbackToPipeline(Deserializer); 6810d840744SZachary Turner Pipeline.addCallbackToPipeline(Dumper); 6820d840744SZachary Turner CVSymbolVisitor Visitor(Pipeline); 6830d840744SZachary Turner return Visitor.visitSymbolStream(Symbols); 684aaad5744SZachary Turner } 685