11b88f4f3SZachary Turner //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===// 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/CodeViewYAMLDebugSections.h" 1628082ab0SEugene Zelenko #include "llvm/ADT/STLExtras.h" 171b88f4f3SZachary Turner #include "llvm/ADT/StringExtras.h" 1828082ab0SEugene Zelenko #include "llvm/ADT/StringRef.h" 1928082ab0SEugene Zelenko #include "llvm/BinaryFormat/COFF.h" 2028082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/CodeView.h" 211b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 2292dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" 23349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h" 24349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" 25deb39130SZachary Turner #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" 2692dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" 2792dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 2892dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 2928082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/DebugSubsection.h" 3092dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" 313226fe95SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h" 32deb39130SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" 3328082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/Line.h" 34a8cfc29cSZachary Turner #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" 3528082ab0SEugene Zelenko #include "llvm/DebugInfo/CodeView/TypeIndex.h" 36deb39130SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" 3728082ab0SEugene Zelenko #include "llvm/Support/Allocator.h" 3828082ab0SEugene Zelenko #include "llvm/Support/BinaryStreamReader.h" 3928082ab0SEugene Zelenko #include "llvm/Support/Endian.h" 4028082ab0SEugene Zelenko #include "llvm/Support/Error.h" 4128082ab0SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 4228082ab0SEugene Zelenko #include "llvm/Support/YAMLTraits.h" 4328082ab0SEugene Zelenko #include "llvm/Support/raw_ostream.h" 4428082ab0SEugene Zelenko #include <algorithm> 4528082ab0SEugene Zelenko #include <cassert> 4628082ab0SEugene Zelenko #include <cstdint> 4728082ab0SEugene Zelenko #include <memory> 4828082ab0SEugene Zelenko #include <string> 4928082ab0SEugene Zelenko #include <tuple> 5028082ab0SEugene Zelenko #include <vector> 5128082ab0SEugene Zelenko 521b88f4f3SZachary Turner using namespace llvm; 531b88f4f3SZachary Turner using namespace llvm::codeview; 541b88f4f3SZachary Turner using namespace llvm::CodeViewYAML; 551b88f4f3SZachary Turner using namespace llvm::CodeViewYAML::detail; 561b88f4f3SZachary Turner using namespace llvm::yaml; 571b88f4f3SZachary Turner 581b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry) 591b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry) 601b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry) 611b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock) 621b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo) 631b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite) 641b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) 65349c18f8SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport) 66349c18f8SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport) 67deb39130SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData) 681b88f4f3SZachary Turner 69b213b27eSFrancis Visoiu Mistrih LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None) 7092dcdda6SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind) 711b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) 721b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) 731b88f4f3SZachary Turner 74349c18f8SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport) 75deb39130SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData) 76349c18f8SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport) 77349c18f8SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem) 7892dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) 7992dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry) 8092dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry) 8192dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock) 8292dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite) 8392dcdda6SZachary Turner 8492dcdda6SZachary Turner namespace llvm { 8592dcdda6SZachary Turner namespace CodeViewYAML { 8692dcdda6SZachary Turner namespace detail { 8728082ab0SEugene Zelenko 8892dcdda6SZachary Turner struct YAMLSubsectionBase { 8992dcdda6SZachary Turner explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {} 9028082ab0SEugene Zelenko virtual ~YAMLSubsectionBase() = default; 9192dcdda6SZachary Turner 9292dcdda6SZachary Turner virtual void map(IO &IO) = 0; 93a8cfc29cSZachary Turner virtual std::shared_ptr<DebugSubsection> 94deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 95a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const = 0; 9628082ab0SEugene Zelenko 9728082ab0SEugene Zelenko DebugSubsectionKind Kind; 9892dcdda6SZachary Turner }; 9928082ab0SEugene Zelenko 10028082ab0SEugene Zelenko } // end namespace detail 10128082ab0SEugene Zelenko } // end namespace CodeViewYAML 10228082ab0SEugene Zelenko } // end namespace llvm 10392dcdda6SZachary Turner 10492dcdda6SZachary Turner namespace { 10528082ab0SEugene Zelenko 10692dcdda6SZachary Turner struct YAMLChecksumsSubsection : public YAMLSubsectionBase { 10792dcdda6SZachary Turner YAMLChecksumsSubsection() 10892dcdda6SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} 10992dcdda6SZachary Turner 11092dcdda6SZachary Turner void map(IO &IO) override; 111a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 112deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 113a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 11492dcdda6SZachary Turner static Expected<std::shared_ptr<YAMLChecksumsSubsection>> 11592dcdda6SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 11692dcdda6SZachary Turner const DebugChecksumsSubsectionRef &FC); 11792dcdda6SZachary Turner 11892dcdda6SZachary Turner std::vector<SourceFileChecksumEntry> Checksums; 11992dcdda6SZachary Turner }; 12092dcdda6SZachary Turner 12192dcdda6SZachary Turner struct YAMLLinesSubsection : public YAMLSubsectionBase { 12292dcdda6SZachary Turner YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} 12392dcdda6SZachary Turner 12492dcdda6SZachary Turner void map(IO &IO) override; 125a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 126deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 127a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 12892dcdda6SZachary Turner static Expected<std::shared_ptr<YAMLLinesSubsection>> 12992dcdda6SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 13092dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 13192dcdda6SZachary Turner const DebugLinesSubsectionRef &Lines); 13292dcdda6SZachary Turner 13392dcdda6SZachary Turner SourceLineInfo Lines; 13492dcdda6SZachary Turner }; 13592dcdda6SZachary Turner 13692dcdda6SZachary Turner struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { 13792dcdda6SZachary Turner YAMLInlineeLinesSubsection() 13892dcdda6SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} 13992dcdda6SZachary Turner 14092dcdda6SZachary Turner void map(IO &IO) override; 141a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 142deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 143a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 14492dcdda6SZachary Turner static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> 14592dcdda6SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 14692dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 14792dcdda6SZachary Turner const DebugInlineeLinesSubsectionRef &Lines); 14892dcdda6SZachary Turner 14992dcdda6SZachary Turner InlineeInfo InlineeLines; 15092dcdda6SZachary Turner }; 151349c18f8SZachary Turner 152349c18f8SZachary Turner struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase { 153349c18f8SZachary Turner YAMLCrossModuleExportsSubsection() 154349c18f8SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {} 155349c18f8SZachary Turner 156349c18f8SZachary Turner void map(IO &IO) override; 157a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 158deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 159a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 160349c18f8SZachary Turner static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> 161349c18f8SZachary Turner fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports); 162349c18f8SZachary Turner 163349c18f8SZachary Turner std::vector<CrossModuleExport> Exports; 164349c18f8SZachary Turner }; 165349c18f8SZachary Turner 166349c18f8SZachary Turner struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { 167349c18f8SZachary Turner YAMLCrossModuleImportsSubsection() 168349c18f8SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {} 169349c18f8SZachary Turner 170349c18f8SZachary Turner void map(IO &IO) override; 171a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 172deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 173a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 174349c18f8SZachary Turner static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> 175349c18f8SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 176349c18f8SZachary Turner const DebugCrossModuleImportsSubsectionRef &Imports); 177349c18f8SZachary Turner 178349c18f8SZachary Turner std::vector<YAMLCrossModuleImport> Imports; 179349c18f8SZachary Turner }; 180deb39130SZachary Turner 181deb39130SZachary Turner struct YAMLSymbolsSubsection : public YAMLSubsectionBase { 182deb39130SZachary Turner YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {} 183deb39130SZachary Turner 184deb39130SZachary Turner void map(IO &IO) override; 185a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 186deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 187a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 188deb39130SZachary Turner static Expected<std::shared_ptr<YAMLSymbolsSubsection>> 189deb39130SZachary Turner fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols); 190deb39130SZachary Turner 191deb39130SZachary Turner std::vector<CodeViewYAML::SymbolRecord> Symbols; 192deb39130SZachary Turner }; 193deb39130SZachary Turner 194deb39130SZachary Turner struct YAMLStringTableSubsection : public YAMLSubsectionBase { 195deb39130SZachary Turner YAMLStringTableSubsection() 196deb39130SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {} 197deb39130SZachary Turner 198deb39130SZachary Turner void map(IO &IO) override; 199a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 200deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 201a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 202deb39130SZachary Turner static Expected<std::shared_ptr<YAMLStringTableSubsection>> 203deb39130SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings); 204deb39130SZachary Turner 205deb39130SZachary Turner std::vector<StringRef> Strings; 206deb39130SZachary Turner }; 207deb39130SZachary Turner 208deb39130SZachary Turner struct YAMLFrameDataSubsection : public YAMLSubsectionBase { 209deb39130SZachary Turner YAMLFrameDataSubsection() 210deb39130SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {} 211deb39130SZachary Turner 212deb39130SZachary Turner void map(IO &IO) override; 213a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 214deb39130SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 215a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 216deb39130SZachary Turner static Expected<std::shared_ptr<YAMLFrameDataSubsection>> 217deb39130SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 218deb39130SZachary Turner const DebugFrameDataSubsectionRef &Frames); 219deb39130SZachary Turner 220deb39130SZachary Turner std::vector<YAMLFrameData> Frames; 221deb39130SZachary Turner }; 2223226fe95SZachary Turner 2233226fe95SZachary Turner struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase { 2243226fe95SZachary Turner YAMLCoffSymbolRVASubsection() 2253226fe95SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {} 2263226fe95SZachary Turner 2273226fe95SZachary Turner void map(IO &IO) override; 228a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 2293226fe95SZachary Turner toCodeViewSubsection(BumpPtrAllocator &Allocator, 230a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const override; 2313226fe95SZachary Turner static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> 2323226fe95SZachary Turner fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs); 2333226fe95SZachary Turner 2343226fe95SZachary Turner std::vector<uint32_t> RVAs; 2353226fe95SZachary Turner }; 23628082ab0SEugene Zelenko 23728082ab0SEugene Zelenko } // end anonymous namespace 2381b88f4f3SZachary Turner 2391b88f4f3SZachary Turner void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) { 2401b88f4f3SZachary Turner io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); 2411b88f4f3SZachary Turner io.enumFallback<Hex16>(Flags); 2421b88f4f3SZachary Turner } 2431b88f4f3SZachary Turner 2441b88f4f3SZachary Turner void ScalarEnumerationTraits<FileChecksumKind>::enumeration( 2451b88f4f3SZachary Turner IO &io, FileChecksumKind &Kind) { 2461b88f4f3SZachary Turner io.enumCase(Kind, "None", FileChecksumKind::None); 2471b88f4f3SZachary Turner io.enumCase(Kind, "MD5", FileChecksumKind::MD5); 2481b88f4f3SZachary Turner io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1); 2491b88f4f3SZachary Turner io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256); 2501b88f4f3SZachary Turner } 2511b88f4f3SZachary Turner 2521b88f4f3SZachary Turner void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value, 2531b88f4f3SZachary Turner void *ctx, raw_ostream &Out) { 2541b88f4f3SZachary Turner StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()), 2551b88f4f3SZachary Turner Value.Bytes.size()); 2561b88f4f3SZachary Turner Out << toHex(Bytes); 2571b88f4f3SZachary Turner } 2581b88f4f3SZachary Turner 2591b88f4f3SZachary Turner StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt, 2601b88f4f3SZachary Turner HexFormattedString &Value) { 2611b88f4f3SZachary Turner std::string H = fromHex(Scalar); 2621b88f4f3SZachary Turner Value.Bytes.assign(H.begin(), H.end()); 2631b88f4f3SZachary Turner return StringRef(); 2641b88f4f3SZachary Turner } 2651b88f4f3SZachary Turner 2661b88f4f3SZachary Turner void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) { 2671b88f4f3SZachary Turner IO.mapRequired("Offset", Obj.Offset); 2681b88f4f3SZachary Turner IO.mapRequired("LineStart", Obj.LineStart); 2691b88f4f3SZachary Turner IO.mapRequired("IsStatement", Obj.IsStatement); 2701b88f4f3SZachary Turner IO.mapRequired("EndDelta", Obj.EndDelta); 2711b88f4f3SZachary Turner } 2721b88f4f3SZachary Turner 2731b88f4f3SZachary Turner void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) { 2741b88f4f3SZachary Turner IO.mapRequired("StartColumn", Obj.StartColumn); 2751b88f4f3SZachary Turner IO.mapRequired("EndColumn", Obj.EndColumn); 2761b88f4f3SZachary Turner } 2771b88f4f3SZachary Turner 2781b88f4f3SZachary Turner void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) { 2791b88f4f3SZachary Turner IO.mapRequired("FileName", Obj.FileName); 2801b88f4f3SZachary Turner IO.mapRequired("Lines", Obj.Lines); 2811b88f4f3SZachary Turner IO.mapRequired("Columns", Obj.Columns); 2821b88f4f3SZachary Turner } 2831b88f4f3SZachary Turner 284349c18f8SZachary Turner void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) { 285349c18f8SZachary Turner IO.mapRequired("LocalId", Obj.Local); 286349c18f8SZachary Turner IO.mapRequired("GlobalId", Obj.Global); 287349c18f8SZachary Turner } 288349c18f8SZachary Turner 289349c18f8SZachary Turner void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO, 290349c18f8SZachary Turner YAMLCrossModuleImport &Obj) { 291349c18f8SZachary Turner IO.mapRequired("Module", Obj.ModuleName); 292349c18f8SZachary Turner IO.mapRequired("Imports", Obj.ImportIds); 293349c18f8SZachary Turner } 294349c18f8SZachary Turner 2951b88f4f3SZachary Turner void MappingTraits<SourceFileChecksumEntry>::mapping( 2961b88f4f3SZachary Turner IO &IO, SourceFileChecksumEntry &Obj) { 2971b88f4f3SZachary Turner IO.mapRequired("FileName", Obj.FileName); 2981b88f4f3SZachary Turner IO.mapRequired("Kind", Obj.Kind); 2991b88f4f3SZachary Turner IO.mapRequired("Checksum", Obj.ChecksumBytes); 3001b88f4f3SZachary Turner } 3011b88f4f3SZachary Turner 3021b88f4f3SZachary Turner void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { 3031b88f4f3SZachary Turner IO.mapRequired("FileName", Obj.FileName); 3041b88f4f3SZachary Turner IO.mapRequired("LineNum", Obj.SourceLineNum); 3051b88f4f3SZachary Turner IO.mapRequired("Inlinee", Obj.Inlinee); 3061b88f4f3SZachary Turner IO.mapOptional("ExtraFiles", Obj.ExtraFiles); 3071b88f4f3SZachary Turner } 3081b88f4f3SZachary Turner 309deb39130SZachary Turner void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) { 310deb39130SZachary Turner IO.mapRequired("CodeSize", Obj.CodeSize); 311deb39130SZachary Turner IO.mapRequired("FrameFunc", Obj.FrameFunc); 312deb39130SZachary Turner IO.mapRequired("LocalSize", Obj.LocalSize); 313deb39130SZachary Turner IO.mapOptional("MaxStackSize", Obj.MaxStackSize); 314deb39130SZachary Turner IO.mapOptional("ParamsSize", Obj.ParamsSize); 315deb39130SZachary Turner IO.mapOptional("PrologSize", Obj.PrologSize); 316deb39130SZachary Turner IO.mapOptional("RvaStart", Obj.RvaStart); 317deb39130SZachary Turner IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize); 318deb39130SZachary Turner } 319deb39130SZachary Turner 32092dcdda6SZachary Turner void YAMLChecksumsSubsection::map(IO &IO) { 32192dcdda6SZachary Turner IO.mapTag("!FileChecksums", true); 32292dcdda6SZachary Turner IO.mapRequired("Checksums", Checksums); 32392dcdda6SZachary Turner } 32492dcdda6SZachary Turner 32592dcdda6SZachary Turner void YAMLLinesSubsection::map(IO &IO) { 32692dcdda6SZachary Turner IO.mapTag("!Lines", true); 32792dcdda6SZachary Turner IO.mapRequired("CodeSize", Lines.CodeSize); 32892dcdda6SZachary Turner 32992dcdda6SZachary Turner IO.mapRequired("Flags", Lines.Flags); 33092dcdda6SZachary Turner IO.mapRequired("RelocOffset", Lines.RelocOffset); 33192dcdda6SZachary Turner IO.mapRequired("RelocSegment", Lines.RelocSegment); 33292dcdda6SZachary Turner IO.mapRequired("Blocks", Lines.Blocks); 33392dcdda6SZachary Turner } 33492dcdda6SZachary Turner 33592dcdda6SZachary Turner void YAMLInlineeLinesSubsection::map(IO &IO) { 33692dcdda6SZachary Turner IO.mapTag("!InlineeLines", true); 33792dcdda6SZachary Turner IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles); 33892dcdda6SZachary Turner IO.mapRequired("Sites", InlineeLines.Sites); 33992dcdda6SZachary Turner } 34092dcdda6SZachary Turner 341349c18f8SZachary Turner void YAMLCrossModuleExportsSubsection::map(IO &IO) { 342349c18f8SZachary Turner IO.mapTag("!CrossModuleExports", true); 343349c18f8SZachary Turner IO.mapOptional("Exports", Exports); 344349c18f8SZachary Turner } 345349c18f8SZachary Turner 346349c18f8SZachary Turner void YAMLCrossModuleImportsSubsection::map(IO &IO) { 347349c18f8SZachary Turner IO.mapTag("!CrossModuleImports", true); 348349c18f8SZachary Turner IO.mapOptional("Imports", Imports); 349349c18f8SZachary Turner } 350349c18f8SZachary Turner 351deb39130SZachary Turner void YAMLSymbolsSubsection::map(IO &IO) { 352deb39130SZachary Turner IO.mapTag("!Symbols", true); 353deb39130SZachary Turner IO.mapRequired("Records", Symbols); 354deb39130SZachary Turner } 355deb39130SZachary Turner 356deb39130SZachary Turner void YAMLStringTableSubsection::map(IO &IO) { 357deb39130SZachary Turner IO.mapTag("!StringTable", true); 358deb39130SZachary Turner IO.mapRequired("Strings", Strings); 359deb39130SZachary Turner } 360deb39130SZachary Turner 361deb39130SZachary Turner void YAMLFrameDataSubsection::map(IO &IO) { 362deb39130SZachary Turner IO.mapTag("!FrameData", true); 363deb39130SZachary Turner IO.mapRequired("Frames", Frames); 364deb39130SZachary Turner } 365deb39130SZachary Turner 3663226fe95SZachary Turner void YAMLCoffSymbolRVASubsection::map(IO &IO) { 3673226fe95SZachary Turner IO.mapTag("!COFFSymbolRVAs", true); 3683226fe95SZachary Turner IO.mapRequired("RVAs", RVAs); 3693226fe95SZachary Turner } 3703226fe95SZachary Turner 37192dcdda6SZachary Turner void MappingTraits<YAMLDebugSubsection>::mapping( 37292dcdda6SZachary Turner IO &IO, YAMLDebugSubsection &Subsection) { 37392dcdda6SZachary Turner if (!IO.outputting()) { 37492dcdda6SZachary Turner if (IO.mapTag("!FileChecksums")) { 37592dcdda6SZachary Turner auto SS = std::make_shared<YAMLChecksumsSubsection>(); 37692dcdda6SZachary Turner Subsection.Subsection = SS; 37792dcdda6SZachary Turner } else if (IO.mapTag("!Lines")) { 37892dcdda6SZachary Turner Subsection.Subsection = std::make_shared<YAMLLinesSubsection>(); 37992dcdda6SZachary Turner } else if (IO.mapTag("!InlineeLines")) { 38092dcdda6SZachary Turner Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>(); 381349c18f8SZachary Turner } else if (IO.mapTag("!CrossModuleExports")) { 382349c18f8SZachary Turner Subsection.Subsection = 383349c18f8SZachary Turner std::make_shared<YAMLCrossModuleExportsSubsection>(); 384349c18f8SZachary Turner } else if (IO.mapTag("!CrossModuleImports")) { 385349c18f8SZachary Turner Subsection.Subsection = 386349c18f8SZachary Turner std::make_shared<YAMLCrossModuleImportsSubsection>(); 387deb39130SZachary Turner } else if (IO.mapTag("!Symbols")) { 388deb39130SZachary Turner Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>(); 389deb39130SZachary Turner } else if (IO.mapTag("!StringTable")) { 390deb39130SZachary Turner Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>(); 391deb39130SZachary Turner } else if (IO.mapTag("!FrameData")) { 392deb39130SZachary Turner Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>(); 3933226fe95SZachary Turner } else if (IO.mapTag("!COFFSymbolRVAs")) { 3943226fe95SZachary Turner Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>(); 39592dcdda6SZachary Turner } else { 39692dcdda6SZachary Turner llvm_unreachable("Unexpected subsection tag!"); 39792dcdda6SZachary Turner } 39892dcdda6SZachary Turner } 39992dcdda6SZachary Turner Subsection.Subsection->map(IO); 40092dcdda6SZachary Turner } 40192dcdda6SZachary Turner 402a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection( 403a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 404a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 405a8cfc29cSZachary Turner assert(SC.hasStrings()); 406a8cfc29cSZachary Turner auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings()); 40792dcdda6SZachary Turner for (const auto &CS : Checksums) { 40892dcdda6SZachary Turner Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); 40992dcdda6SZachary Turner } 410a8cfc29cSZachary Turner return Result; 41192dcdda6SZachary Turner } 41292dcdda6SZachary Turner 413a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection( 414a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 415a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 416a8cfc29cSZachary Turner assert(SC.hasStrings() && SC.hasChecksums()); 41792dcdda6SZachary Turner auto Result = 418a8cfc29cSZachary Turner std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings()); 41992dcdda6SZachary Turner Result->setCodeSize(Lines.CodeSize); 42092dcdda6SZachary Turner Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); 42192dcdda6SZachary Turner Result->setFlags(Lines.Flags); 42292dcdda6SZachary Turner for (const auto &LC : Lines.Blocks) { 42392dcdda6SZachary Turner Result->createBlock(LC.FileName); 42492dcdda6SZachary Turner if (Result->hasColumnInfo()) { 42592dcdda6SZachary Turner for (const auto &Item : zip(LC.Lines, LC.Columns)) { 42692dcdda6SZachary Turner auto &L = std::get<0>(Item); 42792dcdda6SZachary Turner auto &C = std::get<1>(Item); 42892dcdda6SZachary Turner uint32_t LE = L.LineStart + L.EndDelta; 42992dcdda6SZachary Turner Result->addLineAndColumnInfo(L.Offset, 43092dcdda6SZachary Turner LineInfo(L.LineStart, LE, L.IsStatement), 43192dcdda6SZachary Turner C.StartColumn, C.EndColumn); 43292dcdda6SZachary Turner } 43392dcdda6SZachary Turner } else { 43492dcdda6SZachary Turner for (const auto &L : LC.Lines) { 43592dcdda6SZachary Turner uint32_t LE = L.LineStart + L.EndDelta; 43692dcdda6SZachary Turner Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement)); 43792dcdda6SZachary Turner } 43892dcdda6SZachary Turner } 43992dcdda6SZachary Turner } 440a8cfc29cSZachary Turner return Result; 44192dcdda6SZachary Turner } 44292dcdda6SZachary Turner 443a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 44492dcdda6SZachary Turner YAMLInlineeLinesSubsection::toCodeViewSubsection( 445a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 446a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 447a8cfc29cSZachary Turner assert(SC.hasChecksums()); 448a8cfc29cSZachary Turner auto Result = std::make_shared<DebugInlineeLinesSubsection>( 449a8cfc29cSZachary Turner *SC.checksums(), InlineeLines.HasExtraFiles); 45092dcdda6SZachary Turner 45192dcdda6SZachary Turner for (const auto &Site : InlineeLines.Sites) { 45292dcdda6SZachary Turner Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, 45392dcdda6SZachary Turner Site.SourceLineNum); 45492dcdda6SZachary Turner if (!InlineeLines.HasExtraFiles) 45592dcdda6SZachary Turner continue; 45692dcdda6SZachary Turner 45792dcdda6SZachary Turner for (auto EF : Site.ExtraFiles) { 45892dcdda6SZachary Turner Result->addExtraFile(EF); 45992dcdda6SZachary Turner } 46092dcdda6SZachary Turner } 461a8cfc29cSZachary Turner return Result; 46292dcdda6SZachary Turner } 46392dcdda6SZachary Turner 464a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 465349c18f8SZachary Turner YAMLCrossModuleExportsSubsection::toCodeViewSubsection( 466a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 467a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 468a8cfc29cSZachary Turner auto Result = std::make_shared<DebugCrossModuleExportsSubsection>(); 469349c18f8SZachary Turner for (const auto &M : Exports) 470349c18f8SZachary Turner Result->addMapping(M.Local, M.Global); 471a8cfc29cSZachary Turner return Result; 472349c18f8SZachary Turner } 473349c18f8SZachary Turner 474a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 475349c18f8SZachary Turner YAMLCrossModuleImportsSubsection::toCodeViewSubsection( 476a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 477a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 478a8cfc29cSZachary Turner assert(SC.hasStrings()); 479a8cfc29cSZachary Turner 480a8cfc29cSZachary Turner auto Result = 481a8cfc29cSZachary Turner std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings()); 482349c18f8SZachary Turner for (const auto &M : Imports) { 483349c18f8SZachary Turner for (const auto Id : M.ImportIds) 484349c18f8SZachary Turner Result->addImport(M.ModuleName, Id); 485349c18f8SZachary Turner } 486a8cfc29cSZachary Turner return Result; 487349c18f8SZachary Turner } 488349c18f8SZachary Turner 489a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection( 490a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 491a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 492a8cfc29cSZachary Turner auto Result = std::make_shared<DebugSymbolsSubsection>(); 493deb39130SZachary Turner for (const auto &Sym : Symbols) 494deb39130SZachary Turner Result->addSymbol( 495deb39130SZachary Turner Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile)); 496a8cfc29cSZachary Turner return Result; 497deb39130SZachary Turner } 498deb39130SZachary Turner 499a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 500deb39130SZachary Turner YAMLStringTableSubsection::toCodeViewSubsection( 501a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 502a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 503a8cfc29cSZachary Turner auto Result = std::make_shared<DebugStringTableSubsection>(); 504deb39130SZachary Turner for (const auto &Str : this->Strings) 505deb39130SZachary Turner Result->insert(Str); 506a8cfc29cSZachary Turner return Result; 507deb39130SZachary Turner } 508deb39130SZachary Turner 509a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection( 510a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 511a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 512a8cfc29cSZachary Turner assert(SC.hasStrings()); 513a8cfc29cSZachary Turner 514*42e7cc1bSZachary Turner auto Result = std::make_shared<DebugFrameDataSubsection>(true); 515deb39130SZachary Turner for (const auto &YF : Frames) { 516deb39130SZachary Turner codeview::FrameData F; 517deb39130SZachary Turner F.CodeSize = YF.CodeSize; 518deb39130SZachary Turner F.Flags = YF.Flags; 519deb39130SZachary Turner F.LocalSize = YF.LocalSize; 520deb39130SZachary Turner F.MaxStackSize = YF.MaxStackSize; 521deb39130SZachary Turner F.ParamsSize = YF.ParamsSize; 522deb39130SZachary Turner F.PrologSize = YF.PrologSize; 523deb39130SZachary Turner F.RvaStart = YF.RvaStart; 524deb39130SZachary Turner F.SavedRegsSize = YF.SavedRegsSize; 525a8cfc29cSZachary Turner F.FrameFunc = SC.strings()->insert(YF.FrameFunc); 526deb39130SZachary Turner Result->addFrameData(F); 527deb39130SZachary Turner } 528a8cfc29cSZachary Turner return Result; 529deb39130SZachary Turner } 530deb39130SZachary Turner 531a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> 5323226fe95SZachary Turner YAMLCoffSymbolRVASubsection::toCodeViewSubsection( 533a8cfc29cSZachary Turner BumpPtrAllocator &Allocator, 534a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) const { 535a8cfc29cSZachary Turner auto Result = std::make_shared<DebugSymbolRVASubsection>(); 5363226fe95SZachary Turner for (const auto &RVA : RVAs) 5373226fe95SZachary Turner Result->addRVA(RVA); 538a8cfc29cSZachary Turner return Result; 5393226fe95SZachary Turner } 5403226fe95SZachary Turner 54192dcdda6SZachary Turner static Expected<SourceFileChecksumEntry> 54292dcdda6SZachary Turner convertOneChecksum(const DebugStringTableSubsectionRef &Strings, 54392dcdda6SZachary Turner const FileChecksumEntry &CS) { 54492dcdda6SZachary Turner auto ExpectedString = Strings.getString(CS.FileNameOffset); 54592dcdda6SZachary Turner if (!ExpectedString) 54692dcdda6SZachary Turner return ExpectedString.takeError(); 54792dcdda6SZachary Turner 54892dcdda6SZachary Turner SourceFileChecksumEntry Result; 54992dcdda6SZachary Turner Result.ChecksumBytes.Bytes = CS.Checksum; 55092dcdda6SZachary Turner Result.Kind = CS.Kind; 55192dcdda6SZachary Turner Result.FileName = *ExpectedString; 55292dcdda6SZachary Turner return Result; 55392dcdda6SZachary Turner } 55492dcdda6SZachary Turner 55592dcdda6SZachary Turner static Expected<StringRef> 55692dcdda6SZachary Turner getFileName(const DebugStringTableSubsectionRef &Strings, 55792dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { 55892dcdda6SZachary Turner auto Iter = Checksums.getArray().at(FileID); 55992dcdda6SZachary Turner if (Iter == Checksums.getArray().end()) 56092dcdda6SZachary Turner return make_error<CodeViewError>(cv_error_code::no_records); 56192dcdda6SZachary Turner uint32_t Offset = Iter->FileNameOffset; 56292dcdda6SZachary Turner return Strings.getString(Offset); 56392dcdda6SZachary Turner } 56492dcdda6SZachary Turner 56592dcdda6SZachary Turner Expected<std::shared_ptr<YAMLChecksumsSubsection>> 56692dcdda6SZachary Turner YAMLChecksumsSubsection::fromCodeViewSubsection( 56792dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 56892dcdda6SZachary Turner const DebugChecksumsSubsectionRef &FC) { 56992dcdda6SZachary Turner auto Result = std::make_shared<YAMLChecksumsSubsection>(); 57092dcdda6SZachary Turner 57192dcdda6SZachary Turner for (const auto &CS : FC) { 57292dcdda6SZachary Turner auto ConvertedCS = convertOneChecksum(Strings, CS); 57392dcdda6SZachary Turner if (!ConvertedCS) 57492dcdda6SZachary Turner return ConvertedCS.takeError(); 57592dcdda6SZachary Turner Result->Checksums.push_back(*ConvertedCS); 57692dcdda6SZachary Turner } 57792dcdda6SZachary Turner return Result; 57892dcdda6SZachary Turner } 57992dcdda6SZachary Turner 58092dcdda6SZachary Turner Expected<std::shared_ptr<YAMLLinesSubsection>> 58192dcdda6SZachary Turner YAMLLinesSubsection::fromCodeViewSubsection( 58292dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 58392dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 58492dcdda6SZachary Turner const DebugLinesSubsectionRef &Lines) { 58592dcdda6SZachary Turner auto Result = std::make_shared<YAMLLinesSubsection>(); 58692dcdda6SZachary Turner Result->Lines.CodeSize = Lines.header()->CodeSize; 58792dcdda6SZachary Turner Result->Lines.RelocOffset = Lines.header()->RelocOffset; 58892dcdda6SZachary Turner Result->Lines.RelocSegment = Lines.header()->RelocSegment; 58992dcdda6SZachary Turner Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags)); 59092dcdda6SZachary Turner for (const auto &L : Lines) { 59192dcdda6SZachary Turner SourceLineBlock Block; 59292dcdda6SZachary Turner auto EF = getFileName(Strings, Checksums, L.NameIndex); 59392dcdda6SZachary Turner if (!EF) 59492dcdda6SZachary Turner return EF.takeError(); 59592dcdda6SZachary Turner Block.FileName = *EF; 59692dcdda6SZachary Turner if (Lines.hasColumnInfo()) { 59792dcdda6SZachary Turner for (const auto &C : L.Columns) { 59892dcdda6SZachary Turner SourceColumnEntry SCE; 59992dcdda6SZachary Turner SCE.EndColumn = C.EndColumn; 60092dcdda6SZachary Turner SCE.StartColumn = C.StartColumn; 60192dcdda6SZachary Turner Block.Columns.push_back(SCE); 60292dcdda6SZachary Turner } 60392dcdda6SZachary Turner } 60492dcdda6SZachary Turner for (const auto &LN : L.LineNumbers) { 60592dcdda6SZachary Turner SourceLineEntry SLE; 60692dcdda6SZachary Turner LineInfo LI(LN.Flags); 60792dcdda6SZachary Turner SLE.Offset = LN.Offset; 60892dcdda6SZachary Turner SLE.LineStart = LI.getStartLine(); 60992dcdda6SZachary Turner SLE.EndDelta = LI.getLineDelta(); 61092dcdda6SZachary Turner SLE.IsStatement = LI.isStatement(); 61192dcdda6SZachary Turner Block.Lines.push_back(SLE); 61292dcdda6SZachary Turner } 61392dcdda6SZachary Turner Result->Lines.Blocks.push_back(Block); 61492dcdda6SZachary Turner } 61592dcdda6SZachary Turner return Result; 61692dcdda6SZachary Turner } 61792dcdda6SZachary Turner 61892dcdda6SZachary Turner Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> 61992dcdda6SZachary Turner YAMLInlineeLinesSubsection::fromCodeViewSubsection( 62092dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 62192dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 62292dcdda6SZachary Turner const DebugInlineeLinesSubsectionRef &Lines) { 62392dcdda6SZachary Turner auto Result = std::make_shared<YAMLInlineeLinesSubsection>(); 62492dcdda6SZachary Turner 62592dcdda6SZachary Turner Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles(); 62692dcdda6SZachary Turner for (const auto &IL : Lines) { 62792dcdda6SZachary Turner InlineeSite Site; 62892dcdda6SZachary Turner auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID); 62992dcdda6SZachary Turner if (!ExpF) 63092dcdda6SZachary Turner return ExpF.takeError(); 63192dcdda6SZachary Turner Site.FileName = *ExpF; 63292dcdda6SZachary Turner Site.Inlinee = IL.Header->Inlinee.getIndex(); 63392dcdda6SZachary Turner Site.SourceLineNum = IL.Header->SourceLineNum; 63492dcdda6SZachary Turner if (Lines.hasExtraFiles()) { 63592dcdda6SZachary Turner for (const auto EF : IL.ExtraFiles) { 63692dcdda6SZachary Turner auto ExpF2 = getFileName(Strings, Checksums, EF); 63792dcdda6SZachary Turner if (!ExpF2) 63892dcdda6SZachary Turner return ExpF2.takeError(); 63992dcdda6SZachary Turner Site.ExtraFiles.push_back(*ExpF2); 64092dcdda6SZachary Turner } 64192dcdda6SZachary Turner } 64292dcdda6SZachary Turner Result->InlineeLines.Sites.push_back(Site); 64392dcdda6SZachary Turner } 64492dcdda6SZachary Turner return Result; 64592dcdda6SZachary Turner } 64692dcdda6SZachary Turner 647349c18f8SZachary Turner Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> 648349c18f8SZachary Turner YAMLCrossModuleExportsSubsection::fromCodeViewSubsection( 649349c18f8SZachary Turner const DebugCrossModuleExportsSubsectionRef &Exports) { 650349c18f8SZachary Turner auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>(); 651349c18f8SZachary Turner Result->Exports.assign(Exports.begin(), Exports.end()); 652349c18f8SZachary Turner return Result; 653349c18f8SZachary Turner } 654349c18f8SZachary Turner 655349c18f8SZachary Turner Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> 656349c18f8SZachary Turner YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( 657349c18f8SZachary Turner const DebugStringTableSubsectionRef &Strings, 658349c18f8SZachary Turner const DebugCrossModuleImportsSubsectionRef &Imports) { 659349c18f8SZachary Turner auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>(); 660349c18f8SZachary Turner for (const auto &CMI : Imports) { 661349c18f8SZachary Turner YAMLCrossModuleImport YCMI; 662349c18f8SZachary Turner auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset); 663349c18f8SZachary Turner if (!ExpectedStr) 664349c18f8SZachary Turner return ExpectedStr.takeError(); 665349c18f8SZachary Turner YCMI.ModuleName = *ExpectedStr; 666349c18f8SZachary Turner YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end()); 667349c18f8SZachary Turner Result->Imports.push_back(YCMI); 668349c18f8SZachary Turner } 669349c18f8SZachary Turner return Result; 670349c18f8SZachary Turner } 671349c18f8SZachary Turner 672deb39130SZachary Turner Expected<std::shared_ptr<YAMLSymbolsSubsection>> 673deb39130SZachary Turner YAMLSymbolsSubsection::fromCodeViewSubsection( 674deb39130SZachary Turner const DebugSymbolsSubsectionRef &Symbols) { 675deb39130SZachary Turner auto Result = std::make_shared<YAMLSymbolsSubsection>(); 676deb39130SZachary Turner for (const auto &Sym : Symbols) { 677deb39130SZachary Turner auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym); 678deb39130SZachary Turner if (!S) 679deb39130SZachary Turner return joinErrors(make_error<CodeViewError>( 680deb39130SZachary Turner cv_error_code::corrupt_record, 681deb39130SZachary Turner "Invalid CodeView Symbol Record in SymbolRecord " 682deb39130SZachary Turner "subsection of .debug$S while converting to YAML!"), 683deb39130SZachary Turner S.takeError()); 684deb39130SZachary Turner 685deb39130SZachary Turner Result->Symbols.push_back(*S); 686deb39130SZachary Turner } 687deb39130SZachary Turner return Result; 688deb39130SZachary Turner } 689deb39130SZachary Turner 690deb39130SZachary Turner Expected<std::shared_ptr<YAMLStringTableSubsection>> 691deb39130SZachary Turner YAMLStringTableSubsection::fromCodeViewSubsection( 692deb39130SZachary Turner const DebugStringTableSubsectionRef &Strings) { 693deb39130SZachary Turner auto Result = std::make_shared<YAMLStringTableSubsection>(); 694deb39130SZachary Turner BinaryStreamReader Reader(Strings.getBuffer()); 695deb39130SZachary Turner StringRef S; 696deb39130SZachary Turner // First item is a single null string, skip it. 697deb39130SZachary Turner if (auto EC = Reader.readCString(S)) 698deb39130SZachary Turner return std::move(EC); 699deb39130SZachary Turner assert(S.empty()); 700deb39130SZachary Turner while (Reader.bytesRemaining() > 0) { 701deb39130SZachary Turner if (auto EC = Reader.readCString(S)) 702deb39130SZachary Turner return std::move(EC); 703deb39130SZachary Turner Result->Strings.push_back(S); 704deb39130SZachary Turner } 705deb39130SZachary Turner return Result; 706deb39130SZachary Turner } 707deb39130SZachary Turner 708deb39130SZachary Turner Expected<std::shared_ptr<YAMLFrameDataSubsection>> 709deb39130SZachary Turner YAMLFrameDataSubsection::fromCodeViewSubsection( 710deb39130SZachary Turner const DebugStringTableSubsectionRef &Strings, 711deb39130SZachary Turner const DebugFrameDataSubsectionRef &Frames) { 712deb39130SZachary Turner auto Result = std::make_shared<YAMLFrameDataSubsection>(); 713deb39130SZachary Turner for (const auto &F : Frames) { 714deb39130SZachary Turner YAMLFrameData YF; 715deb39130SZachary Turner YF.CodeSize = F.CodeSize; 716deb39130SZachary Turner YF.Flags = F.Flags; 717deb39130SZachary Turner YF.LocalSize = F.LocalSize; 718deb39130SZachary Turner YF.MaxStackSize = F.MaxStackSize; 719deb39130SZachary Turner YF.ParamsSize = F.ParamsSize; 720deb39130SZachary Turner YF.PrologSize = F.PrologSize; 721deb39130SZachary Turner YF.RvaStart = F.RvaStart; 722deb39130SZachary Turner YF.SavedRegsSize = F.SavedRegsSize; 723deb39130SZachary Turner 724deb39130SZachary Turner auto ES = Strings.getString(F.FrameFunc); 725deb39130SZachary Turner if (!ES) 726deb39130SZachary Turner return joinErrors( 727deb39130SZachary Turner make_error<CodeViewError>( 728deb39130SZachary Turner cv_error_code::no_records, 729deb39130SZachary Turner "Could not find string for string id while mapping FrameData!"), 730deb39130SZachary Turner ES.takeError()); 731deb39130SZachary Turner YF.FrameFunc = *ES; 732deb39130SZachary Turner Result->Frames.push_back(YF); 733deb39130SZachary Turner } 734deb39130SZachary Turner return Result; 735deb39130SZachary Turner } 736deb39130SZachary Turner 7373226fe95SZachary Turner Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> 7383226fe95SZachary Turner YAMLCoffSymbolRVASubsection::fromCodeViewSubsection( 7393226fe95SZachary Turner const DebugSymbolRVASubsectionRef &Section) { 7403226fe95SZachary Turner auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>(); 7413226fe95SZachary Turner for (const auto &RVA : Section) { 7423226fe95SZachary Turner Result->RVAs.push_back(RVA); 7433226fe95SZachary Turner } 7443226fe95SZachary Turner return Result; 7453226fe95SZachary Turner } 7463226fe95SZachary Turner 747a8cfc29cSZachary Turner Expected<std::vector<std::shared_ptr<DebugSubsection>>> 748deb39130SZachary Turner llvm::CodeViewYAML::toCodeViewSubsectionList( 749deb39130SZachary Turner BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections, 750a8cfc29cSZachary Turner const codeview::StringsAndChecksums &SC) { 751a8cfc29cSZachary Turner std::vector<std::shared_ptr<DebugSubsection>> Result; 75292dcdda6SZachary Turner if (Subsections.empty()) 75364726f22SZachary Turner return std::move(Result); 75492dcdda6SZachary Turner 75592dcdda6SZachary Turner for (const auto &SS : Subsections) { 756a8cfc29cSZachary Turner std::shared_ptr<DebugSubsection> CVS; 757a8cfc29cSZachary Turner CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC); 758349c18f8SZachary Turner assert(CVS != nullptr); 75992dcdda6SZachary Turner Result.push_back(std::move(CVS)); 76092dcdda6SZachary Turner } 76192dcdda6SZachary Turner return std::move(Result); 76292dcdda6SZachary Turner } 76392dcdda6SZachary Turner 76492dcdda6SZachary Turner namespace { 76528082ab0SEugene Zelenko 76692dcdda6SZachary Turner struct SubsectionConversionVisitor : public DebugSubsectionVisitor { 76728082ab0SEugene Zelenko SubsectionConversionVisitor() = default; 76892dcdda6SZachary Turner 76992dcdda6SZachary Turner Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; 7701bf77620SZachary Turner Error visitLines(DebugLinesSubsectionRef &Lines, 771a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 7721bf77620SZachary Turner Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, 773a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 7741bf77620SZachary Turner Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, 775a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 7761bf77620SZachary Turner Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums, 777a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 7781bf77620SZachary Turner Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees, 779a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 780deb39130SZachary Turner Error visitStringTable(DebugStringTableSubsectionRef &ST, 781a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 782deb39130SZachary Turner Error visitSymbols(DebugSymbolsSubsectionRef &Symbols, 783a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 784deb39130SZachary Turner Error visitFrameData(DebugFrameDataSubsectionRef &Symbols, 785a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 7863226fe95SZachary Turner Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols, 787a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) override; 78892dcdda6SZachary Turner 78992dcdda6SZachary Turner YAMLDebugSubsection Subsection; 79092dcdda6SZachary Turner }; 79192dcdda6SZachary Turner 79228082ab0SEugene Zelenko } // end anonymous namespace 79328082ab0SEugene Zelenko 79492dcdda6SZachary Turner Error SubsectionConversionVisitor::visitUnknown( 79592dcdda6SZachary Turner DebugUnknownSubsectionRef &Unknown) { 79692dcdda6SZachary Turner return make_error<CodeViewError>(cv_error_code::operation_unsupported); 79792dcdda6SZachary Turner } 79892dcdda6SZachary Turner 7991bf77620SZachary Turner Error SubsectionConversionVisitor::visitLines( 800a8cfc29cSZachary Turner DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) { 8011bf77620SZachary Turner auto Result = YAMLLinesSubsection::fromCodeViewSubsection( 8021bf77620SZachary Turner State.strings(), State.checksums(), Lines); 80392dcdda6SZachary Turner if (!Result) 80492dcdda6SZachary Turner return Result.takeError(); 80592dcdda6SZachary Turner Subsection.Subsection = *Result; 80692dcdda6SZachary Turner return Error::success(); 80792dcdda6SZachary Turner } 80892dcdda6SZachary Turner 80992dcdda6SZachary Turner Error SubsectionConversionVisitor::visitFileChecksums( 810a8cfc29cSZachary Turner DebugChecksumsSubsectionRef &Checksums, 811a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) { 8121bf77620SZachary Turner auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(), 8131bf77620SZachary Turner Checksums); 81492dcdda6SZachary Turner if (!Result) 81592dcdda6SZachary Turner return Result.takeError(); 81692dcdda6SZachary Turner Subsection.Subsection = *Result; 81792dcdda6SZachary Turner return Error::success(); 81892dcdda6SZachary Turner } 81992dcdda6SZachary Turner 82092dcdda6SZachary Turner Error SubsectionConversionVisitor::visitInlineeLines( 8211bf77620SZachary Turner DebugInlineeLinesSubsectionRef &Inlinees, 822a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) { 82392dcdda6SZachary Turner auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( 8241bf77620SZachary Turner State.strings(), State.checksums(), Inlinees); 82592dcdda6SZachary Turner if (!Result) 82692dcdda6SZachary Turner return Result.takeError(); 82792dcdda6SZachary Turner Subsection.Subsection = *Result; 82892dcdda6SZachary Turner return Error::success(); 82992dcdda6SZachary Turner } 830349c18f8SZachary Turner 831349c18f8SZachary Turner Error SubsectionConversionVisitor::visitCrossModuleExports( 8321bf77620SZachary Turner DebugCrossModuleExportsSubsectionRef &Exports, 833a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) { 834349c18f8SZachary Turner auto Result = 835349c18f8SZachary Turner YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports); 836349c18f8SZachary Turner if (!Result) 837349c18f8SZachary Turner return Result.takeError(); 838349c18f8SZachary Turner Subsection.Subsection = *Result; 839349c18f8SZachary Turner return Error::success(); 840349c18f8SZachary Turner } 841349c18f8SZachary Turner 842349c18f8SZachary Turner Error SubsectionConversionVisitor::visitCrossModuleImports( 8431bf77620SZachary Turner DebugCrossModuleImportsSubsectionRef &Imports, 844a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) { 845349c18f8SZachary Turner auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( 8461bf77620SZachary Turner State.strings(), Imports); 847349c18f8SZachary Turner if (!Result) 848349c18f8SZachary Turner return Result.takeError(); 849349c18f8SZachary Turner Subsection.Subsection = *Result; 850349c18f8SZachary Turner return Error::success(); 851349c18f8SZachary Turner } 852deb39130SZachary Turner 853deb39130SZachary Turner Error SubsectionConversionVisitor::visitStringTable( 854a8cfc29cSZachary Turner DebugStringTableSubsectionRef &Strings, 855a8cfc29cSZachary Turner const StringsAndChecksumsRef &State) { 856deb39130SZachary Turner auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings); 857deb39130SZachary Turner if (!Result) 858deb39130SZachary Turner return Result.takeError(); 859deb39130SZachary Turner Subsection.Subsection = *Result; 860deb39130SZachary Turner return Error::success(); 861deb39130SZachary Turner } 862deb39130SZachary Turner 863deb39130SZachary Turner Error SubsectionConversionVisitor::visitSymbols( 864a8cfc29cSZachary Turner DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) { 865deb39130SZachary Turner auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols); 866deb39130SZachary Turner if (!Result) 867deb39130SZachary Turner return Result.takeError(); 868deb39130SZachary Turner Subsection.Subsection = *Result; 869deb39130SZachary Turner return Error::success(); 870deb39130SZachary Turner } 871deb39130SZachary Turner 872deb39130SZachary Turner Error SubsectionConversionVisitor::visitFrameData( 873a8cfc29cSZachary Turner DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) { 874deb39130SZachary Turner auto Result = 875deb39130SZachary Turner YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames); 876deb39130SZachary Turner if (!Result) 877deb39130SZachary Turner return Result.takeError(); 878deb39130SZachary Turner Subsection.Subsection = *Result; 879deb39130SZachary Turner return Error::success(); 880deb39130SZachary Turner } 8813226fe95SZachary Turner 8823226fe95SZachary Turner Error SubsectionConversionVisitor::visitCOFFSymbolRVAs( 883a8cfc29cSZachary Turner DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) { 8843226fe95SZachary Turner auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs); 8853226fe95SZachary Turner if (!Result) 8863226fe95SZachary Turner return Result.takeError(); 8873226fe95SZachary Turner Subsection.Subsection = *Result; 8883226fe95SZachary Turner return Error::success(); 8893226fe95SZachary Turner } 89092dcdda6SZachary Turner 891a8cfc29cSZachary Turner Expected<YAMLDebugSubsection> 892a8cfc29cSZachary Turner YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC, 89392dcdda6SZachary Turner const DebugSubsectionRecord &SS) { 8941bf77620SZachary Turner SubsectionConversionVisitor V; 895a8cfc29cSZachary Turner if (auto EC = visitDebugSubsection(SS, V, SC)) 89692dcdda6SZachary Turner return std::move(EC); 89792dcdda6SZachary Turner 89892dcdda6SZachary Turner return V.Subsection; 8991b88f4f3SZachary Turner } 900deb39130SZachary Turner 901a8cfc29cSZachary Turner std::vector<YAMLDebugSubsection> 902a8cfc29cSZachary Turner llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data, 903a8cfc29cSZachary Turner const StringsAndChecksumsRef &SC) { 904a8cfc29cSZachary Turner BinaryStreamReader Reader(Data, support::little); 905a8cfc29cSZachary Turner uint32_t Magic; 906a8cfc29cSZachary Turner 907a8cfc29cSZachary Turner ExitOnError Err("Invalid .debug$S section!"); 908a8cfc29cSZachary Turner Err(Reader.readInteger(Magic)); 909a8cfc29cSZachary Turner assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!"); 910a8cfc29cSZachary Turner 911a8cfc29cSZachary Turner DebugSubsectionArray Subsections; 912a8cfc29cSZachary Turner Err(Reader.readArray(Subsections, Reader.bytesRemaining())); 913a8cfc29cSZachary Turner 914a8cfc29cSZachary Turner std::vector<YAMLDebugSubsection> Result; 915a8cfc29cSZachary Turner 916a8cfc29cSZachary Turner for (const auto &SS : Subsections) { 917a8cfc29cSZachary Turner auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS)); 918a8cfc29cSZachary Turner Result.push_back(YamlSS); 919a8cfc29cSZachary Turner } 920a8cfc29cSZachary Turner return Result; 921a8cfc29cSZachary Turner } 922a8cfc29cSZachary Turner 923a8cfc29cSZachary Turner void llvm::CodeViewYAML::initializeStringsAndChecksums( 924a8cfc29cSZachary Turner ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) { 925a8cfc29cSZachary Turner // String Table and Checksums subsections don't use the allocator. 926a8cfc29cSZachary Turner BumpPtrAllocator Allocator; 927a8cfc29cSZachary Turner 928a8cfc29cSZachary Turner // It's possible for checksums and strings to even appear in different debug$S 929a8cfc29cSZachary Turner // sections, so we have to make this a stateful function that can build up 930a8cfc29cSZachary Turner // the strings and checksums field over multiple iterations. 931a8cfc29cSZachary Turner 932a8cfc29cSZachary Turner // File Checksums require the string table, but may become before it, so we 933a8cfc29cSZachary Turner // have to scan for strings first, then scan for checksums again from the 934a8cfc29cSZachary Turner // beginning. 935a8cfc29cSZachary Turner if (!SC.hasStrings()) { 936deb39130SZachary Turner for (const auto &SS : Sections) { 937deb39130SZachary Turner if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) 938deb39130SZachary Turner continue; 939deb39130SZachary Turner 940a8cfc29cSZachary Turner auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); 941a8cfc29cSZachary Turner SC.setStrings( 942a8cfc29cSZachary Turner std::static_pointer_cast<DebugStringTableSubsection>(Result)); 943a8cfc29cSZachary Turner break; 944deb39130SZachary Turner } 945a8cfc29cSZachary Turner } 946a8cfc29cSZachary Turner 947a8cfc29cSZachary Turner if (SC.hasStrings() && !SC.hasChecksums()) { 948a8cfc29cSZachary Turner for (const auto &SS : Sections) { 949a8cfc29cSZachary Turner if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums) 950a8cfc29cSZachary Turner continue; 951a8cfc29cSZachary Turner 952a8cfc29cSZachary Turner auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); 953a8cfc29cSZachary Turner SC.setChecksums( 954a8cfc29cSZachary Turner std::static_pointer_cast<DebugChecksumsSubsection>(Result)); 955a8cfc29cSZachary Turner break; 956a8cfc29cSZachary Turner } 957a8cfc29cSZachary Turner } 958deb39130SZachary Turner } 959