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