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