Path: blob/main/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
35233 views
//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines classes for handling the YAML representation of CodeView9// Debug Info.10//11//===----------------------------------------------------------------------===//1213#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"14#include "llvm/ADT/ArrayRef.h"15#include "llvm/ADT/StringRef.h"16#include "llvm/DebugInfo/CodeView/CodeView.h"17#include "llvm/DebugInfo/CodeView/CodeViewError.h"18#include "llvm/DebugInfo/CodeView/EnumTables.h"19#include "llvm/DebugInfo/CodeView/RecordSerialization.h"20#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"21#include "llvm/DebugInfo/CodeView/SymbolRecord.h"22#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"23#include "llvm/DebugInfo/CodeView/TypeIndex.h"24#include "llvm/ObjectYAML/YAML.h"25#include "llvm/Support/Allocator.h"26#include "llvm/Support/Error.h"27#include "llvm/Support/ScopedPrinter.h"28#include "llvm/Support/YAMLTraits.h"29#include <algorithm>30#include <cstdint>31#include <cstring>32#include <optional>33#include <string>34#include <vector>3536using namespace llvm;37using namespace llvm::codeview;38using namespace llvm::CodeViewYAML;39using namespace llvm::CodeViewYAML::detail;40using namespace llvm::yaml;4142LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)43LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)4445// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp46LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)47LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)4849LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)50LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)5152LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)53LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)54LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)55LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)56LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)57LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)58LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)59LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)60LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)61LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)62LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)63LLVM_YAML_DECLARE_ENUM_TRAITS(JumpTableEntrySize)6465LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)6667LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)6869StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {70return ScalarTraits<StringRef>::input(S, V, T.value);71}7273void ScalarTraits<TypeName>::output(const TypeName &T, void *V,74raw_ostream &R) {75ScalarTraits<StringRef>::output(T.value, V, R);76}7778void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,79SymbolKind &Value) {80auto SymbolNames = getSymbolTypeNames();81for (const auto &E : SymbolNames)82io.enumCase(Value, E.Name.str().c_str(), E.Value);83}8485void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,86CompileSym2Flags &Flags) {87auto FlagNames = getCompileSym2FlagNames();88for (const auto &E : FlagNames) {89io.bitSetCase(Flags, E.Name.str().c_str(),90static_cast<CompileSym2Flags>(E.Value));91}92}9394void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,95CompileSym3Flags &Flags) {96auto FlagNames = getCompileSym3FlagNames();97for (const auto &E : FlagNames) {98io.bitSetCase(Flags, E.Name.str().c_str(),99static_cast<CompileSym3Flags>(E.Value));100}101}102103void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {104auto FlagNames = getExportSymFlagNames();105for (const auto &E : FlagNames) {106io.bitSetCase(Flags, E.Name.str().c_str(),107static_cast<ExportFlags>(E.Value));108}109}110111void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {112auto FlagNames = getPublicSymFlagNames();113for (const auto &E : FlagNames) {114io.bitSetCase(Flags, E.Name.str().c_str(),115static_cast<PublicSymFlags>(E.Value));116}117}118119void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {120auto FlagNames = getLocalFlagNames();121for (const auto &E : FlagNames) {122io.bitSetCase(Flags, E.Name.str().c_str(),123static_cast<LocalSymFlags>(E.Value));124}125}126127void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {128auto FlagNames = getProcSymFlagNames();129for (const auto &E : FlagNames) {130io.bitSetCase(Flags, E.Name.str().c_str(),131static_cast<ProcSymFlags>(E.Value));132}133}134135void ScalarBitSetTraits<FrameProcedureOptions>::bitset(136IO &io, FrameProcedureOptions &Flags) {137auto FlagNames = getFrameProcSymFlagNames();138for (const auto &E : FlagNames) {139io.bitSetCase(Flags, E.Name.str().c_str(),140static_cast<FrameProcedureOptions>(E.Value));141}142}143144void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {145auto CpuNames = getCPUTypeNames();146for (const auto &E : CpuNames) {147io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));148}149}150151void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {152const auto *Header = static_cast<COFF::header *>(io.getContext());153assert(Header && "The IO context is not initialized");154155std::optional<CPUType> CpuType;156ArrayRef<EnumEntry<uint16_t>> RegNames;157158switch (Header->Machine) {159case COFF::IMAGE_FILE_MACHINE_I386:160CpuType = CPUType::Pentium3;161break;162case COFF::IMAGE_FILE_MACHINE_AMD64:163CpuType = CPUType::X64;164break;165case COFF::IMAGE_FILE_MACHINE_ARMNT:166CpuType = CPUType::ARMNT;167break;168case COFF::IMAGE_FILE_MACHINE_ARM64:169case COFF::IMAGE_FILE_MACHINE_ARM64EC:170case COFF::IMAGE_FILE_MACHINE_ARM64X:171CpuType = CPUType::ARM64;172break;173}174175if (CpuType)176RegNames = getRegisterNames(*CpuType);177178for (const auto &E : RegNames) {179io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));180}181io.enumFallback<Hex16>(Reg);182}183184void ScalarEnumerationTraits<TrampolineType>::enumeration(185IO &io, TrampolineType &Tramp) {186auto TrampNames = getTrampolineNames();187for (const auto &E : TrampNames) {188io.enumCase(Tramp, E.Name.str().c_str(),189static_cast<TrampolineType>(E.Value));190}191}192193void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,194ThunkOrdinal &Ord) {195auto ThunkNames = getThunkOrdinalNames();196for (const auto &E : ThunkNames) {197io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));198}199}200201void ScalarEnumerationTraits<FrameCookieKind>::enumeration(202IO &io, FrameCookieKind &FC) {203auto ThunkNames = getFrameCookieKindNames();204for (const auto &E : ThunkNames) {205io.enumCase(FC, E.Name.str().c_str(),206static_cast<FrameCookieKind>(E.Value));207}208}209210void ScalarEnumerationTraits<JumpTableEntrySize>::enumeration(211IO &io, JumpTableEntrySize &FC) {212auto ThunkNames = getJumpTableEntrySizeNames();213for (const auto &E : ThunkNames) {214io.enumCase(FC, E.Name.str().c_str(),215static_cast<JumpTableEntrySize>(E.Value));216}217}218219namespace llvm {220namespace yaml {221template <> struct MappingTraits<LocalVariableAddrRange> {222static void mapping(IO &io, LocalVariableAddrRange &Range) {223io.mapRequired("OffsetStart", Range.OffsetStart);224io.mapRequired("ISectStart", Range.ISectStart);225io.mapRequired("Range", Range.Range);226}227};228template <> struct MappingTraits<LocalVariableAddrGap> {229static void mapping(IO &io, LocalVariableAddrGap &Gap) {230io.mapRequired("GapStartOffset", Gap.GapStartOffset);231io.mapRequired("Range", Gap.Range);232}233};234} // namespace yaml235} // namespace llvm236237namespace llvm {238namespace CodeViewYAML {239namespace detail {240241struct SymbolRecordBase {242codeview::SymbolKind Kind;243244explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}245virtual ~SymbolRecordBase() = default;246247virtual void map(yaml::IO &io) = 0;248virtual codeview::CVSymbol249toCodeViewSymbol(BumpPtrAllocator &Allocator,250CodeViewContainer Container) const = 0;251virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;252};253254template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {255explicit SymbolRecordImpl(codeview::SymbolKind K)256: SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}257258void map(yaml::IO &io) override;259260codeview::CVSymbol261toCodeViewSymbol(BumpPtrAllocator &Allocator,262CodeViewContainer Container) const override {263return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);264}265266Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {267return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);268}269270mutable T Symbol;271};272273struct UnknownSymbolRecord : public SymbolRecordBase {274explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}275276void map(yaml::IO &io) override;277278CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,279CodeViewContainer Container) const override {280RecordPrefix Prefix;281uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();282Prefix.RecordKind = Kind;283Prefix.RecordLen = TotalLen - 2;284uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);285::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));286::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());287return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));288}289290Error fromCodeViewSymbol(CVSymbol CVS) override {291this->Kind = CVS.kind();292Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));293return Error::success();294}295296std::vector<uint8_t> Data;297};298299template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}300301void UnknownSymbolRecord::map(yaml::IO &io) {302yaml::BinaryRef Binary;303if (io.outputting())304Binary = yaml::BinaryRef(Data);305io.mapRequired("Data", Binary);306if (!io.outputting()) {307std::string Str;308raw_string_ostream OS(Str);309Binary.writeAsBinary(OS);310OS.flush();311Data.assign(Str.begin(), Str.end());312}313}314315template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {316IO.mapRequired("Parent", Symbol.Parent);317IO.mapRequired("End", Symbol.End);318IO.mapRequired("Next", Symbol.Next);319IO.mapRequired("Off", Symbol.Offset);320IO.mapRequired("Seg", Symbol.Segment);321IO.mapRequired("Len", Symbol.Length);322IO.mapRequired("Ordinal", Symbol.Thunk);323}324325template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {326IO.mapRequired("Type", Symbol.Type);327IO.mapRequired("Size", Symbol.Size);328IO.mapRequired("ThunkOff", Symbol.ThunkOffset);329IO.mapRequired("TargetOff", Symbol.TargetOffset);330IO.mapRequired("ThunkSection", Symbol.ThunkSection);331IO.mapRequired("TargetSection", Symbol.TargetSection);332}333334template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {335IO.mapRequired("SectionNumber", Symbol.SectionNumber);336IO.mapRequired("Alignment", Symbol.Alignment);337IO.mapRequired("Rva", Symbol.Rva);338IO.mapRequired("Length", Symbol.Length);339IO.mapRequired("Characteristics", Symbol.Characteristics);340IO.mapRequired("Name", Symbol.Name);341}342343template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {344IO.mapRequired("Size", Symbol.Size);345IO.mapRequired("Characteristics", Symbol.Characteristics);346IO.mapRequired("Offset", Symbol.Offset);347IO.mapRequired("Segment", Symbol.Segment);348IO.mapRequired("Name", Symbol.Name);349}350351template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {352IO.mapRequired("Ordinal", Symbol.Ordinal);353IO.mapRequired("Flags", Symbol.Flags);354IO.mapRequired("Name", Symbol.Name);355}356357template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {358IO.mapOptional("PtrParent", Symbol.Parent, 0U);359IO.mapOptional("PtrEnd", Symbol.End, 0U);360IO.mapOptional("PtrNext", Symbol.Next, 0U);361IO.mapRequired("CodeSize", Symbol.CodeSize);362IO.mapRequired("DbgStart", Symbol.DbgStart);363IO.mapRequired("DbgEnd", Symbol.DbgEnd);364IO.mapRequired("FunctionType", Symbol.FunctionType);365IO.mapOptional("Offset", Symbol.CodeOffset, 0U);366IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));367IO.mapRequired("Flags", Symbol.Flags);368IO.mapRequired("DisplayName", Symbol.Name);369}370371template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {372IO.mapRequired("Type", Symbol.Index);373IO.mapRequired("Seg", Symbol.Register);374IO.mapRequired("Name", Symbol.Name);375}376377template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {378IO.mapRequired("Flags", Symbol.Flags);379IO.mapOptional("Offset", Symbol.Offset, 0U);380IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));381IO.mapRequired("Name", Symbol.Name);382}383384template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {385IO.mapRequired("SumName", Symbol.SumName);386IO.mapRequired("SymOffset", Symbol.SymOffset);387IO.mapRequired("Mod", Symbol.Module);388IO.mapRequired("Name", Symbol.Name);389}390391template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {392IO.mapRequired("Entries", Symbol.Fields);393}394395template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {396IO.mapOptional("PtrParent", Symbol.Parent, 0U);397IO.mapOptional("PtrEnd", Symbol.End, 0U);398IO.mapRequired("Inlinee", Symbol.Inlinee);399// TODO: The binary annotations400}401402template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {403IO.mapRequired("Type", Symbol.Type);404IO.mapRequired("Flags", Symbol.Flags);405406IO.mapRequired("VarName", Symbol.Name);407}408409template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {410IO.mapRequired("Program", Symbol.Program);411IO.mapRequired("Range", Symbol.Range);412IO.mapRequired("Gaps", Symbol.Gaps);413}414415template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {416IO.mapRequired("Program", Symbol.Program);417IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);418IO.mapRequired("Range", Symbol.Range);419IO.mapRequired("Gaps", Symbol.Gaps);420}421422template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {423IO.mapRequired("Register", Symbol.Hdr.Register);424IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);425IO.mapRequired("Range", Symbol.Range);426IO.mapRequired("Gaps", Symbol.Gaps);427}428429template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {430IO.mapRequired("Offset", Symbol.Hdr.Offset);431IO.mapRequired("Range", Symbol.Range);432IO.mapRequired("Gaps", Symbol.Gaps);433}434435template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {436IO.mapRequired("Register", Symbol.Hdr.Register);437IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);438IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);439IO.mapRequired("Range", Symbol.Range);440IO.mapRequired("Gaps", Symbol.Gaps);441}442443template <>444void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {445IO.mapRequired("Register", Symbol.Offset);446}447448template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {449IO.mapRequired("Register", Symbol.Hdr.Register);450IO.mapRequired("Flags", Symbol.Hdr.Flags);451IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);452IO.mapRequired("Range", Symbol.Range);453IO.mapRequired("Gaps", Symbol.Gaps);454}455456template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {457IO.mapOptional("PtrParent", Symbol.Parent, 0U);458IO.mapOptional("PtrEnd", Symbol.End, 0U);459IO.mapRequired("CodeSize", Symbol.CodeSize);460IO.mapOptional("Offset", Symbol.CodeOffset, 0U);461IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));462IO.mapRequired("BlockName", Symbol.Name);463}464465template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {466IO.mapOptional("Offset", Symbol.CodeOffset, 0U);467IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));468IO.mapRequired("Flags", Symbol.Flags);469IO.mapRequired("DisplayName", Symbol.Name);470}471472template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {473IO.mapRequired("Signature", Symbol.Signature);474IO.mapRequired("ObjectName", Symbol.Name);475}476477template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {478IO.mapRequired("Flags", Symbol.Flags);479IO.mapRequired("Machine", Symbol.Machine);480IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);481IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);482IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);483IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);484IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);485IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);486IO.mapRequired("Version", Symbol.Version);487}488489template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {490IO.mapRequired("Flags", Symbol.Flags);491IO.mapRequired("Machine", Symbol.Machine);492IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);493IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);494IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);495IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);496IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);497IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);498IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);499IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);500IO.mapRequired("Version", Symbol.Version);501}502503template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {504IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);505IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);506IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);507IO.mapRequired("BytesOfCalleeSavedRegisters",508Symbol.BytesOfCalleeSavedRegisters);509IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);510IO.mapRequired("SectionIdOfExceptionHandler",511Symbol.SectionIdOfExceptionHandler);512IO.mapRequired("Flags", Symbol.Flags);513}514515template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {516IO.mapOptional("Offset", Symbol.CodeOffset, 0U);517IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));518IO.mapRequired("Type", Symbol.Type);519}520521template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {522IO.mapRequired("Index", Symbol.Index);523IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);524IO.mapRequired("Flags", Symbol.Flags);525IO.mapRequired("Name", Symbol.Name);526}527528template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {529IO.mapOptional("Offset", Symbol.CodeOffset, 0U);530IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));531IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);532IO.mapRequired("Type", Symbol.Type);533}534535template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {536IO.mapRequired("Register", Symbol.Register);537IO.mapRequired("CookieKind", Symbol.CookieKind);538IO.mapRequired("Flags", Symbol.Flags);539}540541template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {542IO.mapRequired("FuncID", Symbol.Indices);543}544545template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {546IO.mapRequired("Type", Symbol.Type);547IO.mapRequired("UDTName", Symbol.Name);548}549550template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {551IO.mapRequired("BuildId", Symbol.BuildId);552}553554template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {555IO.mapRequired("Offset", Symbol.Offset);556IO.mapRequired("Type", Symbol.Type);557IO.mapRequired("VarName", Symbol.Name);558}559560template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {561IO.mapRequired("Offset", Symbol.Offset);562IO.mapRequired("Type", Symbol.Type);563IO.mapRequired("Register", Symbol.Register);564IO.mapRequired("VarName", Symbol.Name);565}566567template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {568IO.mapRequired("Type", Symbol.Type);569IO.mapRequired("Value", Symbol.Value);570IO.mapRequired("Name", Symbol.Name);571}572573template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {574IO.mapRequired("Type", Symbol.Type);575IO.mapOptional("Offset", Symbol.DataOffset, 0U);576IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));577IO.mapRequired("DisplayName", Symbol.Name);578}579580template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {581IO.mapRequired("Type", Symbol.Type);582IO.mapOptional("Offset", Symbol.DataOffset, 0U);583IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));584IO.mapRequired("DisplayName", Symbol.Name);585}586587template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {588IO.mapRequired("Namespace", Symbol.Name);589}590591template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {592IO.mapOptional("Offset", Symbol.CodeOffset, 0U);593IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));594IO.mapRequired("Strings", Symbol.Strings);595}596597template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) {598IO.mapRequired("BaseOffset", Symbol.BaseOffset);599IO.mapRequired("BaseSegment", Symbol.BaseSegment);600IO.mapRequired("SwitchType", Symbol.SwitchType);601IO.mapRequired("BranchOffset", Symbol.BranchOffset);602IO.mapRequired("TableOffset", Symbol.TableOffset);603IO.mapRequired("BranchSegment", Symbol.BranchSegment);604IO.mapRequired("TableSegment", Symbol.TableSegment);605IO.mapRequired("EntriesCount", Symbol.EntriesCount);606}607608} // end namespace detail609} // end namespace CodeViewYAML610} // end namespace llvm611612CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(613BumpPtrAllocator &Allocator, CodeViewContainer Container) const {614return Symbol->toCodeViewSymbol(Allocator, Container);615}616617namespace llvm {618namespace yaml {619620template <> struct MappingTraits<SymbolRecordBase> {621static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }622};623624} // end namespace yaml625} // end namespace llvm626627template <typename SymbolType>628static inline Expected<CodeViewYAML::SymbolRecord>629fromCodeViewSymbolImpl(CVSymbol Symbol) {630CodeViewYAML::SymbolRecord Result;631632auto Impl = std::make_shared<SymbolType>(Symbol.kind());633if (auto EC = Impl->fromCodeViewSymbol(Symbol))634return std::move(EC);635Result.Symbol = Impl;636return Result;637}638639Expected<CodeViewYAML::SymbolRecord>640CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {641#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \642case EnumName: \643return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);644#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \645SYMBOL_RECORD(EnumName, EnumVal, ClassName)646switch (Symbol.kind()) {647#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"648default:649return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);650}651return make_error<CodeViewError>(cv_error_code::corrupt_record);652}653654template <typename ConcreteType>655static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,656CodeViewYAML::SymbolRecord &Obj) {657if (!IO.outputting())658Obj.Symbol = std::make_shared<ConcreteType>(Kind);659660IO.mapRequired(Class, *Obj.Symbol);661}662663void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(664IO &IO, CodeViewYAML::SymbolRecord &Obj) {665SymbolKind Kind;666if (IO.outputting())667Kind = Obj.Symbol->Kind;668IO.mapRequired("Kind", Kind);669670#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \671case EnumName: \672mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \673Obj); \674break;675#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \676SYMBOL_RECORD(EnumName, EnumVal, ClassName)677switch (Kind) {678#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"679default:680mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);681}682}683684685