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