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/DebugStringTableSubsection.h" 15 #include "llvm/DebugInfo/CodeView/EnumTables.h" 16 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 17 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" 18 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 19 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" 20 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.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(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate, 36 ScopedPrinter &W, bool PrintRecordBytes) 37 : Types(Types), 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/CodeViewSymbols.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 void printTypeIndex(StringRef FieldName, TypeIndex TI); 55 56 TypeCollection &Types; 57 SymbolDumpDelegate *ObjDelegate; 58 ScopedPrinter &W; 59 60 bool PrintRecordBytes; 61 bool InFunctionScope; 62 }; 63 } 64 65 static StringRef getSymbolKindName(SymbolKind Kind) { 66 switch (Kind) { 67 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 68 case EnumName: \ 69 return #Name; 70 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 71 default: 72 break; 73 } 74 return "UnknownSym"; 75 } 76 77 void CVSymbolDumperImpl::printLocalVariableAddrRange( 78 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) { 79 DictScope S(W, "LocalVariableAddrRange"); 80 if (ObjDelegate) 81 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset, 82 Range.OffsetStart); 83 W.printHex("ISectStart", Range.ISectStart); 84 W.printHex("Range", Range.Range); 85 } 86 87 void CVSymbolDumperImpl::printLocalVariableAddrGap( 88 ArrayRef<LocalVariableAddrGap> Gaps) { 89 for (auto &Gap : Gaps) { 90 ListScope S(W, "LocalVariableAddrGap"); 91 W.printHex("GapStartOffset", Gap.GapStartOffset); 92 W.printHex("Range", Gap.Range); 93 } 94 } 95 96 void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) { 97 codeview::printTypeIndex(W, FieldName, TI, Types); 98 } 99 100 Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) { 101 W.startLine() << getSymbolKindName(CVR.Type); 102 W.getOStream() << " {\n"; 103 W.indent(); 104 W.printEnum("Kind", unsigned(CVR.Type), getSymbolTypeNames()); 105 return Error::success(); 106 } 107 108 Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) { 109 if (PrintRecordBytes && ObjDelegate) 110 ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content()); 111 112 W.unindent(); 113 W.startLine() << "}\n"; 114 return Error::success(); 115 } 116 117 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 118 StringRef LinkageName; 119 W.printHex("PtrParent", Block.Parent); 120 W.printHex("PtrEnd", Block.End); 121 W.printHex("CodeSize", Block.CodeSize); 122 if (ObjDelegate) { 123 ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(), 124 Block.CodeOffset, &LinkageName); 125 } 126 W.printHex("Segment", Block.Segment); 127 W.printString("BlockName", Block.Name); 128 W.printString("LinkageName", LinkageName); 129 return Error::success(); 130 } 131 132 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 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.printNumber("BaseRegister", DefRangeRegisterRel.Hdr.Register); 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.printNumber("Register", DefRangeRegister.Hdr.Register); 334 W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName); 335 printLocalVariableAddrRange(DefRangeRegister.Range, 336 DefRangeRegister.getRelocationOffset()); 337 printLocalVariableAddrGap(DefRangeRegister.Gaps); 338 return Error::success(); 339 } 340 341 Error CVSymbolDumperImpl::visitKnownRecord( 342 CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { 343 W.printNumber("Register", DefRangeSubfieldRegister.Hdr.Register); 344 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName); 345 W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent); 346 printLocalVariableAddrRange(DefRangeSubfieldRegister.Range, 347 DefRangeSubfieldRegister.getRelocationOffset()); 348 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps); 349 return Error::success(); 350 } 351 352 Error CVSymbolDumperImpl::visitKnownRecord( 353 CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) { 354 if (ObjDelegate) { 355 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable(); 356 auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program); 357 if (!ExpectedProgram) { 358 consumeError(ExpectedProgram.takeError()); 359 return llvm::make_error<CodeViewError>( 360 "String table offset outside of bounds of String Table!"); 361 } 362 W.printString("Program", *ExpectedProgram); 363 } 364 W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent); 365 printLocalVariableAddrRange(DefRangeSubfield.Range, 366 DefRangeSubfield.getRelocationOffset()); 367 printLocalVariableAddrGap(DefRangeSubfield.Gaps); 368 return Error::success(); 369 } 370 371 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 372 DefRangeSym &DefRange) { 373 if (ObjDelegate) { 374 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable(); 375 auto ExpectedProgram = Strings.getString(DefRange.Program); 376 if (!ExpectedProgram) { 377 consumeError(ExpectedProgram.takeError()); 378 return llvm::make_error<CodeViewError>( 379 "String table offset outside of bounds of String Table!"); 380 } 381 W.printString("Program", *ExpectedProgram); 382 } 383 printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset()); 384 printLocalVariableAddrGap(DefRange.Gaps); 385 return Error::success(); 386 } 387 388 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 389 FrameCookieSym &FrameCookie) { 390 StringRef LinkageName; 391 if (ObjDelegate) { 392 ObjDelegate->printRelocatedField("CodeOffset", 393 FrameCookie.getRelocationOffset(), 394 FrameCookie.CodeOffset, &LinkageName); 395 } 396 W.printHex("Register", FrameCookie.Register); 397 W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind), 398 getFrameCookieKindNames()); 399 W.printHex("Flags", FrameCookie.Flags); 400 return Error::success(); 401 } 402 403 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 404 FrameProcSym &FrameProc) { 405 W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes); 406 W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes); 407 W.printHex("OffsetToPadding", FrameProc.OffsetToPadding); 408 W.printHex("BytesOfCalleeSavedRegisters", 409 FrameProc.BytesOfCalleeSavedRegisters); 410 W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler); 411 W.printHex("SectionIdOfExceptionHandler", 412 FrameProc.SectionIdOfExceptionHandler); 413 W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags), 414 getFrameProcSymFlagNames()); 415 return Error::success(); 416 } 417 418 Error CVSymbolDumperImpl::visitKnownRecord( 419 CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) { 420 StringRef LinkageName; 421 if (ObjDelegate) { 422 ObjDelegate->printRelocatedField("CodeOffset", 423 HeapAllocSite.getRelocationOffset(), 424 HeapAllocSite.CodeOffset, &LinkageName); 425 } 426 W.printHex("Segment", HeapAllocSite.Segment); 427 W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize); 428 printTypeIndex("Type", HeapAllocSite.Type); 429 if (!LinkageName.empty()) 430 W.printString("LinkageName", LinkageName); 431 return Error::success(); 432 } 433 434 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 435 InlineSiteSym &InlineSite) { 436 W.printHex("PtrParent", InlineSite.Parent); 437 W.printHex("PtrEnd", InlineSite.End); 438 printTypeIndex("Inlinee", InlineSite.Inlinee); 439 440 ListScope BinaryAnnotations(W, "BinaryAnnotations"); 441 for (auto &Annotation : InlineSite.annotations()) { 442 switch (Annotation.OpCode) { 443 case BinaryAnnotationsOpCode::Invalid: 444 W.printString("(Annotation Padding)"); 445 break; 446 case BinaryAnnotationsOpCode::CodeOffset: 447 case BinaryAnnotationsOpCode::ChangeCodeOffset: 448 case BinaryAnnotationsOpCode::ChangeCodeLength: 449 W.printHex(Annotation.Name, Annotation.U1); 450 break; 451 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 452 case BinaryAnnotationsOpCode::ChangeLineEndDelta: 453 case BinaryAnnotationsOpCode::ChangeRangeKind: 454 case BinaryAnnotationsOpCode::ChangeColumnStart: 455 case BinaryAnnotationsOpCode::ChangeColumnEnd: 456 W.printNumber(Annotation.Name, Annotation.U1); 457 break; 458 case BinaryAnnotationsOpCode::ChangeLineOffset: 459 case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 460 W.printNumber(Annotation.Name, Annotation.S1); 461 break; 462 case BinaryAnnotationsOpCode::ChangeFile: 463 if (ObjDelegate) { 464 W.printHex("ChangeFile", 465 ObjDelegate->getFileNameForFileOffset(Annotation.U1), 466 Annotation.U1); 467 } else { 468 W.printHex("ChangeFile", Annotation.U1); 469 } 470 471 break; 472 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: { 473 W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: " 474 << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1 475 << "}\n"; 476 break; 477 } 478 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: { 479 W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: " 480 << W.hex(Annotation.U2) 481 << ", Length: " << W.hex(Annotation.U1) << "}\n"; 482 break; 483 } 484 } 485 } 486 return Error::success(); 487 } 488 489 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 490 RegisterSym &Register) { 491 printTypeIndex("Type", Register.Index); 492 W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); 493 W.printString("Name", Register.Name); 494 return Error::success(); 495 } 496 497 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) { 498 W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames()); 499 W.printNumber("Seg", Public.Segment); 500 W.printNumber("Off", Public.Offset); 501 W.printString("Name", Public.Name); 502 return Error::success(); 503 } 504 505 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) { 506 W.printNumber("SumName", ProcRef.SumName); 507 W.printNumber("SymOffset", ProcRef.SymOffset); 508 W.printNumber("Mod", ProcRef.Module); 509 W.printString("Name", ProcRef.Name); 510 return Error::success(); 511 } 512 513 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 514 StringRef LinkageName; 515 if (ObjDelegate) { 516 ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(), 517 Label.CodeOffset, &LinkageName); 518 } 519 W.printHex("Segment", Label.Segment); 520 W.printHex("Flags", uint8_t(Label.Flags)); 521 W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames()); 522 W.printString("DisplayName", Label.Name); 523 if (!LinkageName.empty()) 524 W.printString("LinkageName", LinkageName); 525 return Error::success(); 526 } 527 528 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 529 printTypeIndex("Type", Local.Type); 530 W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames()); 531 W.printString("VarName", Local.Name); 532 return Error::success(); 533 } 534 535 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) { 536 W.printHex("Signature", ObjName.Signature); 537 W.printString("ObjectName", ObjName.Name); 538 return Error::success(); 539 } 540 541 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 542 if (InFunctionScope) 543 return llvm::make_error<CodeViewError>( 544 "Visiting a ProcSym while inside function scope!"); 545 546 InFunctionScope = true; 547 548 StringRef LinkageName; 549 W.printHex("PtrParent", Proc.Parent); 550 W.printHex("PtrEnd", Proc.End); 551 W.printHex("PtrNext", Proc.Next); 552 W.printHex("CodeSize", Proc.CodeSize); 553 W.printHex("DbgStart", Proc.DbgStart); 554 W.printHex("DbgEnd", Proc.DbgEnd); 555 printTypeIndex("FunctionType", Proc.FunctionType); 556 if (ObjDelegate) { 557 ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(), 558 Proc.CodeOffset, &LinkageName); 559 } 560 W.printHex("Segment", Proc.Segment); 561 W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags), 562 getProcSymFlagNames()); 563 W.printString("DisplayName", Proc.Name); 564 if (!LinkageName.empty()) 565 W.printString("LinkageName", LinkageName); 566 return Error::success(); 567 } 568 569 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 570 ScopeEndSym &ScopeEnd) { 571 InFunctionScope = false; 572 return Error::success(); 573 } 574 575 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 576 ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers"); 577 for (auto FuncID : Caller.Indices) 578 printTypeIndex("FuncID", FuncID); 579 return Error::success(); 580 } 581 582 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 583 RegRelativeSym &RegRel) { 584 W.printHex("Offset", RegRel.Offset); 585 printTypeIndex("Type", RegRel.Type); 586 W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames()); 587 W.printString("VarName", RegRel.Name); 588 return Error::success(); 589 } 590 591 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, 592 ThreadLocalDataSym &Data) { 593 StringRef LinkageName; 594 if (ObjDelegate) { 595 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(), 596 Data.DataOffset, &LinkageName); 597 } 598 printTypeIndex("Type", Data.Type); 599 W.printString("DisplayName", Data.Name); 600 if (!LinkageName.empty()) 601 W.printString("LinkageName", LinkageName); 602 return Error::success(); 603 } 604 605 Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 606 printTypeIndex("Type", UDT.Type); 607 W.printString("UDTName", UDT.Name); 608 return Error::success(); 609 } 610 611 Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) { 612 W.printNumber("Length", CVR.length()); 613 return Error::success(); 614 } 615 616 Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) { 617 SymbolVisitorCallbackPipeline Pipeline; 618 SymbolDeserializer Deserializer(ObjDelegate.get(), Container); 619 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes); 620 621 Pipeline.addCallbackToPipeline(Deserializer); 622 Pipeline.addCallbackToPipeline(Dumper); 623 CVSymbolVisitor Visitor(Pipeline); 624 return Visitor.visitSymbolRecord(Record); 625 } 626 627 Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) { 628 SymbolVisitorCallbackPipeline Pipeline; 629 SymbolDeserializer Deserializer(ObjDelegate.get(), Container); 630 CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes); 631 632 Pipeline.addCallbackToPipeline(Deserializer); 633 Pipeline.addCallbackToPipeline(Dumper); 634 CVSymbolVisitor Visitor(Pipeline); 635 return Visitor.visitSymbolStream(Symbols); 636 } 637