10b57cec5SDimitry Andric //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===// 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 // This file defines classes for handling the YAML representation of CodeView 100b57cec5SDimitry Andric // Debug Info. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" 150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 180b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h" 190b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/EnumTables.h" 200b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 210b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 220b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 230b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" 240b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 250b57cec5SDimitry Andric #include "llvm/ObjectYAML/YAML.h" 260b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 270b57cec5SDimitry Andric #include "llvm/Support/Error.h" 2881ad6265SDimitry Andric #include "llvm/Support/ScopedPrinter.h" 290b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h" 300b57cec5SDimitry Andric #include <algorithm> 310b57cec5SDimitry Andric #include <cstdint> 320b57cec5SDimitry Andric #include <cstring> 33bdd1243dSDimitry Andric #include <optional> 340b57cec5SDimitry Andric #include <string> 350b57cec5SDimitry Andric #include <vector> 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric using namespace llvm; 380b57cec5SDimitry Andric using namespace llvm::codeview; 390b57cec5SDimitry Andric using namespace llvm::CodeViewYAML; 400b57cec5SDimitry Andric using namespace llvm::CodeViewYAML::detail; 410b57cec5SDimitry Andric using namespace llvm::yaml; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) 440b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap) 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp 470b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None) 480b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None) 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) 510b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind) 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) 540b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) 550b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags) 560b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags) 570b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags) 580b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags) 590b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions) 600b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType) 610b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId) 620b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType) 630b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal) 64*5f757f3fSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(JumpTableEntrySize) 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName) 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single) 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) { 710b57cec5SDimitry Andric return ScalarTraits<StringRef>::input(S, V, T.value); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric void ScalarTraits<TypeName>::output(const TypeName &T, void *V, 750b57cec5SDimitry Andric raw_ostream &R) { 760b57cec5SDimitry Andric ScalarTraits<StringRef>::output(T.value, V, R); 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io, 800b57cec5SDimitry Andric SymbolKind &Value) { 810b57cec5SDimitry Andric auto SymbolNames = getSymbolTypeNames(); 820b57cec5SDimitry Andric for (const auto &E : SymbolNames) 830b57cec5SDimitry Andric io.enumCase(Value, E.Name.str().c_str(), E.Value); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io, 870b57cec5SDimitry Andric CompileSym2Flags &Flags) { 880b57cec5SDimitry Andric auto FlagNames = getCompileSym2FlagNames(); 890b57cec5SDimitry Andric for (const auto &E : FlagNames) { 900b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 910b57cec5SDimitry Andric static_cast<CompileSym2Flags>(E.Value)); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io, 960b57cec5SDimitry Andric CompileSym3Flags &Flags) { 970b57cec5SDimitry Andric auto FlagNames = getCompileSym3FlagNames(); 980b57cec5SDimitry Andric for (const auto &E : FlagNames) { 990b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 1000b57cec5SDimitry Andric static_cast<CompileSym3Flags>(E.Value)); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) { 1050b57cec5SDimitry Andric auto FlagNames = getExportSymFlagNames(); 1060b57cec5SDimitry Andric for (const auto &E : FlagNames) { 1070b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 1080b57cec5SDimitry Andric static_cast<ExportFlags>(E.Value)); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) { 1130b57cec5SDimitry Andric auto FlagNames = getPublicSymFlagNames(); 1140b57cec5SDimitry Andric for (const auto &E : FlagNames) { 1150b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 1160b57cec5SDimitry Andric static_cast<PublicSymFlags>(E.Value)); 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) { 1210b57cec5SDimitry Andric auto FlagNames = getLocalFlagNames(); 1220b57cec5SDimitry Andric for (const auto &E : FlagNames) { 1230b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 1240b57cec5SDimitry Andric static_cast<LocalSymFlags>(E.Value)); 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) { 1290b57cec5SDimitry Andric auto FlagNames = getProcSymFlagNames(); 1300b57cec5SDimitry Andric for (const auto &E : FlagNames) { 1310b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 1320b57cec5SDimitry Andric static_cast<ProcSymFlags>(E.Value)); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric void ScalarBitSetTraits<FrameProcedureOptions>::bitset( 1370b57cec5SDimitry Andric IO &io, FrameProcedureOptions &Flags) { 1380b57cec5SDimitry Andric auto FlagNames = getFrameProcSymFlagNames(); 1390b57cec5SDimitry Andric for (const auto &E : FlagNames) { 1400b57cec5SDimitry Andric io.bitSetCase(Flags, E.Name.str().c_str(), 1410b57cec5SDimitry Andric static_cast<FrameProcedureOptions>(E.Value)); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) { 1460b57cec5SDimitry Andric auto CpuNames = getCPUTypeNames(); 1470b57cec5SDimitry Andric for (const auto &E : CpuNames) { 1480b57cec5SDimitry Andric io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value)); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) { 153e8d8bef9SDimitry Andric const auto *Header = static_cast<COFF::header *>(io.getContext()); 154e8d8bef9SDimitry Andric assert(Header && "The IO context is not initialized"); 155e8d8bef9SDimitry Andric 156bdd1243dSDimitry Andric std::optional<CPUType> CpuType; 157e8d8bef9SDimitry Andric ArrayRef<EnumEntry<uint16_t>> RegNames; 158e8d8bef9SDimitry Andric 159e8d8bef9SDimitry Andric switch (Header->Machine) { 160e8d8bef9SDimitry Andric case COFF::IMAGE_FILE_MACHINE_I386: 161e8d8bef9SDimitry Andric CpuType = CPUType::Pentium3; 162e8d8bef9SDimitry Andric break; 163e8d8bef9SDimitry Andric case COFF::IMAGE_FILE_MACHINE_AMD64: 164e8d8bef9SDimitry Andric CpuType = CPUType::X64; 165e8d8bef9SDimitry Andric break; 166e8d8bef9SDimitry Andric case COFF::IMAGE_FILE_MACHINE_ARMNT: 167e8d8bef9SDimitry Andric CpuType = CPUType::ARMNT; 168e8d8bef9SDimitry Andric break; 169e8d8bef9SDimitry Andric case COFF::IMAGE_FILE_MACHINE_ARM64: 170bdd1243dSDimitry Andric case COFF::IMAGE_FILE_MACHINE_ARM64EC: 17106c3fb27SDimitry Andric case COFF::IMAGE_FILE_MACHINE_ARM64X: 172e8d8bef9SDimitry Andric CpuType = CPUType::ARM64; 173e8d8bef9SDimitry Andric break; 174e8d8bef9SDimitry Andric } 175e8d8bef9SDimitry Andric 176e8d8bef9SDimitry Andric if (CpuType) 177e8d8bef9SDimitry Andric RegNames = getRegisterNames(*CpuType); 178e8d8bef9SDimitry Andric 1790b57cec5SDimitry Andric for (const auto &E : RegNames) { 1800b57cec5SDimitry Andric io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric io.enumFallback<Hex16>(Reg); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric void ScalarEnumerationTraits<TrampolineType>::enumeration( 1860b57cec5SDimitry Andric IO &io, TrampolineType &Tramp) { 1870b57cec5SDimitry Andric auto TrampNames = getTrampolineNames(); 1880b57cec5SDimitry Andric for (const auto &E : TrampNames) { 1890b57cec5SDimitry Andric io.enumCase(Tramp, E.Name.str().c_str(), 1900b57cec5SDimitry Andric static_cast<TrampolineType>(E.Value)); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, 1950b57cec5SDimitry Andric ThunkOrdinal &Ord) { 1960b57cec5SDimitry Andric auto ThunkNames = getThunkOrdinalNames(); 1970b57cec5SDimitry Andric for (const auto &E : ThunkNames) { 1980b57cec5SDimitry Andric io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric void ScalarEnumerationTraits<FrameCookieKind>::enumeration( 2030b57cec5SDimitry Andric IO &io, FrameCookieKind &FC) { 2040b57cec5SDimitry Andric auto ThunkNames = getFrameCookieKindNames(); 2050b57cec5SDimitry Andric for (const auto &E : ThunkNames) { 2060b57cec5SDimitry Andric io.enumCase(FC, E.Name.str().c_str(), 2070b57cec5SDimitry Andric static_cast<FrameCookieKind>(E.Value)); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 211*5f757f3fSDimitry Andric void ScalarEnumerationTraits<JumpTableEntrySize>::enumeration( 212*5f757f3fSDimitry Andric IO &io, JumpTableEntrySize &FC) { 213*5f757f3fSDimitry Andric auto ThunkNames = getJumpTableEntrySizeNames(); 214*5f757f3fSDimitry Andric for (const auto &E : ThunkNames) { 215*5f757f3fSDimitry Andric io.enumCase(FC, E.Name.str().c_str(), 216*5f757f3fSDimitry Andric static_cast<JumpTableEntrySize>(E.Value)); 217*5f757f3fSDimitry Andric } 218*5f757f3fSDimitry Andric } 219*5f757f3fSDimitry Andric 2200b57cec5SDimitry Andric namespace llvm { 2210b57cec5SDimitry Andric namespace yaml { 2220b57cec5SDimitry Andric template <> struct MappingTraits<LocalVariableAddrRange> { 2230b57cec5SDimitry Andric static void mapping(IO &io, LocalVariableAddrRange &Range) { 2240b57cec5SDimitry Andric io.mapRequired("OffsetStart", Range.OffsetStart); 2250b57cec5SDimitry Andric io.mapRequired("ISectStart", Range.ISectStart); 2260b57cec5SDimitry Andric io.mapRequired("Range", Range.Range); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric }; 2290b57cec5SDimitry Andric template <> struct MappingTraits<LocalVariableAddrGap> { 2300b57cec5SDimitry Andric static void mapping(IO &io, LocalVariableAddrGap &Gap) { 2310b57cec5SDimitry Andric io.mapRequired("GapStartOffset", Gap.GapStartOffset); 2320b57cec5SDimitry Andric io.mapRequired("Range", Gap.Range); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric }; 2350b57cec5SDimitry Andric } // namespace yaml 2360b57cec5SDimitry Andric } // namespace llvm 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric namespace llvm { 2390b57cec5SDimitry Andric namespace CodeViewYAML { 2400b57cec5SDimitry Andric namespace detail { 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric struct SymbolRecordBase { 2430b57cec5SDimitry Andric codeview::SymbolKind Kind; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} 2460b57cec5SDimitry Andric virtual ~SymbolRecordBase() = default; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric virtual void map(yaml::IO &io) = 0; 2490b57cec5SDimitry Andric virtual codeview::CVSymbol 2500b57cec5SDimitry Andric toCodeViewSymbol(BumpPtrAllocator &Allocator, 2510b57cec5SDimitry Andric CodeViewContainer Container) const = 0; 2520b57cec5SDimitry Andric virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; 2530b57cec5SDimitry Andric }; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { 2560b57cec5SDimitry Andric explicit SymbolRecordImpl(codeview::SymbolKind K) 2570b57cec5SDimitry Andric : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric void map(yaml::IO &io) override; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric codeview::CVSymbol 2620b57cec5SDimitry Andric toCodeViewSymbol(BumpPtrAllocator &Allocator, 2630b57cec5SDimitry Andric CodeViewContainer Container) const override { 2640b57cec5SDimitry Andric return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { 2680b57cec5SDimitry Andric return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric mutable T Symbol; 2720b57cec5SDimitry Andric }; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric struct UnknownSymbolRecord : public SymbolRecordBase { 2750b57cec5SDimitry Andric explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric void map(yaml::IO &io) override; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, 2800b57cec5SDimitry Andric CodeViewContainer Container) const override { 2810b57cec5SDimitry Andric RecordPrefix Prefix; 2820b57cec5SDimitry Andric uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); 2830b57cec5SDimitry Andric Prefix.RecordKind = Kind; 2840b57cec5SDimitry Andric Prefix.RecordLen = TotalLen - 2; 2850b57cec5SDimitry Andric uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen); 2860b57cec5SDimitry Andric ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); 2870b57cec5SDimitry Andric ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); 2880b57cec5SDimitry Andric return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen)); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric Error fromCodeViewSymbol(CVSymbol CVS) override { 2920b57cec5SDimitry Andric this->Kind = CVS.kind(); 2930b57cec5SDimitry Andric Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); 2940b57cec5SDimitry Andric return Error::success(); 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric std::vector<uint8_t> Data; 2980b57cec5SDimitry Andric }; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric void UnknownSymbolRecord::map(yaml::IO &io) { 3030b57cec5SDimitry Andric yaml::BinaryRef Binary; 3040b57cec5SDimitry Andric if (io.outputting()) 3050b57cec5SDimitry Andric Binary = yaml::BinaryRef(Data); 3060b57cec5SDimitry Andric io.mapRequired("Data", Binary); 3070b57cec5SDimitry Andric if (!io.outputting()) { 3080b57cec5SDimitry Andric std::string Str; 3090b57cec5SDimitry Andric raw_string_ostream OS(Str); 3100b57cec5SDimitry Andric Binary.writeAsBinary(OS); 3110b57cec5SDimitry Andric OS.flush(); 3120b57cec5SDimitry Andric Data.assign(Str.begin(), Str.end()); 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { 3170b57cec5SDimitry Andric IO.mapRequired("Parent", Symbol.Parent); 3180b57cec5SDimitry Andric IO.mapRequired("End", Symbol.End); 3190b57cec5SDimitry Andric IO.mapRequired("Next", Symbol.Next); 3200b57cec5SDimitry Andric IO.mapRequired("Off", Symbol.Offset); 3210b57cec5SDimitry Andric IO.mapRequired("Seg", Symbol.Segment); 3220b57cec5SDimitry Andric IO.mapRequired("Len", Symbol.Length); 3230b57cec5SDimitry Andric IO.mapRequired("Ordinal", Symbol.Thunk); 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { 3270b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 3280b57cec5SDimitry Andric IO.mapRequired("Size", Symbol.Size); 3290b57cec5SDimitry Andric IO.mapRequired("ThunkOff", Symbol.ThunkOffset); 3300b57cec5SDimitry Andric IO.mapRequired("TargetOff", Symbol.TargetOffset); 3310b57cec5SDimitry Andric IO.mapRequired("ThunkSection", Symbol.ThunkSection); 3320b57cec5SDimitry Andric IO.mapRequired("TargetSection", Symbol.TargetSection); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { 3360b57cec5SDimitry Andric IO.mapRequired("SectionNumber", Symbol.SectionNumber); 3370b57cec5SDimitry Andric IO.mapRequired("Alignment", Symbol.Alignment); 3380b57cec5SDimitry Andric IO.mapRequired("Rva", Symbol.Rva); 3390b57cec5SDimitry Andric IO.mapRequired("Length", Symbol.Length); 3400b57cec5SDimitry Andric IO.mapRequired("Characteristics", Symbol.Characteristics); 3410b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { 3450b57cec5SDimitry Andric IO.mapRequired("Size", Symbol.Size); 3460b57cec5SDimitry Andric IO.mapRequired("Characteristics", Symbol.Characteristics); 3470b57cec5SDimitry Andric IO.mapRequired("Offset", Symbol.Offset); 3480b57cec5SDimitry Andric IO.mapRequired("Segment", Symbol.Segment); 3490b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { 3530b57cec5SDimitry Andric IO.mapRequired("Ordinal", Symbol.Ordinal); 3540b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 3550b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { 3590b57cec5SDimitry Andric IO.mapOptional("PtrParent", Symbol.Parent, 0U); 3600b57cec5SDimitry Andric IO.mapOptional("PtrEnd", Symbol.End, 0U); 3610b57cec5SDimitry Andric IO.mapOptional("PtrNext", Symbol.Next, 0U); 3620b57cec5SDimitry Andric IO.mapRequired("CodeSize", Symbol.CodeSize); 3630b57cec5SDimitry Andric IO.mapRequired("DbgStart", Symbol.DbgStart); 3640b57cec5SDimitry Andric IO.mapRequired("DbgEnd", Symbol.DbgEnd); 3650b57cec5SDimitry Andric IO.mapRequired("FunctionType", Symbol.FunctionType); 3660b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 3670b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 3680b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 3690b57cec5SDimitry Andric IO.mapRequired("DisplayName", Symbol.Name); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { 3730b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Index); 3740b57cec5SDimitry Andric IO.mapRequired("Seg", Symbol.Register); 3750b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { 3790b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 3800b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.Offset, 0U); 3810b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 3820b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { 3860b57cec5SDimitry Andric IO.mapRequired("SumName", Symbol.SumName); 3870b57cec5SDimitry Andric IO.mapRequired("SymOffset", Symbol.SymOffset); 3880b57cec5SDimitry Andric IO.mapRequired("Mod", Symbol.Module); 3890b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { 3930b57cec5SDimitry Andric IO.mapRequired("Entries", Symbol.Fields); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { 3970b57cec5SDimitry Andric IO.mapOptional("PtrParent", Symbol.Parent, 0U); 3980b57cec5SDimitry Andric IO.mapOptional("PtrEnd", Symbol.End, 0U); 3990b57cec5SDimitry Andric IO.mapRequired("Inlinee", Symbol.Inlinee); 4000b57cec5SDimitry Andric // TODO: The binary annotations 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { 4040b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 4050b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric IO.mapRequired("VarName", Symbol.Name); 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { 4110b57cec5SDimitry Andric IO.mapRequired("Program", Symbol.Program); 4120b57cec5SDimitry Andric IO.mapRequired("Range", Symbol.Range); 4130b57cec5SDimitry Andric IO.mapRequired("Gaps", Symbol.Gaps); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { 4170b57cec5SDimitry Andric IO.mapRequired("Program", Symbol.Program); 4180b57cec5SDimitry Andric IO.mapRequired("OffsetInParent", Symbol.OffsetInParent); 4190b57cec5SDimitry Andric IO.mapRequired("Range", Symbol.Range); 4200b57cec5SDimitry Andric IO.mapRequired("Gaps", Symbol.Gaps); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { 4240b57cec5SDimitry Andric IO.mapRequired("Register", Symbol.Hdr.Register); 4250b57cec5SDimitry Andric IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName); 4260b57cec5SDimitry Andric IO.mapRequired("Range", Symbol.Range); 4270b57cec5SDimitry Andric IO.mapRequired("Gaps", Symbol.Gaps); 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { 4318bcb0991SDimitry Andric IO.mapRequired("Offset", Symbol.Hdr.Offset); 4320b57cec5SDimitry Andric IO.mapRequired("Range", Symbol.Range); 4330b57cec5SDimitry Andric IO.mapRequired("Gaps", Symbol.Gaps); 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { 4370b57cec5SDimitry Andric IO.mapRequired("Register", Symbol.Hdr.Register); 4380b57cec5SDimitry Andric IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName); 4390b57cec5SDimitry Andric IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent); 4400b57cec5SDimitry Andric IO.mapRequired("Range", Symbol.Range); 4410b57cec5SDimitry Andric IO.mapRequired("Gaps", Symbol.Gaps); 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric template <> 4450b57cec5SDimitry Andric void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { 4460b57cec5SDimitry Andric IO.mapRequired("Register", Symbol.Offset); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { 4500b57cec5SDimitry Andric IO.mapRequired("Register", Symbol.Hdr.Register); 4510b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Hdr.Flags); 4520b57cec5SDimitry Andric IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset); 4530b57cec5SDimitry Andric IO.mapRequired("Range", Symbol.Range); 4540b57cec5SDimitry Andric IO.mapRequired("Gaps", Symbol.Gaps); 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { 4580b57cec5SDimitry Andric IO.mapOptional("PtrParent", Symbol.Parent, 0U); 4590b57cec5SDimitry Andric IO.mapOptional("PtrEnd", Symbol.End, 0U); 4600b57cec5SDimitry Andric IO.mapRequired("CodeSize", Symbol.CodeSize); 4610b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 4620b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 4630b57cec5SDimitry Andric IO.mapRequired("BlockName", Symbol.Name); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { 4670b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 4680b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 4690b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 4700b57cec5SDimitry Andric IO.mapRequired("DisplayName", Symbol.Name); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { 4740b57cec5SDimitry Andric IO.mapRequired("Signature", Symbol.Signature); 4750b57cec5SDimitry Andric IO.mapRequired("ObjectName", Symbol.Name); 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { 4790b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 4800b57cec5SDimitry Andric IO.mapRequired("Machine", Symbol.Machine); 4810b57cec5SDimitry Andric IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 4820b57cec5SDimitry Andric IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 4830b57cec5SDimitry Andric IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 4840b57cec5SDimitry Andric IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 4850b57cec5SDimitry Andric IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 4860b57cec5SDimitry Andric IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 4870b57cec5SDimitry Andric IO.mapRequired("Version", Symbol.Version); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { 4910b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 4920b57cec5SDimitry Andric IO.mapRequired("Machine", Symbol.Machine); 4930b57cec5SDimitry Andric IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 4940b57cec5SDimitry Andric IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 4950b57cec5SDimitry Andric IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 4960b57cec5SDimitry Andric IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); 4970b57cec5SDimitry Andric IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 4980b57cec5SDimitry Andric IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 4990b57cec5SDimitry Andric IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 5000b57cec5SDimitry Andric IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); 5010b57cec5SDimitry Andric IO.mapRequired("Version", Symbol.Version); 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { 5050b57cec5SDimitry Andric IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); 5060b57cec5SDimitry Andric IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); 5070b57cec5SDimitry Andric IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); 5080b57cec5SDimitry Andric IO.mapRequired("BytesOfCalleeSavedRegisters", 5090b57cec5SDimitry Andric Symbol.BytesOfCalleeSavedRegisters); 5100b57cec5SDimitry Andric IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); 5110b57cec5SDimitry Andric IO.mapRequired("SectionIdOfExceptionHandler", 5120b57cec5SDimitry Andric Symbol.SectionIdOfExceptionHandler); 5130b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { 5170b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 5180b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 5190b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { 5230b57cec5SDimitry Andric IO.mapRequired("Index", Symbol.Index); 5240b57cec5SDimitry Andric IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); 5250b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 5260b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { 5300b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 5310b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 5320b57cec5SDimitry Andric IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); 5330b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { 5370b57cec5SDimitry Andric IO.mapRequired("Register", Symbol.Register); 5380b57cec5SDimitry Andric IO.mapRequired("CookieKind", Symbol.CookieKind); 5390b57cec5SDimitry Andric IO.mapRequired("Flags", Symbol.Flags); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { 5430b57cec5SDimitry Andric IO.mapRequired("FuncID", Symbol.Indices); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { 5470b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5480b57cec5SDimitry Andric IO.mapRequired("UDTName", Symbol.Name); 5490b57cec5SDimitry Andric } 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { 5520b57cec5SDimitry Andric IO.mapRequired("BuildId", Symbol.BuildId); 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { 5560b57cec5SDimitry Andric IO.mapRequired("Offset", Symbol.Offset); 5570b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5580b57cec5SDimitry Andric IO.mapRequired("VarName", Symbol.Name); 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { 5620b57cec5SDimitry Andric IO.mapRequired("Offset", Symbol.Offset); 5630b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5640b57cec5SDimitry Andric IO.mapRequired("Register", Symbol.Register); 5650b57cec5SDimitry Andric IO.mapRequired("VarName", Symbol.Name); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { 5690b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5700b57cec5SDimitry Andric IO.mapRequired("Value", Symbol.Value); 5710b57cec5SDimitry Andric IO.mapRequired("Name", Symbol.Name); 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { 5750b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5760b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.DataOffset, 0U); 5770b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 5780b57cec5SDimitry Andric IO.mapRequired("DisplayName", Symbol.Name); 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { 5820b57cec5SDimitry Andric IO.mapRequired("Type", Symbol.Type); 5830b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.DataOffset, 0U); 5840b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 5850b57cec5SDimitry Andric IO.mapRequired("DisplayName", Symbol.Name); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) { 5890b57cec5SDimitry Andric IO.mapRequired("Namespace", Symbol.Name); 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) { 5930b57cec5SDimitry Andric IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 5940b57cec5SDimitry Andric IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 5950b57cec5SDimitry Andric IO.mapRequired("Strings", Symbol.Strings); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 598*5f757f3fSDimitry Andric template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) { 599*5f757f3fSDimitry Andric IO.mapRequired("BaseOffset", Symbol.BaseOffset); 600*5f757f3fSDimitry Andric IO.mapRequired("BaseSegment", Symbol.BaseSegment); 601*5f757f3fSDimitry Andric IO.mapRequired("SwitchType", Symbol.SwitchType); 602*5f757f3fSDimitry Andric IO.mapRequired("BranchOffset", Symbol.BranchOffset); 603*5f757f3fSDimitry Andric IO.mapRequired("TableOffset", Symbol.TableOffset); 604*5f757f3fSDimitry Andric IO.mapRequired("BranchSegment", Symbol.BranchSegment); 605*5f757f3fSDimitry Andric IO.mapRequired("TableSegment", Symbol.TableSegment); 606*5f757f3fSDimitry Andric IO.mapRequired("EntriesCount", Symbol.EntriesCount); 607*5f757f3fSDimitry Andric } 608*5f757f3fSDimitry Andric 6090b57cec5SDimitry Andric } // end namespace detail 6100b57cec5SDimitry Andric } // end namespace CodeViewYAML 6110b57cec5SDimitry Andric } // end namespace llvm 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( 6140b57cec5SDimitry Andric BumpPtrAllocator &Allocator, CodeViewContainer Container) const { 6150b57cec5SDimitry Andric return Symbol->toCodeViewSymbol(Allocator, Container); 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric namespace llvm { 6190b57cec5SDimitry Andric namespace yaml { 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric template <> struct MappingTraits<SymbolRecordBase> { 6220b57cec5SDimitry Andric static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } 6230b57cec5SDimitry Andric }; 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric } // end namespace yaml 6260b57cec5SDimitry Andric } // end namespace llvm 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric template <typename SymbolType> 6290b57cec5SDimitry Andric static inline Expected<CodeViewYAML::SymbolRecord> 6300b57cec5SDimitry Andric fromCodeViewSymbolImpl(CVSymbol Symbol) { 6310b57cec5SDimitry Andric CodeViewYAML::SymbolRecord Result; 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric auto Impl = std::make_shared<SymbolType>(Symbol.kind()); 6340b57cec5SDimitry Andric if (auto EC = Impl->fromCodeViewSymbol(Symbol)) 6350b57cec5SDimitry Andric return std::move(EC); 6360b57cec5SDimitry Andric Result.Symbol = Impl; 6370b57cec5SDimitry Andric return Result; 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric Expected<CodeViewYAML::SymbolRecord> 6410b57cec5SDimitry Andric CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { 6420b57cec5SDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 6430b57cec5SDimitry Andric case EnumName: \ 6440b57cec5SDimitry Andric return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol); 6450b57cec5SDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 6460b57cec5SDimitry Andric SYMBOL_RECORD(EnumName, EnumVal, ClassName) 6470b57cec5SDimitry Andric switch (Symbol.kind()) { 6480b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 6490b57cec5SDimitry Andric default: 6500b57cec5SDimitry Andric return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol); 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric return make_error<CodeViewError>(cv_error_code::corrupt_record); 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric template <typename ConcreteType> 6560b57cec5SDimitry Andric static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, 6570b57cec5SDimitry Andric CodeViewYAML::SymbolRecord &Obj) { 6580b57cec5SDimitry Andric if (!IO.outputting()) 6590b57cec5SDimitry Andric Obj.Symbol = std::make_shared<ConcreteType>(Kind); 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric IO.mapRequired(Class, *Obj.Symbol); 6620b57cec5SDimitry Andric } 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( 6650b57cec5SDimitry Andric IO &IO, CodeViewYAML::SymbolRecord &Obj) { 6660b57cec5SDimitry Andric SymbolKind Kind; 6670b57cec5SDimitry Andric if (IO.outputting()) 6680b57cec5SDimitry Andric Kind = Obj.Symbol->Kind; 6690b57cec5SDimitry Andric IO.mapRequired("Kind", Kind); 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 6720b57cec5SDimitry Andric case EnumName: \ 6730b57cec5SDimitry Andric mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \ 6740b57cec5SDimitry Andric Obj); \ 6750b57cec5SDimitry Andric break; 6760b57cec5SDimitry Andric #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 6770b57cec5SDimitry Andric SYMBOL_RECORD(EnumName, EnumVal, ClassName) 6780b57cec5SDimitry Andric switch (Kind) { 6790b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 6800b57cec5SDimitry Andric default: 6810b57cec5SDimitry Andric mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); 6820b57cec5SDimitry Andric } 6830b57cec5SDimitry Andric } 684