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