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