1*0b57cec5SDimitry Andric //===- MinimalSymbolDumper.cpp -------------------------------- *- C++ --*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "MinimalSymbolDumper.h" 10*0b57cec5SDimitry Andric 11*0b57cec5SDimitry Andric #include "FormatUtil.h" 12*0b57cec5SDimitry Andric #include "InputFile.h" 13*0b57cec5SDimitry Andric #include "LinePrinter.h" 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVRecord.h" 16*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 17*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/Formatters.h" 18*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" 19*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 20*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h" 21*0b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h" 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric using namespace llvm; 25*0b57cec5SDimitry Andric using namespace llvm::codeview; 26*0b57cec5SDimitry Andric using namespace llvm::pdb; 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric static std::string formatLocalSymFlags(uint32_t IndentLevel, 29*0b57cec5SDimitry Andric LocalSymFlags Flags) { 30*0b57cec5SDimitry Andric std::vector<std::string> Opts; 31*0b57cec5SDimitry Andric if (Flags == LocalSymFlags::None) 32*0b57cec5SDimitry Andric return "none"; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsParameter, Flags, "param"); 35*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAddressTaken, Flags, "address is taken"); 36*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsCompilerGenerated, Flags, "compiler generated"); 37*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAggregate, Flags, "aggregate"); 38*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAggregated, Flags, "aggregated"); 39*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAliased, Flags, "aliased"); 40*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAlias, Flags, "alias"); 41*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsReturnValue, Flags, "return val"); 42*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsOptimizedOut, Flags, "optimized away"); 43*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsEnregisteredGlobal, Flags, "enreg global"); 44*0b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsEnregisteredStatic, Flags, "enreg static"); 45*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 46*0b57cec5SDimitry Andric } 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric static std::string formatExportFlags(uint32_t IndentLevel, ExportFlags Flags) { 49*0b57cec5SDimitry Andric std::vector<std::string> Opts; 50*0b57cec5SDimitry Andric if (Flags == ExportFlags::None) 51*0b57cec5SDimitry Andric return "none"; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsConstant, Flags, "constant"); 54*0b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsData, Flags, "data"); 55*0b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsPrivate, Flags, "private"); 56*0b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, HasNoName, Flags, "no name"); 57*0b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, HasExplicitOrdinal, Flags, "explicit ord"); 58*0b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsForwarder, Flags, "forwarder"); 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 61*0b57cec5SDimitry Andric } 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric static std::string formatCompileSym2Flags(uint32_t IndentLevel, 64*0b57cec5SDimitry Andric CompileSym2Flags Flags) { 65*0b57cec5SDimitry Andric std::vector<std::string> Opts; 66*0b57cec5SDimitry Andric Flags &= ~CompileSym2Flags::SourceLanguageMask; 67*0b57cec5SDimitry Andric if (Flags == CompileSym2Flags::None) 68*0b57cec5SDimitry Andric return "none"; 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, EC, Flags, "edit and continue"); 71*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, NoDbgInfo, Flags, "no dbg info"); 72*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, LTCG, Flags, "ltcg"); 73*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, NoDataAlign, Flags, "no data align"); 74*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, ManagedPresent, Flags, "has managed code"); 75*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, SecurityChecks, Flags, "security checks"); 76*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, HotPatch, Flags, "hot patchable"); 77*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, CVTCIL, Flags, "cvtcil"); 78*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, MSILModule, Flags, "msil module"); 79*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 80*0b57cec5SDimitry Andric } 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric static std::string formatCompileSym3Flags(uint32_t IndentLevel, 83*0b57cec5SDimitry Andric CompileSym3Flags Flags) { 84*0b57cec5SDimitry Andric std::vector<std::string> Opts; 85*0b57cec5SDimitry Andric Flags &= ~CompileSym3Flags::SourceLanguageMask; 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric if (Flags == CompileSym3Flags::None) 88*0b57cec5SDimitry Andric return "none"; 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, EC, Flags, "edit and continue"); 91*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, NoDbgInfo, Flags, "no dbg info"); 92*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, LTCG, Flags, "ltcg"); 93*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, NoDataAlign, Flags, "no data align"); 94*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, ManagedPresent, Flags, "has managed code"); 95*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, SecurityChecks, Flags, "security checks"); 96*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, HotPatch, Flags, "hot patchable"); 97*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, CVTCIL, Flags, "cvtcil"); 98*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, MSILModule, Flags, "msil module"); 99*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, Sdl, Flags, "sdl"); 100*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, PGO, Flags, "pgo"); 101*0b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, Exp, Flags, "exp"); 102*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric static std::string formatFrameProcedureOptions(uint32_t IndentLevel, 106*0b57cec5SDimitry Andric FrameProcedureOptions FPO) { 107*0b57cec5SDimitry Andric std::vector<std::string> Opts; 108*0b57cec5SDimitry Andric if (FPO == FrameProcedureOptions::None) 109*0b57cec5SDimitry Andric return "none"; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasAlloca, FPO, "has alloca"); 112*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasSetJmp, FPO, "has setjmp"); 113*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasLongJmp, FPO, "has longjmp"); 114*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasInlineAssembly, FPO, "has inline asm"); 115*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasExceptionHandling, FPO, "has eh"); 116*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, MarkedInline, FPO, "marked inline"); 117*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasStructuredExceptionHandling, FPO, 118*0b57cec5SDimitry Andric "has seh"); 119*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, Naked, FPO, "naked"); 120*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, SecurityChecks, FPO, "secure checks"); 121*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, AsynchronousExceptionHandling, FPO, 122*0b57cec5SDimitry Andric "has async eh"); 123*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, NoStackOrderingForSecurityChecks, FPO, 124*0b57cec5SDimitry Andric "no stack order"); 125*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, Inlined, FPO, "inlined"); 126*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, StrictSecurityChecks, FPO, 127*0b57cec5SDimitry Andric "strict secure checks"); 128*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, SafeBuffers, FPO, "safe buffers"); 129*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, ProfileGuidedOptimization, FPO, "pgo"); 130*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, ValidProfileCounts, FPO, 131*0b57cec5SDimitry Andric "has profile counts"); 132*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, OptimizedForSpeed, FPO, "opt speed"); 133*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, GuardCfg, FPO, "guard cfg"); 134*0b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, GuardCfw, FPO, "guard cfw"); 135*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 136*0b57cec5SDimitry Andric } 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric static std::string formatPublicSymFlags(uint32_t IndentLevel, 139*0b57cec5SDimitry Andric PublicSymFlags Flags) { 140*0b57cec5SDimitry Andric std::vector<std::string> Opts; 141*0b57cec5SDimitry Andric if (Flags == PublicSymFlags::None) 142*0b57cec5SDimitry Andric return "none"; 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, Code, Flags, "code"); 145*0b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, Function, Flags, "function"); 146*0b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, Managed, Flags, "managed"); 147*0b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, MSIL, Flags, "msil"); 148*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 149*0b57cec5SDimitry Andric } 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric static std::string formatProcSymFlags(uint32_t IndentLevel, 152*0b57cec5SDimitry Andric ProcSymFlags Flags) { 153*0b57cec5SDimitry Andric std::vector<std::string> Opts; 154*0b57cec5SDimitry Andric if (Flags == ProcSymFlags::None) 155*0b57cec5SDimitry Andric return "none"; 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasFP, Flags, "has fp"); 158*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasIRET, Flags, "has iret"); 159*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasFRET, Flags, "has fret"); 160*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, IsNoReturn, Flags, "noreturn"); 161*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, IsUnreachable, Flags, "unreachable"); 162*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasCustomCallingConv, Flags, "custom calling conv"); 163*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, IsNoInline, Flags, "noinline"); 164*0b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasOptimizedDebugInfo, Flags, "opt debuginfo"); 165*0b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 166*0b57cec5SDimitry Andric } 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric static std::string formatThunkOrdinal(ThunkOrdinal Ordinal) { 169*0b57cec5SDimitry Andric switch (Ordinal) { 170*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, Standard, "thunk"); 171*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, ThisAdjustor, "this adjustor"); 172*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, Vcall, "vcall"); 173*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, Pcode, "pcode"); 174*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, UnknownLoad, "unknown load"); 175*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, TrampIncremental, "tramp incremental"); 176*0b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, BranchIsland, "branch island"); 177*0b57cec5SDimitry Andric } 178*0b57cec5SDimitry Andric return formatUnknownEnum(Ordinal); 179*0b57cec5SDimitry Andric } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric static std::string formatTrampolineType(TrampolineType Tramp) { 182*0b57cec5SDimitry Andric switch (Tramp) { 183*0b57cec5SDimitry Andric RETURN_CASE(TrampolineType, TrampIncremental, "tramp incremental"); 184*0b57cec5SDimitry Andric RETURN_CASE(TrampolineType, BranchIsland, "branch island"); 185*0b57cec5SDimitry Andric } 186*0b57cec5SDimitry Andric return formatUnknownEnum(Tramp); 187*0b57cec5SDimitry Andric } 188*0b57cec5SDimitry Andric 189*0b57cec5SDimitry Andric static std::string formatSourceLanguage(SourceLanguage Lang) { 190*0b57cec5SDimitry Andric switch (Lang) { 191*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, C, "c"); 192*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cpp, "c++"); 193*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Fortran, "fortran"); 194*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Masm, "masm"); 195*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Pascal, "pascal"); 196*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Basic, "basic"); 197*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cobol, "cobol"); 198*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Link, "link"); 199*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, VB, "vb"); 200*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cvtres, "cvtres"); 201*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cvtpgd, "cvtpgd"); 202*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, CSharp, "c#"); 203*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, ILAsm, "il asm"); 204*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Java, "java"); 205*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, JScript, "javascript"); 206*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, MSIL, "msil"); 207*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, HLSL, "hlsl"); 208*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, D, "d"); 209*0b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Swift, "swift"); 210*0b57cec5SDimitry Andric } 211*0b57cec5SDimitry Andric return formatUnknownEnum(Lang); 212*0b57cec5SDimitry Andric } 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric static std::string formatMachineType(CPUType Cpu) { 215*0b57cec5SDimitry Andric switch (Cpu) { 216*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel8080, "intel 8080"); 217*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel8086, "intel 8086"); 218*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel80286, "intel 80286"); 219*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel80386, "intel 80386"); 220*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel80486, "intel 80486"); 221*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Pentium, "intel pentium"); 222*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PentiumPro, "intel pentium pro"); 223*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Pentium3, "intel pentium 3"); 224*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS, "mips"); 225*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS16, "mips-16"); 226*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS32, "mips-32"); 227*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS64, "mips-64"); 228*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSI, "mips i"); 229*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSII, "mips ii"); 230*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSIII, "mips iii"); 231*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSIV, "mips iv"); 232*0b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSV, "mips v"); 233*0b57cec5SDimitry Andric RETURN_CASE(CPUType, M68000, "motorola 68000"); 234*0b57cec5SDimitry Andric RETURN_CASE(CPUType, M68010, "motorola 68010"); 235*0b57cec5SDimitry Andric RETURN_CASE(CPUType, M68020, "motorola 68020"); 236*0b57cec5SDimitry Andric RETURN_CASE(CPUType, M68030, "motorola 68030"); 237*0b57cec5SDimitry Andric RETURN_CASE(CPUType, M68040, "motorola 68040"); 238*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha, "alpha"); 239*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21164, "alpha 21164"); 240*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21164A, "alpha 21164a"); 241*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21264, "alpha 21264"); 242*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21364, "alpha 21364"); 243*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC601, "powerpc 601"); 244*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC603, "powerpc 603"); 245*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC604, "powerpc 604"); 246*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC620, "powerpc 620"); 247*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PPCFP, "powerpc fp"); 248*0b57cec5SDimitry Andric RETURN_CASE(CPUType, PPCBE, "powerpc be"); 249*0b57cec5SDimitry Andric RETURN_CASE(CPUType, SH3, "sh3"); 250*0b57cec5SDimitry Andric RETURN_CASE(CPUType, SH3E, "sh3e"); 251*0b57cec5SDimitry Andric RETURN_CASE(CPUType, SH3DSP, "sh3 dsp"); 252*0b57cec5SDimitry Andric RETURN_CASE(CPUType, SH4, "sh4"); 253*0b57cec5SDimitry Andric RETURN_CASE(CPUType, SHMedia, "shmedia"); 254*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM3, "arm 3"); 255*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM4, "arm 4"); 256*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM4T, "arm 4t"); 257*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM5, "arm 5"); 258*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM5T, "arm 5t"); 259*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM6, "arm 6"); 260*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM_XMAC, "arm xmac"); 261*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM_WMMX, "arm wmmx"); 262*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM7, "arm 7"); 263*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM64, "arm64"); 264*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Omni, "omni"); 265*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Ia64, "intel itanium ia64"); 266*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Ia64_2, "intel itanium ia64 2"); 267*0b57cec5SDimitry Andric RETURN_CASE(CPUType, CEE, "cee"); 268*0b57cec5SDimitry Andric RETURN_CASE(CPUType, AM33, "am33"); 269*0b57cec5SDimitry Andric RETURN_CASE(CPUType, M32R, "m32r"); 270*0b57cec5SDimitry Andric RETURN_CASE(CPUType, TriCore, "tri-core"); 271*0b57cec5SDimitry Andric RETURN_CASE(CPUType, X64, "intel x86-x64"); 272*0b57cec5SDimitry Andric RETURN_CASE(CPUType, EBC, "ebc"); 273*0b57cec5SDimitry Andric RETURN_CASE(CPUType, Thumb, "thumb"); 274*0b57cec5SDimitry Andric RETURN_CASE(CPUType, ARMNT, "arm nt"); 275*0b57cec5SDimitry Andric RETURN_CASE(CPUType, D3D11_Shader, "d3d11 shader"); 276*0b57cec5SDimitry Andric } 277*0b57cec5SDimitry Andric return formatUnknownEnum(Cpu); 278*0b57cec5SDimitry Andric } 279*0b57cec5SDimitry Andric 280*0b57cec5SDimitry Andric static std::string formatCookieKind(FrameCookieKind Kind) { 281*0b57cec5SDimitry Andric switch (Kind) { 282*0b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, Copy, "copy"); 283*0b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, XorStackPointer, "xor stack ptr"); 284*0b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, XorFramePointer, "xor frame ptr"); 285*0b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, XorR13, "xor rot13"); 286*0b57cec5SDimitry Andric } 287*0b57cec5SDimitry Andric return formatUnknownEnum(Kind); 288*0b57cec5SDimitry Andric } 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric static std::string formatRegisterId(RegisterId Id, CPUType Cpu) { 291*0b57cec5SDimitry Andric if (Cpu == CPUType::ARM64) { 292*0b57cec5SDimitry Andric switch (Id) { 293*0b57cec5SDimitry Andric #define CV_REGISTERS_ARM64 294*0b57cec5SDimitry Andric #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name) 295*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" 296*0b57cec5SDimitry Andric #undef CV_REGISTER 297*0b57cec5SDimitry Andric #undef CV_REGISTERS_ARM64 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric default: 300*0b57cec5SDimitry Andric break; 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric } else { 303*0b57cec5SDimitry Andric switch (Id) { 304*0b57cec5SDimitry Andric #define CV_REGISTERS_X86 305*0b57cec5SDimitry Andric #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name) 306*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" 307*0b57cec5SDimitry Andric #undef CV_REGISTER 308*0b57cec5SDimitry Andric #undef CV_REGISTERS_X86 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric default: 311*0b57cec5SDimitry Andric break; 312*0b57cec5SDimitry Andric } 313*0b57cec5SDimitry Andric } 314*0b57cec5SDimitry Andric return formatUnknownEnum(Id); 315*0b57cec5SDimitry Andric } 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric static std::string formatRegisterId(uint16_t Reg16, CPUType Cpu) { 318*0b57cec5SDimitry Andric return formatRegisterId(RegisterId(Reg16), Cpu); 319*0b57cec5SDimitry Andric } 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric static std::string formatRegisterId(ulittle16_t &Reg16, CPUType Cpu) { 322*0b57cec5SDimitry Andric return formatRegisterId(uint16_t(Reg16), Cpu); 323*0b57cec5SDimitry Andric } 324*0b57cec5SDimitry Andric 325*0b57cec5SDimitry Andric static std::string formatRange(LocalVariableAddrRange Range) { 326*0b57cec5SDimitry Andric return formatv("[{0},+{1})", 327*0b57cec5SDimitry Andric formatSegmentOffset(Range.ISectStart, Range.OffsetStart), 328*0b57cec5SDimitry Andric Range.Range) 329*0b57cec5SDimitry Andric .str(); 330*0b57cec5SDimitry Andric } 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric static std::string formatGaps(uint32_t IndentLevel, 333*0b57cec5SDimitry Andric ArrayRef<LocalVariableAddrGap> Gaps) { 334*0b57cec5SDimitry Andric std::vector<std::string> GapStrs; 335*0b57cec5SDimitry Andric for (const auto &G : Gaps) { 336*0b57cec5SDimitry Andric GapStrs.push_back(formatv("({0},{1})", G.GapStartOffset, G.Range).str()); 337*0b57cec5SDimitry Andric } 338*0b57cec5SDimitry Andric return typesetItemList(GapStrs, 7, IndentLevel, ", "); 339*0b57cec5SDimitry Andric } 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record) { 342*0b57cec5SDimitry Andric return visitSymbolBegin(Record, 0); 343*0b57cec5SDimitry Andric } 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record, 346*0b57cec5SDimitry Andric uint32_t Offset) { 347*0b57cec5SDimitry Andric // formatLine puts the newline at the beginning, so we use formatLine here 348*0b57cec5SDimitry Andric // to start a new line, and then individual visit methods use format to 349*0b57cec5SDimitry Andric // append to the existing line. 350*0b57cec5SDimitry Andric P.formatLine("{0} | {1} [size = {2}]", 351*0b57cec5SDimitry Andric fmt_align(Offset, AlignStyle::Right, 6), 352*0b57cec5SDimitry Andric formatSymbolKind(Record.kind()), Record.length()); 353*0b57cec5SDimitry Andric P.Indent(); 354*0b57cec5SDimitry Andric return Error::success(); 355*0b57cec5SDimitry Andric } 356*0b57cec5SDimitry Andric 357*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitSymbolEnd(CVSymbol &Record) { 358*0b57cec5SDimitry Andric if (RecordBytes) { 359*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 360*0b57cec5SDimitry Andric P.formatBinary("bytes", Record.content(), 0); 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric P.Unindent(); 363*0b57cec5SDimitry Andric return Error::success(); 364*0b57cec5SDimitry Andric } 365*0b57cec5SDimitry Andric 366*0b57cec5SDimitry Andric std::string MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI, 367*0b57cec5SDimitry Andric bool IsType) const { 368*0b57cec5SDimitry Andric if (TI.isSimple() || TI.isDecoratedItemId()) 369*0b57cec5SDimitry Andric return formatv("{0}", TI).str(); 370*0b57cec5SDimitry Andric auto &Container = IsType ? Types : Ids; 371*0b57cec5SDimitry Andric StringRef Name = Container.getTypeName(TI); 372*0b57cec5SDimitry Andric if (Name.size() > 32) { 373*0b57cec5SDimitry Andric Name = Name.take_front(32); 374*0b57cec5SDimitry Andric return formatv("{0} ({1}...)", TI, Name); 375*0b57cec5SDimitry Andric } else 376*0b57cec5SDimitry Andric return formatv("{0} ({1})", TI, Name); 377*0b57cec5SDimitry Andric } 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andric std::string MinimalSymbolDumper::idIndex(codeview::TypeIndex TI) const { 380*0b57cec5SDimitry Andric return typeOrIdIndex(TI, false); 381*0b57cec5SDimitry Andric } 382*0b57cec5SDimitry Andric 383*0b57cec5SDimitry Andric std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const { 384*0b57cec5SDimitry Andric return typeOrIdIndex(TI, true); 385*0b57cec5SDimitry Andric } 386*0b57cec5SDimitry Andric 387*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 388*0b57cec5SDimitry Andric P.format(" `{0}`", Block.Name); 389*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 390*0b57cec5SDimitry Andric P.formatLine("parent = {0}, end = {1}", Block.Parent, Block.End); 391*0b57cec5SDimitry Andric P.formatLine("code size = {0}, addr = {1}", Block.CodeSize, 392*0b57cec5SDimitry Andric formatSegmentOffset(Block.Segment, Block.CodeOffset)); 393*0b57cec5SDimitry Andric return Error::success(); 394*0b57cec5SDimitry Andric } 395*0b57cec5SDimitry Andric 396*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 397*0b57cec5SDimitry Andric P.format(" `{0}`", Thunk.Name); 398*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 399*0b57cec5SDimitry Andric P.formatLine("parent = {0}, end = {1}, next = {2}", Thunk.Parent, Thunk.End, 400*0b57cec5SDimitry Andric Thunk.Next); 401*0b57cec5SDimitry Andric P.formatLine("kind = {0}, size = {1}, addr = {2}", 402*0b57cec5SDimitry Andric formatThunkOrdinal(Thunk.Thunk), Thunk.Length, 403*0b57cec5SDimitry Andric formatSegmentOffset(Thunk.Segment, Thunk.Offset)); 404*0b57cec5SDimitry Andric 405*0b57cec5SDimitry Andric return Error::success(); 406*0b57cec5SDimitry Andric } 407*0b57cec5SDimitry Andric 408*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 409*0b57cec5SDimitry Andric TrampolineSym &Tramp) { 410*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 411*0b57cec5SDimitry Andric P.formatLine("type = {0}, size = {1}, source = {2}, target = {3}", 412*0b57cec5SDimitry Andric formatTrampolineType(Tramp.Type), Tramp.Size, 413*0b57cec5SDimitry Andric formatSegmentOffset(Tramp.ThunkSection, Tramp.ThunkOffset), 414*0b57cec5SDimitry Andric formatSegmentOffset(Tramp.TargetSection, Tramp.ThunkOffset)); 415*0b57cec5SDimitry Andric 416*0b57cec5SDimitry Andric return Error::success(); 417*0b57cec5SDimitry Andric } 418*0b57cec5SDimitry Andric 419*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 420*0b57cec5SDimitry Andric SectionSym &Section) { 421*0b57cec5SDimitry Andric P.format(" `{0}`", Section.Name); 422*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 423*0b57cec5SDimitry Andric P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}", 424*0b57cec5SDimitry Andric Section.Length, Section.Alignment, Section.Rva, 425*0b57cec5SDimitry Andric Section.SectionNumber); 426*0b57cec5SDimitry Andric P.printLine("characteristics ="); 427*0b57cec5SDimitry Andric AutoIndent Indent2(P, 2); 428*0b57cec5SDimitry Andric P.printLine(formatSectionCharacteristics(P.getIndentLevel(), 429*0b57cec5SDimitry Andric Section.Characteristics, 1, "", 430*0b57cec5SDimitry Andric CharacteristicStyle::Descriptive)); 431*0b57cec5SDimitry Andric return Error::success(); 432*0b57cec5SDimitry Andric } 433*0b57cec5SDimitry Andric 434*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CoffGroupSym &CG) { 435*0b57cec5SDimitry Andric P.format(" `{0}`", CG.Name); 436*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 437*0b57cec5SDimitry Andric P.formatLine("length = {0}, addr = {1}", CG.Size, 438*0b57cec5SDimitry Andric formatSegmentOffset(CG.Segment, CG.Offset)); 439*0b57cec5SDimitry Andric P.printLine("characteristics ="); 440*0b57cec5SDimitry Andric AutoIndent Indent2(P, 2); 441*0b57cec5SDimitry Andric P.printLine(formatSectionCharacteristics(P.getIndentLevel(), 442*0b57cec5SDimitry Andric CG.Characteristics, 1, "", 443*0b57cec5SDimitry Andric CharacteristicStyle::Descriptive)); 444*0b57cec5SDimitry Andric return Error::success(); 445*0b57cec5SDimitry Andric } 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 448*0b57cec5SDimitry Andric BPRelativeSym &BPRel) { 449*0b57cec5SDimitry Andric P.format(" `{0}`", BPRel.Name); 450*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 451*0b57cec5SDimitry Andric P.formatLine("type = {0}, offset = {1}", typeIndex(BPRel.Type), BPRel.Offset); 452*0b57cec5SDimitry Andric return Error::success(); 453*0b57cec5SDimitry Andric } 454*0b57cec5SDimitry Andric 455*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 456*0b57cec5SDimitry Andric BuildInfoSym &BuildInfo) { 457*0b57cec5SDimitry Andric P.format(" BuildId = `{0}`", BuildInfo.BuildId); 458*0b57cec5SDimitry Andric return Error::success(); 459*0b57cec5SDimitry Andric } 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 462*0b57cec5SDimitry Andric CallSiteInfoSym &CSI) { 463*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 464*0b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1}", typeIndex(CSI.Type), 465*0b57cec5SDimitry Andric formatSegmentOffset(CSI.Segment, CSI.CodeOffset)); 466*0b57cec5SDimitry Andric return Error::success(); 467*0b57cec5SDimitry Andric } 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 470*0b57cec5SDimitry Andric EnvBlockSym &EnvBlock) { 471*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 472*0b57cec5SDimitry Andric for (const auto &Entry : EnvBlock.Fields) { 473*0b57cec5SDimitry Andric P.formatLine("- {0}", Entry); 474*0b57cec5SDimitry Andric } 475*0b57cec5SDimitry Andric return Error::success(); 476*0b57cec5SDimitry Andric } 477*0b57cec5SDimitry Andric 478*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FileStaticSym &FS) { 479*0b57cec5SDimitry Andric P.format(" `{0}`", FS.Name); 480*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 481*0b57cec5SDimitry Andric if (SymGroup) { 482*0b57cec5SDimitry Andric Expected<StringRef> FileName = 483*0b57cec5SDimitry Andric SymGroup->getNameFromStringTable(FS.ModFilenameOffset); 484*0b57cec5SDimitry Andric if (FileName) { 485*0b57cec5SDimitry Andric P.formatLine("type = {0}, file name = {1} ({2}), flags = {3}", 486*0b57cec5SDimitry Andric typeIndex(FS.Index), FS.ModFilenameOffset, *FileName, 487*0b57cec5SDimitry Andric formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags)); 488*0b57cec5SDimitry Andric } 489*0b57cec5SDimitry Andric return Error::success(); 490*0b57cec5SDimitry Andric } 491*0b57cec5SDimitry Andric 492*0b57cec5SDimitry Andric P.formatLine("type = {0}, file name offset = {1}, flags = {2}", 493*0b57cec5SDimitry Andric typeIndex(FS.Index), FS.ModFilenameOffset, 494*0b57cec5SDimitry Andric formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags)); 495*0b57cec5SDimitry Andric return Error::success(); 496*0b57cec5SDimitry Andric } 497*0b57cec5SDimitry Andric 498*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) { 499*0b57cec5SDimitry Andric P.format(" `{0}`", Export.Name); 500*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 501*0b57cec5SDimitry Andric P.formatLine("ordinal = {0}, flags = {1}", Export.Ordinal, 502*0b57cec5SDimitry Andric formatExportFlags(P.getIndentLevel() + 9, Export.Flags)); 503*0b57cec5SDimitry Andric return Error::success(); 504*0b57cec5SDimitry Andric } 505*0b57cec5SDimitry Andric 506*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 507*0b57cec5SDimitry Andric Compile2Sym &Compile2) { 508*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 509*0b57cec5SDimitry Andric SourceLanguage Lang = static_cast<SourceLanguage>( 510*0b57cec5SDimitry Andric Compile2.Flags & CompileSym2Flags::SourceLanguageMask); 511*0b57cec5SDimitry Andric CompilationCPU = Compile2.Machine; 512*0b57cec5SDimitry Andric P.formatLine("machine = {0}, ver = {1}, language = {2}", 513*0b57cec5SDimitry Andric formatMachineType(Compile2.Machine), Compile2.Version, 514*0b57cec5SDimitry Andric formatSourceLanguage(Lang)); 515*0b57cec5SDimitry Andric P.formatLine("frontend = {0}.{1}.{2}, backend = {3}.{4}.{5}", 516*0b57cec5SDimitry Andric Compile2.VersionFrontendMajor, Compile2.VersionFrontendMinor, 517*0b57cec5SDimitry Andric Compile2.VersionFrontendBuild, Compile2.VersionBackendMajor, 518*0b57cec5SDimitry Andric Compile2.VersionBackendMinor, Compile2.VersionBackendBuild); 519*0b57cec5SDimitry Andric P.formatLine("flags = {0}", 520*0b57cec5SDimitry Andric formatCompileSym2Flags(P.getIndentLevel() + 9, Compile2.Flags)); 521*0b57cec5SDimitry Andric P.formatLine( 522*0b57cec5SDimitry Andric "extra strings = {0}", 523*0b57cec5SDimitry Andric typesetStringList(P.getIndentLevel() + 9 + 2, Compile2.ExtraStrings)); 524*0b57cec5SDimitry Andric return Error::success(); 525*0b57cec5SDimitry Andric } 526*0b57cec5SDimitry Andric 527*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 528*0b57cec5SDimitry Andric Compile3Sym &Compile3) { 529*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 530*0b57cec5SDimitry Andric SourceLanguage Lang = static_cast<SourceLanguage>( 531*0b57cec5SDimitry Andric Compile3.Flags & CompileSym3Flags::SourceLanguageMask); 532*0b57cec5SDimitry Andric CompilationCPU = Compile3.Machine; 533*0b57cec5SDimitry Andric P.formatLine("machine = {0}, Ver = {1}, language = {2}", 534*0b57cec5SDimitry Andric formatMachineType(Compile3.Machine), Compile3.Version, 535*0b57cec5SDimitry Andric formatSourceLanguage(Lang)); 536*0b57cec5SDimitry Andric P.formatLine("frontend = {0}.{1}.{2}.{3}, backend = {4}.{5}.{6}.{7}", 537*0b57cec5SDimitry Andric Compile3.VersionFrontendMajor, Compile3.VersionFrontendMinor, 538*0b57cec5SDimitry Andric Compile3.VersionFrontendBuild, Compile3.VersionFrontendQFE, 539*0b57cec5SDimitry Andric Compile3.VersionBackendMajor, Compile3.VersionBackendMinor, 540*0b57cec5SDimitry Andric Compile3.VersionBackendBuild, Compile3.VersionBackendQFE); 541*0b57cec5SDimitry Andric P.formatLine("flags = {0}", 542*0b57cec5SDimitry Andric formatCompileSym3Flags(P.getIndentLevel() + 9, Compile3.Flags)); 543*0b57cec5SDimitry Andric return Error::success(); 544*0b57cec5SDimitry Andric } 545*0b57cec5SDimitry Andric 546*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 547*0b57cec5SDimitry Andric ConstantSym &Constant) { 548*0b57cec5SDimitry Andric P.format(" `{0}`", Constant.Name); 549*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 550*0b57cec5SDimitry Andric P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type), 551*0b57cec5SDimitry Andric Constant.Value.toString(10)); 552*0b57cec5SDimitry Andric return Error::success(); 553*0b57cec5SDimitry Andric } 554*0b57cec5SDimitry Andric 555*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { 556*0b57cec5SDimitry Andric P.format(" `{0}`", Data.Name); 557*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 558*0b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type), 559*0b57cec5SDimitry Andric formatSegmentOffset(Data.Segment, Data.DataOffset)); 560*0b57cec5SDimitry Andric return Error::success(); 561*0b57cec5SDimitry Andric } 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord( 564*0b57cec5SDimitry Andric CVSymbol &CVR, DefRangeFramePointerRelFullScopeSym &Def) { 565*0b57cec5SDimitry Andric P.format(" offset = {0}", Def.Offset); 566*0b57cec5SDimitry Andric return Error::success(); 567*0b57cec5SDimitry Andric } 568*0b57cec5SDimitry Andric 569*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 570*0b57cec5SDimitry Andric DefRangeFramePointerRelSym &Def) { 571*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 572*0b57cec5SDimitry Andric P.formatLine("offset = {0}, range = {1}", Def.Offset, formatRange(Def.Range)); 573*0b57cec5SDimitry Andric P.formatLine("gaps = {2}", Def.Offset, 574*0b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 575*0b57cec5SDimitry Andric return Error::success(); 576*0b57cec5SDimitry Andric } 577*0b57cec5SDimitry Andric 578*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 579*0b57cec5SDimitry Andric DefRangeRegisterRelSym &Def) { 580*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 581*0b57cec5SDimitry Andric P.formatLine("register = {0}, offset = {1}, offset in parent = {2}, has " 582*0b57cec5SDimitry Andric "spilled udt = {3}", 583*0b57cec5SDimitry Andric formatRegisterId(Def.Hdr.Register, CompilationCPU), 584*0b57cec5SDimitry Andric int32_t(Def.Hdr.BasePointerOffset), Def.offsetInParent(), 585*0b57cec5SDimitry Andric Def.hasSpilledUDTMember()); 586*0b57cec5SDimitry Andric P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range), 587*0b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 588*0b57cec5SDimitry Andric return Error::success(); 589*0b57cec5SDimitry Andric } 590*0b57cec5SDimitry Andric 591*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord( 592*0b57cec5SDimitry Andric CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { 593*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 594*0b57cec5SDimitry Andric P.formatLine("register = {0}, may have no name = {1}, range start = " 595*0b57cec5SDimitry Andric "{2}, length = {3}", 596*0b57cec5SDimitry Andric formatRegisterId(DefRangeRegister.Hdr.Register, CompilationCPU), 597*0b57cec5SDimitry Andric bool(DefRangeRegister.Hdr.MayHaveNoName), 598*0b57cec5SDimitry Andric formatSegmentOffset(DefRangeRegister.Range.ISectStart, 599*0b57cec5SDimitry Andric DefRangeRegister.Range.OffsetStart), 600*0b57cec5SDimitry Andric DefRangeRegister.Range.Range); 601*0b57cec5SDimitry Andric P.formatLine("gaps = [{0}]", 602*0b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, DefRangeRegister.Gaps)); 603*0b57cec5SDimitry Andric return Error::success(); 604*0b57cec5SDimitry Andric } 605*0b57cec5SDimitry Andric 606*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 607*0b57cec5SDimitry Andric DefRangeSubfieldRegisterSym &Def) { 608*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 609*0b57cec5SDimitry Andric bool NoName = !!(Def.Hdr.MayHaveNoName == 0); 610*0b57cec5SDimitry Andric P.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}", 611*0b57cec5SDimitry Andric formatRegisterId(Def.Hdr.Register, CompilationCPU), NoName, 612*0b57cec5SDimitry Andric uint32_t(Def.Hdr.OffsetInParent)); 613*0b57cec5SDimitry Andric P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range), 614*0b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 615*0b57cec5SDimitry Andric return Error::success(); 616*0b57cec5SDimitry Andric } 617*0b57cec5SDimitry Andric 618*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 619*0b57cec5SDimitry Andric DefRangeSubfieldSym &Def) { 620*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 621*0b57cec5SDimitry Andric P.formatLine("program = {0}, offset in parent = {1}, range = {2}", 622*0b57cec5SDimitry Andric Def.Program, Def.OffsetInParent, formatRange(Def.Range)); 623*0b57cec5SDimitry Andric P.formatLine("gaps = {0}", formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 624*0b57cec5SDimitry Andric return Error::success(); 625*0b57cec5SDimitry Andric } 626*0b57cec5SDimitry Andric 627*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DefRangeSym &Def) { 628*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 629*0b57cec5SDimitry Andric P.formatLine("program = {0}, range = {1}", Def.Program, 630*0b57cec5SDimitry Andric formatRange(Def.Range)); 631*0b57cec5SDimitry Andric P.formatLine("gaps = {0}", formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 632*0b57cec5SDimitry Andric return Error::success(); 633*0b57cec5SDimitry Andric } 634*0b57cec5SDimitry Andric 635*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameCookieSym &FC) { 636*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 637*0b57cec5SDimitry Andric P.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}", 638*0b57cec5SDimitry Andric FC.CodeOffset, formatRegisterId(FC.Register, CompilationCPU), 639*0b57cec5SDimitry Andric formatCookieKind(FC.CookieKind), FC.Flags); 640*0b57cec5SDimitry Andric return Error::success(); 641*0b57cec5SDimitry Andric } 642*0b57cec5SDimitry Andric 643*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameProcSym &FP) { 644*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 645*0b57cec5SDimitry Andric P.formatLine("size = {0}, padding size = {1}, offset to padding = {2}", 646*0b57cec5SDimitry Andric FP.TotalFrameBytes, FP.PaddingFrameBytes, FP.OffsetToPadding); 647*0b57cec5SDimitry Andric P.formatLine("bytes of callee saved registers = {0}, exception handler addr " 648*0b57cec5SDimitry Andric "= {1}", 649*0b57cec5SDimitry Andric FP.BytesOfCalleeSavedRegisters, 650*0b57cec5SDimitry Andric formatSegmentOffset(FP.SectionIdOfExceptionHandler, 651*0b57cec5SDimitry Andric FP.OffsetOfExceptionHandler)); 652*0b57cec5SDimitry Andric P.formatLine( 653*0b57cec5SDimitry Andric "local fp reg = {0}, param fp reg = {1}", 654*0b57cec5SDimitry Andric formatRegisterId(FP.getLocalFramePtrReg(CompilationCPU), CompilationCPU), 655*0b57cec5SDimitry Andric formatRegisterId(FP.getParamFramePtrReg(CompilationCPU), CompilationCPU)); 656*0b57cec5SDimitry Andric P.formatLine("flags = {0}", 657*0b57cec5SDimitry Andric formatFrameProcedureOptions(P.getIndentLevel() + 9, FP.Flags)); 658*0b57cec5SDimitry Andric return Error::success(); 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric 661*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 662*0b57cec5SDimitry Andric HeapAllocationSiteSym &HAS) { 663*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 664*0b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1} call size = {2}", typeIndex(HAS.Type), 665*0b57cec5SDimitry Andric formatSegmentOffset(HAS.Segment, HAS.CodeOffset), 666*0b57cec5SDimitry Andric HAS.CallInstructionSize); 667*0b57cec5SDimitry Andric return Error::success(); 668*0b57cec5SDimitry Andric } 669*0b57cec5SDimitry Andric 670*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, InlineSiteSym &IS) { 671*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 672*0b57cec5SDimitry Andric P.formatLine("inlinee = {0}, parent = {1}, end = {2}", idIndex(IS.Inlinee), 673*0b57cec5SDimitry Andric IS.Parent, IS.End); 674*0b57cec5SDimitry Andric 675*0b57cec5SDimitry Andric // Break down the annotation byte code and calculate code and line offsets. 676*0b57cec5SDimitry Andric // FIXME: It would be helpful if we could look up the initial file and inlinee 677*0b57cec5SDimitry Andric // lines offset using the inlinee index above. 678*0b57cec5SDimitry Andric uint32_t CodeOffset = 0; 679*0b57cec5SDimitry Andric int32_t LineOffset = 0; 680*0b57cec5SDimitry Andric for (auto &Annot : IS.annotations()) { 681*0b57cec5SDimitry Andric P.formatLine(" {0}", fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9)); 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric auto formatCodeOffset = [&](uint32_t Delta) { 684*0b57cec5SDimitry Andric CodeOffset += Delta; 685*0b57cec5SDimitry Andric P.format(" code 0x{0} (+0x{1})", utohexstr(CodeOffset), utohexstr(Delta)); 686*0b57cec5SDimitry Andric }; 687*0b57cec5SDimitry Andric auto formatCodeLength = [&](uint32_t Length) { 688*0b57cec5SDimitry Andric // Notably, changing the code length does not affect the code offset. 689*0b57cec5SDimitry Andric P.format(" code end 0x{0} (+0x{1})", utohexstr(CodeOffset + Length), 690*0b57cec5SDimitry Andric utohexstr(Length)); 691*0b57cec5SDimitry Andric }; 692*0b57cec5SDimitry Andric auto formatLineOffset = [&](int32_t Delta) { 693*0b57cec5SDimitry Andric LineOffset += Delta; 694*0b57cec5SDimitry Andric char Sign = Delta > 0 ? '+' : '-'; 695*0b57cec5SDimitry Andric P.format(" line {0} ({1}{2})", LineOffset, Sign, std::abs(Delta)); 696*0b57cec5SDimitry Andric }; 697*0b57cec5SDimitry Andric 698*0b57cec5SDimitry Andric // Use the opcode to interpret the integer values. 699*0b57cec5SDimitry Andric switch (Annot.OpCode) { 700*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::Invalid: 701*0b57cec5SDimitry Andric break; 702*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::CodeOffset: 703*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeOffset: 704*0b57cec5SDimitry Andric formatCodeOffset(Annot.U1); 705*0b57cec5SDimitry Andric break; 706*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeLineOffset: 707*0b57cec5SDimitry Andric formatLineOffset(Annot.S1); 708*0b57cec5SDimitry Andric break; 709*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeLength: 710*0b57cec5SDimitry Andric formatCodeLength(Annot.U1); 711*0b57cec5SDimitry Andric // Apparently this annotation updates the code offset. It's hard to make 712*0b57cec5SDimitry Andric // MSVC produce this opcode, but clang uses it, and debuggers seem to use 713*0b57cec5SDimitry Andric // this interpretation. 714*0b57cec5SDimitry Andric CodeOffset += Annot.U1; 715*0b57cec5SDimitry Andric break; 716*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: 717*0b57cec5SDimitry Andric formatCodeOffset(Annot.U1); 718*0b57cec5SDimitry Andric formatLineOffset(Annot.S1); 719*0b57cec5SDimitry Andric break; 720*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: 721*0b57cec5SDimitry Andric formatCodeOffset(Annot.U2); 722*0b57cec5SDimitry Andric formatCodeLength(Annot.U1); 723*0b57cec5SDimitry Andric break; 724*0b57cec5SDimitry Andric 725*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeFile: { 726*0b57cec5SDimitry Andric uint32_t FileOffset = Annot.U1; 727*0b57cec5SDimitry Andric StringRef Filename = "<unknown>"; 728*0b57cec5SDimitry Andric if (SymGroup) { 729*0b57cec5SDimitry Andric if (Expected<StringRef> MaybeFile = 730*0b57cec5SDimitry Andric SymGroup->getNameFromStringTable(FileOffset)) 731*0b57cec5SDimitry Andric Filename = *MaybeFile; 732*0b57cec5SDimitry Andric else 733*0b57cec5SDimitry Andric return MaybeFile.takeError(); 734*0b57cec5SDimitry Andric } 735*0b57cec5SDimitry Andric P.format(" setfile {0} 0x{1}", utohexstr(FileOffset)); 736*0b57cec5SDimitry Andric break; 737*0b57cec5SDimitry Andric } 738*0b57cec5SDimitry Andric 739*0b57cec5SDimitry Andric // The rest of these are hard to convince MSVC to emit, so they are not as 740*0b57cec5SDimitry Andric // well understood. 741*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 742*0b57cec5SDimitry Andric formatCodeOffset(Annot.U1); 743*0b57cec5SDimitry Andric break; 744*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeLineEndDelta: 745*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeRangeKind: 746*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeColumnStart: 747*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeColumnEnd: 748*0b57cec5SDimitry Andric P.format(" {0} {1}", Annot.Name, Annot.U1); 749*0b57cec5SDimitry Andric break; 750*0b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 751*0b57cec5SDimitry Andric P.format(" {0} {1}", Annot.Name, Annot.S1); 752*0b57cec5SDimitry Andric break; 753*0b57cec5SDimitry Andric } 754*0b57cec5SDimitry Andric } 755*0b57cec5SDimitry Andric return Error::success(); 756*0b57cec5SDimitry Andric } 757*0b57cec5SDimitry Andric 758*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 759*0b57cec5SDimitry Andric RegisterSym &Register) { 760*0b57cec5SDimitry Andric P.format(" `{0}`", Register.Name); 761*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 762*0b57cec5SDimitry Andric P.formatLine("register = {0}, type = {1}", 763*0b57cec5SDimitry Andric formatRegisterId(Register.Register, CompilationCPU), 764*0b57cec5SDimitry Andric typeIndex(Register.Index)); 765*0b57cec5SDimitry Andric return Error::success(); 766*0b57cec5SDimitry Andric } 767*0b57cec5SDimitry Andric 768*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 769*0b57cec5SDimitry Andric PublicSym32 &Public) { 770*0b57cec5SDimitry Andric P.format(" `{0}`", Public.Name); 771*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 772*0b57cec5SDimitry Andric P.formatLine("flags = {0}, addr = {1}", 773*0b57cec5SDimitry Andric formatPublicSymFlags(P.getIndentLevel() + 9, Public.Flags), 774*0b57cec5SDimitry Andric formatSegmentOffset(Public.Segment, Public.Offset)); 775*0b57cec5SDimitry Andric return Error::success(); 776*0b57cec5SDimitry Andric } 777*0b57cec5SDimitry Andric 778*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcRefSym &PR) { 779*0b57cec5SDimitry Andric P.format(" `{0}`", PR.Name); 780*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 781*0b57cec5SDimitry Andric P.formatLine("module = {0}, sum name = {1}, offset = {2}", PR.Module, 782*0b57cec5SDimitry Andric PR.SumName, PR.SymOffset); 783*0b57cec5SDimitry Andric return Error::success(); 784*0b57cec5SDimitry Andric } 785*0b57cec5SDimitry Andric 786*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 787*0b57cec5SDimitry Andric P.format(" `{0}` (addr = {1})", Label.Name, 788*0b57cec5SDimitry Andric formatSegmentOffset(Label.Segment, Label.CodeOffset)); 789*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 790*0b57cec5SDimitry Andric P.formatLine("flags = {0}", 791*0b57cec5SDimitry Andric formatProcSymFlags(P.getIndentLevel() + 9, Label.Flags)); 792*0b57cec5SDimitry Andric return Error::success(); 793*0b57cec5SDimitry Andric } 794*0b57cec5SDimitry Andric 795*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 796*0b57cec5SDimitry Andric P.format(" `{0}`", Local.Name); 797*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 798*0b57cec5SDimitry Andric 799*0b57cec5SDimitry Andric std::string FlagStr = 800*0b57cec5SDimitry Andric formatLocalSymFlags(P.getIndentLevel() + 9, Local.Flags); 801*0b57cec5SDimitry Andric P.formatLine("type={0}, flags = {1}", typeIndex(Local.Type), FlagStr); 802*0b57cec5SDimitry Andric return Error::success(); 803*0b57cec5SDimitry Andric } 804*0b57cec5SDimitry Andric 805*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 806*0b57cec5SDimitry Andric ObjNameSym &ObjName) { 807*0b57cec5SDimitry Andric P.format(" sig={0}, `{1}`", ObjName.Signature, ObjName.Name); 808*0b57cec5SDimitry Andric return Error::success(); 809*0b57cec5SDimitry Andric } 810*0b57cec5SDimitry Andric 811*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 812*0b57cec5SDimitry Andric P.format(" `{0}`", Proc.Name); 813*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 814*0b57cec5SDimitry Andric P.formatLine("parent = {0}, end = {1}, addr = {2}, code size = {3}", 815*0b57cec5SDimitry Andric Proc.Parent, Proc.End, 816*0b57cec5SDimitry Andric formatSegmentOffset(Proc.Segment, Proc.CodeOffset), 817*0b57cec5SDimitry Andric Proc.CodeSize); 818*0b57cec5SDimitry Andric bool IsType = true; 819*0b57cec5SDimitry Andric switch (Proc.getKind()) { 820*0b57cec5SDimitry Andric case SymbolRecordKind::GlobalProcIdSym: 821*0b57cec5SDimitry Andric case SymbolRecordKind::ProcIdSym: 822*0b57cec5SDimitry Andric case SymbolRecordKind::DPCProcIdSym: 823*0b57cec5SDimitry Andric IsType = false; 824*0b57cec5SDimitry Andric break; 825*0b57cec5SDimitry Andric default: 826*0b57cec5SDimitry Andric break; 827*0b57cec5SDimitry Andric } 828*0b57cec5SDimitry Andric P.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}", 829*0b57cec5SDimitry Andric typeOrIdIndex(Proc.FunctionType, IsType), Proc.DbgStart, 830*0b57cec5SDimitry Andric Proc.DbgEnd, 831*0b57cec5SDimitry Andric formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags)); 832*0b57cec5SDimitry Andric return Error::success(); 833*0b57cec5SDimitry Andric } 834*0b57cec5SDimitry Andric 835*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 836*0b57cec5SDimitry Andric ScopeEndSym &ScopeEnd) { 837*0b57cec5SDimitry Andric return Error::success(); 838*0b57cec5SDimitry Andric } 839*0b57cec5SDimitry Andric 840*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 841*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 842*0b57cec5SDimitry Andric for (const auto &I : Caller.Indices) { 843*0b57cec5SDimitry Andric P.formatLine("callee: {0}", idIndex(I)); 844*0b57cec5SDimitry Andric } 845*0b57cec5SDimitry Andric return Error::success(); 846*0b57cec5SDimitry Andric } 847*0b57cec5SDimitry Andric 848*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 849*0b57cec5SDimitry Andric RegRelativeSym &RegRel) { 850*0b57cec5SDimitry Andric P.format(" `{0}`", RegRel.Name); 851*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 852*0b57cec5SDimitry Andric P.formatLine( 853*0b57cec5SDimitry Andric "type = {0}, register = {1}, offset = {2}", typeIndex(RegRel.Type), 854*0b57cec5SDimitry Andric formatRegisterId(RegRel.Register, CompilationCPU), RegRel.Offset); 855*0b57cec5SDimitry Andric return Error::success(); 856*0b57cec5SDimitry Andric } 857*0b57cec5SDimitry Andric 858*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 859*0b57cec5SDimitry Andric ThreadLocalDataSym &Data) { 860*0b57cec5SDimitry Andric P.format(" `{0}`", Data.Name); 861*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 862*0b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type), 863*0b57cec5SDimitry Andric formatSegmentOffset(Data.Segment, Data.DataOffset)); 864*0b57cec5SDimitry Andric return Error::success(); 865*0b57cec5SDimitry Andric } 866*0b57cec5SDimitry Andric 867*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 868*0b57cec5SDimitry Andric P.format(" `{0}`", UDT.Name); 869*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 870*0b57cec5SDimitry Andric P.formatLine("original type = {0}", UDT.Type); 871*0b57cec5SDimitry Andric return Error::success(); 872*0b57cec5SDimitry Andric } 873*0b57cec5SDimitry Andric 874*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 875*0b57cec5SDimitry Andric UsingNamespaceSym &UN) { 876*0b57cec5SDimitry Andric P.format(" `{0}`", UN.Name); 877*0b57cec5SDimitry Andric return Error::success(); 878*0b57cec5SDimitry Andric } 879*0b57cec5SDimitry Andric 880*0b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 881*0b57cec5SDimitry Andric AnnotationSym &Annot) { 882*0b57cec5SDimitry Andric AutoIndent Indent(P, 7); 883*0b57cec5SDimitry Andric P.formatLine("addr = {0}", formatSegmentOffset(Annot.Segment, Annot.CodeOffset)); 884*0b57cec5SDimitry Andric P.formatLine("strings = {0}", typesetStringList(P.getIndentLevel() + 9 + 2, 885*0b57cec5SDimitry Andric Annot.Strings)); 886*0b57cec5SDimitry Andric return Error::success(); 887*0b57cec5SDimitry Andric } 888