brintos

brintos / llvm-project-archived public Read only

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