1*0b57cec5SDimitry Andric //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines classes for handling the YAML representation of CodeView 10*0b57cec5SDimitry Andric // Debug Info. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 18*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 19*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 20*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h" 21*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" 22*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h" 23*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" 24*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" 25*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" 26*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 27*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 28*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsection.h" 29*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" 30*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h" 31*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" 32*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h" 33*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" 34*0b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 35*0b57cec5SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" 36*0b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 37*0b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamReader.h" 38*0b57cec5SDimitry Andric #include "llvm/Support/Endian.h" 39*0b57cec5SDimitry Andric #include "llvm/Support/Error.h" 40*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 41*0b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h" 42*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 43*0b57cec5SDimitry Andric #include <algorithm> 44*0b57cec5SDimitry Andric #include <cassert> 45*0b57cec5SDimitry Andric #include <cstdint> 46*0b57cec5SDimitry Andric #include <memory> 47*0b57cec5SDimitry Andric #include <string> 48*0b57cec5SDimitry Andric #include <tuple> 49*0b57cec5SDimitry Andric #include <vector> 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric using namespace llvm; 52*0b57cec5SDimitry Andric using namespace llvm::codeview; 53*0b57cec5SDimitry Andric using namespace llvm::CodeViewYAML; 54*0b57cec5SDimitry Andric using namespace llvm::CodeViewYAML::detail; 55*0b57cec5SDimitry Andric using namespace llvm::yaml; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry) 58*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry) 59*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry) 60*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock) 61*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo) 62*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite) 63*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) 64*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport) 65*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport) 66*0b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData) 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None) 69*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind) 70*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) 71*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport) 74*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData) 75*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport) 76*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem) 77*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) 78*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry) 79*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry) 80*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock) 81*0b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite) 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric namespace llvm { 84*0b57cec5SDimitry Andric namespace CodeViewYAML { 85*0b57cec5SDimitry Andric namespace detail { 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric struct YAMLSubsectionBase { 88*0b57cec5SDimitry Andric explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {} 89*0b57cec5SDimitry Andric virtual ~YAMLSubsectionBase() = default; 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric virtual void map(IO &IO) = 0; 92*0b57cec5SDimitry Andric virtual std::shared_ptr<DebugSubsection> 93*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 94*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const = 0; 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric DebugSubsectionKind Kind; 97*0b57cec5SDimitry Andric }; 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric } // end namespace detail 100*0b57cec5SDimitry Andric } // end namespace CodeViewYAML 101*0b57cec5SDimitry Andric } // end namespace llvm 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric namespace { 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric struct YAMLChecksumsSubsection : public YAMLSubsectionBase { 106*0b57cec5SDimitry Andric YAMLChecksumsSubsection() 107*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric void map(IO &IO) override; 110*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 111*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 112*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 113*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLChecksumsSubsection>> 114*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 115*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &FC); 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric std::vector<SourceFileChecksumEntry> Checksums; 118*0b57cec5SDimitry Andric }; 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric struct YAMLLinesSubsection : public YAMLSubsectionBase { 121*0b57cec5SDimitry Andric YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric void map(IO &IO) override; 124*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 125*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 126*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 127*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLLinesSubsection>> 128*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 129*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &Checksums, 130*0b57cec5SDimitry Andric const DebugLinesSubsectionRef &Lines); 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric SourceLineInfo Lines; 133*0b57cec5SDimitry Andric }; 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { 136*0b57cec5SDimitry Andric YAMLInlineeLinesSubsection() 137*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric void map(IO &IO) override; 140*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 141*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 142*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 143*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> 144*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 145*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &Checksums, 146*0b57cec5SDimitry Andric const DebugInlineeLinesSubsectionRef &Lines); 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric InlineeInfo InlineeLines; 149*0b57cec5SDimitry Andric }; 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase { 152*0b57cec5SDimitry Andric YAMLCrossModuleExportsSubsection() 153*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {} 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric void map(IO &IO) override; 156*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 157*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 158*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 159*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> 160*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports); 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric std::vector<CrossModuleExport> Exports; 163*0b57cec5SDimitry Andric }; 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { 166*0b57cec5SDimitry Andric YAMLCrossModuleImportsSubsection() 167*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {} 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric void map(IO &IO) override; 170*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 171*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 172*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 173*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> 174*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 175*0b57cec5SDimitry Andric const DebugCrossModuleImportsSubsectionRef &Imports); 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andric std::vector<YAMLCrossModuleImport> Imports; 178*0b57cec5SDimitry Andric }; 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric struct YAMLSymbolsSubsection : public YAMLSubsectionBase { 181*0b57cec5SDimitry Andric YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {} 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric void map(IO &IO) override; 184*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 185*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 186*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 187*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLSymbolsSubsection>> 188*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols); 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric std::vector<CodeViewYAML::SymbolRecord> Symbols; 191*0b57cec5SDimitry Andric }; 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric struct YAMLStringTableSubsection : public YAMLSubsectionBase { 194*0b57cec5SDimitry Andric YAMLStringTableSubsection() 195*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {} 196*0b57cec5SDimitry Andric 197*0b57cec5SDimitry Andric void map(IO &IO) override; 198*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 199*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 200*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 201*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLStringTableSubsection>> 202*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings); 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric std::vector<StringRef> Strings; 205*0b57cec5SDimitry Andric }; 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andric struct YAMLFrameDataSubsection : public YAMLSubsectionBase { 208*0b57cec5SDimitry Andric YAMLFrameDataSubsection() 209*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {} 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric void map(IO &IO) override; 212*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 213*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 214*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 215*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLFrameDataSubsection>> 216*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 217*0b57cec5SDimitry Andric const DebugFrameDataSubsectionRef &Frames); 218*0b57cec5SDimitry Andric 219*0b57cec5SDimitry Andric std::vector<YAMLFrameData> Frames; 220*0b57cec5SDimitry Andric }; 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase { 223*0b57cec5SDimitry Andric YAMLCoffSymbolRVASubsection() 224*0b57cec5SDimitry Andric : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {} 225*0b57cec5SDimitry Andric 226*0b57cec5SDimitry Andric void map(IO &IO) override; 227*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 228*0b57cec5SDimitry Andric toCodeViewSubsection(BumpPtrAllocator &Allocator, 229*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const override; 230*0b57cec5SDimitry Andric static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> 231*0b57cec5SDimitry Andric fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs); 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric std::vector<uint32_t> RVAs; 234*0b57cec5SDimitry Andric }; 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric } // end anonymous namespace 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) { 239*0b57cec5SDimitry Andric io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); 240*0b57cec5SDimitry Andric io.enumFallback<Hex16>(Flags); 241*0b57cec5SDimitry Andric } 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric void ScalarEnumerationTraits<FileChecksumKind>::enumeration( 244*0b57cec5SDimitry Andric IO &io, FileChecksumKind &Kind) { 245*0b57cec5SDimitry Andric io.enumCase(Kind, "None", FileChecksumKind::None); 246*0b57cec5SDimitry Andric io.enumCase(Kind, "MD5", FileChecksumKind::MD5); 247*0b57cec5SDimitry Andric io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1); 248*0b57cec5SDimitry Andric io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256); 249*0b57cec5SDimitry Andric } 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value, 252*0b57cec5SDimitry Andric void *ctx, raw_ostream &Out) { 253*0b57cec5SDimitry Andric StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()), 254*0b57cec5SDimitry Andric Value.Bytes.size()); 255*0b57cec5SDimitry Andric Out << toHex(Bytes); 256*0b57cec5SDimitry Andric } 257*0b57cec5SDimitry Andric 258*0b57cec5SDimitry Andric StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt, 259*0b57cec5SDimitry Andric HexFormattedString &Value) { 260*0b57cec5SDimitry Andric std::string H = fromHex(Scalar); 261*0b57cec5SDimitry Andric Value.Bytes.assign(H.begin(), H.end()); 262*0b57cec5SDimitry Andric return StringRef(); 263*0b57cec5SDimitry Andric } 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) { 266*0b57cec5SDimitry Andric IO.mapRequired("Offset", Obj.Offset); 267*0b57cec5SDimitry Andric IO.mapRequired("LineStart", Obj.LineStart); 268*0b57cec5SDimitry Andric IO.mapRequired("IsStatement", Obj.IsStatement); 269*0b57cec5SDimitry Andric IO.mapRequired("EndDelta", Obj.EndDelta); 270*0b57cec5SDimitry Andric } 271*0b57cec5SDimitry Andric 272*0b57cec5SDimitry Andric void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) { 273*0b57cec5SDimitry Andric IO.mapRequired("StartColumn", Obj.StartColumn); 274*0b57cec5SDimitry Andric IO.mapRequired("EndColumn", Obj.EndColumn); 275*0b57cec5SDimitry Andric } 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) { 278*0b57cec5SDimitry Andric IO.mapRequired("FileName", Obj.FileName); 279*0b57cec5SDimitry Andric IO.mapRequired("Lines", Obj.Lines); 280*0b57cec5SDimitry Andric IO.mapRequired("Columns", Obj.Columns); 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) { 284*0b57cec5SDimitry Andric IO.mapRequired("LocalId", Obj.Local); 285*0b57cec5SDimitry Andric IO.mapRequired("GlobalId", Obj.Global); 286*0b57cec5SDimitry Andric } 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO, 289*0b57cec5SDimitry Andric YAMLCrossModuleImport &Obj) { 290*0b57cec5SDimitry Andric IO.mapRequired("Module", Obj.ModuleName); 291*0b57cec5SDimitry Andric IO.mapRequired("Imports", Obj.ImportIds); 292*0b57cec5SDimitry Andric } 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andric void MappingTraits<SourceFileChecksumEntry>::mapping( 295*0b57cec5SDimitry Andric IO &IO, SourceFileChecksumEntry &Obj) { 296*0b57cec5SDimitry Andric IO.mapRequired("FileName", Obj.FileName); 297*0b57cec5SDimitry Andric IO.mapRequired("Kind", Obj.Kind); 298*0b57cec5SDimitry Andric IO.mapRequired("Checksum", Obj.ChecksumBytes); 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { 302*0b57cec5SDimitry Andric IO.mapRequired("FileName", Obj.FileName); 303*0b57cec5SDimitry Andric IO.mapRequired("LineNum", Obj.SourceLineNum); 304*0b57cec5SDimitry Andric IO.mapRequired("Inlinee", Obj.Inlinee); 305*0b57cec5SDimitry Andric IO.mapOptional("ExtraFiles", Obj.ExtraFiles); 306*0b57cec5SDimitry Andric } 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) { 309*0b57cec5SDimitry Andric IO.mapRequired("CodeSize", Obj.CodeSize); 310*0b57cec5SDimitry Andric IO.mapRequired("FrameFunc", Obj.FrameFunc); 311*0b57cec5SDimitry Andric IO.mapRequired("LocalSize", Obj.LocalSize); 312*0b57cec5SDimitry Andric IO.mapOptional("MaxStackSize", Obj.MaxStackSize); 313*0b57cec5SDimitry Andric IO.mapOptional("ParamsSize", Obj.ParamsSize); 314*0b57cec5SDimitry Andric IO.mapOptional("PrologSize", Obj.PrologSize); 315*0b57cec5SDimitry Andric IO.mapOptional("RvaStart", Obj.RvaStart); 316*0b57cec5SDimitry Andric IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize); 317*0b57cec5SDimitry Andric } 318*0b57cec5SDimitry Andric 319*0b57cec5SDimitry Andric void YAMLChecksumsSubsection::map(IO &IO) { 320*0b57cec5SDimitry Andric IO.mapTag("!FileChecksums", true); 321*0b57cec5SDimitry Andric IO.mapRequired("Checksums", Checksums); 322*0b57cec5SDimitry Andric } 323*0b57cec5SDimitry Andric 324*0b57cec5SDimitry Andric void YAMLLinesSubsection::map(IO &IO) { 325*0b57cec5SDimitry Andric IO.mapTag("!Lines", true); 326*0b57cec5SDimitry Andric IO.mapRequired("CodeSize", Lines.CodeSize); 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric IO.mapRequired("Flags", Lines.Flags); 329*0b57cec5SDimitry Andric IO.mapRequired("RelocOffset", Lines.RelocOffset); 330*0b57cec5SDimitry Andric IO.mapRequired("RelocSegment", Lines.RelocSegment); 331*0b57cec5SDimitry Andric IO.mapRequired("Blocks", Lines.Blocks); 332*0b57cec5SDimitry Andric } 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric void YAMLInlineeLinesSubsection::map(IO &IO) { 335*0b57cec5SDimitry Andric IO.mapTag("!InlineeLines", true); 336*0b57cec5SDimitry Andric IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles); 337*0b57cec5SDimitry Andric IO.mapRequired("Sites", InlineeLines.Sites); 338*0b57cec5SDimitry Andric } 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric void YAMLCrossModuleExportsSubsection::map(IO &IO) { 341*0b57cec5SDimitry Andric IO.mapTag("!CrossModuleExports", true); 342*0b57cec5SDimitry Andric IO.mapOptional("Exports", Exports); 343*0b57cec5SDimitry Andric } 344*0b57cec5SDimitry Andric 345*0b57cec5SDimitry Andric void YAMLCrossModuleImportsSubsection::map(IO &IO) { 346*0b57cec5SDimitry Andric IO.mapTag("!CrossModuleImports", true); 347*0b57cec5SDimitry Andric IO.mapOptional("Imports", Imports); 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric void YAMLSymbolsSubsection::map(IO &IO) { 351*0b57cec5SDimitry Andric IO.mapTag("!Symbols", true); 352*0b57cec5SDimitry Andric IO.mapRequired("Records", Symbols); 353*0b57cec5SDimitry Andric } 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andric void YAMLStringTableSubsection::map(IO &IO) { 356*0b57cec5SDimitry Andric IO.mapTag("!StringTable", true); 357*0b57cec5SDimitry Andric IO.mapRequired("Strings", Strings); 358*0b57cec5SDimitry Andric } 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric void YAMLFrameDataSubsection::map(IO &IO) { 361*0b57cec5SDimitry Andric IO.mapTag("!FrameData", true); 362*0b57cec5SDimitry Andric IO.mapRequired("Frames", Frames); 363*0b57cec5SDimitry Andric } 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric void YAMLCoffSymbolRVASubsection::map(IO &IO) { 366*0b57cec5SDimitry Andric IO.mapTag("!COFFSymbolRVAs", true); 367*0b57cec5SDimitry Andric IO.mapRequired("RVAs", RVAs); 368*0b57cec5SDimitry Andric } 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric void MappingTraits<YAMLDebugSubsection>::mapping( 371*0b57cec5SDimitry Andric IO &IO, YAMLDebugSubsection &Subsection) { 372*0b57cec5SDimitry Andric if (!IO.outputting()) { 373*0b57cec5SDimitry Andric if (IO.mapTag("!FileChecksums")) { 374*0b57cec5SDimitry Andric auto SS = std::make_shared<YAMLChecksumsSubsection>(); 375*0b57cec5SDimitry Andric Subsection.Subsection = SS; 376*0b57cec5SDimitry Andric } else if (IO.mapTag("!Lines")) { 377*0b57cec5SDimitry Andric Subsection.Subsection = std::make_shared<YAMLLinesSubsection>(); 378*0b57cec5SDimitry Andric } else if (IO.mapTag("!InlineeLines")) { 379*0b57cec5SDimitry Andric Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>(); 380*0b57cec5SDimitry Andric } else if (IO.mapTag("!CrossModuleExports")) { 381*0b57cec5SDimitry Andric Subsection.Subsection = 382*0b57cec5SDimitry Andric std::make_shared<YAMLCrossModuleExportsSubsection>(); 383*0b57cec5SDimitry Andric } else if (IO.mapTag("!CrossModuleImports")) { 384*0b57cec5SDimitry Andric Subsection.Subsection = 385*0b57cec5SDimitry Andric std::make_shared<YAMLCrossModuleImportsSubsection>(); 386*0b57cec5SDimitry Andric } else if (IO.mapTag("!Symbols")) { 387*0b57cec5SDimitry Andric Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>(); 388*0b57cec5SDimitry Andric } else if (IO.mapTag("!StringTable")) { 389*0b57cec5SDimitry Andric Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>(); 390*0b57cec5SDimitry Andric } else if (IO.mapTag("!FrameData")) { 391*0b57cec5SDimitry Andric Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>(); 392*0b57cec5SDimitry Andric } else if (IO.mapTag("!COFFSymbolRVAs")) { 393*0b57cec5SDimitry Andric Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>(); 394*0b57cec5SDimitry Andric } else { 395*0b57cec5SDimitry Andric llvm_unreachable("Unexpected subsection tag!"); 396*0b57cec5SDimitry Andric } 397*0b57cec5SDimitry Andric } 398*0b57cec5SDimitry Andric Subsection.Subsection->map(IO); 399*0b57cec5SDimitry Andric } 400*0b57cec5SDimitry Andric 401*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection( 402*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 403*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 404*0b57cec5SDimitry Andric assert(SC.hasStrings()); 405*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings()); 406*0b57cec5SDimitry Andric for (const auto &CS : Checksums) { 407*0b57cec5SDimitry Andric Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); 408*0b57cec5SDimitry Andric } 409*0b57cec5SDimitry Andric return Result; 410*0b57cec5SDimitry Andric } 411*0b57cec5SDimitry Andric 412*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection( 413*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 414*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 415*0b57cec5SDimitry Andric assert(SC.hasStrings() && SC.hasChecksums()); 416*0b57cec5SDimitry Andric auto Result = 417*0b57cec5SDimitry Andric std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings()); 418*0b57cec5SDimitry Andric Result->setCodeSize(Lines.CodeSize); 419*0b57cec5SDimitry Andric Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); 420*0b57cec5SDimitry Andric Result->setFlags(Lines.Flags); 421*0b57cec5SDimitry Andric for (const auto &LC : Lines.Blocks) { 422*0b57cec5SDimitry Andric Result->createBlock(LC.FileName); 423*0b57cec5SDimitry Andric if (Result->hasColumnInfo()) { 424*0b57cec5SDimitry Andric for (const auto &Item : zip(LC.Lines, LC.Columns)) { 425*0b57cec5SDimitry Andric auto &L = std::get<0>(Item); 426*0b57cec5SDimitry Andric auto &C = std::get<1>(Item); 427*0b57cec5SDimitry Andric uint32_t LE = L.LineStart + L.EndDelta; 428*0b57cec5SDimitry Andric Result->addLineAndColumnInfo(L.Offset, 429*0b57cec5SDimitry Andric LineInfo(L.LineStart, LE, L.IsStatement), 430*0b57cec5SDimitry Andric C.StartColumn, C.EndColumn); 431*0b57cec5SDimitry Andric } 432*0b57cec5SDimitry Andric } else { 433*0b57cec5SDimitry Andric for (const auto &L : LC.Lines) { 434*0b57cec5SDimitry Andric uint32_t LE = L.LineStart + L.EndDelta; 435*0b57cec5SDimitry Andric Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement)); 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric } 438*0b57cec5SDimitry Andric } 439*0b57cec5SDimitry Andric return Result; 440*0b57cec5SDimitry Andric } 441*0b57cec5SDimitry Andric 442*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 443*0b57cec5SDimitry Andric YAMLInlineeLinesSubsection::toCodeViewSubsection( 444*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 445*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 446*0b57cec5SDimitry Andric assert(SC.hasChecksums()); 447*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugInlineeLinesSubsection>( 448*0b57cec5SDimitry Andric *SC.checksums(), InlineeLines.HasExtraFiles); 449*0b57cec5SDimitry Andric 450*0b57cec5SDimitry Andric for (const auto &Site : InlineeLines.Sites) { 451*0b57cec5SDimitry Andric Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, 452*0b57cec5SDimitry Andric Site.SourceLineNum); 453*0b57cec5SDimitry Andric if (!InlineeLines.HasExtraFiles) 454*0b57cec5SDimitry Andric continue; 455*0b57cec5SDimitry Andric 456*0b57cec5SDimitry Andric for (auto EF : Site.ExtraFiles) { 457*0b57cec5SDimitry Andric Result->addExtraFile(EF); 458*0b57cec5SDimitry Andric } 459*0b57cec5SDimitry Andric } 460*0b57cec5SDimitry Andric return Result; 461*0b57cec5SDimitry Andric } 462*0b57cec5SDimitry Andric 463*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 464*0b57cec5SDimitry Andric YAMLCrossModuleExportsSubsection::toCodeViewSubsection( 465*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 466*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 467*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugCrossModuleExportsSubsection>(); 468*0b57cec5SDimitry Andric for (const auto &M : Exports) 469*0b57cec5SDimitry Andric Result->addMapping(M.Local, M.Global); 470*0b57cec5SDimitry Andric return Result; 471*0b57cec5SDimitry Andric } 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 474*0b57cec5SDimitry Andric YAMLCrossModuleImportsSubsection::toCodeViewSubsection( 475*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 476*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 477*0b57cec5SDimitry Andric assert(SC.hasStrings()); 478*0b57cec5SDimitry Andric 479*0b57cec5SDimitry Andric auto Result = 480*0b57cec5SDimitry Andric std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings()); 481*0b57cec5SDimitry Andric for (const auto &M : Imports) { 482*0b57cec5SDimitry Andric for (const auto Id : M.ImportIds) 483*0b57cec5SDimitry Andric Result->addImport(M.ModuleName, Id); 484*0b57cec5SDimitry Andric } 485*0b57cec5SDimitry Andric return Result; 486*0b57cec5SDimitry Andric } 487*0b57cec5SDimitry Andric 488*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection( 489*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 490*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 491*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugSymbolsSubsection>(); 492*0b57cec5SDimitry Andric for (const auto &Sym : Symbols) 493*0b57cec5SDimitry Andric Result->addSymbol( 494*0b57cec5SDimitry Andric Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile)); 495*0b57cec5SDimitry Andric return Result; 496*0b57cec5SDimitry Andric } 497*0b57cec5SDimitry Andric 498*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 499*0b57cec5SDimitry Andric YAMLStringTableSubsection::toCodeViewSubsection( 500*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 501*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 502*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugStringTableSubsection>(); 503*0b57cec5SDimitry Andric for (const auto &Str : this->Strings) 504*0b57cec5SDimitry Andric Result->insert(Str); 505*0b57cec5SDimitry Andric return Result; 506*0b57cec5SDimitry Andric } 507*0b57cec5SDimitry Andric 508*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection( 509*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 510*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 511*0b57cec5SDimitry Andric assert(SC.hasStrings()); 512*0b57cec5SDimitry Andric 513*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugFrameDataSubsection>(true); 514*0b57cec5SDimitry Andric for (const auto &YF : Frames) { 515*0b57cec5SDimitry Andric codeview::FrameData F; 516*0b57cec5SDimitry Andric F.CodeSize = YF.CodeSize; 517*0b57cec5SDimitry Andric F.Flags = YF.Flags; 518*0b57cec5SDimitry Andric F.LocalSize = YF.LocalSize; 519*0b57cec5SDimitry Andric F.MaxStackSize = YF.MaxStackSize; 520*0b57cec5SDimitry Andric F.ParamsSize = YF.ParamsSize; 521*0b57cec5SDimitry Andric F.PrologSize = YF.PrologSize; 522*0b57cec5SDimitry Andric F.RvaStart = YF.RvaStart; 523*0b57cec5SDimitry Andric F.SavedRegsSize = YF.SavedRegsSize; 524*0b57cec5SDimitry Andric F.FrameFunc = SC.strings()->insert(YF.FrameFunc); 525*0b57cec5SDimitry Andric Result->addFrameData(F); 526*0b57cec5SDimitry Andric } 527*0b57cec5SDimitry Andric return Result; 528*0b57cec5SDimitry Andric } 529*0b57cec5SDimitry Andric 530*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> 531*0b57cec5SDimitry Andric YAMLCoffSymbolRVASubsection::toCodeViewSubsection( 532*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, 533*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) const { 534*0b57cec5SDimitry Andric auto Result = std::make_shared<DebugSymbolRVASubsection>(); 535*0b57cec5SDimitry Andric for (const auto &RVA : RVAs) 536*0b57cec5SDimitry Andric Result->addRVA(RVA); 537*0b57cec5SDimitry Andric return Result; 538*0b57cec5SDimitry Andric } 539*0b57cec5SDimitry Andric 540*0b57cec5SDimitry Andric static Expected<SourceFileChecksumEntry> 541*0b57cec5SDimitry Andric convertOneChecksum(const DebugStringTableSubsectionRef &Strings, 542*0b57cec5SDimitry Andric const FileChecksumEntry &CS) { 543*0b57cec5SDimitry Andric auto ExpectedString = Strings.getString(CS.FileNameOffset); 544*0b57cec5SDimitry Andric if (!ExpectedString) 545*0b57cec5SDimitry Andric return ExpectedString.takeError(); 546*0b57cec5SDimitry Andric 547*0b57cec5SDimitry Andric SourceFileChecksumEntry Result; 548*0b57cec5SDimitry Andric Result.ChecksumBytes.Bytes = CS.Checksum; 549*0b57cec5SDimitry Andric Result.Kind = CS.Kind; 550*0b57cec5SDimitry Andric Result.FileName = *ExpectedString; 551*0b57cec5SDimitry Andric return Result; 552*0b57cec5SDimitry Andric } 553*0b57cec5SDimitry Andric 554*0b57cec5SDimitry Andric static Expected<StringRef> 555*0b57cec5SDimitry Andric getFileName(const DebugStringTableSubsectionRef &Strings, 556*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { 557*0b57cec5SDimitry Andric auto Iter = Checksums.getArray().at(FileID); 558*0b57cec5SDimitry Andric if (Iter == Checksums.getArray().end()) 559*0b57cec5SDimitry Andric return make_error<CodeViewError>(cv_error_code::no_records); 560*0b57cec5SDimitry Andric uint32_t Offset = Iter->FileNameOffset; 561*0b57cec5SDimitry Andric return Strings.getString(Offset); 562*0b57cec5SDimitry Andric } 563*0b57cec5SDimitry Andric 564*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLChecksumsSubsection>> 565*0b57cec5SDimitry Andric YAMLChecksumsSubsection::fromCodeViewSubsection( 566*0b57cec5SDimitry Andric const DebugStringTableSubsectionRef &Strings, 567*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &FC) { 568*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLChecksumsSubsection>(); 569*0b57cec5SDimitry Andric 570*0b57cec5SDimitry Andric for (const auto &CS : FC) { 571*0b57cec5SDimitry Andric auto ConvertedCS = convertOneChecksum(Strings, CS); 572*0b57cec5SDimitry Andric if (!ConvertedCS) 573*0b57cec5SDimitry Andric return ConvertedCS.takeError(); 574*0b57cec5SDimitry Andric Result->Checksums.push_back(*ConvertedCS); 575*0b57cec5SDimitry Andric } 576*0b57cec5SDimitry Andric return Result; 577*0b57cec5SDimitry Andric } 578*0b57cec5SDimitry Andric 579*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLLinesSubsection>> 580*0b57cec5SDimitry Andric YAMLLinesSubsection::fromCodeViewSubsection( 581*0b57cec5SDimitry Andric const DebugStringTableSubsectionRef &Strings, 582*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &Checksums, 583*0b57cec5SDimitry Andric const DebugLinesSubsectionRef &Lines) { 584*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLLinesSubsection>(); 585*0b57cec5SDimitry Andric Result->Lines.CodeSize = Lines.header()->CodeSize; 586*0b57cec5SDimitry Andric Result->Lines.RelocOffset = Lines.header()->RelocOffset; 587*0b57cec5SDimitry Andric Result->Lines.RelocSegment = Lines.header()->RelocSegment; 588*0b57cec5SDimitry Andric Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags)); 589*0b57cec5SDimitry Andric for (const auto &L : Lines) { 590*0b57cec5SDimitry Andric SourceLineBlock Block; 591*0b57cec5SDimitry Andric auto EF = getFileName(Strings, Checksums, L.NameIndex); 592*0b57cec5SDimitry Andric if (!EF) 593*0b57cec5SDimitry Andric return EF.takeError(); 594*0b57cec5SDimitry Andric Block.FileName = *EF; 595*0b57cec5SDimitry Andric if (Lines.hasColumnInfo()) { 596*0b57cec5SDimitry Andric for (const auto &C : L.Columns) { 597*0b57cec5SDimitry Andric SourceColumnEntry SCE; 598*0b57cec5SDimitry Andric SCE.EndColumn = C.EndColumn; 599*0b57cec5SDimitry Andric SCE.StartColumn = C.StartColumn; 600*0b57cec5SDimitry Andric Block.Columns.push_back(SCE); 601*0b57cec5SDimitry Andric } 602*0b57cec5SDimitry Andric } 603*0b57cec5SDimitry Andric for (const auto &LN : L.LineNumbers) { 604*0b57cec5SDimitry Andric SourceLineEntry SLE; 605*0b57cec5SDimitry Andric LineInfo LI(LN.Flags); 606*0b57cec5SDimitry Andric SLE.Offset = LN.Offset; 607*0b57cec5SDimitry Andric SLE.LineStart = LI.getStartLine(); 608*0b57cec5SDimitry Andric SLE.EndDelta = LI.getLineDelta(); 609*0b57cec5SDimitry Andric SLE.IsStatement = LI.isStatement(); 610*0b57cec5SDimitry Andric Block.Lines.push_back(SLE); 611*0b57cec5SDimitry Andric } 612*0b57cec5SDimitry Andric Result->Lines.Blocks.push_back(Block); 613*0b57cec5SDimitry Andric } 614*0b57cec5SDimitry Andric return Result; 615*0b57cec5SDimitry Andric } 616*0b57cec5SDimitry Andric 617*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> 618*0b57cec5SDimitry Andric YAMLInlineeLinesSubsection::fromCodeViewSubsection( 619*0b57cec5SDimitry Andric const DebugStringTableSubsectionRef &Strings, 620*0b57cec5SDimitry Andric const DebugChecksumsSubsectionRef &Checksums, 621*0b57cec5SDimitry Andric const DebugInlineeLinesSubsectionRef &Lines) { 622*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLInlineeLinesSubsection>(); 623*0b57cec5SDimitry Andric 624*0b57cec5SDimitry Andric Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles(); 625*0b57cec5SDimitry Andric for (const auto &IL : Lines) { 626*0b57cec5SDimitry Andric InlineeSite Site; 627*0b57cec5SDimitry Andric auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID); 628*0b57cec5SDimitry Andric if (!ExpF) 629*0b57cec5SDimitry Andric return ExpF.takeError(); 630*0b57cec5SDimitry Andric Site.FileName = *ExpF; 631*0b57cec5SDimitry Andric Site.Inlinee = IL.Header->Inlinee.getIndex(); 632*0b57cec5SDimitry Andric Site.SourceLineNum = IL.Header->SourceLineNum; 633*0b57cec5SDimitry Andric if (Lines.hasExtraFiles()) { 634*0b57cec5SDimitry Andric for (const auto EF : IL.ExtraFiles) { 635*0b57cec5SDimitry Andric auto ExpF2 = getFileName(Strings, Checksums, EF); 636*0b57cec5SDimitry Andric if (!ExpF2) 637*0b57cec5SDimitry Andric return ExpF2.takeError(); 638*0b57cec5SDimitry Andric Site.ExtraFiles.push_back(*ExpF2); 639*0b57cec5SDimitry Andric } 640*0b57cec5SDimitry Andric } 641*0b57cec5SDimitry Andric Result->InlineeLines.Sites.push_back(Site); 642*0b57cec5SDimitry Andric } 643*0b57cec5SDimitry Andric return Result; 644*0b57cec5SDimitry Andric } 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> 647*0b57cec5SDimitry Andric YAMLCrossModuleExportsSubsection::fromCodeViewSubsection( 648*0b57cec5SDimitry Andric const DebugCrossModuleExportsSubsectionRef &Exports) { 649*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>(); 650*0b57cec5SDimitry Andric Result->Exports.assign(Exports.begin(), Exports.end()); 651*0b57cec5SDimitry Andric return Result; 652*0b57cec5SDimitry Andric } 653*0b57cec5SDimitry Andric 654*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> 655*0b57cec5SDimitry Andric YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( 656*0b57cec5SDimitry Andric const DebugStringTableSubsectionRef &Strings, 657*0b57cec5SDimitry Andric const DebugCrossModuleImportsSubsectionRef &Imports) { 658*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>(); 659*0b57cec5SDimitry Andric for (const auto &CMI : Imports) { 660*0b57cec5SDimitry Andric YAMLCrossModuleImport YCMI; 661*0b57cec5SDimitry Andric auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset); 662*0b57cec5SDimitry Andric if (!ExpectedStr) 663*0b57cec5SDimitry Andric return ExpectedStr.takeError(); 664*0b57cec5SDimitry Andric YCMI.ModuleName = *ExpectedStr; 665*0b57cec5SDimitry Andric YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end()); 666*0b57cec5SDimitry Andric Result->Imports.push_back(YCMI); 667*0b57cec5SDimitry Andric } 668*0b57cec5SDimitry Andric return Result; 669*0b57cec5SDimitry Andric } 670*0b57cec5SDimitry Andric 671*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLSymbolsSubsection>> 672*0b57cec5SDimitry Andric YAMLSymbolsSubsection::fromCodeViewSubsection( 673*0b57cec5SDimitry Andric const DebugSymbolsSubsectionRef &Symbols) { 674*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLSymbolsSubsection>(); 675*0b57cec5SDimitry Andric for (const auto &Sym : Symbols) { 676*0b57cec5SDimitry Andric auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym); 677*0b57cec5SDimitry Andric if (!S) 678*0b57cec5SDimitry Andric return joinErrors(make_error<CodeViewError>( 679*0b57cec5SDimitry Andric cv_error_code::corrupt_record, 680*0b57cec5SDimitry Andric "Invalid CodeView Symbol Record in SymbolRecord " 681*0b57cec5SDimitry Andric "subsection of .debug$S while converting to YAML!"), 682*0b57cec5SDimitry Andric S.takeError()); 683*0b57cec5SDimitry Andric 684*0b57cec5SDimitry Andric Result->Symbols.push_back(*S); 685*0b57cec5SDimitry Andric } 686*0b57cec5SDimitry Andric return Result; 687*0b57cec5SDimitry Andric } 688*0b57cec5SDimitry Andric 689*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLStringTableSubsection>> 690*0b57cec5SDimitry Andric YAMLStringTableSubsection::fromCodeViewSubsection( 691*0b57cec5SDimitry Andric const DebugStringTableSubsectionRef &Strings) { 692*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLStringTableSubsection>(); 693*0b57cec5SDimitry Andric BinaryStreamReader Reader(Strings.getBuffer()); 694*0b57cec5SDimitry Andric StringRef S; 695*0b57cec5SDimitry Andric // First item is a single null string, skip it. 696*0b57cec5SDimitry Andric if (auto EC = Reader.readCString(S)) 697*0b57cec5SDimitry Andric return std::move(EC); 698*0b57cec5SDimitry Andric assert(S.empty()); 699*0b57cec5SDimitry Andric while (Reader.bytesRemaining() > 0) { 700*0b57cec5SDimitry Andric if (auto EC = Reader.readCString(S)) 701*0b57cec5SDimitry Andric return std::move(EC); 702*0b57cec5SDimitry Andric Result->Strings.push_back(S); 703*0b57cec5SDimitry Andric } 704*0b57cec5SDimitry Andric return Result; 705*0b57cec5SDimitry Andric } 706*0b57cec5SDimitry Andric 707*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLFrameDataSubsection>> 708*0b57cec5SDimitry Andric YAMLFrameDataSubsection::fromCodeViewSubsection( 709*0b57cec5SDimitry Andric const DebugStringTableSubsectionRef &Strings, 710*0b57cec5SDimitry Andric const DebugFrameDataSubsectionRef &Frames) { 711*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLFrameDataSubsection>(); 712*0b57cec5SDimitry Andric for (const auto &F : Frames) { 713*0b57cec5SDimitry Andric YAMLFrameData YF; 714*0b57cec5SDimitry Andric YF.CodeSize = F.CodeSize; 715*0b57cec5SDimitry Andric YF.Flags = F.Flags; 716*0b57cec5SDimitry Andric YF.LocalSize = F.LocalSize; 717*0b57cec5SDimitry Andric YF.MaxStackSize = F.MaxStackSize; 718*0b57cec5SDimitry Andric YF.ParamsSize = F.ParamsSize; 719*0b57cec5SDimitry Andric YF.PrologSize = F.PrologSize; 720*0b57cec5SDimitry Andric YF.RvaStart = F.RvaStart; 721*0b57cec5SDimitry Andric YF.SavedRegsSize = F.SavedRegsSize; 722*0b57cec5SDimitry Andric 723*0b57cec5SDimitry Andric auto ES = Strings.getString(F.FrameFunc); 724*0b57cec5SDimitry Andric if (!ES) 725*0b57cec5SDimitry Andric return joinErrors( 726*0b57cec5SDimitry Andric make_error<CodeViewError>( 727*0b57cec5SDimitry Andric cv_error_code::no_records, 728*0b57cec5SDimitry Andric "Could not find string for string id while mapping FrameData!"), 729*0b57cec5SDimitry Andric ES.takeError()); 730*0b57cec5SDimitry Andric YF.FrameFunc = *ES; 731*0b57cec5SDimitry Andric Result->Frames.push_back(YF); 732*0b57cec5SDimitry Andric } 733*0b57cec5SDimitry Andric return Result; 734*0b57cec5SDimitry Andric } 735*0b57cec5SDimitry Andric 736*0b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> 737*0b57cec5SDimitry Andric YAMLCoffSymbolRVASubsection::fromCodeViewSubsection( 738*0b57cec5SDimitry Andric const DebugSymbolRVASubsectionRef &Section) { 739*0b57cec5SDimitry Andric auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>(); 740*0b57cec5SDimitry Andric for (const auto &RVA : Section) { 741*0b57cec5SDimitry Andric Result->RVAs.push_back(RVA); 742*0b57cec5SDimitry Andric } 743*0b57cec5SDimitry Andric return Result; 744*0b57cec5SDimitry Andric } 745*0b57cec5SDimitry Andric 746*0b57cec5SDimitry Andric Expected<std::vector<std::shared_ptr<DebugSubsection>>> 747*0b57cec5SDimitry Andric llvm::CodeViewYAML::toCodeViewSubsectionList( 748*0b57cec5SDimitry Andric BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections, 749*0b57cec5SDimitry Andric const codeview::StringsAndChecksums &SC) { 750*0b57cec5SDimitry Andric std::vector<std::shared_ptr<DebugSubsection>> Result; 751*0b57cec5SDimitry Andric if (Subsections.empty()) 752*0b57cec5SDimitry Andric return std::move(Result); 753*0b57cec5SDimitry Andric 754*0b57cec5SDimitry Andric for (const auto &SS : Subsections) { 755*0b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> CVS; 756*0b57cec5SDimitry Andric CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC); 757*0b57cec5SDimitry Andric assert(CVS != nullptr); 758*0b57cec5SDimitry Andric Result.push_back(std::move(CVS)); 759*0b57cec5SDimitry Andric } 760*0b57cec5SDimitry Andric return std::move(Result); 761*0b57cec5SDimitry Andric } 762*0b57cec5SDimitry Andric 763*0b57cec5SDimitry Andric namespace { 764*0b57cec5SDimitry Andric 765*0b57cec5SDimitry Andric struct SubsectionConversionVisitor : public DebugSubsectionVisitor { 766*0b57cec5SDimitry Andric SubsectionConversionVisitor() = default; 767*0b57cec5SDimitry Andric 768*0b57cec5SDimitry Andric Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; 769*0b57cec5SDimitry Andric Error visitLines(DebugLinesSubsectionRef &Lines, 770*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 771*0b57cec5SDimitry Andric Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, 772*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 773*0b57cec5SDimitry Andric Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, 774*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 775*0b57cec5SDimitry Andric Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums, 776*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 777*0b57cec5SDimitry Andric Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees, 778*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 779*0b57cec5SDimitry Andric Error visitStringTable(DebugStringTableSubsectionRef &ST, 780*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 781*0b57cec5SDimitry Andric Error visitSymbols(DebugSymbolsSubsectionRef &Symbols, 782*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 783*0b57cec5SDimitry Andric Error visitFrameData(DebugFrameDataSubsectionRef &Symbols, 784*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 785*0b57cec5SDimitry Andric Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols, 786*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) override; 787*0b57cec5SDimitry Andric 788*0b57cec5SDimitry Andric YAMLDebugSubsection Subsection; 789*0b57cec5SDimitry Andric }; 790*0b57cec5SDimitry Andric 791*0b57cec5SDimitry Andric } // end anonymous namespace 792*0b57cec5SDimitry Andric 793*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitUnknown( 794*0b57cec5SDimitry Andric DebugUnknownSubsectionRef &Unknown) { 795*0b57cec5SDimitry Andric return make_error<CodeViewError>(cv_error_code::operation_unsupported); 796*0b57cec5SDimitry Andric } 797*0b57cec5SDimitry Andric 798*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitLines( 799*0b57cec5SDimitry Andric DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) { 800*0b57cec5SDimitry Andric auto Result = YAMLLinesSubsection::fromCodeViewSubsection( 801*0b57cec5SDimitry Andric State.strings(), State.checksums(), Lines); 802*0b57cec5SDimitry Andric if (!Result) 803*0b57cec5SDimitry Andric return Result.takeError(); 804*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 805*0b57cec5SDimitry Andric return Error::success(); 806*0b57cec5SDimitry Andric } 807*0b57cec5SDimitry Andric 808*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitFileChecksums( 809*0b57cec5SDimitry Andric DebugChecksumsSubsectionRef &Checksums, 810*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) { 811*0b57cec5SDimitry Andric auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(), 812*0b57cec5SDimitry Andric Checksums); 813*0b57cec5SDimitry Andric if (!Result) 814*0b57cec5SDimitry Andric return Result.takeError(); 815*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 816*0b57cec5SDimitry Andric return Error::success(); 817*0b57cec5SDimitry Andric } 818*0b57cec5SDimitry Andric 819*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitInlineeLines( 820*0b57cec5SDimitry Andric DebugInlineeLinesSubsectionRef &Inlinees, 821*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) { 822*0b57cec5SDimitry Andric auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( 823*0b57cec5SDimitry Andric State.strings(), State.checksums(), Inlinees); 824*0b57cec5SDimitry Andric if (!Result) 825*0b57cec5SDimitry Andric return Result.takeError(); 826*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 827*0b57cec5SDimitry Andric return Error::success(); 828*0b57cec5SDimitry Andric } 829*0b57cec5SDimitry Andric 830*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleExports( 831*0b57cec5SDimitry Andric DebugCrossModuleExportsSubsectionRef &Exports, 832*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) { 833*0b57cec5SDimitry Andric auto Result = 834*0b57cec5SDimitry Andric YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports); 835*0b57cec5SDimitry Andric if (!Result) 836*0b57cec5SDimitry Andric return Result.takeError(); 837*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 838*0b57cec5SDimitry Andric return Error::success(); 839*0b57cec5SDimitry Andric } 840*0b57cec5SDimitry Andric 841*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleImports( 842*0b57cec5SDimitry Andric DebugCrossModuleImportsSubsectionRef &Imports, 843*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) { 844*0b57cec5SDimitry Andric auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( 845*0b57cec5SDimitry Andric State.strings(), Imports); 846*0b57cec5SDimitry Andric if (!Result) 847*0b57cec5SDimitry Andric return Result.takeError(); 848*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 849*0b57cec5SDimitry Andric return Error::success(); 850*0b57cec5SDimitry Andric } 851*0b57cec5SDimitry Andric 852*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitStringTable( 853*0b57cec5SDimitry Andric DebugStringTableSubsectionRef &Strings, 854*0b57cec5SDimitry Andric const StringsAndChecksumsRef &State) { 855*0b57cec5SDimitry Andric auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings); 856*0b57cec5SDimitry Andric if (!Result) 857*0b57cec5SDimitry Andric return Result.takeError(); 858*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 859*0b57cec5SDimitry Andric return Error::success(); 860*0b57cec5SDimitry Andric } 861*0b57cec5SDimitry Andric 862*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitSymbols( 863*0b57cec5SDimitry Andric DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) { 864*0b57cec5SDimitry Andric auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols); 865*0b57cec5SDimitry Andric if (!Result) 866*0b57cec5SDimitry Andric return Result.takeError(); 867*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 868*0b57cec5SDimitry Andric return Error::success(); 869*0b57cec5SDimitry Andric } 870*0b57cec5SDimitry Andric 871*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitFrameData( 872*0b57cec5SDimitry Andric DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) { 873*0b57cec5SDimitry Andric auto Result = 874*0b57cec5SDimitry Andric YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames); 875*0b57cec5SDimitry Andric if (!Result) 876*0b57cec5SDimitry Andric return Result.takeError(); 877*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 878*0b57cec5SDimitry Andric return Error::success(); 879*0b57cec5SDimitry Andric } 880*0b57cec5SDimitry Andric 881*0b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitCOFFSymbolRVAs( 882*0b57cec5SDimitry Andric DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) { 883*0b57cec5SDimitry Andric auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs); 884*0b57cec5SDimitry Andric if (!Result) 885*0b57cec5SDimitry Andric return Result.takeError(); 886*0b57cec5SDimitry Andric Subsection.Subsection = *Result; 887*0b57cec5SDimitry Andric return Error::success(); 888*0b57cec5SDimitry Andric } 889*0b57cec5SDimitry Andric 890*0b57cec5SDimitry Andric Expected<YAMLDebugSubsection> 891*0b57cec5SDimitry Andric YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC, 892*0b57cec5SDimitry Andric const DebugSubsectionRecord &SS) { 893*0b57cec5SDimitry Andric SubsectionConversionVisitor V; 894*0b57cec5SDimitry Andric if (auto EC = visitDebugSubsection(SS, V, SC)) 895*0b57cec5SDimitry Andric return std::move(EC); 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andric return V.Subsection; 898*0b57cec5SDimitry Andric } 899*0b57cec5SDimitry Andric 900*0b57cec5SDimitry Andric std::vector<YAMLDebugSubsection> 901*0b57cec5SDimitry Andric llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data, 902*0b57cec5SDimitry Andric const StringsAndChecksumsRef &SC) { 903*0b57cec5SDimitry Andric BinaryStreamReader Reader(Data, support::little); 904*0b57cec5SDimitry Andric uint32_t Magic; 905*0b57cec5SDimitry Andric 906*0b57cec5SDimitry Andric ExitOnError Err("Invalid .debug$S section!"); 907*0b57cec5SDimitry Andric Err(Reader.readInteger(Magic)); 908*0b57cec5SDimitry Andric assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!"); 909*0b57cec5SDimitry Andric 910*0b57cec5SDimitry Andric DebugSubsectionArray Subsections; 911*0b57cec5SDimitry Andric Err(Reader.readArray(Subsections, Reader.bytesRemaining())); 912*0b57cec5SDimitry Andric 913*0b57cec5SDimitry Andric std::vector<YAMLDebugSubsection> Result; 914*0b57cec5SDimitry Andric 915*0b57cec5SDimitry Andric for (const auto &SS : Subsections) { 916*0b57cec5SDimitry Andric auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS)); 917*0b57cec5SDimitry Andric Result.push_back(YamlSS); 918*0b57cec5SDimitry Andric } 919*0b57cec5SDimitry Andric return Result; 920*0b57cec5SDimitry Andric } 921*0b57cec5SDimitry Andric 922*0b57cec5SDimitry Andric void llvm::CodeViewYAML::initializeStringsAndChecksums( 923*0b57cec5SDimitry Andric ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) { 924*0b57cec5SDimitry Andric // String Table and Checksums subsections don't use the allocator. 925*0b57cec5SDimitry Andric BumpPtrAllocator Allocator; 926*0b57cec5SDimitry Andric 927*0b57cec5SDimitry Andric // It's possible for checksums and strings to even appear in different debug$S 928*0b57cec5SDimitry Andric // sections, so we have to make this a stateful function that can build up 929*0b57cec5SDimitry Andric // the strings and checksums field over multiple iterations. 930*0b57cec5SDimitry Andric 931*0b57cec5SDimitry Andric // File Checksums require the string table, but may become before it, so we 932*0b57cec5SDimitry Andric // have to scan for strings first, then scan for checksums again from the 933*0b57cec5SDimitry Andric // beginning. 934*0b57cec5SDimitry Andric if (!SC.hasStrings()) { 935*0b57cec5SDimitry Andric for (const auto &SS : Sections) { 936*0b57cec5SDimitry Andric if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) 937*0b57cec5SDimitry Andric continue; 938*0b57cec5SDimitry Andric 939*0b57cec5SDimitry Andric auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); 940*0b57cec5SDimitry Andric SC.setStrings( 941*0b57cec5SDimitry Andric std::static_pointer_cast<DebugStringTableSubsection>(Result)); 942*0b57cec5SDimitry Andric break; 943*0b57cec5SDimitry Andric } 944*0b57cec5SDimitry Andric } 945*0b57cec5SDimitry Andric 946*0b57cec5SDimitry Andric if (SC.hasStrings() && !SC.hasChecksums()) { 947*0b57cec5SDimitry Andric for (const auto &SS : Sections) { 948*0b57cec5SDimitry Andric if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums) 949*0b57cec5SDimitry Andric continue; 950*0b57cec5SDimitry Andric 951*0b57cec5SDimitry Andric auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); 952*0b57cec5SDimitry Andric SC.setChecksums( 953*0b57cec5SDimitry Andric std::static_pointer_cast<DebugChecksumsSubsection>(Result)); 954*0b57cec5SDimitry Andric break; 955*0b57cec5SDimitry Andric } 956*0b57cec5SDimitry Andric } 957*0b57cec5SDimitry Andric } 958