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" 14a9054dddSZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeDumper.h" 1593839cb4SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h" 16*2d5c2cd3SZachary Turner #include "llvm/DebugInfo/CodeView/StringTable.h" 170d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 18aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" 19aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 200d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" 210d840744SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" 22aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/TypeIndex.h" 230d840744SZachary Turner #include "llvm/Support/Error.h" 24aaad5744SZachary Turner #include "llvm/Support/ScopedPrinter.h" 25aaad5744SZachary Turner 26aaad5744SZachary Turner #include <system_error> 27aaad5744SZachary Turner 28aaad5744SZachary Turner using namespace llvm; 29aaad5744SZachary Turner using namespace llvm::codeview; 30aaad5744SZachary Turner 31aaad5744SZachary Turner namespace { 32aaad5744SZachary Turner /// Use this private dumper implementation to keep implementation details about 33aaad5744SZachary Turner /// the visitor out of SymbolDumper.h. 340d840744SZachary Turner class CVSymbolDumperImpl : public SymbolVisitorCallbacks { 35aaad5744SZachary Turner public: 36629cb7d8SZachary Turner CVSymbolDumperImpl(TypeDatabase &TypeDB, SymbolDumpDelegate *ObjDelegate, 373e78e2d4SZachary Turner ScopedPrinter &W, bool PrintRecordBytes) 38629cb7d8SZachary Turner : TypeDB(TypeDB), ObjDelegate(ObjDelegate), W(W), 390d840744SZachary Turner PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {} 40aaad5744SZachary Turner 41aaad5744SZachary Turner /// CVSymbolVisitor overrides. 42aaad5744SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 430d840744SZachary Turner Error visitKnownRecord(CVSymbol &CVR, Name &Record) override; 44aaad5744SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 45aaad5744SZachary Turner #include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" 46aaad5744SZachary Turner 470d840744SZachary Turner Error visitSymbolBegin(CVSymbol &Record) override; 480d840744SZachary Turner Error visitSymbolEnd(CVSymbol &Record) override; 490d840744SZachary Turner Error visitUnknownSymbol(CVSymbol &Record) override; 50aaad5744SZachary Turner 51aaad5744SZachary Turner private: 52aaad5744SZachary Turner void printLocalVariableAddrRange(const LocalVariableAddrRange &Range, 53aaad5744SZachary Turner uint32_t RelocationOffset); 54aaad5744SZachary Turner void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps); 55629cb7d8SZachary Turner void printTypeIndex(StringRef FieldName, TypeIndex TI); 56aaad5744SZachary Turner 57629cb7d8SZachary Turner TypeDatabase &TypeDB; 58aaad5744SZachary Turner SymbolDumpDelegate *ObjDelegate; 59aaad5744SZachary Turner ScopedPrinter &W; 60aaad5744SZachary Turner 61aaad5744SZachary Turner bool PrintRecordBytes; 62aaad5744SZachary Turner bool InFunctionScope; 63aaad5744SZachary Turner }; 64aaad5744SZachary Turner } 65aaad5744SZachary Turner 66aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrRange( 67aaad5744SZachary Turner const LocalVariableAddrRange &Range, uint32_t RelocationOffset) { 68aaad5744SZachary Turner DictScope S(W, "LocalVariableAddrRange"); 69aaad5744SZachary Turner if (ObjDelegate) 70aaad5744SZachary Turner ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset, 71aaad5744SZachary Turner Range.OffsetStart); 72aaad5744SZachary Turner W.printHex("ISectStart", Range.ISectStart); 73aaad5744SZachary Turner W.printHex("Range", Range.Range); 74aaad5744SZachary Turner } 75aaad5744SZachary Turner 76aaad5744SZachary Turner void CVSymbolDumperImpl::printLocalVariableAddrGap( 77aaad5744SZachary Turner ArrayRef<LocalVariableAddrGap> Gaps) { 78aaad5744SZachary Turner for (auto &Gap : Gaps) { 79aaad5744SZachary Turner ListScope S(W, "LocalVariableAddrGap"); 80aaad5744SZachary Turner W.printHex("GapStartOffset", Gap.GapStartOffset); 81aaad5744SZachary Turner W.printHex("Range", Gap.Range); 82aaad5744SZachary Turner } 83aaad5744SZachary Turner } 84aaad5744SZachary Turner 85629cb7d8SZachary Turner void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) { 86629cb7d8SZachary Turner CVTypeDumper::printTypeIndex(W, FieldName, TI, TypeDB); 87629cb7d8SZachary Turner } 88629cb7d8SZachary Turner 890d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) { 900d840744SZachary Turner return Error::success(); 91aaad5744SZachary Turner } 92aaad5744SZachary Turner 930d840744SZachary Turner Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) { 940d840744SZachary Turner if (PrintRecordBytes && ObjDelegate) 950d840744SZachary Turner ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content()); 960d840744SZachary Turner return Error::success(); 970d840744SZachary Turner } 980d840744SZachary Turner 990d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 100aaad5744SZachary Turner DictScope S(W, "BlockStart"); 101aaad5744SZachary Turner 102aaad5744SZachary Turner StringRef LinkageName; 10346225b19SZachary Turner W.printHex("PtrParent", Block.Parent); 10446225b19SZachary Turner W.printHex("PtrEnd", Block.End); 10546225b19SZachary Turner W.printHex("CodeSize", Block.CodeSize); 106aaad5744SZachary Turner if (ObjDelegate) { 107aaad5744SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(), 10846225b19SZachary Turner Block.CodeOffset, &LinkageName); 109aaad5744SZachary Turner } 11046225b19SZachary Turner W.printHex("Segment", Block.Segment); 111aaad5744SZachary Turner W.printString("BlockName", Block.Name); 112aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 1130d840744SZachary Turner return Error::success(); 114aaad5744SZachary Turner } 115aaad5744SZachary Turner 1160d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 1174caa1bf0SZachary Turner DictScope S(W, "Thunk32"); 11846225b19SZachary Turner W.printNumber("Parent", Thunk.Parent); 11946225b19SZachary Turner W.printNumber("End", Thunk.End); 12046225b19SZachary Turner W.printNumber("Next", Thunk.Next); 12146225b19SZachary Turner W.printNumber("Off", Thunk.Offset); 12246225b19SZachary Turner W.printNumber("Seg", Thunk.Segment); 12346225b19SZachary Turner W.printNumber("Len", Thunk.Length); 12446225b19SZachary Turner W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames()); 1250d840744SZachary Turner return Error::success(); 1264caa1bf0SZachary Turner } 1274caa1bf0SZachary Turner 1280d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 1294caa1bf0SZachary Turner TrampolineSym &Tramp) { 1304caa1bf0SZachary Turner DictScope S(W, "Trampoline"); 13146225b19SZachary Turner W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames()); 13246225b19SZachary Turner W.printNumber("Size", Tramp.Size); 13346225b19SZachary Turner W.printNumber("ThunkOff", Tramp.ThunkOffset); 13446225b19SZachary Turner W.printNumber("TargetOff", Tramp.TargetOffset); 13546225b19SZachary Turner W.printNumber("ThunkSection", Tramp.ThunkSection); 13646225b19SZachary Turner W.printNumber("TargetSection", Tramp.TargetSection); 1370d840744SZachary Turner return Error::success(); 1384caa1bf0SZachary Turner } 1394caa1bf0SZachary Turner 1400d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) { 1414caa1bf0SZachary Turner DictScope S(W, "Section"); 14246225b19SZachary Turner W.printNumber("SectionNumber", Section.SectionNumber); 14346225b19SZachary Turner W.printNumber("Alignment", Section.Alignment); 14446225b19SZachary Turner W.printNumber("Rva", Section.Rva); 14546225b19SZachary Turner W.printNumber("Length", Section.Length); 14646225b19SZachary Turner W.printFlags("Characteristics", Section.Characteristics, 14793839cb4SZachary Turner getImageSectionCharacteristicNames(), 14893839cb4SZachary Turner COFF::SectionCharacteristics(0x00F00000)); 14993839cb4SZachary Turner 1504caa1bf0SZachary Turner W.printString("Name", Section.Name); 1510d840744SZachary Turner return Error::success(); 1524caa1bf0SZachary Turner } 1534caa1bf0SZachary Turner 1540d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 1554caa1bf0SZachary Turner CoffGroupSym &CoffGroup) { 1564caa1bf0SZachary Turner DictScope S(W, "COFF Group"); 15746225b19SZachary Turner W.printNumber("Size", CoffGroup.Size); 15846225b19SZachary Turner W.printFlags("Characteristics", CoffGroup.Characteristics, 15993839cb4SZachary Turner getImageSectionCharacteristicNames(), 16093839cb4SZachary Turner COFF::SectionCharacteristics(0x00F00000)); 16146225b19SZachary Turner W.printNumber("Offset", CoffGroup.Offset); 16246225b19SZachary Turner W.printNumber("Segment", CoffGroup.Segment); 1634caa1bf0SZachary Turner W.printString("Name", CoffGroup.Name); 1640d840744SZachary Turner return Error::success(); 1654caa1bf0SZachary Turner } 1664caa1bf0SZachary Turner 1670d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 168aaad5744SZachary Turner BPRelativeSym &BPRel) { 169aaad5744SZachary Turner DictScope S(W, "BPRelativeSym"); 170aaad5744SZachary Turner 17146225b19SZachary Turner W.printNumber("Offset", BPRel.Offset); 172629cb7d8SZachary Turner printTypeIndex("Type", BPRel.Type); 173aaad5744SZachary Turner W.printString("VarName", BPRel.Name); 1740d840744SZachary Turner return Error::success(); 175aaad5744SZachary Turner } 176aaad5744SZachary Turner 1770d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 178aaad5744SZachary Turner BuildInfoSym &BuildInfo) { 179aaad5744SZachary Turner DictScope S(W, "BuildInfo"); 180aaad5744SZachary Turner 18146225b19SZachary Turner W.printNumber("BuildId", BuildInfo.BuildId); 1820d840744SZachary Turner return Error::success(); 183aaad5744SZachary Turner } 184aaad5744SZachary Turner 1850d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 186aaad5744SZachary Turner CallSiteInfoSym &CallSiteInfo) { 187aaad5744SZachary Turner DictScope S(W, "CallSiteInfo"); 188aaad5744SZachary Turner 189aaad5744SZachary Turner StringRef LinkageName; 190aaad5744SZachary Turner if (ObjDelegate) { 19146225b19SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", 19246225b19SZachary Turner CallSiteInfo.getRelocationOffset(), 19346225b19SZachary Turner CallSiteInfo.CodeOffset, &LinkageName); 194aaad5744SZachary Turner } 19546225b19SZachary Turner W.printHex("Segment", CallSiteInfo.Segment); 196629cb7d8SZachary Turner printTypeIndex("Type", CallSiteInfo.Type); 197aaad5744SZachary Turner if (!LinkageName.empty()) 198aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 1990d840744SZachary Turner return Error::success(); 200aaad5744SZachary Turner } 201aaad5744SZachary Turner 2020d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 2034caa1bf0SZachary Turner EnvBlockSym &EnvBlock) { 2044caa1bf0SZachary Turner DictScope S(W, "EnvBlock"); 2054caa1bf0SZachary Turner 2064caa1bf0SZachary Turner ListScope L(W, "Entries"); 2074caa1bf0SZachary Turner for (auto Entry : EnvBlock.Fields) { 2084caa1bf0SZachary Turner W.printString(Entry); 2094caa1bf0SZachary Turner } 2100d840744SZachary Turner return Error::success(); 2114caa1bf0SZachary Turner } 2124caa1bf0SZachary Turner 2130d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 2144caa1bf0SZachary Turner FileStaticSym &FileStatic) { 2154caa1bf0SZachary Turner DictScope S(W, "FileStatic"); 21646225b19SZachary Turner W.printNumber("Index", FileStatic.Index); 21746225b19SZachary Turner W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset); 21846225b19SZachary Turner W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames()); 2194caa1bf0SZachary Turner W.printString("Name", FileStatic.Name); 2200d840744SZachary Turner return Error::success(); 2214caa1bf0SZachary Turner } 2224caa1bf0SZachary Turner 2230d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) { 2249f054d42SZachary Turner DictScope S(W, "Export"); 22546225b19SZachary Turner W.printNumber("Ordinal", Export.Ordinal); 22646225b19SZachary Turner W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames()); 2279f054d42SZachary Turner W.printString("Name", Export.Name); 2280d840744SZachary Turner return Error::success(); 2299f054d42SZachary Turner } 2309f054d42SZachary Turner 2310d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 2324caa1bf0SZachary Turner Compile2Sym &Compile2) { 2334caa1bf0SZachary Turner DictScope S(W, "CompilerFlags2"); 2344caa1bf0SZachary Turner 23546225b19SZachary Turner W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames()); 23646225b19SZachary Turner W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames()); 23746225b19SZachary Turner W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames()); 2384caa1bf0SZachary Turner std::string FrontendVersion; 2394caa1bf0SZachary Turner { 2404caa1bf0SZachary Turner raw_string_ostream Out(FrontendVersion); 24146225b19SZachary Turner Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor 24246225b19SZachary Turner << '.' << Compile2.VersionFrontendBuild; 2434caa1bf0SZachary Turner } 2444caa1bf0SZachary Turner std::string BackendVersion; 2454caa1bf0SZachary Turner { 2464caa1bf0SZachary Turner raw_string_ostream Out(BackendVersion); 24746225b19SZachary Turner Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor 24846225b19SZachary Turner << '.' << Compile2.VersionBackendBuild; 2494caa1bf0SZachary Turner } 2504caa1bf0SZachary Turner W.printString("FrontendVersion", FrontendVersion); 2514caa1bf0SZachary Turner W.printString("BackendVersion", BackendVersion); 2524caa1bf0SZachary Turner W.printString("VersionName", Compile2.Version); 2530d840744SZachary Turner return Error::success(); 2544caa1bf0SZachary Turner } 2554caa1bf0SZachary Turner 2560d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 257aaad5744SZachary Turner Compile3Sym &Compile3) { 2584caa1bf0SZachary Turner DictScope S(W, "CompilerFlags3"); 259aaad5744SZachary Turner 26046225b19SZachary Turner W.printEnum("Language", Compile3.getLanguage(), getSourceLanguageNames()); 26146225b19SZachary Turner W.printFlags("Flags", Compile3.getFlags(), getCompileSym3FlagNames()); 26246225b19SZachary Turner W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames()); 263aaad5744SZachary Turner std::string FrontendVersion; 264aaad5744SZachary Turner { 265aaad5744SZachary Turner raw_string_ostream Out(FrontendVersion); 26646225b19SZachary Turner Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor 26746225b19SZachary Turner << '.' << Compile3.VersionFrontendBuild << '.' 26846225b19SZachary Turner << Compile3.VersionFrontendQFE; 269aaad5744SZachary Turner } 270aaad5744SZachary Turner std::string BackendVersion; 271aaad5744SZachary Turner { 272aaad5744SZachary Turner raw_string_ostream Out(BackendVersion); 27346225b19SZachary Turner Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor 27446225b19SZachary Turner << '.' << Compile3.VersionBackendBuild << '.' 27546225b19SZachary Turner << Compile3.VersionBackendQFE; 276aaad5744SZachary Turner } 277aaad5744SZachary Turner W.printString("FrontendVersion", FrontendVersion); 278aaad5744SZachary Turner W.printString("BackendVersion", BackendVersion); 279aaad5744SZachary Turner W.printString("VersionName", Compile3.Version); 2800d840744SZachary Turner return Error::success(); 281aaad5744SZachary Turner } 282aaad5744SZachary Turner 2830d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 284aaad5744SZachary Turner ConstantSym &Constant) { 285aaad5744SZachary Turner DictScope S(W, "Constant"); 286aaad5744SZachary Turner 287629cb7d8SZachary Turner printTypeIndex("Type", Constant.Type); 288aaad5744SZachary Turner W.printNumber("Value", Constant.Value); 289aaad5744SZachary Turner W.printString("Name", Constant.Name); 2900d840744SZachary Turner return Error::success(); 291aaad5744SZachary Turner } 292aaad5744SZachary Turner 2930d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { 294aaad5744SZachary Turner DictScope S(W, "DataSym"); 295aaad5744SZachary Turner 2960d840744SZachary Turner W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames()); 297aaad5744SZachary Turner StringRef LinkageName; 298aaad5744SZachary Turner if (ObjDelegate) { 299aaad5744SZachary Turner ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 30046225b19SZachary Turner Data.DataOffset, &LinkageName); 301aaad5744SZachary Turner } 302629cb7d8SZachary Turner printTypeIndex("Type", Data.Type); 303aaad5744SZachary Turner W.printString("DisplayName", Data.Name); 304aaad5744SZachary Turner if (!LinkageName.empty()) 305aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 3060d840744SZachary Turner return Error::success(); 307aaad5744SZachary Turner } 308aaad5744SZachary Turner 3090d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3100d840744SZachary Turner CVSymbol &CVR, 311aaad5744SZachary Turner DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) { 312aaad5744SZachary Turner DictScope S(W, "DefRangeFramePointerRelFullScope"); 31346225b19SZachary Turner W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset); 3140d840744SZachary Turner return Error::success(); 315aaad5744SZachary Turner } 316aaad5744SZachary Turner 3170d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3180d840744SZachary Turner CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { 319aaad5744SZachary Turner DictScope S(W, "DefRangeFramePointerRel"); 320aaad5744SZachary Turner 32146225b19SZachary Turner W.printNumber("Offset", DefRangeFramePointerRel.Offset); 32246225b19SZachary Turner printLocalVariableAddrRange(DefRangeFramePointerRel.Range, 323aaad5744SZachary Turner DefRangeFramePointerRel.getRelocationOffset()); 324aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps); 3250d840744SZachary Turner return Error::success(); 326aaad5744SZachary Turner } 327aaad5744SZachary Turner 3280d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3290d840744SZachary Turner CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) { 330aaad5744SZachary Turner DictScope S(W, "DefRangeRegisterRel"); 331aaad5744SZachary Turner 33246225b19SZachary Turner W.printNumber("BaseRegister", DefRangeRegisterRel.Hdr.Register); 333aaad5744SZachary Turner W.printBoolean("HasSpilledUDTMember", 334aaad5744SZachary Turner DefRangeRegisterRel.hasSpilledUDTMember()); 335aaad5744SZachary Turner W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent()); 33646225b19SZachary Turner W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset); 33746225b19SZachary Turner printLocalVariableAddrRange(DefRangeRegisterRel.Range, 338aaad5744SZachary Turner DefRangeRegisterRel.getRelocationOffset()); 339aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeRegisterRel.Gaps); 3400d840744SZachary Turner return Error::success(); 341aaad5744SZachary Turner } 342aaad5744SZachary Turner 3430d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3440d840744SZachary Turner CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { 345aaad5744SZachary Turner DictScope S(W, "DefRangeRegister"); 346aaad5744SZachary Turner 34746225b19SZachary Turner W.printNumber("Register", DefRangeRegister.Hdr.Register); 34846225b19SZachary Turner W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName); 34946225b19SZachary Turner printLocalVariableAddrRange(DefRangeRegister.Range, 350aaad5744SZachary Turner DefRangeRegister.getRelocationOffset()); 351aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeRegister.Gaps); 3520d840744SZachary Turner return Error::success(); 353aaad5744SZachary Turner } 354aaad5744SZachary Turner 3550d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3560d840744SZachary Turner CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { 357aaad5744SZachary Turner DictScope S(W, "DefRangeSubfieldRegister"); 358aaad5744SZachary Turner 35946225b19SZachary Turner W.printNumber("Register", DefRangeSubfieldRegister.Hdr.Register); 36046225b19SZachary Turner W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName); 36146225b19SZachary Turner W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent); 36246225b19SZachary Turner printLocalVariableAddrRange(DefRangeSubfieldRegister.Range, 363aaad5744SZachary Turner DefRangeSubfieldRegister.getRelocationOffset()); 364aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps); 3650d840744SZachary Turner return Error::success(); 366aaad5744SZachary Turner } 367aaad5744SZachary Turner 3680d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 3690d840744SZachary Turner CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) { 370aaad5744SZachary Turner DictScope S(W, "DefRangeSubfield"); 371aaad5744SZachary Turner 372aaad5744SZachary Turner if (ObjDelegate) { 373*2d5c2cd3SZachary Turner StringTableRef Strings = ObjDelegate->getStringTable(); 374*2d5c2cd3SZachary Turner auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program); 375*2d5c2cd3SZachary Turner if (!ExpectedProgram) { 376*2d5c2cd3SZachary Turner consumeError(ExpectedProgram.takeError()); 3770d840744SZachary Turner return llvm::make_error<CodeViewError>( 3780d840744SZachary Turner "String table offset outside of bounds of String Table!"); 379*2d5c2cd3SZachary Turner } 380*2d5c2cd3SZachary Turner W.printString("Program", *ExpectedProgram); 381aaad5744SZachary Turner } 38246225b19SZachary Turner W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent); 38346225b19SZachary Turner printLocalVariableAddrRange(DefRangeSubfield.Range, 384aaad5744SZachary Turner DefRangeSubfield.getRelocationOffset()); 385aaad5744SZachary Turner printLocalVariableAddrGap(DefRangeSubfield.Gaps); 3860d840744SZachary Turner return Error::success(); 387aaad5744SZachary Turner } 388aaad5744SZachary Turner 3890d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 390aaad5744SZachary Turner DefRangeSym &DefRange) { 391aaad5744SZachary Turner DictScope S(W, "DefRange"); 392aaad5744SZachary Turner 393aaad5744SZachary Turner if (ObjDelegate) { 394*2d5c2cd3SZachary Turner StringTableRef Strings = ObjDelegate->getStringTable(); 395*2d5c2cd3SZachary Turner auto ExpectedProgram = Strings.getString(DefRange.Program); 396*2d5c2cd3SZachary Turner if (!ExpectedProgram) { 397*2d5c2cd3SZachary Turner consumeError(ExpectedProgram.takeError()); 3980d840744SZachary Turner return llvm::make_error<CodeViewError>( 3990d840744SZachary Turner "String table offset outside of bounds of String Table!"); 400*2d5c2cd3SZachary Turner } 401*2d5c2cd3SZachary Turner W.printString("Program", *ExpectedProgram); 402aaad5744SZachary Turner } 40346225b19SZachary Turner printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset()); 404aaad5744SZachary Turner printLocalVariableAddrGap(DefRange.Gaps); 4050d840744SZachary Turner return Error::success(); 406aaad5744SZachary Turner } 407aaad5744SZachary Turner 4080d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 409aaad5744SZachary Turner FrameCookieSym &FrameCookie) { 410aaad5744SZachary Turner DictScope S(W, "FrameCookie"); 411aaad5744SZachary Turner 412aaad5744SZachary Turner StringRef LinkageName; 413aaad5744SZachary Turner if (ObjDelegate) { 41446225b19SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", 41546225b19SZachary Turner FrameCookie.getRelocationOffset(), 41646225b19SZachary Turner FrameCookie.CodeOffset, &LinkageName); 417aaad5744SZachary Turner } 41846225b19SZachary Turner W.printHex("Register", FrameCookie.Register); 41946225b19SZachary Turner W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind), 42093839cb4SZachary Turner getFrameCookieKindNames()); 42146225b19SZachary Turner W.printHex("Flags", FrameCookie.Flags); 4220d840744SZachary Turner return Error::success(); 423aaad5744SZachary Turner } 424aaad5744SZachary Turner 4250d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 426aaad5744SZachary Turner FrameProcSym &FrameProc) { 427aaad5744SZachary Turner DictScope S(W, "FrameProc"); 428aaad5744SZachary Turner 42946225b19SZachary Turner W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes); 43046225b19SZachary Turner W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes); 43146225b19SZachary Turner W.printHex("OffsetToPadding", FrameProc.OffsetToPadding); 432aaad5744SZachary Turner W.printHex("BytesOfCalleeSavedRegisters", 43346225b19SZachary Turner FrameProc.BytesOfCalleeSavedRegisters); 43446225b19SZachary Turner W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler); 435aaad5744SZachary Turner W.printHex("SectionIdOfExceptionHandler", 43646225b19SZachary Turner FrameProc.SectionIdOfExceptionHandler); 43746225b19SZachary Turner W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags), 43846225b19SZachary Turner getFrameProcSymFlagNames()); 4390d840744SZachary Turner return Error::success(); 440aaad5744SZachary Turner } 441aaad5744SZachary Turner 4420d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord( 4430d840744SZachary Turner CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) { 444aaad5744SZachary Turner DictScope S(W, "HeapAllocationSite"); 445aaad5744SZachary Turner 446aaad5744SZachary Turner StringRef LinkageName; 447aaad5744SZachary Turner if (ObjDelegate) { 44846225b19SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", 44946225b19SZachary Turner HeapAllocSite.getRelocationOffset(), 45046225b19SZachary Turner HeapAllocSite.CodeOffset, &LinkageName); 451aaad5744SZachary Turner } 45246225b19SZachary Turner W.printHex("Segment", HeapAllocSite.Segment); 45346225b19SZachary Turner W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize); 454629cb7d8SZachary Turner printTypeIndex("Type", HeapAllocSite.Type); 455aaad5744SZachary Turner if (!LinkageName.empty()) 456aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 4570d840744SZachary Turner return Error::success(); 458aaad5744SZachary Turner } 459aaad5744SZachary Turner 4600d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 461aaad5744SZachary Turner InlineSiteSym &InlineSite) { 462aaad5744SZachary Turner DictScope S(W, "InlineSite"); 463aaad5744SZachary Turner 46446225b19SZachary Turner W.printHex("PtrParent", InlineSite.Parent); 46546225b19SZachary Turner W.printHex("PtrEnd", InlineSite.End); 466629cb7d8SZachary Turner printTypeIndex("Inlinee", InlineSite.Inlinee); 467aaad5744SZachary Turner 468aaad5744SZachary Turner ListScope BinaryAnnotations(W, "BinaryAnnotations"); 469aaad5744SZachary Turner for (auto &Annotation : InlineSite.annotations()) { 470aaad5744SZachary Turner switch (Annotation.OpCode) { 471aaad5744SZachary Turner case BinaryAnnotationsOpCode::Invalid: 47242cb87f4SZachary Turner W.printString("(Annotation Padding)"); 47342cb87f4SZachary Turner break; 474aaad5744SZachary Turner case BinaryAnnotationsOpCode::CodeOffset: 475aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeOffset: 476aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeLength: 477aaad5744SZachary Turner W.printHex(Annotation.Name, Annotation.U1); 478aaad5744SZachary Turner break; 479aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 480aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeLineEndDelta: 481aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeRangeKind: 482aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeColumnStart: 483aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeColumnEnd: 484aaad5744SZachary Turner W.printNumber(Annotation.Name, Annotation.U1); 485aaad5744SZachary Turner break; 486aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeLineOffset: 487aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 488aaad5744SZachary Turner W.printNumber(Annotation.Name, Annotation.S1); 489aaad5744SZachary Turner break; 490aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeFile: 491aaad5744SZachary Turner if (ObjDelegate) { 492aaad5744SZachary Turner W.printHex("ChangeFile", 493aaad5744SZachary Turner ObjDelegate->getFileNameForFileOffset(Annotation.U1), 494aaad5744SZachary Turner Annotation.U1); 495aaad5744SZachary Turner } else { 496aaad5744SZachary Turner W.printHex("ChangeFile", Annotation.U1); 497aaad5744SZachary Turner } 498aaad5744SZachary Turner 499aaad5744SZachary Turner break; 500aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: { 501aaad5744SZachary Turner W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: " 502aaad5744SZachary Turner << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1 503aaad5744SZachary Turner << "}\n"; 504aaad5744SZachary Turner break; 505aaad5744SZachary Turner } 506aaad5744SZachary Turner case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: { 507aaad5744SZachary Turner W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: " 508aaad5744SZachary Turner << W.hex(Annotation.U2) 509aaad5744SZachary Turner << ", Length: " << W.hex(Annotation.U1) << "}\n"; 510aaad5744SZachary Turner break; 511aaad5744SZachary Turner } 512aaad5744SZachary Turner } 513aaad5744SZachary Turner } 5140d840744SZachary Turner return Error::success(); 515aaad5744SZachary Turner } 516aaad5744SZachary Turner 5170d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 5184caa1bf0SZachary Turner RegisterSym &Register) { 5194caa1bf0SZachary Turner DictScope S(W, "RegisterSym"); 52046225b19SZachary Turner W.printNumber("Type", Register.Index); 52146225b19SZachary Turner W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); 5224caa1bf0SZachary Turner W.printString("Name", Register.Name); 5230d840744SZachary Turner return Error::success(); 5244caa1bf0SZachary Turner } 5254caa1bf0SZachary Turner 5260d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) { 5279e33e6f8SZachary Turner DictScope S(W, "PublicSym"); 52846225b19SZachary Turner W.printNumber("Type", Public.Index); 52946225b19SZachary Turner W.printNumber("Seg", Public.Segment); 53046225b19SZachary Turner W.printNumber("Off", Public.Offset); 5319e33e6f8SZachary Turner W.printString("Name", Public.Name); 5320d840744SZachary Turner return Error::success(); 5339e33e6f8SZachary Turner } 5349e33e6f8SZachary Turner 5350d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) { 5369e33e6f8SZachary Turner DictScope S(W, "ProcRef"); 53746225b19SZachary Turner W.printNumber("SumName", ProcRef.SumName); 53846225b19SZachary Turner W.printNumber("SymOffset", ProcRef.SymOffset); 53946225b19SZachary Turner W.printNumber("Mod", ProcRef.Module); 5409e33e6f8SZachary Turner W.printString("Name", ProcRef.Name); 5410d840744SZachary Turner return Error::success(); 5429e33e6f8SZachary Turner } 5439e33e6f8SZachary Turner 5440d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 545aaad5744SZachary Turner DictScope S(W, "Label"); 546aaad5744SZachary Turner 547aaad5744SZachary Turner StringRef LinkageName; 548aaad5744SZachary Turner if (ObjDelegate) { 549aaad5744SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(), 55046225b19SZachary Turner Label.CodeOffset, &LinkageName); 551aaad5744SZachary Turner } 55246225b19SZachary Turner W.printHex("Segment", Label.Segment); 55346225b19SZachary Turner W.printHex("Flags", uint8_t(Label.Flags)); 55446225b19SZachary Turner W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames()); 555aaad5744SZachary Turner W.printString("DisplayName", Label.Name); 556aaad5744SZachary Turner if (!LinkageName.empty()) 557aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 5580d840744SZachary Turner return Error::success(); 559aaad5744SZachary Turner } 560aaad5744SZachary Turner 5610d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 562aaad5744SZachary Turner DictScope S(W, "Local"); 563aaad5744SZachary Turner 564629cb7d8SZachary Turner printTypeIndex("Type", Local.Type); 56546225b19SZachary Turner W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames()); 566aaad5744SZachary Turner W.printString("VarName", Local.Name); 5670d840744SZachary Turner return Error::success(); 568aaad5744SZachary Turner } 569aaad5744SZachary Turner 5700d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) { 571aaad5744SZachary Turner DictScope S(W, "ObjectName"); 572aaad5744SZachary Turner 57346225b19SZachary Turner W.printHex("Signature", ObjName.Signature); 574aaad5744SZachary Turner W.printString("ObjectName", ObjName.Name); 5750d840744SZachary Turner return Error::success(); 576aaad5744SZachary Turner } 577aaad5744SZachary Turner 5780d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 579aaad5744SZachary Turner DictScope S(W, "ProcStart"); 580aaad5744SZachary Turner 581aaad5744SZachary Turner if (InFunctionScope) 5820d840744SZachary Turner return llvm::make_error<CodeViewError>( 5830d840744SZachary Turner "Visiting a ProcSym while inside function scope!"); 584aaad5744SZachary Turner 585aaad5744SZachary Turner InFunctionScope = true; 586aaad5744SZachary Turner 587aaad5744SZachary Turner StringRef LinkageName; 5880d840744SZachary Turner W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames()); 58946225b19SZachary Turner W.printHex("PtrParent", Proc.Parent); 59046225b19SZachary Turner W.printHex("PtrEnd", Proc.End); 59146225b19SZachary Turner W.printHex("PtrNext", Proc.Next); 59246225b19SZachary Turner W.printHex("CodeSize", Proc.CodeSize); 59346225b19SZachary Turner W.printHex("DbgStart", Proc.DbgStart); 59446225b19SZachary Turner W.printHex("DbgEnd", Proc.DbgEnd); 595629cb7d8SZachary Turner printTypeIndex("FunctionType", Proc.FunctionType); 596aaad5744SZachary Turner if (ObjDelegate) { 597aaad5744SZachary Turner ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(), 59846225b19SZachary Turner Proc.CodeOffset, &LinkageName); 599aaad5744SZachary Turner } 60046225b19SZachary Turner W.printHex("Segment", Proc.Segment); 60146225b19SZachary Turner W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags), 60293839cb4SZachary Turner getProcSymFlagNames()); 603aaad5744SZachary Turner W.printString("DisplayName", Proc.Name); 604aaad5744SZachary Turner if (!LinkageName.empty()) 605aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 6060d840744SZachary Turner return Error::success(); 607aaad5744SZachary Turner } 608aaad5744SZachary Turner 6090d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 610aaad5744SZachary Turner ScopeEndSym &ScopeEnd) { 6110d840744SZachary Turner if (CVR.kind() == SymbolKind::S_END) 612cac29ae0SZachary Turner DictScope S(W, "BlockEnd"); 6130d840744SZachary Turner else if (CVR.kind() == SymbolKind::S_PROC_ID_END) 614cac29ae0SZachary Turner DictScope S(W, "ProcEnd"); 6150d840744SZachary Turner else if (CVR.kind() == SymbolKind::S_INLINESITE_END) 616aaad5744SZachary Turner DictScope S(W, "InlineSiteEnd"); 617aaad5744SZachary Turner 618aaad5744SZachary Turner InFunctionScope = false; 6190d840744SZachary Turner return Error::success(); 620aaad5744SZachary Turner } 621aaad5744SZachary Turner 6220d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 6230d840744SZachary Turner ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers"); 624aaad5744SZachary Turner for (auto FuncID : Caller.Indices) 625629cb7d8SZachary Turner printTypeIndex("FuncID", FuncID); 6260d840744SZachary Turner return Error::success(); 627aaad5744SZachary Turner } 628aaad5744SZachary Turner 6290d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 630aaad5744SZachary Turner RegRelativeSym &RegRel) { 631aaad5744SZachary Turner DictScope S(W, "RegRelativeSym"); 632aaad5744SZachary Turner 63346225b19SZachary Turner W.printHex("Offset", RegRel.Offset); 634629cb7d8SZachary Turner printTypeIndex("Type", RegRel.Type); 63546225b19SZachary Turner W.printHex("Register", RegRel.Register); 636aaad5744SZachary Turner W.printString("VarName", RegRel.Name); 6370d840744SZachary Turner return Error::success(); 638aaad5744SZachary Turner } 639aaad5744SZachary Turner 6400d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 641aaad5744SZachary Turner ThreadLocalDataSym &Data) { 642aaad5744SZachary Turner DictScope S(W, "ThreadLocalDataSym"); 643aaad5744SZachary Turner 644aaad5744SZachary Turner StringRef LinkageName; 645aaad5744SZachary Turner if (ObjDelegate) { 646aaad5744SZachary Turner ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 64746225b19SZachary Turner Data.DataOffset, &LinkageName); 648aaad5744SZachary Turner } 649629cb7d8SZachary Turner printTypeIndex("Type", Data.Type); 650aaad5744SZachary Turner W.printString("DisplayName", Data.Name); 651aaad5744SZachary Turner if (!LinkageName.empty()) 652aaad5744SZachary Turner W.printString("LinkageName", LinkageName); 6530d840744SZachary Turner return Error::success(); 654aaad5744SZachary Turner } 655aaad5744SZachary Turner 6560d840744SZachary Turner Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 657aaad5744SZachary Turner DictScope S(W, "UDT"); 658629cb7d8SZachary Turner printTypeIndex("Type", UDT.Type); 659aaad5744SZachary Turner W.printString("UDTName", UDT.Name); 6600d840744SZachary Turner return Error::success(); 661aaad5744SZachary Turner } 662aaad5744SZachary Turner 6630d840744SZachary Turner Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) { 664aaad5744SZachary Turner DictScope S(W, "UnknownSym"); 6650d840744SZachary Turner W.printEnum("Kind", uint16_t(CVR.kind()), getSymbolTypeNames()); 6660d840744SZachary Turner W.printNumber("Length", CVR.length()); 6670d840744SZachary Turner return Error::success(); 668aaad5744SZachary Turner } 669aaad5744SZachary Turner 6700d840744SZachary Turner Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) { 6710d840744SZachary Turner SymbolVisitorCallbackPipeline Pipeline; 6720d840744SZachary Turner SymbolDeserializer Deserializer(ObjDelegate.get()); 673629cb7d8SZachary Turner CVSymbolDumperImpl Dumper(TypeDB, ObjDelegate.get(), W, PrintRecordBytes); 6740d840744SZachary Turner 6750d840744SZachary Turner Pipeline.addCallbackToPipeline(Deserializer); 6760d840744SZachary Turner Pipeline.addCallbackToPipeline(Dumper); 6770d840744SZachary Turner CVSymbolVisitor Visitor(Pipeline); 6780d840744SZachary Turner return Visitor.visitSymbolRecord(Record); 679aaad5744SZachary Turner } 680aaad5744SZachary Turner 6810d840744SZachary Turner Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) { 6820d840744SZachary Turner SymbolVisitorCallbackPipeline Pipeline; 6830d840744SZachary Turner SymbolDeserializer Deserializer(ObjDelegate.get()); 684629cb7d8SZachary Turner CVSymbolDumperImpl Dumper(TypeDB, ObjDelegate.get(), W, PrintRecordBytes); 6850d840744SZachary Turner 6860d840744SZachary Turner Pipeline.addCallbackToPipeline(Deserializer); 6870d840744SZachary Turner Pipeline.addCallbackToPipeline(Dumper); 6880d840744SZachary Turner CVSymbolVisitor Visitor(Pipeline); 6890d840744SZachary Turner return Visitor.visitSymbolStream(Symbols); 690aaad5744SZachary Turner } 691