1 //===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/CodeView/SymbolDumper.h" 11 #include "llvm/ADT/DenseMap.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" 14 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 15 #include "llvm/DebugInfo/CodeView/EnumTables.h" 16 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 17 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" 18 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 19 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" 20 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" 21 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 22 #include "llvm/Support/Error.h" 23 #include "llvm/Support/ScopedPrinter.h" 24 25 #include <system_error> 26 27 using namespace llvm; 28 using namespace llvm::codeview; 29 30 namespace { 31 /// Use this private dumper implementation to keep implementation details about 32 /// the visitor out of SymbolDumper.h. 33 class CVSymbolDumperImpl : public SymbolVisitorCallbacks { 34 public: 35 CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate, 36 ScopedPrinter &W, bool PrintRecordBytes) 37 : Types(Types), ObjDelegate(ObjDelegate), W(W), 38 PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {} 39 40 /// CVSymbolVisitor overrides. 41 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 42 Error visitKnownRecord(CVSymbol &CVR, Name &Record) override; 43 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 44 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 45 46 Error visitSymbolBegin(CVSymbol &Record) override; 47 Error visitSymbolEnd(CVSymbol &Record) override; 48 Error visitUnknownSymbol(CVSymbol &Record) override; 49 50 private: 51 void printLocalVariableAddrRange(const LocalVariableAddrRange &Range, 52 uint32_t RelocationOffset); 53 void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps); 54 void printTypeIndex(StringRef FieldName, TypeIndex TI); 55 56 TypeCollection &Types; 57 SymbolDumpDelegate *ObjDelegate; 58 ScopedPrinter &W; 59 60 bool PrintRecordBytes; 61 bool InFunctionScope; 62 }; 63 } 64 65 static StringRef getSymbolKindName(SymbolKind Kind) { 66 switch (Kind) { 67 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 68 case EnumName: \ 69 return #Name; 70 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 71 default: 72 break; 73 } 74 return "UnknownSym"; 75 } 76 77 void CVSymbolDumperImpl::printLocalVariableAddrRange( 78 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) { 79 DictScope S(W, "LocalVariableAddrRange"); 80 if (ObjDelegate) 81 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset, 82 Range.OffsetStart); 83 W.printHex("ISectStart", Range.ISectStart); 84 W.printHex("Range", Range.Range); 85 } 86 87 void CVSymbolDumperImpl::printLocalVariableAddrGap( 88 ArrayRef<LocalVariableAddrGap> Gaps) { 89 for (auto &Gap : Gaps) { 90 ListScope S(W, "LocalVariableAddrGap"); 91 W.printHex("GapStartOffset", Gap.GapStartOffset); 92 W.printHex("Range", Gap.Range); 93 } 94 } 95 96 void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) { 97 codeview::printTypeIndex(W, FieldName, TI, Types); 98 } 99 100 Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) { 101 W.startLine() << getSymbolKindName(CVR.Type); 102 W.getOStream() << " {\n"; 103 W.indent(); 104 W.printEnum("Kind", unsigned(CVR.Type), getSymbolTypeNames()); 105 return Error::success(); 106 } 107 108 Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) { 109 if (PrintRecordBytes && ObjDelegate) 110 ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content()); 111 112 W.unindent(); 113 W.startLine() << "}\n"; 114 return Error::success(); 115 } 116 117 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 118 StringRef LinkageName; 119 W.printHex("PtrParent", Block.Parent); 120 W.printHex("PtrEnd", Block.End); 121 W.printHex("CodeSize", Block.CodeSize); 122 if (ObjDelegate) { 123 ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(), 124 Block.CodeOffset, &LinkageName); 125 } 126 W.printHex("Segment", Block.Segment); 127 W.printString("BlockName", Block.Name); 128 W.printString("LinkageName", LinkageName); 129 return Error::success(); 130 } 131 132 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 133 W.printNumber("Parent", Thunk.Parent); 134 W.printNumber("End", Thunk.End); 135 W.printNumber("Next", Thunk.Next); 136 W.printNumber("Off", Thunk.Offset); 137 W.printNumber("Seg", Thunk.Segment); 138 W.printNumber("Len", Thunk.Length); 139 W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames()); 140 return Error::success(); 141 } 142 143 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 144 TrampolineSym &Tramp) { 145 W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames()); 146 W.printNumber("Size", Tramp.Size); 147 W.printNumber("ThunkOff", Tramp.ThunkOffset); 148 W.printNumber("TargetOff", Tramp.TargetOffset); 149 W.printNumber("ThunkSection", Tramp.ThunkSection); 150 W.printNumber("TargetSection", Tramp.TargetSection); 151 return Error::success(); 152 } 153 154 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) { 155 W.printNumber("SectionNumber", Section.SectionNumber); 156 W.printNumber("Alignment", Section.Alignment); 157 W.printNumber("Rva", Section.Rva); 158 W.printNumber("Length", Section.Length); 159 W.printFlags("Characteristics", Section.Characteristics, 160 getImageSectionCharacteristicNames(), 161 COFF::SectionCharacteristics(0x00F00000)); 162 163 W.printString("Name", Section.Name); 164 return Error::success(); 165 } 166 167 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 168 CoffGroupSym &CoffGroup) { 169 W.printNumber("Size", CoffGroup.Size); 170 W.printFlags("Characteristics", CoffGroup.Characteristics, 171 getImageSectionCharacteristicNames(), 172 COFF::SectionCharacteristics(0x00F00000)); 173 W.printNumber("Offset", CoffGroup.Offset); 174 W.printNumber("Segment", CoffGroup.Segment); 175 W.printString("Name", CoffGroup.Name); 176 return Error::success(); 177 } 178 179 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 180 BPRelativeSym &BPRel) { 181 W.printNumber("Offset", BPRel.Offset); 182 printTypeIndex("Type", BPRel.Type); 183 W.printString("VarName", BPRel.Name); 184 return Error::success(); 185 } 186 187 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 188 BuildInfoSym &BuildInfo) { 189 printTypeIndex("BuildId", BuildInfo.BuildId); 190 return Error::success(); 191 } 192 193 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 194 CallSiteInfoSym &CallSiteInfo) { 195 StringRef LinkageName; 196 if (ObjDelegate) { 197 ObjDelegate->printRelocatedField("CodeOffset", 198 CallSiteInfo.getRelocationOffset(), 199 CallSiteInfo.CodeOffset, &LinkageName); 200 } 201 W.printHex("Segment", CallSiteInfo.Segment); 202 printTypeIndex("Type", CallSiteInfo.Type); 203 if (!LinkageName.empty()) 204 W.printString("LinkageName", LinkageName); 205 return Error::success(); 206 } 207 208 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 209 EnvBlockSym &EnvBlock) { 210 ListScope L(W, "Entries"); 211 for (auto Entry : EnvBlock.Fields) { 212 W.printString(Entry); 213 } 214 return Error::success(); 215 } 216 217 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 218 FileStaticSym &FileStatic) { 219 printTypeIndex("Index", FileStatic.Index); 220 W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset); 221 W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames()); 222 W.printString("Name", FileStatic.Name); 223 return Error::success(); 224 } 225 226 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) { 227 W.printNumber("Ordinal", Export.Ordinal); 228 W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames()); 229 W.printString("Name", Export.Name); 230 return Error::success(); 231 } 232 233 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 234 Compile2Sym &Compile2) { 235 W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames()); 236 W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames()); 237 W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames()); 238 std::string FrontendVersion; 239 { 240 raw_string_ostream Out(FrontendVersion); 241 Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor 242 << '.' << Compile2.VersionFrontendBuild; 243 } 244 std::string BackendVersion; 245 { 246 raw_string_ostream Out(BackendVersion); 247 Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor 248 << '.' << Compile2.VersionBackendBuild; 249 } 250 W.printString("FrontendVersion", FrontendVersion); 251 W.printString("BackendVersion", BackendVersion); 252 W.printString("VersionName", Compile2.Version); 253 return Error::success(); 254 } 255 256 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 257 Compile3Sym &Compile3) { 258 W.printEnum("Language", Compile3.getLanguage(), getSourceLanguageNames()); 259 W.printFlags("Flags", Compile3.getFlags(), getCompileSym3FlagNames()); 260 W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames()); 261 std::string FrontendVersion; 262 { 263 raw_string_ostream Out(FrontendVersion); 264 Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor 265 << '.' << Compile3.VersionFrontendBuild << '.' 266 << Compile3.VersionFrontendQFE; 267 } 268 std::string BackendVersion; 269 { 270 raw_string_ostream Out(BackendVersion); 271 Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor 272 << '.' << Compile3.VersionBackendBuild << '.' 273 << Compile3.VersionBackendQFE; 274 } 275 W.printString("FrontendVersion", FrontendVersion); 276 W.printString("BackendVersion", BackendVersion); 277 W.printString("VersionName", Compile3.Version); 278 return Error::success(); 279 } 280 281 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 282 ConstantSym &Constant) { 283 printTypeIndex("Type", Constant.Type); 284 W.printNumber("Value", Constant.Value); 285 W.printString("Name", Constant.Name); 286 return Error::success(); 287 } 288 289 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { 290 StringRef LinkageName; 291 if (ObjDelegate) { 292 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 293 Data.DataOffset, &LinkageName); 294 } 295 printTypeIndex("Type", Data.Type); 296 W.printString("DisplayName", Data.Name); 297 if (!LinkageName.empty()) 298 W.printString("LinkageName", LinkageName); 299 return Error::success(); 300 } 301 302 Error CVSymbolDumperImpl::visitKnownRecord( 303 CVSymbol &CVR, 304 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) { 305 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset); 306 return Error::success(); 307 } 308 309 Error CVSymbolDumperImpl::visitKnownRecord( 310 CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { 311 W.printNumber("Offset", DefRangeFramePointerRel.Offset); 312 printLocalVariableAddrRange(DefRangeFramePointerRel.Range, 313 DefRangeFramePointerRel.getRelocationOffset()); 314 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps); 315 return Error::success(); 316 } 317 318 Error CVSymbolDumperImpl::visitKnownRecord( 319 CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) { 320 W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register), 321 getRegisterNames()); 322 W.printBoolean("HasSpilledUDTMember", 323 DefRangeRegisterRel.hasSpilledUDTMember()); 324 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent()); 325 W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset); 326 printLocalVariableAddrRange(DefRangeRegisterRel.Range, 327 DefRangeRegisterRel.getRelocationOffset()); 328 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps); 329 return Error::success(); 330 } 331 332 Error CVSymbolDumperImpl::visitKnownRecord( 333 CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { 334 W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register), 335 getRegisterNames()); 336 W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName); 337 printLocalVariableAddrRange(DefRangeRegister.Range, 338 DefRangeRegister.getRelocationOffset()); 339 printLocalVariableAddrGap(DefRangeRegister.Gaps); 340 return Error::success(); 341 } 342 343 Error CVSymbolDumperImpl::visitKnownRecord( 344 CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { 345 W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register), 346 getRegisterNames()); 347 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName); 348 W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent); 349 printLocalVariableAddrRange(DefRangeSubfieldRegister.Range, 350 DefRangeSubfieldRegister.getRelocationOffset()); 351 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps); 352 return Error::success(); 353 } 354 355 Error CVSymbolDumperImpl::visitKnownRecord( 356 CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) { 357 if (ObjDelegate) { 358 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable(); 359 auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program); 360 if (!ExpectedProgram) { 361 consumeError(ExpectedProgram.takeError()); 362 return llvm::make_error<CodeViewError>( 363 "String table offset outside of bounds of String Table!"); 364 } 365 W.printString("Program", *ExpectedProgram); 366 } 367 W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent); 368 printLocalVariableAddrRange(DefRangeSubfield.Range, 369 DefRangeSubfield.getRelocationOffset()); 370 printLocalVariableAddrGap(DefRangeSubfield.Gaps); 371 return Error::success(); 372 } 373 374 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 375 DefRangeSym &DefRange) { 376 if (ObjDelegate) { 377 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable(); 378 auto ExpectedProgram = Strings.getString(DefRange.Program); 379 if (!ExpectedProgram) { 380 consumeError(ExpectedProgram.takeError()); 381 return llvm::make_error<CodeViewError>( 382 "String table offset outside of bounds of String Table!"); 383 } 384 W.printString("Program", *ExpectedProgram); 385 } 386 printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset()); 387 printLocalVariableAddrGap(DefRange.Gaps); 388 return Error::success(); 389 } 390 391 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 392 FrameCookieSym &FrameCookie) { 393 StringRef LinkageName; 394 if (ObjDelegate) { 395 ObjDelegate->printRelocatedField("CodeOffset", 396 FrameCookie.getRelocationOffset(), 397 FrameCookie.CodeOffset, &LinkageName); 398 } 399 W.printEnum("Register", uint16_t(FrameCookie.Register), getRegisterNames()); 400 W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind), 401 getFrameCookieKindNames()); 402 W.printHex("Flags", FrameCookie.Flags); 403 return Error::success(); 404 } 405 406 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 407 FrameProcSym &FrameProc) { 408 W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes); 409 W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes); 410 W.printHex("OffsetToPadding", FrameProc.OffsetToPadding); 411 W.printHex("BytesOfCalleeSavedRegisters", 412 FrameProc.BytesOfCalleeSavedRegisters); 413 W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler); 414 W.printHex("SectionIdOfExceptionHandler", 415 FrameProc.SectionIdOfExceptionHandler); 416 W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags), 417 getFrameProcSymFlagNames()); 418 return Error::success(); 419 } 420 421 Error CVSymbolDumperImpl::visitKnownRecord( 422 CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) { 423 StringRef LinkageName; 424 if (ObjDelegate) { 425 ObjDelegate->printRelocatedField("CodeOffset", 426 HeapAllocSite.getRelocationOffset(), 427 HeapAllocSite.CodeOffset, &LinkageName); 428 } 429 W.printHex("Segment", HeapAllocSite.Segment); 430 W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize); 431 printTypeIndex("Type", HeapAllocSite.Type); 432 if (!LinkageName.empty()) 433 W.printString("LinkageName", LinkageName); 434 return Error::success(); 435 } 436 437 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 438 InlineSiteSym &InlineSite) { 439 W.printHex("PtrParent", InlineSite.Parent); 440 W.printHex("PtrEnd", InlineSite.End); 441 printTypeIndex("Inlinee", InlineSite.Inlinee); 442 443 ListScope BinaryAnnotations(W, "BinaryAnnotations"); 444 for (auto &Annotation : InlineSite.annotations()) { 445 switch (Annotation.OpCode) { 446 case BinaryAnnotationsOpCode::Invalid: 447 W.printString("(Annotation Padding)"); 448 break; 449 case BinaryAnnotationsOpCode::CodeOffset: 450 case BinaryAnnotationsOpCode::ChangeCodeOffset: 451 case BinaryAnnotationsOpCode::ChangeCodeLength: 452 W.printHex(Annotation.Name, Annotation.U1); 453 break; 454 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 455 case BinaryAnnotationsOpCode::ChangeLineEndDelta: 456 case BinaryAnnotationsOpCode::ChangeRangeKind: 457 case BinaryAnnotationsOpCode::ChangeColumnStart: 458 case BinaryAnnotationsOpCode::ChangeColumnEnd: 459 W.printNumber(Annotation.Name, Annotation.U1); 460 break; 461 case BinaryAnnotationsOpCode::ChangeLineOffset: 462 case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 463 W.printNumber(Annotation.Name, Annotation.S1); 464 break; 465 case BinaryAnnotationsOpCode::ChangeFile: 466 if (ObjDelegate) { 467 W.printHex("ChangeFile", 468 ObjDelegate->getFileNameForFileOffset(Annotation.U1), 469 Annotation.U1); 470 } else { 471 W.printHex("ChangeFile", Annotation.U1); 472 } 473 474 break; 475 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: { 476 W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: " 477 << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1 478 << "}\n"; 479 break; 480 } 481 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: { 482 W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: " 483 << W.hex(Annotation.U2) 484 << ", Length: " << W.hex(Annotation.U1) << "}\n"; 485 break; 486 } 487 } 488 } 489 return Error::success(); 490 } 491 492 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 493 RegisterSym &Register) { 494 printTypeIndex("Type", Register.Index); 495 W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); 496 W.printString("Name", Register.Name); 497 return Error::success(); 498 } 499 500 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) { 501 W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames()); 502 W.printNumber("Seg", Public.Segment); 503 W.printNumber("Off", Public.Offset); 504 W.printString("Name", Public.Name); 505 return Error::success(); 506 } 507 508 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) { 509 W.printNumber("SumName", ProcRef.SumName); 510 W.printNumber("SymOffset", ProcRef.SymOffset); 511 W.printNumber("Mod", ProcRef.Module); 512 W.printString("Name", ProcRef.Name); 513 return Error::success(); 514 } 515 516 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 517 StringRef LinkageName; 518 if (ObjDelegate) { 519 ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(), 520 Label.CodeOffset, &LinkageName); 521 } 522 W.printHex("Segment", Label.Segment); 523 W.printHex("Flags", uint8_t(Label.Flags)); 524 W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames()); 525 W.printString("DisplayName", Label.Name); 526 if (!LinkageName.empty()) 527 W.printString("LinkageName", LinkageName); 528 return Error::success(); 529 } 530 531 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 532 printTypeIndex("Type", Local.Type); 533 W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames()); 534 W.printString("VarName", Local.Name); 535 return Error::success(); 536 } 537 538 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) { 539 W.printHex("Signature", ObjName.Signature); 540 W.printString("ObjectName", ObjName.Name); 541 return Error::success(); 542 } 543 544 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 545 if (InFunctionScope) 546 return llvm::make_error<CodeViewError>( 547 "Visiting a ProcSym while inside function scope!"); 548 549 InFunctionScope = true; 550 551 StringRef LinkageName; 552 W.printHex("PtrParent", Proc.Parent); 553 W.printHex("PtrEnd", Proc.End); 554 W.printHex("PtrNext", Proc.Next); 555 W.printHex("CodeSize", Proc.CodeSize); 556 W.printHex("DbgStart", Proc.DbgStart); 557 W.printHex("DbgEnd", Proc.DbgEnd); 558 printTypeIndex("FunctionType", Proc.FunctionType); 559 if (ObjDelegate) { 560 ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(), 561 Proc.CodeOffset, &LinkageName); 562 } 563 W.printHex("Segment", Proc.Segment); 564 W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags), 565 getProcSymFlagNames()); 566 W.printString("DisplayName", Proc.Name); 567 if (!LinkageName.empty()) 568 W.printString("LinkageName", LinkageName); 569 return Error::success(); 570 } 571 572 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 573 ScopeEndSym &ScopeEnd) { 574 InFunctionScope = false; 575 return Error::success(); 576 } 577 578 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 579 ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers"); 580 for (auto FuncID : Caller.Indices) 581 printTypeIndex("FuncID", FuncID); 582 return Error::success(); 583 } 584 585 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 586 RegRelativeSym &RegRel) { 587 W.printHex("Offset", RegRel.Offset); 588 printTypeIndex("Type", RegRel.Type); 589 W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames()); 590 W.printString("VarName", RegRel.Name); 591 return Error::success(); 592 } 593 594 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 595 ThreadLocalDataSym &Data) { 596 StringRef LinkageName; 597 if (ObjDelegate) { 598 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 599 Data.DataOffset, &LinkageName); 600 } 601 printTypeIndex("Type", Data.Type); 602 W.printString("DisplayName", Data.Name); 603 if (!LinkageName.empty()) 604 W.printString("LinkageName", LinkageName); 605 return Error::success(); 606 } 607 608 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 609 printTypeIndex("Type", UDT.Type); 610 W.printString("UDTName", UDT.Name); 611 return Error::success(); 612 } 613 614 Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) { 615 W.printNumber("Length", CVR.length()); 616 return Error::success(); 617 } 618 619 Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) { 620 SymbolVisitorCallbackPipeline Pipeline; 621 SymbolDeserializer Deserializer(ObjDelegate.get(), Container); 622 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes); 623 624 Pipeline.addCallbackToPipeline(Deserializer); 625 Pipeline.addCallbackToPipeline(Dumper); 626 CVSymbolVisitor Visitor(Pipeline); 627 return Visitor.visitSymbolRecord(Record); 628 } 629 630 Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) { 631 SymbolVisitorCallbackPipeline Pipeline; 632 SymbolDeserializer Deserializer(ObjDelegate.get(), Container); 633 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes); 634 635 Pipeline.addCallbackToPipeline(Deserializer); 636 Pipeline.addCallbackToPipeline(Dumper); 637 CVSymbolVisitor Visitor(Pipeline); 638 return Visitor.visitSymbolStream(Symbols); 639 } 640