xref: /freebsd/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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