10b57cec5SDimitry Andric //===- MinimalSymbolDumper.cpp -------------------------------- *- C++ --*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "MinimalSymbolDumper.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "FormatUtil.h" 120b57cec5SDimitry Andric #include "InputFile.h" 130b57cec5SDimitry Andric #include "LinePrinter.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVRecord.h" 160b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 170b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/Formatters.h" 180b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" 190b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 200b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h" 210b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" 220b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace llvm; 250b57cec5SDimitry Andric using namespace llvm::codeview; 260b57cec5SDimitry Andric using namespace llvm::pdb; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric static std::string formatLocalSymFlags(uint32_t IndentLevel, 290b57cec5SDimitry Andric LocalSymFlags Flags) { 300b57cec5SDimitry Andric std::vector<std::string> Opts; 310b57cec5SDimitry Andric if (Flags == LocalSymFlags::None) 320b57cec5SDimitry Andric return "none"; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsParameter, Flags, "param"); 350b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAddressTaken, Flags, "address is taken"); 360b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsCompilerGenerated, Flags, "compiler generated"); 370b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAggregate, Flags, "aggregate"); 380b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAggregated, Flags, "aggregated"); 390b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAliased, Flags, "aliased"); 400b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsAlias, Flags, "alias"); 410b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsReturnValue, Flags, "return val"); 420b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsOptimizedOut, Flags, "optimized away"); 430b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsEnregisteredGlobal, Flags, "enreg global"); 440b57cec5SDimitry Andric PUSH_FLAG(LocalSymFlags, IsEnregisteredStatic, Flags, "enreg static"); 450b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric static std::string formatExportFlags(uint32_t IndentLevel, ExportFlags Flags) { 490b57cec5SDimitry Andric std::vector<std::string> Opts; 500b57cec5SDimitry Andric if (Flags == ExportFlags::None) 510b57cec5SDimitry Andric return "none"; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsConstant, Flags, "constant"); 540b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsData, Flags, "data"); 550b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsPrivate, Flags, "private"); 560b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, HasNoName, Flags, "no name"); 570b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, HasExplicitOrdinal, Flags, "explicit ord"); 580b57cec5SDimitry Andric PUSH_FLAG(ExportFlags, IsForwarder, Flags, "forwarder"); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric static std::string formatCompileSym2Flags(uint32_t IndentLevel, 640b57cec5SDimitry Andric CompileSym2Flags Flags) { 650b57cec5SDimitry Andric std::vector<std::string> Opts; 660b57cec5SDimitry Andric Flags &= ~CompileSym2Flags::SourceLanguageMask; 670b57cec5SDimitry Andric if (Flags == CompileSym2Flags::None) 680b57cec5SDimitry Andric return "none"; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, EC, Flags, "edit and continue"); 710b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, NoDbgInfo, Flags, "no dbg info"); 720b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, LTCG, Flags, "ltcg"); 730b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, NoDataAlign, Flags, "no data align"); 740b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, ManagedPresent, Flags, "has managed code"); 750b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, SecurityChecks, Flags, "security checks"); 760b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, HotPatch, Flags, "hot patchable"); 770b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, CVTCIL, Flags, "cvtcil"); 780b57cec5SDimitry Andric PUSH_FLAG(CompileSym2Flags, MSILModule, Flags, "msil module"); 790b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric static std::string formatCompileSym3Flags(uint32_t IndentLevel, 830b57cec5SDimitry Andric CompileSym3Flags Flags) { 840b57cec5SDimitry Andric std::vector<std::string> Opts; 850b57cec5SDimitry Andric Flags &= ~CompileSym3Flags::SourceLanguageMask; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric if (Flags == CompileSym3Flags::None) 880b57cec5SDimitry Andric return "none"; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, EC, Flags, "edit and continue"); 910b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, NoDbgInfo, Flags, "no dbg info"); 920b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, LTCG, Flags, "ltcg"); 930b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, NoDataAlign, Flags, "no data align"); 940b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, ManagedPresent, Flags, "has managed code"); 950b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, SecurityChecks, Flags, "security checks"); 960b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, HotPatch, Flags, "hot patchable"); 970b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, CVTCIL, Flags, "cvtcil"); 980b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, MSILModule, Flags, "msil module"); 990b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, Sdl, Flags, "sdl"); 1000b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, PGO, Flags, "pgo"); 1010b57cec5SDimitry Andric PUSH_FLAG(CompileSym3Flags, Exp, Flags, "exp"); 1020b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric static std::string formatFrameProcedureOptions(uint32_t IndentLevel, 1060b57cec5SDimitry Andric FrameProcedureOptions FPO) { 1070b57cec5SDimitry Andric std::vector<std::string> Opts; 1080b57cec5SDimitry Andric if (FPO == FrameProcedureOptions::None) 1090b57cec5SDimitry Andric return "none"; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasAlloca, FPO, "has alloca"); 1120b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasSetJmp, FPO, "has setjmp"); 1130b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasLongJmp, FPO, "has longjmp"); 1140b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasInlineAssembly, FPO, "has inline asm"); 1150b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasExceptionHandling, FPO, "has eh"); 1160b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, MarkedInline, FPO, "marked inline"); 1170b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, HasStructuredExceptionHandling, FPO, 1180b57cec5SDimitry Andric "has seh"); 1190b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, Naked, FPO, "naked"); 1200b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, SecurityChecks, FPO, "secure checks"); 1210b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, AsynchronousExceptionHandling, FPO, 1220b57cec5SDimitry Andric "has async eh"); 1230b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, NoStackOrderingForSecurityChecks, FPO, 1240b57cec5SDimitry Andric "no stack order"); 1250b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, Inlined, FPO, "inlined"); 1260b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, StrictSecurityChecks, FPO, 1270b57cec5SDimitry Andric "strict secure checks"); 1280b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, SafeBuffers, FPO, "safe buffers"); 1290b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, ProfileGuidedOptimization, FPO, "pgo"); 1300b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, ValidProfileCounts, FPO, 1310b57cec5SDimitry Andric "has profile counts"); 1320b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, OptimizedForSpeed, FPO, "opt speed"); 1330b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, GuardCfg, FPO, "guard cfg"); 1340b57cec5SDimitry Andric PUSH_FLAG(FrameProcedureOptions, GuardCfw, FPO, "guard cfw"); 1350b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric static std::string formatPublicSymFlags(uint32_t IndentLevel, 1390b57cec5SDimitry Andric PublicSymFlags Flags) { 1400b57cec5SDimitry Andric std::vector<std::string> Opts; 1410b57cec5SDimitry Andric if (Flags == PublicSymFlags::None) 1420b57cec5SDimitry Andric return "none"; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, Code, Flags, "code"); 1450b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, Function, Flags, "function"); 1460b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, Managed, Flags, "managed"); 1470b57cec5SDimitry Andric PUSH_FLAG(PublicSymFlags, MSIL, Flags, "msil"); 1480b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric static std::string formatProcSymFlags(uint32_t IndentLevel, 1520b57cec5SDimitry Andric ProcSymFlags Flags) { 1530b57cec5SDimitry Andric std::vector<std::string> Opts; 1540b57cec5SDimitry Andric if (Flags == ProcSymFlags::None) 1550b57cec5SDimitry Andric return "none"; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasFP, Flags, "has fp"); 1580b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasIRET, Flags, "has iret"); 1590b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasFRET, Flags, "has fret"); 1600b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, IsNoReturn, Flags, "noreturn"); 1610b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, IsUnreachable, Flags, "unreachable"); 1620b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasCustomCallingConv, Flags, "custom calling conv"); 1630b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, IsNoInline, Flags, "noinline"); 1640b57cec5SDimitry Andric PUSH_FLAG(ProcSymFlags, HasOptimizedDebugInfo, Flags, "opt debuginfo"); 1650b57cec5SDimitry Andric return typesetItemList(Opts, 4, IndentLevel, " | "); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric static std::string formatThunkOrdinal(ThunkOrdinal Ordinal) { 1690b57cec5SDimitry Andric switch (Ordinal) { 1700b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, Standard, "thunk"); 1710b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, ThisAdjustor, "this adjustor"); 1720b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, Vcall, "vcall"); 1730b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, Pcode, "pcode"); 1740b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, UnknownLoad, "unknown load"); 1750b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, TrampIncremental, "tramp incremental"); 1760b57cec5SDimitry Andric RETURN_CASE(ThunkOrdinal, BranchIsland, "branch island"); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric return formatUnknownEnum(Ordinal); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric static std::string formatTrampolineType(TrampolineType Tramp) { 1820b57cec5SDimitry Andric switch (Tramp) { 1830b57cec5SDimitry Andric RETURN_CASE(TrampolineType, TrampIncremental, "tramp incremental"); 1840b57cec5SDimitry Andric RETURN_CASE(TrampolineType, BranchIsland, "branch island"); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric return formatUnknownEnum(Tramp); 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric static std::string formatSourceLanguage(SourceLanguage Lang) { 1900b57cec5SDimitry Andric switch (Lang) { 1910b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, C, "c"); 1920b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cpp, "c++"); 1930b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Fortran, "fortran"); 1940b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Masm, "masm"); 1950b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Pascal, "pascal"); 1960b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Basic, "basic"); 1970b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cobol, "cobol"); 1980b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Link, "link"); 1990b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, VB, "vb"); 2000b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cvtres, "cvtres"); 2010b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Cvtpgd, "cvtpgd"); 2020b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, CSharp, "c#"); 2030b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, ILAsm, "il asm"); 2040b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Java, "java"); 2050b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, JScript, "javascript"); 2060b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, MSIL, "msil"); 2070b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, HLSL, "hlsl"); 2080b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, D, "d"); 2090b57cec5SDimitry Andric RETURN_CASE(SourceLanguage, Swift, "swift"); 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric return formatUnknownEnum(Lang); 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric static std::string formatMachineType(CPUType Cpu) { 2150b57cec5SDimitry Andric switch (Cpu) { 2160b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel8080, "intel 8080"); 2170b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel8086, "intel 8086"); 2180b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel80286, "intel 80286"); 2190b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel80386, "intel 80386"); 2200b57cec5SDimitry Andric RETURN_CASE(CPUType, Intel80486, "intel 80486"); 2210b57cec5SDimitry Andric RETURN_CASE(CPUType, Pentium, "intel pentium"); 2220b57cec5SDimitry Andric RETURN_CASE(CPUType, PentiumPro, "intel pentium pro"); 2230b57cec5SDimitry Andric RETURN_CASE(CPUType, Pentium3, "intel pentium 3"); 2240b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS, "mips"); 2250b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS16, "mips-16"); 2260b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS32, "mips-32"); 2270b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPS64, "mips-64"); 2280b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSI, "mips i"); 2290b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSII, "mips ii"); 2300b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSIII, "mips iii"); 2310b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSIV, "mips iv"); 2320b57cec5SDimitry Andric RETURN_CASE(CPUType, MIPSV, "mips v"); 2330b57cec5SDimitry Andric RETURN_CASE(CPUType, M68000, "motorola 68000"); 2340b57cec5SDimitry Andric RETURN_CASE(CPUType, M68010, "motorola 68010"); 2350b57cec5SDimitry Andric RETURN_CASE(CPUType, M68020, "motorola 68020"); 2360b57cec5SDimitry Andric RETURN_CASE(CPUType, M68030, "motorola 68030"); 2370b57cec5SDimitry Andric RETURN_CASE(CPUType, M68040, "motorola 68040"); 2380b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha, "alpha"); 2390b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21164, "alpha 21164"); 2400b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21164A, "alpha 21164a"); 2410b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21264, "alpha 21264"); 2420b57cec5SDimitry Andric RETURN_CASE(CPUType, Alpha21364, "alpha 21364"); 2430b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC601, "powerpc 601"); 2440b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC603, "powerpc 603"); 2450b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC604, "powerpc 604"); 2460b57cec5SDimitry Andric RETURN_CASE(CPUType, PPC620, "powerpc 620"); 2470b57cec5SDimitry Andric RETURN_CASE(CPUType, PPCFP, "powerpc fp"); 2480b57cec5SDimitry Andric RETURN_CASE(CPUType, PPCBE, "powerpc be"); 2490b57cec5SDimitry Andric RETURN_CASE(CPUType, SH3, "sh3"); 2500b57cec5SDimitry Andric RETURN_CASE(CPUType, SH3E, "sh3e"); 2510b57cec5SDimitry Andric RETURN_CASE(CPUType, SH3DSP, "sh3 dsp"); 2520b57cec5SDimitry Andric RETURN_CASE(CPUType, SH4, "sh4"); 2530b57cec5SDimitry Andric RETURN_CASE(CPUType, SHMedia, "shmedia"); 2540b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM3, "arm 3"); 2550b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM4, "arm 4"); 2560b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM4T, "arm 4t"); 2570b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM5, "arm 5"); 2580b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM5T, "arm 5t"); 2590b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM6, "arm 6"); 2600b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM_XMAC, "arm xmac"); 2610b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM_WMMX, "arm wmmx"); 2620b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM7, "arm 7"); 2630b57cec5SDimitry Andric RETURN_CASE(CPUType, ARM64, "arm64"); 2640b57cec5SDimitry Andric RETURN_CASE(CPUType, Omni, "omni"); 2650b57cec5SDimitry Andric RETURN_CASE(CPUType, Ia64, "intel itanium ia64"); 2660b57cec5SDimitry Andric RETURN_CASE(CPUType, Ia64_2, "intel itanium ia64 2"); 2670b57cec5SDimitry Andric RETURN_CASE(CPUType, CEE, "cee"); 2680b57cec5SDimitry Andric RETURN_CASE(CPUType, AM33, "am33"); 2690b57cec5SDimitry Andric RETURN_CASE(CPUType, M32R, "m32r"); 2700b57cec5SDimitry Andric RETURN_CASE(CPUType, TriCore, "tri-core"); 2710b57cec5SDimitry Andric RETURN_CASE(CPUType, X64, "intel x86-x64"); 2720b57cec5SDimitry Andric RETURN_CASE(CPUType, EBC, "ebc"); 2730b57cec5SDimitry Andric RETURN_CASE(CPUType, Thumb, "thumb"); 2740b57cec5SDimitry Andric RETURN_CASE(CPUType, ARMNT, "arm nt"); 2750b57cec5SDimitry Andric RETURN_CASE(CPUType, D3D11_Shader, "d3d11 shader"); 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric return formatUnknownEnum(Cpu); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric static std::string formatCookieKind(FrameCookieKind Kind) { 2810b57cec5SDimitry Andric switch (Kind) { 2820b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, Copy, "copy"); 2830b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, XorStackPointer, "xor stack ptr"); 2840b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, XorFramePointer, "xor frame ptr"); 2850b57cec5SDimitry Andric RETURN_CASE(FrameCookieKind, XorR13, "xor rot13"); 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric return formatUnknownEnum(Kind); 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric static std::string formatRegisterId(RegisterId Id, CPUType Cpu) { 2910b57cec5SDimitry Andric if (Cpu == CPUType::ARM64) { 2920b57cec5SDimitry Andric switch (Id) { 2930b57cec5SDimitry Andric #define CV_REGISTERS_ARM64 2940b57cec5SDimitry Andric #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name) 2950b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" 2960b57cec5SDimitry Andric #undef CV_REGISTER 2970b57cec5SDimitry Andric #undef CV_REGISTERS_ARM64 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric default: 3000b57cec5SDimitry Andric break; 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric } else { 3030b57cec5SDimitry Andric switch (Id) { 3040b57cec5SDimitry Andric #define CV_REGISTERS_X86 3050b57cec5SDimitry Andric #define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name) 3060b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" 3070b57cec5SDimitry Andric #undef CV_REGISTER 3080b57cec5SDimitry Andric #undef CV_REGISTERS_X86 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric default: 3110b57cec5SDimitry Andric break; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric return formatUnknownEnum(Id); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric static std::string formatRegisterId(uint16_t Reg16, CPUType Cpu) { 3180b57cec5SDimitry Andric return formatRegisterId(RegisterId(Reg16), Cpu); 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric static std::string formatRegisterId(ulittle16_t &Reg16, CPUType Cpu) { 3220b57cec5SDimitry Andric return formatRegisterId(uint16_t(Reg16), Cpu); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric static std::string formatRange(LocalVariableAddrRange Range) { 3260b57cec5SDimitry Andric return formatv("[{0},+{1})", 3270b57cec5SDimitry Andric formatSegmentOffset(Range.ISectStart, Range.OffsetStart), 3280b57cec5SDimitry Andric Range.Range) 3290b57cec5SDimitry Andric .str(); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric static std::string formatGaps(uint32_t IndentLevel, 3330b57cec5SDimitry Andric ArrayRef<LocalVariableAddrGap> Gaps) { 3340b57cec5SDimitry Andric std::vector<std::string> GapStrs; 3350b57cec5SDimitry Andric for (const auto &G : Gaps) { 3360b57cec5SDimitry Andric GapStrs.push_back(formatv("({0},{1})", G.GapStartOffset, G.Range).str()); 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric return typesetItemList(GapStrs, 7, IndentLevel, ", "); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record) { 3420b57cec5SDimitry Andric return visitSymbolBegin(Record, 0); 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record, 3460b57cec5SDimitry Andric uint32_t Offset) { 3470b57cec5SDimitry Andric // formatLine puts the newline at the beginning, so we use formatLine here 3480b57cec5SDimitry Andric // to start a new line, and then individual visit methods use format to 3490b57cec5SDimitry Andric // append to the existing line. 3500b57cec5SDimitry Andric P.formatLine("{0} | {1} [size = {2}]", 3510b57cec5SDimitry Andric fmt_align(Offset, AlignStyle::Right, 6), 3520b57cec5SDimitry Andric formatSymbolKind(Record.kind()), Record.length()); 3530b57cec5SDimitry Andric P.Indent(); 3540b57cec5SDimitry Andric return Error::success(); 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric Error MinimalSymbolDumper::visitSymbolEnd(CVSymbol &Record) { 3580b57cec5SDimitry Andric if (RecordBytes) { 3590b57cec5SDimitry Andric AutoIndent Indent(P, 7); 3600b57cec5SDimitry Andric P.formatBinary("bytes", Record.content(), 0); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric P.Unindent(); 3630b57cec5SDimitry Andric return Error::success(); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric std::string MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI, 3670b57cec5SDimitry Andric bool IsType) const { 3680b57cec5SDimitry Andric if (TI.isSimple() || TI.isDecoratedItemId()) 3690b57cec5SDimitry Andric return formatv("{0}", TI).str(); 3700b57cec5SDimitry Andric auto &Container = IsType ? Types : Ids; 3710b57cec5SDimitry Andric StringRef Name = Container.getTypeName(TI); 3720b57cec5SDimitry Andric if (Name.size() > 32) { 3730b57cec5SDimitry Andric Name = Name.take_front(32); 3740b57cec5SDimitry Andric return formatv("{0} ({1}...)", TI, Name); 3750b57cec5SDimitry Andric } else 3760b57cec5SDimitry Andric return formatv("{0} ({1})", TI, Name); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric std::string MinimalSymbolDumper::idIndex(codeview::TypeIndex TI) const { 3800b57cec5SDimitry Andric return typeOrIdIndex(TI, false); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const { 3840b57cec5SDimitry Andric return typeOrIdIndex(TI, true); 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 3880b57cec5SDimitry Andric P.format(" `{0}`", Block.Name); 3890b57cec5SDimitry Andric AutoIndent Indent(P, 7); 3900b57cec5SDimitry Andric P.formatLine("parent = {0}, end = {1}", Block.Parent, Block.End); 3910b57cec5SDimitry Andric P.formatLine("code size = {0}, addr = {1}", Block.CodeSize, 3920b57cec5SDimitry Andric formatSegmentOffset(Block.Segment, Block.CodeOffset)); 3930b57cec5SDimitry Andric return Error::success(); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 3970b57cec5SDimitry Andric P.format(" `{0}`", Thunk.Name); 3980b57cec5SDimitry Andric AutoIndent Indent(P, 7); 3990b57cec5SDimitry Andric P.formatLine("parent = {0}, end = {1}, next = {2}", Thunk.Parent, Thunk.End, 4000b57cec5SDimitry Andric Thunk.Next); 4010b57cec5SDimitry Andric P.formatLine("kind = {0}, size = {1}, addr = {2}", 4020b57cec5SDimitry Andric formatThunkOrdinal(Thunk.Thunk), Thunk.Length, 4030b57cec5SDimitry Andric formatSegmentOffset(Thunk.Segment, Thunk.Offset)); 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric return Error::success(); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 4090b57cec5SDimitry Andric TrampolineSym &Tramp) { 4100b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4110b57cec5SDimitry Andric P.formatLine("type = {0}, size = {1}, source = {2}, target = {3}", 4120b57cec5SDimitry Andric formatTrampolineType(Tramp.Type), Tramp.Size, 4130b57cec5SDimitry Andric formatSegmentOffset(Tramp.ThunkSection, Tramp.ThunkOffset), 4140b57cec5SDimitry Andric formatSegmentOffset(Tramp.TargetSection, Tramp.ThunkOffset)); 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric return Error::success(); 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 4200b57cec5SDimitry Andric SectionSym &Section) { 4210b57cec5SDimitry Andric P.format(" `{0}`", Section.Name); 4220b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4230b57cec5SDimitry Andric P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}", 4240b57cec5SDimitry Andric Section.Length, Section.Alignment, Section.Rva, 4250b57cec5SDimitry Andric Section.SectionNumber); 4260b57cec5SDimitry Andric P.printLine("characteristics ="); 4270b57cec5SDimitry Andric AutoIndent Indent2(P, 2); 4280b57cec5SDimitry Andric P.printLine(formatSectionCharacteristics(P.getIndentLevel(), 4290b57cec5SDimitry Andric Section.Characteristics, 1, "", 4300b57cec5SDimitry Andric CharacteristicStyle::Descriptive)); 4310b57cec5SDimitry Andric return Error::success(); 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CoffGroupSym &CG) { 4350b57cec5SDimitry Andric P.format(" `{0}`", CG.Name); 4360b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4370b57cec5SDimitry Andric P.formatLine("length = {0}, addr = {1}", CG.Size, 4380b57cec5SDimitry Andric formatSegmentOffset(CG.Segment, CG.Offset)); 4390b57cec5SDimitry Andric P.printLine("characteristics ="); 4400b57cec5SDimitry Andric AutoIndent Indent2(P, 2); 4410b57cec5SDimitry Andric P.printLine(formatSectionCharacteristics(P.getIndentLevel(), 4420b57cec5SDimitry Andric CG.Characteristics, 1, "", 4430b57cec5SDimitry Andric CharacteristicStyle::Descriptive)); 4440b57cec5SDimitry Andric return Error::success(); 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 4480b57cec5SDimitry Andric BPRelativeSym &BPRel) { 4490b57cec5SDimitry Andric P.format(" `{0}`", BPRel.Name); 4500b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4510b57cec5SDimitry Andric P.formatLine("type = {0}, offset = {1}", typeIndex(BPRel.Type), BPRel.Offset); 4520b57cec5SDimitry Andric return Error::success(); 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 4560b57cec5SDimitry Andric BuildInfoSym &BuildInfo) { 4570b57cec5SDimitry Andric P.format(" BuildId = `{0}`", BuildInfo.BuildId); 4580b57cec5SDimitry Andric return Error::success(); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 4620b57cec5SDimitry Andric CallSiteInfoSym &CSI) { 4630b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4640b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1}", typeIndex(CSI.Type), 4650b57cec5SDimitry Andric formatSegmentOffset(CSI.Segment, CSI.CodeOffset)); 4660b57cec5SDimitry Andric return Error::success(); 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 4700b57cec5SDimitry Andric EnvBlockSym &EnvBlock) { 4710b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4720b57cec5SDimitry Andric for (const auto &Entry : EnvBlock.Fields) { 4730b57cec5SDimitry Andric P.formatLine("- {0}", Entry); 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric return Error::success(); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FileStaticSym &FS) { 4790b57cec5SDimitry Andric P.format(" `{0}`", FS.Name); 4800b57cec5SDimitry Andric AutoIndent Indent(P, 7); 4810b57cec5SDimitry Andric if (SymGroup) { 4820b57cec5SDimitry Andric Expected<StringRef> FileName = 4830b57cec5SDimitry Andric SymGroup->getNameFromStringTable(FS.ModFilenameOffset); 4840b57cec5SDimitry Andric if (FileName) { 4850b57cec5SDimitry Andric P.formatLine("type = {0}, file name = {1} ({2}), flags = {3}", 4860b57cec5SDimitry Andric typeIndex(FS.Index), FS.ModFilenameOffset, *FileName, 4870b57cec5SDimitry Andric formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags)); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric return Error::success(); 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric P.formatLine("type = {0}, file name offset = {1}, flags = {2}", 4930b57cec5SDimitry Andric typeIndex(FS.Index), FS.ModFilenameOffset, 4940b57cec5SDimitry Andric formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags)); 4950b57cec5SDimitry Andric return Error::success(); 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) { 4990b57cec5SDimitry Andric P.format(" `{0}`", Export.Name); 5000b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5010b57cec5SDimitry Andric P.formatLine("ordinal = {0}, flags = {1}", Export.Ordinal, 5020b57cec5SDimitry Andric formatExportFlags(P.getIndentLevel() + 9, Export.Flags)); 5030b57cec5SDimitry Andric return Error::success(); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 5070b57cec5SDimitry Andric Compile2Sym &Compile2) { 5080b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5090b57cec5SDimitry Andric SourceLanguage Lang = static_cast<SourceLanguage>( 5100b57cec5SDimitry Andric Compile2.Flags & CompileSym2Flags::SourceLanguageMask); 5110b57cec5SDimitry Andric CompilationCPU = Compile2.Machine; 5120b57cec5SDimitry Andric P.formatLine("machine = {0}, ver = {1}, language = {2}", 5130b57cec5SDimitry Andric formatMachineType(Compile2.Machine), Compile2.Version, 5140b57cec5SDimitry Andric formatSourceLanguage(Lang)); 5150b57cec5SDimitry Andric P.formatLine("frontend = {0}.{1}.{2}, backend = {3}.{4}.{5}", 5160b57cec5SDimitry Andric Compile2.VersionFrontendMajor, Compile2.VersionFrontendMinor, 5170b57cec5SDimitry Andric Compile2.VersionFrontendBuild, Compile2.VersionBackendMajor, 5180b57cec5SDimitry Andric Compile2.VersionBackendMinor, Compile2.VersionBackendBuild); 5190b57cec5SDimitry Andric P.formatLine("flags = {0}", 5200b57cec5SDimitry Andric formatCompileSym2Flags(P.getIndentLevel() + 9, Compile2.Flags)); 5210b57cec5SDimitry Andric P.formatLine( 5220b57cec5SDimitry Andric "extra strings = {0}", 5230b57cec5SDimitry Andric typesetStringList(P.getIndentLevel() + 9 + 2, Compile2.ExtraStrings)); 5240b57cec5SDimitry Andric return Error::success(); 5250b57cec5SDimitry Andric } 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 5280b57cec5SDimitry Andric Compile3Sym &Compile3) { 5290b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5300b57cec5SDimitry Andric SourceLanguage Lang = static_cast<SourceLanguage>( 5310b57cec5SDimitry Andric Compile3.Flags & CompileSym3Flags::SourceLanguageMask); 5320b57cec5SDimitry Andric CompilationCPU = Compile3.Machine; 5330b57cec5SDimitry Andric P.formatLine("machine = {0}, Ver = {1}, language = {2}", 5340b57cec5SDimitry Andric formatMachineType(Compile3.Machine), Compile3.Version, 5350b57cec5SDimitry Andric formatSourceLanguage(Lang)); 5360b57cec5SDimitry Andric P.formatLine("frontend = {0}.{1}.{2}.{3}, backend = {4}.{5}.{6}.{7}", 5370b57cec5SDimitry Andric Compile3.VersionFrontendMajor, Compile3.VersionFrontendMinor, 5380b57cec5SDimitry Andric Compile3.VersionFrontendBuild, Compile3.VersionFrontendQFE, 5390b57cec5SDimitry Andric Compile3.VersionBackendMajor, Compile3.VersionBackendMinor, 5400b57cec5SDimitry Andric Compile3.VersionBackendBuild, Compile3.VersionBackendQFE); 5410b57cec5SDimitry Andric P.formatLine("flags = {0}", 5420b57cec5SDimitry Andric formatCompileSym3Flags(P.getIndentLevel() + 9, Compile3.Flags)); 5430b57cec5SDimitry Andric return Error::success(); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 5470b57cec5SDimitry Andric ConstantSym &Constant) { 5480b57cec5SDimitry Andric P.format(" `{0}`", Constant.Name); 5490b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5500b57cec5SDimitry Andric P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type), 5510b57cec5SDimitry Andric Constant.Value.toString(10)); 5520b57cec5SDimitry Andric return Error::success(); 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { 5560b57cec5SDimitry Andric P.format(" `{0}`", Data.Name); 5570b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5580b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type), 5590b57cec5SDimitry Andric formatSegmentOffset(Data.Segment, Data.DataOffset)); 5600b57cec5SDimitry Andric return Error::success(); 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord( 5640b57cec5SDimitry Andric CVSymbol &CVR, DefRangeFramePointerRelFullScopeSym &Def) { 5650b57cec5SDimitry Andric P.format(" offset = {0}", Def.Offset); 5660b57cec5SDimitry Andric return Error::success(); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 5700b57cec5SDimitry Andric DefRangeFramePointerRelSym &Def) { 5710b57cec5SDimitry Andric AutoIndent Indent(P, 7); 572*8bcb0991SDimitry Andric P.formatLine("offset = {0}, range = {1}", Def.Hdr.Offset, 573*8bcb0991SDimitry Andric formatRange(Def.Range)); 574*8bcb0991SDimitry Andric P.formatLine("gaps = {2}", Def.Hdr.Offset, 5750b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 5760b57cec5SDimitry Andric return Error::success(); 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 5800b57cec5SDimitry Andric DefRangeRegisterRelSym &Def) { 5810b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5820b57cec5SDimitry Andric P.formatLine("register = {0}, offset = {1}, offset in parent = {2}, has " 5830b57cec5SDimitry Andric "spilled udt = {3}", 5840b57cec5SDimitry Andric formatRegisterId(Def.Hdr.Register, CompilationCPU), 5850b57cec5SDimitry Andric int32_t(Def.Hdr.BasePointerOffset), Def.offsetInParent(), 5860b57cec5SDimitry Andric Def.hasSpilledUDTMember()); 5870b57cec5SDimitry Andric P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range), 5880b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 5890b57cec5SDimitry Andric return Error::success(); 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord( 5930b57cec5SDimitry Andric CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { 5940b57cec5SDimitry Andric AutoIndent Indent(P, 7); 5950b57cec5SDimitry Andric P.formatLine("register = {0}, may have no name = {1}, range start = " 5960b57cec5SDimitry Andric "{2}, length = {3}", 5970b57cec5SDimitry Andric formatRegisterId(DefRangeRegister.Hdr.Register, CompilationCPU), 5980b57cec5SDimitry Andric bool(DefRangeRegister.Hdr.MayHaveNoName), 5990b57cec5SDimitry Andric formatSegmentOffset(DefRangeRegister.Range.ISectStart, 6000b57cec5SDimitry Andric DefRangeRegister.Range.OffsetStart), 6010b57cec5SDimitry Andric DefRangeRegister.Range.Range); 6020b57cec5SDimitry Andric P.formatLine("gaps = [{0}]", 6030b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, DefRangeRegister.Gaps)); 6040b57cec5SDimitry Andric return Error::success(); 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 6080b57cec5SDimitry Andric DefRangeSubfieldRegisterSym &Def) { 6090b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6100b57cec5SDimitry Andric bool NoName = !!(Def.Hdr.MayHaveNoName == 0); 6110b57cec5SDimitry Andric P.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}", 6120b57cec5SDimitry Andric formatRegisterId(Def.Hdr.Register, CompilationCPU), NoName, 6130b57cec5SDimitry Andric uint32_t(Def.Hdr.OffsetInParent)); 6140b57cec5SDimitry Andric P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range), 6150b57cec5SDimitry Andric formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 6160b57cec5SDimitry Andric return Error::success(); 6170b57cec5SDimitry Andric } 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 6200b57cec5SDimitry Andric DefRangeSubfieldSym &Def) { 6210b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6220b57cec5SDimitry Andric P.formatLine("program = {0}, offset in parent = {1}, range = {2}", 6230b57cec5SDimitry Andric Def.Program, Def.OffsetInParent, formatRange(Def.Range)); 6240b57cec5SDimitry Andric P.formatLine("gaps = {0}", formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 6250b57cec5SDimitry Andric return Error::success(); 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DefRangeSym &Def) { 6290b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6300b57cec5SDimitry Andric P.formatLine("program = {0}, range = {1}", Def.Program, 6310b57cec5SDimitry Andric formatRange(Def.Range)); 6320b57cec5SDimitry Andric P.formatLine("gaps = {0}", formatGaps(P.getIndentLevel() + 9, Def.Gaps)); 6330b57cec5SDimitry Andric return Error::success(); 6340b57cec5SDimitry Andric } 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameCookieSym &FC) { 6370b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6380b57cec5SDimitry Andric P.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}", 6390b57cec5SDimitry Andric FC.CodeOffset, formatRegisterId(FC.Register, CompilationCPU), 6400b57cec5SDimitry Andric formatCookieKind(FC.CookieKind), FC.Flags); 6410b57cec5SDimitry Andric return Error::success(); 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameProcSym &FP) { 6450b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6460b57cec5SDimitry Andric P.formatLine("size = {0}, padding size = {1}, offset to padding = {2}", 6470b57cec5SDimitry Andric FP.TotalFrameBytes, FP.PaddingFrameBytes, FP.OffsetToPadding); 6480b57cec5SDimitry Andric P.formatLine("bytes of callee saved registers = {0}, exception handler addr " 6490b57cec5SDimitry Andric "= {1}", 6500b57cec5SDimitry Andric FP.BytesOfCalleeSavedRegisters, 6510b57cec5SDimitry Andric formatSegmentOffset(FP.SectionIdOfExceptionHandler, 6520b57cec5SDimitry Andric FP.OffsetOfExceptionHandler)); 6530b57cec5SDimitry Andric P.formatLine( 6540b57cec5SDimitry Andric "local fp reg = {0}, param fp reg = {1}", 6550b57cec5SDimitry Andric formatRegisterId(FP.getLocalFramePtrReg(CompilationCPU), CompilationCPU), 6560b57cec5SDimitry Andric formatRegisterId(FP.getParamFramePtrReg(CompilationCPU), CompilationCPU)); 6570b57cec5SDimitry Andric P.formatLine("flags = {0}", 6580b57cec5SDimitry Andric formatFrameProcedureOptions(P.getIndentLevel() + 9, FP.Flags)); 6590b57cec5SDimitry Andric return Error::success(); 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 6630b57cec5SDimitry Andric HeapAllocationSiteSym &HAS) { 6640b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6650b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1} call size = {2}", typeIndex(HAS.Type), 6660b57cec5SDimitry Andric formatSegmentOffset(HAS.Segment, HAS.CodeOffset), 6670b57cec5SDimitry Andric HAS.CallInstructionSize); 6680b57cec5SDimitry Andric return Error::success(); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, InlineSiteSym &IS) { 6720b57cec5SDimitry Andric AutoIndent Indent(P, 7); 6730b57cec5SDimitry Andric P.formatLine("inlinee = {0}, parent = {1}, end = {2}", idIndex(IS.Inlinee), 6740b57cec5SDimitry Andric IS.Parent, IS.End); 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric // Break down the annotation byte code and calculate code and line offsets. 6770b57cec5SDimitry Andric // FIXME: It would be helpful if we could look up the initial file and inlinee 6780b57cec5SDimitry Andric // lines offset using the inlinee index above. 6790b57cec5SDimitry Andric uint32_t CodeOffset = 0; 6800b57cec5SDimitry Andric int32_t LineOffset = 0; 6810b57cec5SDimitry Andric for (auto &Annot : IS.annotations()) { 6820b57cec5SDimitry Andric P.formatLine(" {0}", fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9)); 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric auto formatCodeOffset = [&](uint32_t Delta) { 6850b57cec5SDimitry Andric CodeOffset += Delta; 6860b57cec5SDimitry Andric P.format(" code 0x{0} (+0x{1})", utohexstr(CodeOffset), utohexstr(Delta)); 6870b57cec5SDimitry Andric }; 6880b57cec5SDimitry Andric auto formatCodeLength = [&](uint32_t Length) { 6890b57cec5SDimitry Andric // Notably, changing the code length does not affect the code offset. 6900b57cec5SDimitry Andric P.format(" code end 0x{0} (+0x{1})", utohexstr(CodeOffset + Length), 6910b57cec5SDimitry Andric utohexstr(Length)); 6920b57cec5SDimitry Andric }; 6930b57cec5SDimitry Andric auto formatLineOffset = [&](int32_t Delta) { 6940b57cec5SDimitry Andric LineOffset += Delta; 6950b57cec5SDimitry Andric char Sign = Delta > 0 ? '+' : '-'; 6960b57cec5SDimitry Andric P.format(" line {0} ({1}{2})", LineOffset, Sign, std::abs(Delta)); 6970b57cec5SDimitry Andric }; 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric // Use the opcode to interpret the integer values. 7000b57cec5SDimitry Andric switch (Annot.OpCode) { 7010b57cec5SDimitry Andric case BinaryAnnotationsOpCode::Invalid: 7020b57cec5SDimitry Andric break; 7030b57cec5SDimitry Andric case BinaryAnnotationsOpCode::CodeOffset: 7040b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeOffset: 7050b57cec5SDimitry Andric formatCodeOffset(Annot.U1); 7060b57cec5SDimitry Andric break; 7070b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeLineOffset: 7080b57cec5SDimitry Andric formatLineOffset(Annot.S1); 7090b57cec5SDimitry Andric break; 7100b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeLength: 7110b57cec5SDimitry Andric formatCodeLength(Annot.U1); 7120b57cec5SDimitry Andric // Apparently this annotation updates the code offset. It's hard to make 7130b57cec5SDimitry Andric // MSVC produce this opcode, but clang uses it, and debuggers seem to use 7140b57cec5SDimitry Andric // this interpretation. 7150b57cec5SDimitry Andric CodeOffset += Annot.U1; 7160b57cec5SDimitry Andric break; 7170b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: 7180b57cec5SDimitry Andric formatCodeOffset(Annot.U1); 7190b57cec5SDimitry Andric formatLineOffset(Annot.S1); 7200b57cec5SDimitry Andric break; 7210b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: 7220b57cec5SDimitry Andric formatCodeOffset(Annot.U2); 7230b57cec5SDimitry Andric formatCodeLength(Annot.U1); 7240b57cec5SDimitry Andric break; 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeFile: { 7270b57cec5SDimitry Andric uint32_t FileOffset = Annot.U1; 7280b57cec5SDimitry Andric StringRef Filename = "<unknown>"; 7290b57cec5SDimitry Andric if (SymGroup) { 7300b57cec5SDimitry Andric if (Expected<StringRef> MaybeFile = 7310b57cec5SDimitry Andric SymGroup->getNameFromStringTable(FileOffset)) 7320b57cec5SDimitry Andric Filename = *MaybeFile; 7330b57cec5SDimitry Andric else 7340b57cec5SDimitry Andric return MaybeFile.takeError(); 7350b57cec5SDimitry Andric } 7360b57cec5SDimitry Andric P.format(" setfile {0} 0x{1}", utohexstr(FileOffset)); 7370b57cec5SDimitry Andric break; 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric // The rest of these are hard to convince MSVC to emit, so they are not as 7410b57cec5SDimitry Andric // well understood. 7420b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 7430b57cec5SDimitry Andric formatCodeOffset(Annot.U1); 7440b57cec5SDimitry Andric break; 7450b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeLineEndDelta: 7460b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeRangeKind: 7470b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeColumnStart: 7480b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeColumnEnd: 7490b57cec5SDimitry Andric P.format(" {0} {1}", Annot.Name, Annot.U1); 7500b57cec5SDimitry Andric break; 7510b57cec5SDimitry Andric case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 7520b57cec5SDimitry Andric P.format(" {0} {1}", Annot.Name, Annot.S1); 7530b57cec5SDimitry Andric break; 7540b57cec5SDimitry Andric } 7550b57cec5SDimitry Andric } 7560b57cec5SDimitry Andric return Error::success(); 7570b57cec5SDimitry Andric } 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 7600b57cec5SDimitry Andric RegisterSym &Register) { 7610b57cec5SDimitry Andric P.format(" `{0}`", Register.Name); 7620b57cec5SDimitry Andric AutoIndent Indent(P, 7); 7630b57cec5SDimitry Andric P.formatLine("register = {0}, type = {1}", 7640b57cec5SDimitry Andric formatRegisterId(Register.Register, CompilationCPU), 7650b57cec5SDimitry Andric typeIndex(Register.Index)); 7660b57cec5SDimitry Andric return Error::success(); 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 7700b57cec5SDimitry Andric PublicSym32 &Public) { 7710b57cec5SDimitry Andric P.format(" `{0}`", Public.Name); 7720b57cec5SDimitry Andric AutoIndent Indent(P, 7); 7730b57cec5SDimitry Andric P.formatLine("flags = {0}, addr = {1}", 7740b57cec5SDimitry Andric formatPublicSymFlags(P.getIndentLevel() + 9, Public.Flags), 7750b57cec5SDimitry Andric formatSegmentOffset(Public.Segment, Public.Offset)); 7760b57cec5SDimitry Andric return Error::success(); 7770b57cec5SDimitry Andric } 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcRefSym &PR) { 7800b57cec5SDimitry Andric P.format(" `{0}`", PR.Name); 7810b57cec5SDimitry Andric AutoIndent Indent(P, 7); 7820b57cec5SDimitry Andric P.formatLine("module = {0}, sum name = {1}, offset = {2}", PR.Module, 7830b57cec5SDimitry Andric PR.SumName, PR.SymOffset); 7840b57cec5SDimitry Andric return Error::success(); 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 7880b57cec5SDimitry Andric P.format(" `{0}` (addr = {1})", Label.Name, 7890b57cec5SDimitry Andric formatSegmentOffset(Label.Segment, Label.CodeOffset)); 7900b57cec5SDimitry Andric AutoIndent Indent(P, 7); 7910b57cec5SDimitry Andric P.formatLine("flags = {0}", 7920b57cec5SDimitry Andric formatProcSymFlags(P.getIndentLevel() + 9, Label.Flags)); 7930b57cec5SDimitry Andric return Error::success(); 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 7970b57cec5SDimitry Andric P.format(" `{0}`", Local.Name); 7980b57cec5SDimitry Andric AutoIndent Indent(P, 7); 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric std::string FlagStr = 8010b57cec5SDimitry Andric formatLocalSymFlags(P.getIndentLevel() + 9, Local.Flags); 8020b57cec5SDimitry Andric P.formatLine("type={0}, flags = {1}", typeIndex(Local.Type), FlagStr); 8030b57cec5SDimitry Andric return Error::success(); 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 8070b57cec5SDimitry Andric ObjNameSym &ObjName) { 8080b57cec5SDimitry Andric P.format(" sig={0}, `{1}`", ObjName.Signature, ObjName.Name); 8090b57cec5SDimitry Andric return Error::success(); 8100b57cec5SDimitry Andric } 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 8130b57cec5SDimitry Andric P.format(" `{0}`", Proc.Name); 8140b57cec5SDimitry Andric AutoIndent Indent(P, 7); 8150b57cec5SDimitry Andric P.formatLine("parent = {0}, end = {1}, addr = {2}, code size = {3}", 8160b57cec5SDimitry Andric Proc.Parent, Proc.End, 8170b57cec5SDimitry Andric formatSegmentOffset(Proc.Segment, Proc.CodeOffset), 8180b57cec5SDimitry Andric Proc.CodeSize); 8190b57cec5SDimitry Andric bool IsType = true; 8200b57cec5SDimitry Andric switch (Proc.getKind()) { 8210b57cec5SDimitry Andric case SymbolRecordKind::GlobalProcIdSym: 8220b57cec5SDimitry Andric case SymbolRecordKind::ProcIdSym: 8230b57cec5SDimitry Andric case SymbolRecordKind::DPCProcIdSym: 8240b57cec5SDimitry Andric IsType = false; 8250b57cec5SDimitry Andric break; 8260b57cec5SDimitry Andric default: 8270b57cec5SDimitry Andric break; 8280b57cec5SDimitry Andric } 8290b57cec5SDimitry Andric P.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}", 8300b57cec5SDimitry Andric typeOrIdIndex(Proc.FunctionType, IsType), Proc.DbgStart, 8310b57cec5SDimitry Andric Proc.DbgEnd, 8320b57cec5SDimitry Andric formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags)); 8330b57cec5SDimitry Andric return Error::success(); 8340b57cec5SDimitry Andric } 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 8370b57cec5SDimitry Andric ScopeEndSym &ScopeEnd) { 8380b57cec5SDimitry Andric return Error::success(); 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 8420b57cec5SDimitry Andric AutoIndent Indent(P, 7); 8430b57cec5SDimitry Andric for (const auto &I : Caller.Indices) { 8440b57cec5SDimitry Andric P.formatLine("callee: {0}", idIndex(I)); 8450b57cec5SDimitry Andric } 8460b57cec5SDimitry Andric return Error::success(); 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 8500b57cec5SDimitry Andric RegRelativeSym &RegRel) { 8510b57cec5SDimitry Andric P.format(" `{0}`", RegRel.Name); 8520b57cec5SDimitry Andric AutoIndent Indent(P, 7); 8530b57cec5SDimitry Andric P.formatLine( 8540b57cec5SDimitry Andric "type = {0}, register = {1}, offset = {2}", typeIndex(RegRel.Type), 8550b57cec5SDimitry Andric formatRegisterId(RegRel.Register, CompilationCPU), RegRel.Offset); 8560b57cec5SDimitry Andric return Error::success(); 8570b57cec5SDimitry Andric } 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 8600b57cec5SDimitry Andric ThreadLocalDataSym &Data) { 8610b57cec5SDimitry Andric P.format(" `{0}`", Data.Name); 8620b57cec5SDimitry Andric AutoIndent Indent(P, 7); 8630b57cec5SDimitry Andric P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type), 8640b57cec5SDimitry Andric formatSegmentOffset(Data.Segment, Data.DataOffset)); 8650b57cec5SDimitry Andric return Error::success(); 8660b57cec5SDimitry Andric } 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 8690b57cec5SDimitry Andric P.format(" `{0}`", UDT.Name); 8700b57cec5SDimitry Andric AutoIndent Indent(P, 7); 8710b57cec5SDimitry Andric P.formatLine("original type = {0}", UDT.Type); 8720b57cec5SDimitry Andric return Error::success(); 8730b57cec5SDimitry Andric } 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 8760b57cec5SDimitry Andric UsingNamespaceSym &UN) { 8770b57cec5SDimitry Andric P.format(" `{0}`", UN.Name); 8780b57cec5SDimitry Andric return Error::success(); 8790b57cec5SDimitry Andric } 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, 8820b57cec5SDimitry Andric AnnotationSym &Annot) { 8830b57cec5SDimitry Andric AutoIndent Indent(P, 7); 8840b57cec5SDimitry Andric P.formatLine("addr = {0}", formatSegmentOffset(Annot.Segment, Annot.CodeOffset)); 8850b57cec5SDimitry Andric P.formatLine("strings = {0}", typesetStringList(P.getIndentLevel() + 9 + 2, 8860b57cec5SDimitry Andric Annot.Strings)); 8870b57cec5SDimitry Andric return Error::success(); 8880b57cec5SDimitry Andric } 889