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