11b88f4f3SZachary Turner //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===// 21b88f4f3SZachary Turner // 31b88f4f3SZachary Turner // The LLVM Compiler Infrastructure 41b88f4f3SZachary Turner // 51b88f4f3SZachary Turner // This file is distributed under the University of Illinois Open Source 61b88f4f3SZachary Turner // License. See LICENSE.TXT for details. 71b88f4f3SZachary Turner // 81b88f4f3SZachary Turner //===----------------------------------------------------------------------===// 91b88f4f3SZachary Turner // 101b88f4f3SZachary Turner // This file defines classes for handling the YAML representation of CodeView 111b88f4f3SZachary Turner // Debug Info. 121b88f4f3SZachary Turner // 131b88f4f3SZachary Turner //===----------------------------------------------------------------------===// 141b88f4f3SZachary Turner 151b88f4f3SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" 161b88f4f3SZachary Turner #include "llvm/ADT/StringExtras.h" 171b88f4f3SZachary Turner #include "llvm/ADT/StringSwitch.h" 181b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 191b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 201b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h" 211b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 221b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" 231b88f4f3SZachary Turner 241b88f4f3SZachary Turner using namespace llvm; 251b88f4f3SZachary Turner using namespace llvm::codeview; 261b88f4f3SZachary Turner using namespace llvm::CodeViewYAML; 271b88f4f3SZachary Turner using namespace llvm::CodeViewYAML::detail; 281b88f4f3SZachary Turner using namespace llvm::yaml; 291b88f4f3SZachary Turner 301b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) 311b88f4f3SZachary Turner LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) 321b88f4f3SZachary Turner 331b88f4f3SZachary Turner // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp 341b88f4f3SZachary Turner LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) 351b88f4f3SZachary Turner LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) 361b88f4f3SZachary Turner 371b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) 3863055455SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind) 391b88f4f3SZachary Turner 401b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) 411b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) 421b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags) 4318d90e17SReid Kleckner LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags) 441b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags) 451b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags) 461b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions) 471b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType) 481b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId) 491b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType) 501b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal) 511b88f4f3SZachary Turner 52349c18f8SZachary Turner LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, TypeName) 53349c18f8SZachary Turner 54349c18f8SZachary Turner LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, true) 55349c18f8SZachary Turner 56349c18f8SZachary Turner StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) { 57349c18f8SZachary Turner return ScalarTraits<StringRef>::input(S, V, T.value); 58349c18f8SZachary Turner } 59349c18f8SZachary Turner void ScalarTraits<TypeName>::output(const TypeName &T, void *V, 60349c18f8SZachary Turner llvm::raw_ostream &R) { 61349c18f8SZachary Turner ScalarTraits<StringRef>::output(T.value, V, R); 62349c18f8SZachary Turner } 63349c18f8SZachary Turner 641b88f4f3SZachary Turner void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io, 651b88f4f3SZachary Turner SymbolKind &Value) { 661b88f4f3SZachary Turner auto SymbolNames = getSymbolTypeNames(); 671b88f4f3SZachary Turner for (const auto &E : SymbolNames) 681b88f4f3SZachary Turner io.enumCase(Value, E.Name.str().c_str(), E.Value); 691b88f4f3SZachary Turner } 701b88f4f3SZachary Turner 711b88f4f3SZachary Turner void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io, 721b88f4f3SZachary Turner CompileSym2Flags &Flags) { 731b88f4f3SZachary Turner auto FlagNames = getCompileSym2FlagNames(); 741b88f4f3SZachary Turner for (const auto &E : FlagNames) { 751b88f4f3SZachary Turner io.bitSetCase(Flags, E.Name.str().c_str(), 761b88f4f3SZachary Turner static_cast<CompileSym2Flags>(E.Value)); 771b88f4f3SZachary Turner } 781b88f4f3SZachary Turner } 791b88f4f3SZachary Turner 801b88f4f3SZachary Turner void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io, 811b88f4f3SZachary Turner CompileSym3Flags &Flags) { 821b88f4f3SZachary Turner auto FlagNames = getCompileSym3FlagNames(); 831b88f4f3SZachary Turner for (const auto &E : FlagNames) { 841b88f4f3SZachary Turner io.bitSetCase(Flags, E.Name.str().c_str(), 851b88f4f3SZachary Turner static_cast<CompileSym3Flags>(E.Value)); 861b88f4f3SZachary Turner } 871b88f4f3SZachary Turner } 881b88f4f3SZachary Turner 891b88f4f3SZachary Turner void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) { 901b88f4f3SZachary Turner auto FlagNames = getExportSymFlagNames(); 911b88f4f3SZachary Turner for (const auto &E : FlagNames) { 921b88f4f3SZachary Turner io.bitSetCase(Flags, E.Name.str().c_str(), 931b88f4f3SZachary Turner static_cast<ExportFlags>(E.Value)); 941b88f4f3SZachary Turner } 951b88f4f3SZachary Turner } 961b88f4f3SZachary Turner 9718d90e17SReid Kleckner void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) { 9818d90e17SReid Kleckner auto FlagNames = getProcSymFlagNames(); 9918d90e17SReid Kleckner for (const auto &E : FlagNames) { 10018d90e17SReid Kleckner io.bitSetCase(Flags, E.Name.str().c_str(), 10118d90e17SReid Kleckner static_cast<PublicSymFlags>(E.Value)); 10218d90e17SReid Kleckner } 10318d90e17SReid Kleckner } 10418d90e17SReid Kleckner 1051b88f4f3SZachary Turner void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) { 1061b88f4f3SZachary Turner auto FlagNames = getLocalFlagNames(); 1071b88f4f3SZachary Turner for (const auto &E : FlagNames) { 1081b88f4f3SZachary Turner io.bitSetCase(Flags, E.Name.str().c_str(), 1091b88f4f3SZachary Turner static_cast<LocalSymFlags>(E.Value)); 1101b88f4f3SZachary Turner } 1111b88f4f3SZachary Turner } 1121b88f4f3SZachary Turner 1131b88f4f3SZachary Turner void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) { 1141b88f4f3SZachary Turner auto FlagNames = getProcSymFlagNames(); 1151b88f4f3SZachary Turner for (const auto &E : FlagNames) { 1161b88f4f3SZachary Turner io.bitSetCase(Flags, E.Name.str().c_str(), 1171b88f4f3SZachary Turner static_cast<ProcSymFlags>(E.Value)); 1181b88f4f3SZachary Turner } 1191b88f4f3SZachary Turner } 1201b88f4f3SZachary Turner 1211b88f4f3SZachary Turner void ScalarBitSetTraits<FrameProcedureOptions>::bitset( 1221b88f4f3SZachary Turner IO &io, FrameProcedureOptions &Flags) { 1231b88f4f3SZachary Turner auto FlagNames = getFrameProcSymFlagNames(); 1241b88f4f3SZachary Turner for (const auto &E : FlagNames) { 1251b88f4f3SZachary Turner io.bitSetCase(Flags, E.Name.str().c_str(), 1261b88f4f3SZachary Turner static_cast<FrameProcedureOptions>(E.Value)); 1271b88f4f3SZachary Turner } 1281b88f4f3SZachary Turner } 1291b88f4f3SZachary Turner 1301b88f4f3SZachary Turner void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) { 1311b88f4f3SZachary Turner auto CpuNames = getCPUTypeNames(); 1321b88f4f3SZachary Turner for (const auto &E : CpuNames) { 1331b88f4f3SZachary Turner io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value)); 1341b88f4f3SZachary Turner } 1351b88f4f3SZachary Turner } 1361b88f4f3SZachary Turner 1371b88f4f3SZachary Turner void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) { 1381b88f4f3SZachary Turner auto RegNames = getRegisterNames(); 1391b88f4f3SZachary Turner for (const auto &E : RegNames) { 1401b88f4f3SZachary Turner io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); 1411b88f4f3SZachary Turner } 1421b88f4f3SZachary Turner io.enumFallback<Hex16>(Reg); 1431b88f4f3SZachary Turner } 1441b88f4f3SZachary Turner 1451b88f4f3SZachary Turner void ScalarEnumerationTraits<TrampolineType>::enumeration( 1461b88f4f3SZachary Turner IO &io, TrampolineType &Tramp) { 1471b88f4f3SZachary Turner auto TrampNames = getTrampolineNames(); 1481b88f4f3SZachary Turner for (const auto &E : TrampNames) { 1491b88f4f3SZachary Turner io.enumCase(Tramp, E.Name.str().c_str(), 1501b88f4f3SZachary Turner static_cast<TrampolineType>(E.Value)); 1511b88f4f3SZachary Turner } 1521b88f4f3SZachary Turner } 1531b88f4f3SZachary Turner 1541b88f4f3SZachary Turner void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, 1551b88f4f3SZachary Turner ThunkOrdinal &Ord) { 1561b88f4f3SZachary Turner auto ThunkNames = getThunkOrdinalNames(); 1571b88f4f3SZachary Turner for (const auto &E : ThunkNames) { 1581b88f4f3SZachary Turner io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); 1591b88f4f3SZachary Turner } 1601b88f4f3SZachary Turner } 1611b88f4f3SZachary Turner 16263055455SZachary Turner void ScalarEnumerationTraits<FrameCookieKind>::enumeration( 16363055455SZachary Turner IO &io, FrameCookieKind &FC) { 16463055455SZachary Turner auto ThunkNames = getFrameCookieKindNames(); 16563055455SZachary Turner for (const auto &E : ThunkNames) { 16663055455SZachary Turner io.enumCase(FC, E.Name.str().c_str(), 16763055455SZachary Turner static_cast<FrameCookieKind>(E.Value)); 16863055455SZachary Turner } 16963055455SZachary Turner } 17063055455SZachary Turner 1711b88f4f3SZachary Turner namespace llvm { 1721b88f4f3SZachary Turner namespace CodeViewYAML { 1731b88f4f3SZachary Turner namespace detail { 1741b88f4f3SZachary Turner 1751b88f4f3SZachary Turner struct SymbolRecordBase { 1761b88f4f3SZachary Turner codeview::SymbolKind Kind; 1771b88f4f3SZachary Turner explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} 1781b88f4f3SZachary Turner 1791b88f4f3SZachary Turner virtual ~SymbolRecordBase() {} 1801b88f4f3SZachary Turner virtual void map(yaml::IO &io) = 0; 1811b88f4f3SZachary Turner virtual codeview::CVSymbol 182ebd3ae83SZachary Turner toCodeViewSymbol(BumpPtrAllocator &Allocator, 183ebd3ae83SZachary Turner CodeViewContainer Container) const = 0; 1841b88f4f3SZachary Turner virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; 1851b88f4f3SZachary Turner }; 1861b88f4f3SZachary Turner 1871b88f4f3SZachary Turner template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { 1881b88f4f3SZachary Turner explicit SymbolRecordImpl(codeview::SymbolKind K) 1891b88f4f3SZachary Turner : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} 1901b88f4f3SZachary Turner 1911b88f4f3SZachary Turner void map(yaml::IO &io) override; 1921b88f4f3SZachary Turner 1931b88f4f3SZachary Turner codeview::CVSymbol 194ebd3ae83SZachary Turner toCodeViewSymbol(BumpPtrAllocator &Allocator, 195ebd3ae83SZachary Turner CodeViewContainer Container) const override { 196ebd3ae83SZachary Turner return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); 1971b88f4f3SZachary Turner } 1981b88f4f3SZachary Turner Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { 1991b88f4f3SZachary Turner return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); 2001b88f4f3SZachary Turner } 2011b88f4f3SZachary Turner 2021b88f4f3SZachary Turner mutable T Symbol; 2031b88f4f3SZachary Turner }; 2041b88f4f3SZachary Turner 205606d7665SZachary Turner struct UnknownSymbolRecord : public SymbolRecordBase { 206606d7665SZachary Turner explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} 207606d7665SZachary Turner 208606d7665SZachary Turner void map(yaml::IO &io) override; 209606d7665SZachary Turner 210606d7665SZachary Turner CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, 211606d7665SZachary Turner CodeViewContainer Container) const override { 212606d7665SZachary Turner RecordPrefix Prefix; 213606d7665SZachary Turner uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); 214606d7665SZachary Turner Prefix.RecordKind = Kind; 215606d7665SZachary Turner Prefix.RecordLen = TotalLen - 2; 216606d7665SZachary Turner uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen); 217606d7665SZachary Turner ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); 218606d7665SZachary Turner ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); 219606d7665SZachary Turner return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen)); 220606d7665SZachary Turner } 221606d7665SZachary Turner Error fromCodeViewSymbol(CVSymbol CVS) override { 222606d7665SZachary Turner this->Kind = CVS.kind(); 223606d7665SZachary Turner Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); 224606d7665SZachary Turner return Error::success(); 225606d7665SZachary Turner } 226606d7665SZachary Turner 227606d7665SZachary Turner std::vector<uint8_t> Data; 228606d7665SZachary Turner }; 229606d7665SZachary Turner 2301b88f4f3SZachary Turner template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} 2311b88f4f3SZachary Turner 232606d7665SZachary Turner void UnknownSymbolRecord::map(yaml::IO &io) { 233606d7665SZachary Turner yaml::BinaryRef Binary; 234606d7665SZachary Turner if (io.outputting()) 235606d7665SZachary Turner Binary = yaml::BinaryRef(Data); 236606d7665SZachary Turner io.mapRequired("Data", Binary); 237606d7665SZachary Turner if (!io.outputting()) { 238606d7665SZachary Turner std::string Str; 239606d7665SZachary Turner raw_string_ostream OS(Str); 240606d7665SZachary Turner Binary.writeAsBinary(OS); 241606d7665SZachary Turner OS.flush(); 242606d7665SZachary Turner Data.assign(Str.begin(), Str.end()); 243606d7665SZachary Turner } 244606d7665SZachary Turner } 245606d7665SZachary Turner 2461b88f4f3SZachary Turner template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { 2471b88f4f3SZachary Turner IO.mapRequired("Parent", Symbol.Parent); 2481b88f4f3SZachary Turner IO.mapRequired("End", Symbol.End); 2491b88f4f3SZachary Turner IO.mapRequired("Next", Symbol.Next); 2501b88f4f3SZachary Turner IO.mapRequired("Off", Symbol.Offset); 2511b88f4f3SZachary Turner IO.mapRequired("Seg", Symbol.Segment); 2521b88f4f3SZachary Turner IO.mapRequired("Len", Symbol.Length); 2531b88f4f3SZachary Turner IO.mapRequired("Ordinal", Symbol.Thunk); 2541b88f4f3SZachary Turner } 2551b88f4f3SZachary Turner 2561b88f4f3SZachary Turner template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { 2571b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 2581b88f4f3SZachary Turner IO.mapRequired("Size", Symbol.Size); 2591b88f4f3SZachary Turner IO.mapRequired("ThunkOff", Symbol.ThunkOffset); 2601b88f4f3SZachary Turner IO.mapRequired("TargetOff", Symbol.TargetOffset); 2611b88f4f3SZachary Turner IO.mapRequired("ThunkSection", Symbol.ThunkSection); 2621b88f4f3SZachary Turner IO.mapRequired("TargetSection", Symbol.TargetSection); 2631b88f4f3SZachary Turner } 2641b88f4f3SZachary Turner 2651b88f4f3SZachary Turner template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { 2661b88f4f3SZachary Turner IO.mapRequired("SectionNumber", Symbol.SectionNumber); 2671b88f4f3SZachary Turner IO.mapRequired("Alignment", Symbol.Alignment); 2681b88f4f3SZachary Turner IO.mapRequired("Rva", Symbol.Rva); 2691b88f4f3SZachary Turner IO.mapRequired("Length", Symbol.Length); 2701b88f4f3SZachary Turner IO.mapRequired("Characteristics", Symbol.Characteristics); 2711b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 2721b88f4f3SZachary Turner } 2731b88f4f3SZachary Turner 2741b88f4f3SZachary Turner template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { 2751b88f4f3SZachary Turner IO.mapRequired("Size", Symbol.Size); 2761b88f4f3SZachary Turner IO.mapRequired("Characteristics", Symbol.Characteristics); 2771b88f4f3SZachary Turner IO.mapRequired("Offset", Symbol.Offset); 2781b88f4f3SZachary Turner IO.mapRequired("Segment", Symbol.Segment); 2791b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 2801b88f4f3SZachary Turner } 2811b88f4f3SZachary Turner 2821b88f4f3SZachary Turner template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { 2831b88f4f3SZachary Turner IO.mapRequired("Ordinal", Symbol.Ordinal); 2841b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 2851b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 2861b88f4f3SZachary Turner } 2871b88f4f3SZachary Turner 2881b88f4f3SZachary Turner template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { 289*91ef9de6SReid Kleckner IO.mapOptional("PtrParent", Symbol.Parent, 0U); 290*91ef9de6SReid Kleckner IO.mapOptional("PtrEnd", Symbol.End, 0U); 291*91ef9de6SReid Kleckner IO.mapOptional("PtrNext", Symbol.Next, 0U); 2921b88f4f3SZachary Turner IO.mapRequired("CodeSize", Symbol.CodeSize); 2931b88f4f3SZachary Turner IO.mapRequired("DbgStart", Symbol.DbgStart); 2941b88f4f3SZachary Turner IO.mapRequired("DbgEnd", Symbol.DbgEnd); 2951b88f4f3SZachary Turner IO.mapRequired("FunctionType", Symbol.FunctionType); 296*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 297*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 2981b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 2991b88f4f3SZachary Turner IO.mapRequired("DisplayName", Symbol.Name); 3001b88f4f3SZachary Turner } 3011b88f4f3SZachary Turner 3021b88f4f3SZachary Turner template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { 3031b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Index); 3041b88f4f3SZachary Turner IO.mapRequired("Seg", Symbol.Register); 3051b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 3061b88f4f3SZachary Turner } 3071b88f4f3SZachary Turner 3081b88f4f3SZachary Turner template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { 30918d90e17SReid Kleckner IO.mapRequired("Flags", Symbol.Flags); 310*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.Offset, 0U); 311*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 3121b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 3131b88f4f3SZachary Turner } 3141b88f4f3SZachary Turner 3151b88f4f3SZachary Turner template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { 3161b88f4f3SZachary Turner IO.mapRequired("SumName", Symbol.SumName); 3171b88f4f3SZachary Turner IO.mapRequired("SymOffset", Symbol.SymOffset); 3181b88f4f3SZachary Turner IO.mapRequired("Mod", Symbol.Module); 3191b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 3201b88f4f3SZachary Turner } 3211b88f4f3SZachary Turner 3221b88f4f3SZachary Turner template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { 3231b88f4f3SZachary Turner IO.mapRequired("Entries", Symbol.Fields); 3241b88f4f3SZachary Turner } 3251b88f4f3SZachary Turner 3261b88f4f3SZachary Turner template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { 327*91ef9de6SReid Kleckner IO.mapOptional("PtrParent", Symbol.Parent, 0U); 328*91ef9de6SReid Kleckner IO.mapOptional("PtrEnd", Symbol.End, 0U); 3291b88f4f3SZachary Turner IO.mapRequired("Inlinee", Symbol.Inlinee); 3301b88f4f3SZachary Turner // TODO: The binary annotations 3311b88f4f3SZachary Turner } 3321b88f4f3SZachary Turner 3331b88f4f3SZachary Turner template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { 3341b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 3351b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 336349c18f8SZachary Turner 3371b88f4f3SZachary Turner IO.mapRequired("VarName", Symbol.Name); 3381b88f4f3SZachary Turner } 3391b88f4f3SZachary Turner 3401b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { 3411b88f4f3SZachary Turner // TODO: Print the subfields 3421b88f4f3SZachary Turner } 3431b88f4f3SZachary Turner 3441b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { 3451b88f4f3SZachary Turner // TODO: Print the subfields 3461b88f4f3SZachary Turner } 3471b88f4f3SZachary Turner 3481b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { 3491b88f4f3SZachary Turner // TODO: Print the subfields 3501b88f4f3SZachary Turner } 3511b88f4f3SZachary Turner 3521b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { 3531b88f4f3SZachary Turner // TODO: Print the subfields 3541b88f4f3SZachary Turner } 3551b88f4f3SZachary Turner 3561b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { 3571b88f4f3SZachary Turner // TODO: Print the subfields 3581b88f4f3SZachary Turner } 3591b88f4f3SZachary Turner 3601b88f4f3SZachary Turner template <> 3611b88f4f3SZachary Turner void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { 3621b88f4f3SZachary Turner // TODO: Print the subfields 3631b88f4f3SZachary Turner } 3641b88f4f3SZachary Turner 3651b88f4f3SZachary Turner template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { 3661b88f4f3SZachary Turner // TODO: Print the subfields 3671b88f4f3SZachary Turner } 3681b88f4f3SZachary Turner 3691b88f4f3SZachary Turner template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { 370*91ef9de6SReid Kleckner IO.mapOptional("PtrParent", Symbol.Parent, 0U); 371*91ef9de6SReid Kleckner IO.mapOptional("PtrEnd", Symbol.End, 0U); 3721b88f4f3SZachary Turner IO.mapRequired("CodeSize", Symbol.CodeSize); 373*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 374*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 3751b88f4f3SZachary Turner IO.mapRequired("BlockName", Symbol.Name); 3761b88f4f3SZachary Turner } 3771b88f4f3SZachary Turner 3781b88f4f3SZachary Turner template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { 379*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 380*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 3811b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 3821b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 3831b88f4f3SZachary Turner IO.mapRequired("DisplayName", Symbol.Name); 3841b88f4f3SZachary Turner } 3851b88f4f3SZachary Turner 3861b88f4f3SZachary Turner template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { 3871b88f4f3SZachary Turner IO.mapRequired("Signature", Symbol.Signature); 3881b88f4f3SZachary Turner IO.mapRequired("ObjectName", Symbol.Name); 3891b88f4f3SZachary Turner } 3901b88f4f3SZachary Turner 3911b88f4f3SZachary Turner template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { 3921b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 3931b88f4f3SZachary Turner IO.mapRequired("Machine", Symbol.Machine); 3941b88f4f3SZachary Turner IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 3951b88f4f3SZachary Turner IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 3961b88f4f3SZachary Turner IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 3971b88f4f3SZachary Turner IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 3981b88f4f3SZachary Turner IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 3991b88f4f3SZachary Turner IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 4001b88f4f3SZachary Turner IO.mapRequired("Version", Symbol.Version); 4011b88f4f3SZachary Turner } 4021b88f4f3SZachary Turner 4031b88f4f3SZachary Turner template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { 4041b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 4051b88f4f3SZachary Turner IO.mapRequired("Machine", Symbol.Machine); 4061b88f4f3SZachary Turner IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 4071b88f4f3SZachary Turner IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 4081b88f4f3SZachary Turner IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 4091b88f4f3SZachary Turner IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); 4101b88f4f3SZachary Turner IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 4111b88f4f3SZachary Turner IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 4121b88f4f3SZachary Turner IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 4131b88f4f3SZachary Turner IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); 4141b88f4f3SZachary Turner IO.mapRequired("Version", Symbol.Version); 4151b88f4f3SZachary Turner } 4161b88f4f3SZachary Turner 4171b88f4f3SZachary Turner template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { 4181b88f4f3SZachary Turner IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); 4191b88f4f3SZachary Turner IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); 4201b88f4f3SZachary Turner IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); 4211b88f4f3SZachary Turner IO.mapRequired("BytesOfCalleeSavedRegisters", 4221b88f4f3SZachary Turner Symbol.BytesOfCalleeSavedRegisters); 4231b88f4f3SZachary Turner IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); 4241b88f4f3SZachary Turner IO.mapRequired("SectionIdOfExceptionHandler", 4251b88f4f3SZachary Turner Symbol.SectionIdOfExceptionHandler); 4261b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 4271b88f4f3SZachary Turner } 4281b88f4f3SZachary Turner 4291b88f4f3SZachary Turner template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { 430*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 431*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 4321b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 4331b88f4f3SZachary Turner } 4341b88f4f3SZachary Turner 4351b88f4f3SZachary Turner template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { 4361b88f4f3SZachary Turner IO.mapRequired("Index", Symbol.Index); 4371b88f4f3SZachary Turner IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); 4381b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 4391b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 4401b88f4f3SZachary Turner } 4411b88f4f3SZachary Turner 4421b88f4f3SZachary Turner template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { 443*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 444*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 4451b88f4f3SZachary Turner IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); 4461b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 4471b88f4f3SZachary Turner } 4481b88f4f3SZachary Turner 4491b88f4f3SZachary Turner template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { 4501b88f4f3SZachary Turner IO.mapRequired("Register", Symbol.Register); 4511b88f4f3SZachary Turner IO.mapRequired("CookieKind", Symbol.CookieKind); 4521b88f4f3SZachary Turner IO.mapRequired("Flags", Symbol.Flags); 4531b88f4f3SZachary Turner } 4541b88f4f3SZachary Turner 4551b88f4f3SZachary Turner template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { 4561b88f4f3SZachary Turner IO.mapRequired("FuncID", Symbol.Indices); 4571b88f4f3SZachary Turner } 4581b88f4f3SZachary Turner 4591b88f4f3SZachary Turner template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { 4601b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 4611b88f4f3SZachary Turner IO.mapRequired("UDTName", Symbol.Name); 4621b88f4f3SZachary Turner } 4631b88f4f3SZachary Turner 4641b88f4f3SZachary Turner template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { 4651b88f4f3SZachary Turner IO.mapRequired("BuildId", Symbol.BuildId); 4661b88f4f3SZachary Turner } 4671b88f4f3SZachary Turner 4681b88f4f3SZachary Turner template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { 4691b88f4f3SZachary Turner IO.mapRequired("Offset", Symbol.Offset); 4701b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 4711b88f4f3SZachary Turner IO.mapRequired("VarName", Symbol.Name); 4721b88f4f3SZachary Turner } 4731b88f4f3SZachary Turner 4741b88f4f3SZachary Turner template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { 4751b88f4f3SZachary Turner IO.mapRequired("Offset", Symbol.Offset); 4761b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 4771b88f4f3SZachary Turner IO.mapRequired("Register", Symbol.Register); 4781b88f4f3SZachary Turner IO.mapRequired("VarName", Symbol.Name); 4791b88f4f3SZachary Turner } 4801b88f4f3SZachary Turner 4811b88f4f3SZachary Turner template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { 4821b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 4831b88f4f3SZachary Turner IO.mapRequired("Value", Symbol.Value); 4841b88f4f3SZachary Turner IO.mapRequired("Name", Symbol.Name); 4851b88f4f3SZachary Turner } 4861b88f4f3SZachary Turner 4871b88f4f3SZachary Turner template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { 4881b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 489*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.DataOffset, 0U); 490665e1c92SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 4911b88f4f3SZachary Turner IO.mapRequired("DisplayName", Symbol.Name); 4921b88f4f3SZachary Turner } 4931b88f4f3SZachary Turner 4941b88f4f3SZachary Turner template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { 4951b88f4f3SZachary Turner IO.mapRequired("Type", Symbol.Type); 496*91ef9de6SReid Kleckner IO.mapOptional("Offset", Symbol.DataOffset, 0U); 497*91ef9de6SReid Kleckner IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 4981b88f4f3SZachary Turner IO.mapRequired("DisplayName", Symbol.Name); 4991b88f4f3SZachary Turner } 5001b88f4f3SZachary Turner } 5011b88f4f3SZachary Turner } 5021b88f4f3SZachary Turner } 5031b88f4f3SZachary Turner 5041b88f4f3SZachary Turner CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( 505ebd3ae83SZachary Turner BumpPtrAllocator &Allocator, CodeViewContainer Container) const { 506ebd3ae83SZachary Turner return Symbol->toCodeViewSymbol(Allocator, Container); 5071b88f4f3SZachary Turner } 5081b88f4f3SZachary Turner 5091b88f4f3SZachary Turner namespace llvm { 5101b88f4f3SZachary Turner namespace yaml { 5111b88f4f3SZachary Turner template <> struct MappingTraits<SymbolRecordBase> { 5121b88f4f3SZachary Turner static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } 5131b88f4f3SZachary Turner }; 5141b88f4f3SZachary Turner } 5151b88f4f3SZachary Turner } 5161b88f4f3SZachary Turner 5171b88f4f3SZachary Turner template <typename SymbolType> 5181b88f4f3SZachary Turner static inline Expected<CodeViewYAML::SymbolRecord> 5191b88f4f3SZachary Turner fromCodeViewSymbolImpl(CVSymbol Symbol) { 5201b88f4f3SZachary Turner CodeViewYAML::SymbolRecord Result; 5211b88f4f3SZachary Turner 522606d7665SZachary Turner auto Impl = std::make_shared<SymbolType>(Symbol.kind()); 5231b88f4f3SZachary Turner if (auto EC = Impl->fromCodeViewSymbol(Symbol)) 5241b88f4f3SZachary Turner return std::move(EC); 5251b88f4f3SZachary Turner Result.Symbol = Impl; 5261b88f4f3SZachary Turner return Result; 5271b88f4f3SZachary Turner } 5281b88f4f3SZachary Turner 5291b88f4f3SZachary Turner Expected<CodeViewYAML::SymbolRecord> 5301b88f4f3SZachary Turner CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { 5311b88f4f3SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 5321b88f4f3SZachary Turner case EnumName: \ 533606d7665SZachary Turner return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol); 5341b88f4f3SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 5351b88f4f3SZachary Turner SYMBOL_RECORD(EnumName, EnumVal, ClassName) 5361b88f4f3SZachary Turner switch (Symbol.kind()) { 5371b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 538606d7665SZachary Turner default: 539606d7665SZachary Turner return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol); 5401b88f4f3SZachary Turner } 5411b88f4f3SZachary Turner return make_error<CodeViewError>(cv_error_code::corrupt_record); 5421b88f4f3SZachary Turner } 5431b88f4f3SZachary Turner 5441b88f4f3SZachary Turner template <typename ConcreteType> 5451b88f4f3SZachary Turner static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, 5461b88f4f3SZachary Turner CodeViewYAML::SymbolRecord &Obj) { 5471b88f4f3SZachary Turner if (!IO.outputting()) 548606d7665SZachary Turner Obj.Symbol = std::make_shared<ConcreteType>(Kind); 5491b88f4f3SZachary Turner 5501b88f4f3SZachary Turner IO.mapRequired(Class, *Obj.Symbol); 5511b88f4f3SZachary Turner } 5521b88f4f3SZachary Turner 5531b88f4f3SZachary Turner void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( 5541b88f4f3SZachary Turner IO &IO, CodeViewYAML::SymbolRecord &Obj) { 5551b88f4f3SZachary Turner SymbolKind Kind; 5561b88f4f3SZachary Turner if (IO.outputting()) 5571b88f4f3SZachary Turner Kind = Obj.Symbol->Kind; 5581b88f4f3SZachary Turner IO.mapRequired("Kind", Kind); 5591b88f4f3SZachary Turner 5601b88f4f3SZachary Turner #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 5611b88f4f3SZachary Turner case EnumName: \ 562606d7665SZachary Turner mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \ 563606d7665SZachary Turner Obj); \ 5641b88f4f3SZachary Turner break; 5651b88f4f3SZachary Turner #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 5661b88f4f3SZachary Turner SYMBOL_RECORD(EnumName, EnumVal, ClassName) 5671b88f4f3SZachary Turner switch (Kind) { 5681b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 569606d7665SZachary Turner default: 570606d7665SZachary Turner mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); 5711b88f4f3SZachary Turner } 5721b88f4f3SZachary Turner } 573