1f9448bf3SDimitry Andric //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
2f9448bf3SDimitry Andric //
3f9448bf3SDimitry Andric //                     The LLVM Compiler Infrastructure
4f9448bf3SDimitry Andric //
5f9448bf3SDimitry Andric // This file is distributed under the University of Illinois Open Source
6f9448bf3SDimitry Andric // License. See LICENSE.TXT for details.
7f9448bf3SDimitry Andric //
8f9448bf3SDimitry Andric //===----------------------------------------------------------------------===//
9f9448bf3SDimitry Andric //
10f9448bf3SDimitry Andric // This file defines classes for handling the YAML representation of CodeView
11f9448bf3SDimitry Andric // Debug Info.
12f9448bf3SDimitry Andric //
13f9448bf3SDimitry Andric //===----------------------------------------------------------------------===//
14f9448bf3SDimitry Andric 
15f9448bf3SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
16a580b014SDimitry Andric #include "llvm/ADT/STLExtras.h"
17f9448bf3SDimitry Andric #include "llvm/ADT/StringExtras.h"
18a580b014SDimitry Andric #include "llvm/ADT/StringRef.h"
19a580b014SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
20a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
21f9448bf3SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
226d97bb29SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
23db17bf38SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
24db17bf38SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
25db17bf38SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
266d97bb29SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
276d97bb29SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
286d97bb29SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
29a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
306d97bb29SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
31db17bf38SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
32db17bf38SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
33a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h"
3424d58133SDimitry Andric #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
35a580b014SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
36db17bf38SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
37a580b014SDimitry Andric #include "llvm/Support/Allocator.h"
38a580b014SDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
39a580b014SDimitry Andric #include "llvm/Support/Endian.h"
40a580b014SDimitry Andric #include "llvm/Support/Error.h"
41a580b014SDimitry Andric #include "llvm/Support/ErrorHandling.h"
42a580b014SDimitry Andric #include "llvm/Support/YAMLTraits.h"
43a580b014SDimitry Andric #include "llvm/Support/raw_ostream.h"
44a580b014SDimitry Andric #include <algorithm>
45a580b014SDimitry Andric #include <cassert>
46a580b014SDimitry Andric #include <cstdint>
47a580b014SDimitry Andric #include <memory>
48a580b014SDimitry Andric #include <string>
49a580b014SDimitry Andric #include <tuple>
50a580b014SDimitry Andric #include <vector>
51a580b014SDimitry Andric 
52f9448bf3SDimitry Andric using namespace llvm;
53f9448bf3SDimitry Andric using namespace llvm::codeview;
54f9448bf3SDimitry Andric using namespace llvm::CodeViewYAML;
55f9448bf3SDimitry Andric using namespace llvm::CodeViewYAML::detail;
56f9448bf3SDimitry Andric using namespace llvm::yaml;
57f9448bf3SDimitry Andric 
58f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry)
59f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry)
60f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry)
61f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock)
62f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo)
63f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite)
64f9448bf3SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
65db17bf38SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport)
66db17bf38SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
67db17bf38SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
68f9448bf3SDimitry Andric 
692cab237bSDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
706d97bb29SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
71f9448bf3SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
72f9448bf3SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
73f9448bf3SDimitry Andric 
74db17bf38SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport)
75db17bf38SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData)
76db17bf38SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport)
77db17bf38SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem)
786d97bb29SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry)
796d97bb29SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry)
806d97bb29SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry)
816d97bb29SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock)
826d97bb29SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite)
836d97bb29SDimitry Andric 
846d97bb29SDimitry Andric namespace llvm {
856d97bb29SDimitry Andric namespace CodeViewYAML {
866d97bb29SDimitry Andric namespace detail {
87a580b014SDimitry Andric 
886d97bb29SDimitry Andric struct YAMLSubsectionBase {
YAMLSubsectionBasellvm::CodeViewYAML::detail::YAMLSubsectionBase896d97bb29SDimitry Andric   explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {}
90a580b014SDimitry Andric   virtual ~YAMLSubsectionBase() = default;
916d97bb29SDimitry Andric 
926d97bb29SDimitry Andric   virtual void map(IO &IO) = 0;
9324d58133SDimitry Andric   virtual std::shared_ptr<DebugSubsection>
94db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
9524d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const = 0;
96a580b014SDimitry Andric 
97a580b014SDimitry Andric   DebugSubsectionKind Kind;
986d97bb29SDimitry Andric };
99a580b014SDimitry Andric 
100a580b014SDimitry Andric } // end namespace detail
101a580b014SDimitry Andric } // end namespace CodeViewYAML
102a580b014SDimitry Andric } // end namespace llvm
1036d97bb29SDimitry Andric 
1046d97bb29SDimitry Andric namespace {
105a580b014SDimitry Andric 
1066d97bb29SDimitry Andric struct YAMLChecksumsSubsection : public YAMLSubsectionBase {
YAMLChecksumsSubsection__anon6e21efa60111::YAMLChecksumsSubsection1076d97bb29SDimitry Andric   YAMLChecksumsSubsection()
1086d97bb29SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
1096d97bb29SDimitry Andric 
1106d97bb29SDimitry Andric   void map(IO &IO) override;
11124d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
112db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
11324d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1146d97bb29SDimitry Andric   static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
1156d97bb29SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1166d97bb29SDimitry Andric                          const DebugChecksumsSubsectionRef &FC);
1176d97bb29SDimitry Andric 
1186d97bb29SDimitry Andric   std::vector<SourceFileChecksumEntry> Checksums;
1196d97bb29SDimitry Andric };
1206d97bb29SDimitry Andric 
1216d97bb29SDimitry Andric struct YAMLLinesSubsection : public YAMLSubsectionBase {
YAMLLinesSubsection__anon6e21efa60111::YAMLLinesSubsection1226d97bb29SDimitry Andric   YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
1236d97bb29SDimitry Andric 
1246d97bb29SDimitry Andric   void map(IO &IO) override;
12524d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
126db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
12724d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1286d97bb29SDimitry Andric   static Expected<std::shared_ptr<YAMLLinesSubsection>>
1296d97bb29SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1306d97bb29SDimitry Andric                          const DebugChecksumsSubsectionRef &Checksums,
1316d97bb29SDimitry Andric                          const DebugLinesSubsectionRef &Lines);
1326d97bb29SDimitry Andric 
1336d97bb29SDimitry Andric   SourceLineInfo Lines;
1346d97bb29SDimitry Andric };
1356d97bb29SDimitry Andric 
1366d97bb29SDimitry Andric struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase {
YAMLInlineeLinesSubsection__anon6e21efa60111::YAMLInlineeLinesSubsection1376d97bb29SDimitry Andric   YAMLInlineeLinesSubsection()
1386d97bb29SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
1396d97bb29SDimitry Andric 
1406d97bb29SDimitry Andric   void map(IO &IO) override;
14124d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
142db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
14324d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1446d97bb29SDimitry Andric   static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
1456d97bb29SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1466d97bb29SDimitry Andric                          const DebugChecksumsSubsectionRef &Checksums,
1476d97bb29SDimitry Andric                          const DebugInlineeLinesSubsectionRef &Lines);
1486d97bb29SDimitry Andric 
1496d97bb29SDimitry Andric   InlineeInfo InlineeLines;
1506d97bb29SDimitry Andric };
151db17bf38SDimitry Andric 
152db17bf38SDimitry Andric struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleExportsSubsection__anon6e21efa60111::YAMLCrossModuleExportsSubsection153db17bf38SDimitry Andric   YAMLCrossModuleExportsSubsection()
154db17bf38SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}
155db17bf38SDimitry Andric 
156db17bf38SDimitry Andric   void map(IO &IO) override;
15724d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
158db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
15924d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
160db17bf38SDimitry Andric   static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
161db17bf38SDimitry Andric   fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);
162db17bf38SDimitry Andric 
163db17bf38SDimitry Andric   std::vector<CrossModuleExport> Exports;
164db17bf38SDimitry Andric };
165db17bf38SDimitry Andric 
166db17bf38SDimitry Andric struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleImportsSubsection__anon6e21efa60111::YAMLCrossModuleImportsSubsection167db17bf38SDimitry Andric   YAMLCrossModuleImportsSubsection()
168db17bf38SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}
169db17bf38SDimitry Andric 
170db17bf38SDimitry Andric   void map(IO &IO) override;
17124d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
172db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
17324d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
174db17bf38SDimitry Andric   static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
175db17bf38SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
176db17bf38SDimitry Andric                          const DebugCrossModuleImportsSubsectionRef &Imports);
177db17bf38SDimitry Andric 
178db17bf38SDimitry Andric   std::vector<YAMLCrossModuleImport> Imports;
179db17bf38SDimitry Andric };
180db17bf38SDimitry Andric 
181db17bf38SDimitry Andric struct YAMLSymbolsSubsection : public YAMLSubsectionBase {
YAMLSymbolsSubsection__anon6e21efa60111::YAMLSymbolsSubsection182db17bf38SDimitry Andric   YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}
183db17bf38SDimitry Andric 
184db17bf38SDimitry Andric   void map(IO &IO) override;
18524d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
186db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
18724d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
188db17bf38SDimitry Andric   static Expected<std::shared_ptr<YAMLSymbolsSubsection>>
189db17bf38SDimitry Andric   fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);
190db17bf38SDimitry Andric 
191db17bf38SDimitry Andric   std::vector<CodeViewYAML::SymbolRecord> Symbols;
192db17bf38SDimitry Andric };
193db17bf38SDimitry Andric 
194db17bf38SDimitry Andric struct YAMLStringTableSubsection : public YAMLSubsectionBase {
YAMLStringTableSubsection__anon6e21efa60111::YAMLStringTableSubsection195db17bf38SDimitry Andric   YAMLStringTableSubsection()
196db17bf38SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}
197db17bf38SDimitry Andric 
198db17bf38SDimitry Andric   void map(IO &IO) override;
19924d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
200db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
20124d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
202db17bf38SDimitry Andric   static Expected<std::shared_ptr<YAMLStringTableSubsection>>
203db17bf38SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);
204db17bf38SDimitry Andric 
205db17bf38SDimitry Andric   std::vector<StringRef> Strings;
206db17bf38SDimitry Andric };
207db17bf38SDimitry Andric 
208db17bf38SDimitry Andric struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
YAMLFrameDataSubsection__anon6e21efa60111::YAMLFrameDataSubsection209db17bf38SDimitry Andric   YAMLFrameDataSubsection()
210db17bf38SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}
211db17bf38SDimitry Andric 
212db17bf38SDimitry Andric   void map(IO &IO) override;
21324d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
214db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
21524d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
216db17bf38SDimitry Andric   static Expected<std::shared_ptr<YAMLFrameDataSubsection>>
217db17bf38SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
218db17bf38SDimitry Andric                          const DebugFrameDataSubsectionRef &Frames);
219db17bf38SDimitry Andric 
220db17bf38SDimitry Andric   std::vector<YAMLFrameData> Frames;
221db17bf38SDimitry Andric };
222db17bf38SDimitry Andric 
223db17bf38SDimitry Andric struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
YAMLCoffSymbolRVASubsection__anon6e21efa60111::YAMLCoffSymbolRVASubsection224db17bf38SDimitry Andric   YAMLCoffSymbolRVASubsection()
225db17bf38SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
226db17bf38SDimitry Andric 
227db17bf38SDimitry Andric   void map(IO &IO) override;
22824d58133SDimitry Andric   std::shared_ptr<DebugSubsection>
229db17bf38SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
23024d58133SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
231db17bf38SDimitry Andric   static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
232db17bf38SDimitry Andric   fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
233db17bf38SDimitry Andric 
234db17bf38SDimitry Andric   std::vector<uint32_t> RVAs;
235db17bf38SDimitry Andric };
236a580b014SDimitry Andric 
237a580b014SDimitry Andric } // end anonymous namespace
238f9448bf3SDimitry Andric 
bitset(IO & io,LineFlags & Flags)239f9448bf3SDimitry Andric void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
240f9448bf3SDimitry Andric   io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
241f9448bf3SDimitry Andric   io.enumFallback<Hex16>(Flags);
242f9448bf3SDimitry Andric }
243f9448bf3SDimitry Andric 
enumeration(IO & io,FileChecksumKind & Kind)244f9448bf3SDimitry Andric void ScalarEnumerationTraits<FileChecksumKind>::enumeration(
245f9448bf3SDimitry Andric     IO &io, FileChecksumKind &Kind) {
246f9448bf3SDimitry Andric   io.enumCase(Kind, "None", FileChecksumKind::None);
247f9448bf3SDimitry Andric   io.enumCase(Kind, "MD5", FileChecksumKind::MD5);
248f9448bf3SDimitry Andric   io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1);
249f9448bf3SDimitry Andric   io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256);
250f9448bf3SDimitry Andric }
251f9448bf3SDimitry Andric 
output(const HexFormattedString & Value,void * ctx,raw_ostream & Out)252f9448bf3SDimitry Andric void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
253f9448bf3SDimitry Andric                                               void *ctx, raw_ostream &Out) {
254f9448bf3SDimitry Andric   StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
255f9448bf3SDimitry Andric                   Value.Bytes.size());
256f9448bf3SDimitry Andric   Out << toHex(Bytes);
257f9448bf3SDimitry Andric }
258f9448bf3SDimitry Andric 
input(StringRef Scalar,void * ctxt,HexFormattedString & Value)259f9448bf3SDimitry Andric StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
260f9448bf3SDimitry Andric                                                   HexFormattedString &Value) {
261f9448bf3SDimitry Andric   std::string H = fromHex(Scalar);
262f9448bf3SDimitry Andric   Value.Bytes.assign(H.begin(), H.end());
263f9448bf3SDimitry Andric   return StringRef();
264f9448bf3SDimitry Andric }
265f9448bf3SDimitry Andric 
mapping(IO & IO,SourceLineEntry & Obj)266f9448bf3SDimitry Andric void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) {
267f9448bf3SDimitry Andric   IO.mapRequired("Offset", Obj.Offset);
268f9448bf3SDimitry Andric   IO.mapRequired("LineStart", Obj.LineStart);
269f9448bf3SDimitry Andric   IO.mapRequired("IsStatement", Obj.IsStatement);
270f9448bf3SDimitry Andric   IO.mapRequired("EndDelta", Obj.EndDelta);
271f9448bf3SDimitry Andric }
272f9448bf3SDimitry Andric 
mapping(IO & IO,SourceColumnEntry & Obj)273f9448bf3SDimitry Andric void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) {
274f9448bf3SDimitry Andric   IO.mapRequired("StartColumn", Obj.StartColumn);
275f9448bf3SDimitry Andric   IO.mapRequired("EndColumn", Obj.EndColumn);
276f9448bf3SDimitry Andric }
277f9448bf3SDimitry Andric 
mapping(IO & IO,SourceLineBlock & Obj)278f9448bf3SDimitry Andric void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) {
279f9448bf3SDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
280f9448bf3SDimitry Andric   IO.mapRequired("Lines", Obj.Lines);
281f9448bf3SDimitry Andric   IO.mapRequired("Columns", Obj.Columns);
282f9448bf3SDimitry Andric }
283f9448bf3SDimitry Andric 
mapping(IO & IO,CrossModuleExport & Obj)284db17bf38SDimitry Andric void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) {
285db17bf38SDimitry Andric   IO.mapRequired("LocalId", Obj.Local);
286db17bf38SDimitry Andric   IO.mapRequired("GlobalId", Obj.Global);
287db17bf38SDimitry Andric }
288db17bf38SDimitry Andric 
mapping(IO & IO,YAMLCrossModuleImport & Obj)289db17bf38SDimitry Andric void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO,
290db17bf38SDimitry Andric                                                    YAMLCrossModuleImport &Obj) {
291db17bf38SDimitry Andric   IO.mapRequired("Module", Obj.ModuleName);
292db17bf38SDimitry Andric   IO.mapRequired("Imports", Obj.ImportIds);
293db17bf38SDimitry Andric }
294db17bf38SDimitry Andric 
mapping(IO & IO,SourceFileChecksumEntry & Obj)295f9448bf3SDimitry Andric void MappingTraits<SourceFileChecksumEntry>::mapping(
296f9448bf3SDimitry Andric     IO &IO, SourceFileChecksumEntry &Obj) {
297f9448bf3SDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
298f9448bf3SDimitry Andric   IO.mapRequired("Kind", Obj.Kind);
299f9448bf3SDimitry Andric   IO.mapRequired("Checksum", Obj.ChecksumBytes);
300f9448bf3SDimitry Andric }
301f9448bf3SDimitry Andric 
mapping(IO & IO,InlineeSite & Obj)302f9448bf3SDimitry Andric void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
303f9448bf3SDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
304f9448bf3SDimitry Andric   IO.mapRequired("LineNum", Obj.SourceLineNum);
305f9448bf3SDimitry Andric   IO.mapRequired("Inlinee", Obj.Inlinee);
306f9448bf3SDimitry Andric   IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
307f9448bf3SDimitry Andric }
308f9448bf3SDimitry Andric 
mapping(IO & IO,YAMLFrameData & Obj)309db17bf38SDimitry Andric void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) {
310db17bf38SDimitry Andric   IO.mapRequired("CodeSize", Obj.CodeSize);
311db17bf38SDimitry Andric   IO.mapRequired("FrameFunc", Obj.FrameFunc);
312db17bf38SDimitry Andric   IO.mapRequired("LocalSize", Obj.LocalSize);
313db17bf38SDimitry Andric   IO.mapOptional("MaxStackSize", Obj.MaxStackSize);
314db17bf38SDimitry Andric   IO.mapOptional("ParamsSize", Obj.ParamsSize);
315db17bf38SDimitry Andric   IO.mapOptional("PrologSize", Obj.PrologSize);
316db17bf38SDimitry Andric   IO.mapOptional("RvaStart", Obj.RvaStart);
317db17bf38SDimitry Andric   IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize);
318db17bf38SDimitry Andric }
319db17bf38SDimitry Andric 
map(IO & IO)3206d97bb29SDimitry Andric void YAMLChecksumsSubsection::map(IO &IO) {
3216d97bb29SDimitry Andric   IO.mapTag("!FileChecksums", true);
3226d97bb29SDimitry Andric   IO.mapRequired("Checksums", Checksums);
3236d97bb29SDimitry Andric }
3246d97bb29SDimitry Andric 
map(IO & IO)3256d97bb29SDimitry Andric void YAMLLinesSubsection::map(IO &IO) {
3266d97bb29SDimitry Andric   IO.mapTag("!Lines", true);
3276d97bb29SDimitry Andric   IO.mapRequired("CodeSize", Lines.CodeSize);
3286d97bb29SDimitry Andric 
3296d97bb29SDimitry Andric   IO.mapRequired("Flags", Lines.Flags);
3306d97bb29SDimitry Andric   IO.mapRequired("RelocOffset", Lines.RelocOffset);
3316d97bb29SDimitry Andric   IO.mapRequired("RelocSegment", Lines.RelocSegment);
3326d97bb29SDimitry Andric   IO.mapRequired("Blocks", Lines.Blocks);
3336d97bb29SDimitry Andric }
3346d97bb29SDimitry Andric 
map(IO & IO)3356d97bb29SDimitry Andric void YAMLInlineeLinesSubsection::map(IO &IO) {
3366d97bb29SDimitry Andric   IO.mapTag("!InlineeLines", true);
3376d97bb29SDimitry Andric   IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles);
3386d97bb29SDimitry Andric   IO.mapRequired("Sites", InlineeLines.Sites);
3396d97bb29SDimitry Andric }
3406d97bb29SDimitry Andric 
map(IO & IO)341db17bf38SDimitry Andric void YAMLCrossModuleExportsSubsection::map(IO &IO) {
342db17bf38SDimitry Andric   IO.mapTag("!CrossModuleExports", true);
343db17bf38SDimitry Andric   IO.mapOptional("Exports", Exports);
344db17bf38SDimitry Andric }
345db17bf38SDimitry Andric 
map(IO & IO)346db17bf38SDimitry Andric void YAMLCrossModuleImportsSubsection::map(IO &IO) {
347db17bf38SDimitry Andric   IO.mapTag("!CrossModuleImports", true);
348db17bf38SDimitry Andric   IO.mapOptional("Imports", Imports);
349db17bf38SDimitry Andric }
350db17bf38SDimitry Andric 
map(IO & IO)351db17bf38SDimitry Andric void YAMLSymbolsSubsection::map(IO &IO) {
352db17bf38SDimitry Andric   IO.mapTag("!Symbols", true);
353db17bf38SDimitry Andric   IO.mapRequired("Records", Symbols);
354db17bf38SDimitry Andric }
355db17bf38SDimitry Andric 
map(IO & IO)356db17bf38SDimitry Andric void YAMLStringTableSubsection::map(IO &IO) {
357db17bf38SDimitry Andric   IO.mapTag("!StringTable", true);
358db17bf38SDimitry Andric   IO.mapRequired("Strings", Strings);
359db17bf38SDimitry Andric }
360db17bf38SDimitry Andric 
map(IO & IO)361db17bf38SDimitry Andric void YAMLFrameDataSubsection::map(IO &IO) {
362db17bf38SDimitry Andric   IO.mapTag("!FrameData", true);
363db17bf38SDimitry Andric   IO.mapRequired("Frames", Frames);
364db17bf38SDimitry Andric }
365db17bf38SDimitry Andric 
map(IO & IO)366db17bf38SDimitry Andric void YAMLCoffSymbolRVASubsection::map(IO &IO) {
367db17bf38SDimitry Andric   IO.mapTag("!COFFSymbolRVAs", true);
368db17bf38SDimitry Andric   IO.mapRequired("RVAs", RVAs);
369db17bf38SDimitry Andric }
370db17bf38SDimitry Andric 
mapping(IO & IO,YAMLDebugSubsection & Subsection)3716d97bb29SDimitry Andric void MappingTraits<YAMLDebugSubsection>::mapping(
3726d97bb29SDimitry Andric     IO &IO, YAMLDebugSubsection &Subsection) {
3736d97bb29SDimitry Andric   if (!IO.outputting()) {
3746d97bb29SDimitry Andric     if (IO.mapTag("!FileChecksums")) {
3756d97bb29SDimitry Andric       auto SS = std::make_shared<YAMLChecksumsSubsection>();
3766d97bb29SDimitry Andric       Subsection.Subsection = SS;
3776d97bb29SDimitry Andric     } else if (IO.mapTag("!Lines")) {
3786d97bb29SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLLinesSubsection>();
3796d97bb29SDimitry Andric     } else if (IO.mapTag("!InlineeLines")) {
3806d97bb29SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>();
381db17bf38SDimitry Andric     } else if (IO.mapTag("!CrossModuleExports")) {
382db17bf38SDimitry Andric       Subsection.Subsection =
383db17bf38SDimitry Andric           std::make_shared<YAMLCrossModuleExportsSubsection>();
384db17bf38SDimitry Andric     } else if (IO.mapTag("!CrossModuleImports")) {
385db17bf38SDimitry Andric       Subsection.Subsection =
386db17bf38SDimitry Andric           std::make_shared<YAMLCrossModuleImportsSubsection>();
387db17bf38SDimitry Andric     } else if (IO.mapTag("!Symbols")) {
388db17bf38SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>();
389db17bf38SDimitry Andric     } else if (IO.mapTag("!StringTable")) {
390db17bf38SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
391db17bf38SDimitry Andric     } else if (IO.mapTag("!FrameData")) {
392db17bf38SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
393db17bf38SDimitry Andric     } else if (IO.mapTag("!COFFSymbolRVAs")) {
394db17bf38SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
3956d97bb29SDimitry Andric     } else {
3966d97bb29SDimitry Andric       llvm_unreachable("Unexpected subsection tag!");
3976d97bb29SDimitry Andric     }
3986d97bb29SDimitry Andric   }
3996d97bb29SDimitry Andric   Subsection.Subsection->map(IO);
4006d97bb29SDimitry Andric }
4016d97bb29SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const40224d58133SDimitry Andric std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
40324d58133SDimitry Andric     BumpPtrAllocator &Allocator,
40424d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
40524d58133SDimitry Andric   assert(SC.hasStrings());
40624d58133SDimitry Andric   auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings());
4076d97bb29SDimitry Andric   for (const auto &CS : Checksums) {
4086d97bb29SDimitry Andric     Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
4096d97bb29SDimitry Andric   }
41024d58133SDimitry Andric   return Result;
4116d97bb29SDimitry Andric }
4126d97bb29SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const41324d58133SDimitry Andric std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
41424d58133SDimitry Andric     BumpPtrAllocator &Allocator,
41524d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
41624d58133SDimitry Andric   assert(SC.hasStrings() && SC.hasChecksums());
4176d97bb29SDimitry Andric   auto Result =
41824d58133SDimitry Andric       std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings());
4196d97bb29SDimitry Andric   Result->setCodeSize(Lines.CodeSize);
4206d97bb29SDimitry Andric   Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
4216d97bb29SDimitry Andric   Result->setFlags(Lines.Flags);
4226d97bb29SDimitry Andric   for (const auto &LC : Lines.Blocks) {
4236d97bb29SDimitry Andric     Result->createBlock(LC.FileName);
4246d97bb29SDimitry Andric     if (Result->hasColumnInfo()) {
4256d97bb29SDimitry Andric       for (const auto &Item : zip(LC.Lines, LC.Columns)) {
4266d97bb29SDimitry Andric         auto &L = std::get<0>(Item);
4276d97bb29SDimitry Andric         auto &C = std::get<1>(Item);
4286d97bb29SDimitry Andric         uint32_t LE = L.LineStart + L.EndDelta;
4296d97bb29SDimitry Andric         Result->addLineAndColumnInfo(L.Offset,
4306d97bb29SDimitry Andric                                      LineInfo(L.LineStart, LE, L.IsStatement),
4316d97bb29SDimitry Andric                                      C.StartColumn, C.EndColumn);
4326d97bb29SDimitry Andric       }
4336d97bb29SDimitry Andric     } else {
4346d97bb29SDimitry Andric       for (const auto &L : LC.Lines) {
4356d97bb29SDimitry Andric         uint32_t LE = L.LineStart + L.EndDelta;
4366d97bb29SDimitry Andric         Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement));
4376d97bb29SDimitry Andric       }
4386d97bb29SDimitry Andric     }
4396d97bb29SDimitry Andric   }
44024d58133SDimitry Andric   return Result;
4416d97bb29SDimitry Andric }
4426d97bb29SDimitry Andric 
44324d58133SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4446d97bb29SDimitry Andric YAMLInlineeLinesSubsection::toCodeViewSubsection(
44524d58133SDimitry Andric     BumpPtrAllocator &Allocator,
44624d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
44724d58133SDimitry Andric   assert(SC.hasChecksums());
44824d58133SDimitry Andric   auto Result = std::make_shared<DebugInlineeLinesSubsection>(
44924d58133SDimitry Andric       *SC.checksums(), InlineeLines.HasExtraFiles);
4506d97bb29SDimitry Andric 
4516d97bb29SDimitry Andric   for (const auto &Site : InlineeLines.Sites) {
4526d97bb29SDimitry Andric     Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
4536d97bb29SDimitry Andric                           Site.SourceLineNum);
4546d97bb29SDimitry Andric     if (!InlineeLines.HasExtraFiles)
4556d97bb29SDimitry Andric       continue;
4566d97bb29SDimitry Andric 
4576d97bb29SDimitry Andric     for (auto EF : Site.ExtraFiles) {
4586d97bb29SDimitry Andric       Result->addExtraFile(EF);
4596d97bb29SDimitry Andric     }
4606d97bb29SDimitry Andric   }
46124d58133SDimitry Andric   return Result;
4626d97bb29SDimitry Andric }
4636d97bb29SDimitry Andric 
46424d58133SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const465db17bf38SDimitry Andric YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
46624d58133SDimitry Andric     BumpPtrAllocator &Allocator,
46724d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
46824d58133SDimitry Andric   auto Result = std::make_shared<DebugCrossModuleExportsSubsection>();
469db17bf38SDimitry Andric   for (const auto &M : Exports)
470db17bf38SDimitry Andric     Result->addMapping(M.Local, M.Global);
47124d58133SDimitry Andric   return Result;
472db17bf38SDimitry Andric }
473db17bf38SDimitry Andric 
47424d58133SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const475db17bf38SDimitry Andric YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
47624d58133SDimitry Andric     BumpPtrAllocator &Allocator,
47724d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
47824d58133SDimitry Andric   assert(SC.hasStrings());
47924d58133SDimitry Andric 
48024d58133SDimitry Andric   auto Result =
48124d58133SDimitry Andric       std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings());
482db17bf38SDimitry Andric   for (const auto &M : Imports) {
483db17bf38SDimitry Andric     for (const auto Id : M.ImportIds)
484db17bf38SDimitry Andric       Result->addImport(M.ModuleName, Id);
485db17bf38SDimitry Andric   }
48624d58133SDimitry Andric   return Result;
487db17bf38SDimitry Andric }
488db17bf38SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const48924d58133SDimitry Andric std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
49024d58133SDimitry Andric     BumpPtrAllocator &Allocator,
49124d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
49224d58133SDimitry Andric   auto Result = std::make_shared<DebugSymbolsSubsection>();
493db17bf38SDimitry Andric   for (const auto &Sym : Symbols)
494db17bf38SDimitry Andric     Result->addSymbol(
495db17bf38SDimitry Andric         Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
49624d58133SDimitry Andric   return Result;
497db17bf38SDimitry Andric }
498db17bf38SDimitry Andric 
49924d58133SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const500db17bf38SDimitry Andric YAMLStringTableSubsection::toCodeViewSubsection(
50124d58133SDimitry Andric     BumpPtrAllocator &Allocator,
50224d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
50324d58133SDimitry Andric   auto Result = std::make_shared<DebugStringTableSubsection>();
504db17bf38SDimitry Andric   for (const auto &Str : this->Strings)
505db17bf38SDimitry Andric     Result->insert(Str);
50624d58133SDimitry Andric   return Result;
507db17bf38SDimitry Andric }
508db17bf38SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const50924d58133SDimitry Andric std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
51024d58133SDimitry Andric     BumpPtrAllocator &Allocator,
51124d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
51224d58133SDimitry Andric   assert(SC.hasStrings());
51324d58133SDimitry Andric 
514*b5893f02SDimitry Andric   auto Result = std::make_shared<DebugFrameDataSubsection>(true);
515db17bf38SDimitry Andric   for (const auto &YF : Frames) {
516db17bf38SDimitry Andric     codeview::FrameData F;
517db17bf38SDimitry Andric     F.CodeSize = YF.CodeSize;
518db17bf38SDimitry Andric     F.Flags = YF.Flags;
519db17bf38SDimitry Andric     F.LocalSize = YF.LocalSize;
520db17bf38SDimitry Andric     F.MaxStackSize = YF.MaxStackSize;
521db17bf38SDimitry Andric     F.ParamsSize = YF.ParamsSize;
522db17bf38SDimitry Andric     F.PrologSize = YF.PrologSize;
523db17bf38SDimitry Andric     F.RvaStart = YF.RvaStart;
524db17bf38SDimitry Andric     F.SavedRegsSize = YF.SavedRegsSize;
52524d58133SDimitry Andric     F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
526db17bf38SDimitry Andric     Result->addFrameData(F);
527db17bf38SDimitry Andric   }
52824d58133SDimitry Andric   return Result;
529db17bf38SDimitry Andric }
530db17bf38SDimitry Andric 
53124d58133SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const532db17bf38SDimitry Andric YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
53324d58133SDimitry Andric     BumpPtrAllocator &Allocator,
53424d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
53524d58133SDimitry Andric   auto Result = std::make_shared<DebugSymbolRVASubsection>();
536db17bf38SDimitry Andric   for (const auto &RVA : RVAs)
537db17bf38SDimitry Andric     Result->addRVA(RVA);
53824d58133SDimitry Andric   return Result;
539db17bf38SDimitry Andric }
540db17bf38SDimitry Andric 
5416d97bb29SDimitry Andric static Expected<SourceFileChecksumEntry>
convertOneChecksum(const DebugStringTableSubsectionRef & Strings,const FileChecksumEntry & CS)5426d97bb29SDimitry Andric convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
5436d97bb29SDimitry Andric                    const FileChecksumEntry &CS) {
5446d97bb29SDimitry Andric   auto ExpectedString = Strings.getString(CS.FileNameOffset);
5456d97bb29SDimitry Andric   if (!ExpectedString)
5466d97bb29SDimitry Andric     return ExpectedString.takeError();
5476d97bb29SDimitry Andric 
5486d97bb29SDimitry Andric   SourceFileChecksumEntry Result;
5496d97bb29SDimitry Andric   Result.ChecksumBytes.Bytes = CS.Checksum;
5506d97bb29SDimitry Andric   Result.Kind = CS.Kind;
5516d97bb29SDimitry Andric   Result.FileName = *ExpectedString;
5526d97bb29SDimitry Andric   return Result;
5536d97bb29SDimitry Andric }
5546d97bb29SDimitry Andric 
5556d97bb29SDimitry Andric static Expected<StringRef>
getFileName(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,uint32_t FileID)5566d97bb29SDimitry Andric getFileName(const DebugStringTableSubsectionRef &Strings,
5576d97bb29SDimitry Andric             const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
5586d97bb29SDimitry Andric   auto Iter = Checksums.getArray().at(FileID);
5596d97bb29SDimitry Andric   if (Iter == Checksums.getArray().end())
5606d97bb29SDimitry Andric     return make_error<CodeViewError>(cv_error_code::no_records);
5616d97bb29SDimitry Andric   uint32_t Offset = Iter->FileNameOffset;
5626d97bb29SDimitry Andric   return Strings.getString(Offset);
5636d97bb29SDimitry Andric }
5646d97bb29SDimitry Andric 
5656d97bb29SDimitry Andric Expected<std::shared_ptr<YAMLChecksumsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & FC)5666d97bb29SDimitry Andric YAMLChecksumsSubsection::fromCodeViewSubsection(
5676d97bb29SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
5686d97bb29SDimitry Andric     const DebugChecksumsSubsectionRef &FC) {
5696d97bb29SDimitry Andric   auto Result = std::make_shared<YAMLChecksumsSubsection>();
5706d97bb29SDimitry Andric 
5716d97bb29SDimitry Andric   for (const auto &CS : FC) {
5726d97bb29SDimitry Andric     auto ConvertedCS = convertOneChecksum(Strings, CS);
5736d97bb29SDimitry Andric     if (!ConvertedCS)
5746d97bb29SDimitry Andric       return ConvertedCS.takeError();
5756d97bb29SDimitry Andric     Result->Checksums.push_back(*ConvertedCS);
5766d97bb29SDimitry Andric   }
5776d97bb29SDimitry Andric   return Result;
5786d97bb29SDimitry Andric }
5796d97bb29SDimitry Andric 
5806d97bb29SDimitry Andric Expected<std::shared_ptr<YAMLLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugLinesSubsectionRef & Lines)5816d97bb29SDimitry Andric YAMLLinesSubsection::fromCodeViewSubsection(
5826d97bb29SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
5836d97bb29SDimitry Andric     const DebugChecksumsSubsectionRef &Checksums,
5846d97bb29SDimitry Andric     const DebugLinesSubsectionRef &Lines) {
5856d97bb29SDimitry Andric   auto Result = std::make_shared<YAMLLinesSubsection>();
5866d97bb29SDimitry Andric   Result->Lines.CodeSize = Lines.header()->CodeSize;
5876d97bb29SDimitry Andric   Result->Lines.RelocOffset = Lines.header()->RelocOffset;
5886d97bb29SDimitry Andric   Result->Lines.RelocSegment = Lines.header()->RelocSegment;
5896d97bb29SDimitry Andric   Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags));
5906d97bb29SDimitry Andric   for (const auto &L : Lines) {
5916d97bb29SDimitry Andric     SourceLineBlock Block;
5926d97bb29SDimitry Andric     auto EF = getFileName(Strings, Checksums, L.NameIndex);
5936d97bb29SDimitry Andric     if (!EF)
5946d97bb29SDimitry Andric       return EF.takeError();
5956d97bb29SDimitry Andric     Block.FileName = *EF;
5966d97bb29SDimitry Andric     if (Lines.hasColumnInfo()) {
5976d97bb29SDimitry Andric       for (const auto &C : L.Columns) {
5986d97bb29SDimitry Andric         SourceColumnEntry SCE;
5996d97bb29SDimitry Andric         SCE.EndColumn = C.EndColumn;
6006d97bb29SDimitry Andric         SCE.StartColumn = C.StartColumn;
6016d97bb29SDimitry Andric         Block.Columns.push_back(SCE);
6026d97bb29SDimitry Andric       }
6036d97bb29SDimitry Andric     }
6046d97bb29SDimitry Andric     for (const auto &LN : L.LineNumbers) {
6056d97bb29SDimitry Andric       SourceLineEntry SLE;
6066d97bb29SDimitry Andric       LineInfo LI(LN.Flags);
6076d97bb29SDimitry Andric       SLE.Offset = LN.Offset;
6086d97bb29SDimitry Andric       SLE.LineStart = LI.getStartLine();
6096d97bb29SDimitry Andric       SLE.EndDelta = LI.getLineDelta();
6106d97bb29SDimitry Andric       SLE.IsStatement = LI.isStatement();
6116d97bb29SDimitry Andric       Block.Lines.push_back(SLE);
6126d97bb29SDimitry Andric     }
6136d97bb29SDimitry Andric     Result->Lines.Blocks.push_back(Block);
6146d97bb29SDimitry Andric   }
6156d97bb29SDimitry Andric   return Result;
6166d97bb29SDimitry Andric }
6176d97bb29SDimitry Andric 
6186d97bb29SDimitry Andric Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugInlineeLinesSubsectionRef & Lines)6196d97bb29SDimitry Andric YAMLInlineeLinesSubsection::fromCodeViewSubsection(
6206d97bb29SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
6216d97bb29SDimitry Andric     const DebugChecksumsSubsectionRef &Checksums,
6226d97bb29SDimitry Andric     const DebugInlineeLinesSubsectionRef &Lines) {
6236d97bb29SDimitry Andric   auto Result = std::make_shared<YAMLInlineeLinesSubsection>();
6246d97bb29SDimitry Andric 
6256d97bb29SDimitry Andric   Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles();
6266d97bb29SDimitry Andric   for (const auto &IL : Lines) {
6276d97bb29SDimitry Andric     InlineeSite Site;
6286d97bb29SDimitry Andric     auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID);
6296d97bb29SDimitry Andric     if (!ExpF)
6306d97bb29SDimitry Andric       return ExpF.takeError();
6316d97bb29SDimitry Andric     Site.FileName = *ExpF;
6326d97bb29SDimitry Andric     Site.Inlinee = IL.Header->Inlinee.getIndex();
6336d97bb29SDimitry Andric     Site.SourceLineNum = IL.Header->SourceLineNum;
6346d97bb29SDimitry Andric     if (Lines.hasExtraFiles()) {
6356d97bb29SDimitry Andric       for (const auto EF : IL.ExtraFiles) {
6366d97bb29SDimitry Andric         auto ExpF2 = getFileName(Strings, Checksums, EF);
6376d97bb29SDimitry Andric         if (!ExpF2)
6386d97bb29SDimitry Andric           return ExpF2.takeError();
6396d97bb29SDimitry Andric         Site.ExtraFiles.push_back(*ExpF2);
6406d97bb29SDimitry Andric       }
6416d97bb29SDimitry Andric     }
6426d97bb29SDimitry Andric     Result->InlineeLines.Sites.push_back(Site);
6436d97bb29SDimitry Andric   }
6446d97bb29SDimitry Andric   return Result;
6456d97bb29SDimitry Andric }
6466d97bb29SDimitry Andric 
647db17bf38SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef & Exports)648db17bf38SDimitry Andric YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(
649db17bf38SDimitry Andric     const DebugCrossModuleExportsSubsectionRef &Exports) {
650db17bf38SDimitry Andric   auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>();
651db17bf38SDimitry Andric   Result->Exports.assign(Exports.begin(), Exports.end());
652db17bf38SDimitry Andric   return Result;
653db17bf38SDimitry Andric }
654db17bf38SDimitry Andric 
655db17bf38SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugCrossModuleImportsSubsectionRef & Imports)656db17bf38SDimitry Andric YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
657db17bf38SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
658db17bf38SDimitry Andric     const DebugCrossModuleImportsSubsectionRef &Imports) {
659db17bf38SDimitry Andric   auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>();
660db17bf38SDimitry Andric   for (const auto &CMI : Imports) {
661db17bf38SDimitry Andric     YAMLCrossModuleImport YCMI;
662db17bf38SDimitry Andric     auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset);
663db17bf38SDimitry Andric     if (!ExpectedStr)
664db17bf38SDimitry Andric       return ExpectedStr.takeError();
665db17bf38SDimitry Andric     YCMI.ModuleName = *ExpectedStr;
666db17bf38SDimitry Andric     YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end());
667db17bf38SDimitry Andric     Result->Imports.push_back(YCMI);
668db17bf38SDimitry Andric   }
669db17bf38SDimitry Andric   return Result;
670db17bf38SDimitry Andric }
671db17bf38SDimitry Andric 
672db17bf38SDimitry Andric Expected<std::shared_ptr<YAMLSymbolsSubsection>>
fromCodeViewSubsection(const DebugSymbolsSubsectionRef & Symbols)673db17bf38SDimitry Andric YAMLSymbolsSubsection::fromCodeViewSubsection(
674db17bf38SDimitry Andric     const DebugSymbolsSubsectionRef &Symbols) {
675db17bf38SDimitry Andric   auto Result = std::make_shared<YAMLSymbolsSubsection>();
676db17bf38SDimitry Andric   for (const auto &Sym : Symbols) {
677db17bf38SDimitry Andric     auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
678db17bf38SDimitry Andric     if (!S)
679db17bf38SDimitry Andric       return joinErrors(make_error<CodeViewError>(
680db17bf38SDimitry Andric                             cv_error_code::corrupt_record,
681db17bf38SDimitry Andric                             "Invalid CodeView Symbol Record in SymbolRecord "
682db17bf38SDimitry Andric                             "subsection of .debug$S while converting to YAML!"),
683db17bf38SDimitry Andric                         S.takeError());
684db17bf38SDimitry Andric 
685db17bf38SDimitry Andric     Result->Symbols.push_back(*S);
686db17bf38SDimitry Andric   }
687db17bf38SDimitry Andric   return Result;
688db17bf38SDimitry Andric }
689db17bf38SDimitry Andric 
690db17bf38SDimitry Andric Expected<std::shared_ptr<YAMLStringTableSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings)691db17bf38SDimitry Andric YAMLStringTableSubsection::fromCodeViewSubsection(
692db17bf38SDimitry Andric     const DebugStringTableSubsectionRef &Strings) {
693db17bf38SDimitry Andric   auto Result = std::make_shared<YAMLStringTableSubsection>();
694db17bf38SDimitry Andric   BinaryStreamReader Reader(Strings.getBuffer());
695db17bf38SDimitry Andric   StringRef S;
696db17bf38SDimitry Andric   // First item is a single null string, skip it.
697db17bf38SDimitry Andric   if (auto EC = Reader.readCString(S))
698db17bf38SDimitry Andric     return std::move(EC);
699db17bf38SDimitry Andric   assert(S.empty());
700db17bf38SDimitry Andric   while (Reader.bytesRemaining() > 0) {
701db17bf38SDimitry Andric     if (auto EC = Reader.readCString(S))
702db17bf38SDimitry Andric       return std::move(EC);
703db17bf38SDimitry Andric     Result->Strings.push_back(S);
704db17bf38SDimitry Andric   }
705db17bf38SDimitry Andric   return Result;
706db17bf38SDimitry Andric }
707db17bf38SDimitry Andric 
708db17bf38SDimitry Andric Expected<std::shared_ptr<YAMLFrameDataSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugFrameDataSubsectionRef & Frames)709db17bf38SDimitry Andric YAMLFrameDataSubsection::fromCodeViewSubsection(
710db17bf38SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
711db17bf38SDimitry Andric     const DebugFrameDataSubsectionRef &Frames) {
712db17bf38SDimitry Andric   auto Result = std::make_shared<YAMLFrameDataSubsection>();
713db17bf38SDimitry Andric   for (const auto &F : Frames) {
714db17bf38SDimitry Andric     YAMLFrameData YF;
715db17bf38SDimitry Andric     YF.CodeSize = F.CodeSize;
716db17bf38SDimitry Andric     YF.Flags = F.Flags;
717db17bf38SDimitry Andric     YF.LocalSize = F.LocalSize;
718db17bf38SDimitry Andric     YF.MaxStackSize = F.MaxStackSize;
719db17bf38SDimitry Andric     YF.ParamsSize = F.ParamsSize;
720db17bf38SDimitry Andric     YF.PrologSize = F.PrologSize;
721db17bf38SDimitry Andric     YF.RvaStart = F.RvaStart;
722db17bf38SDimitry Andric     YF.SavedRegsSize = F.SavedRegsSize;
723db17bf38SDimitry Andric 
724db17bf38SDimitry Andric     auto ES = Strings.getString(F.FrameFunc);
725db17bf38SDimitry Andric     if (!ES)
726db17bf38SDimitry Andric       return joinErrors(
727db17bf38SDimitry Andric           make_error<CodeViewError>(
728db17bf38SDimitry Andric               cv_error_code::no_records,
729db17bf38SDimitry Andric               "Could not find string for string id while mapping FrameData!"),
730db17bf38SDimitry Andric           ES.takeError());
731db17bf38SDimitry Andric     YF.FrameFunc = *ES;
732db17bf38SDimitry Andric     Result->Frames.push_back(YF);
733db17bf38SDimitry Andric   }
734db17bf38SDimitry Andric   return Result;
735db17bf38SDimitry Andric }
736db17bf38SDimitry Andric 
737db17bf38SDimitry Andric Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
fromCodeViewSubsection(const DebugSymbolRVASubsectionRef & Section)738db17bf38SDimitry Andric YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
739db17bf38SDimitry Andric     const DebugSymbolRVASubsectionRef &Section) {
740db17bf38SDimitry Andric   auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
741db17bf38SDimitry Andric   for (const auto &RVA : Section) {
742db17bf38SDimitry Andric     Result->RVAs.push_back(RVA);
743db17bf38SDimitry Andric   }
744db17bf38SDimitry Andric   return Result;
745db17bf38SDimitry Andric }
746db17bf38SDimitry Andric 
74724d58133SDimitry Andric Expected<std::vector<std::shared_ptr<DebugSubsection>>>
toCodeViewSubsectionList(BumpPtrAllocator & Allocator,ArrayRef<YAMLDebugSubsection> Subsections,const codeview::StringsAndChecksums & SC)748db17bf38SDimitry Andric llvm::CodeViewYAML::toCodeViewSubsectionList(
749db17bf38SDimitry Andric     BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
75024d58133SDimitry Andric     const codeview::StringsAndChecksums &SC) {
75124d58133SDimitry Andric   std::vector<std::shared_ptr<DebugSubsection>> Result;
7526d97bb29SDimitry Andric   if (Subsections.empty())
7536d97bb29SDimitry Andric     return std::move(Result);
7546d97bb29SDimitry Andric 
7556d97bb29SDimitry Andric   for (const auto &SS : Subsections) {
75624d58133SDimitry Andric     std::shared_ptr<DebugSubsection> CVS;
75724d58133SDimitry Andric     CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
758db17bf38SDimitry Andric     assert(CVS != nullptr);
7596d97bb29SDimitry Andric     Result.push_back(std::move(CVS));
7606d97bb29SDimitry Andric   }
7616d97bb29SDimitry Andric   return std::move(Result);
7626d97bb29SDimitry Andric }
7636d97bb29SDimitry Andric 
7646d97bb29SDimitry Andric namespace {
765a580b014SDimitry Andric 
7666d97bb29SDimitry Andric struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
767a580b014SDimitry Andric   SubsectionConversionVisitor() = default;
7686d97bb29SDimitry Andric 
7696d97bb29SDimitry Andric   Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
770db17bf38SDimitry Andric   Error visitLines(DebugLinesSubsectionRef &Lines,
77124d58133SDimitry Andric                    const StringsAndChecksumsRef &State) override;
772db17bf38SDimitry Andric   Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
77324d58133SDimitry Andric                            const StringsAndChecksumsRef &State) override;
774db17bf38SDimitry Andric   Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
77524d58133SDimitry Andric                           const StringsAndChecksumsRef &State) override;
776db17bf38SDimitry Andric   Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
77724d58133SDimitry Andric                                 const StringsAndChecksumsRef &State) override;
778db17bf38SDimitry Andric   Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
77924d58133SDimitry Andric                                 const StringsAndChecksumsRef &State) override;
780db17bf38SDimitry Andric   Error visitStringTable(DebugStringTableSubsectionRef &ST,
78124d58133SDimitry Andric                          const StringsAndChecksumsRef &State) override;
782db17bf38SDimitry Andric   Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
78324d58133SDimitry Andric                      const StringsAndChecksumsRef &State) override;
784db17bf38SDimitry Andric   Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
78524d58133SDimitry Andric                        const StringsAndChecksumsRef &State) override;
786db17bf38SDimitry Andric   Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
78724d58133SDimitry Andric                             const StringsAndChecksumsRef &State) override;
7886d97bb29SDimitry Andric 
7896d97bb29SDimitry Andric   YAMLDebugSubsection Subsection;
7906d97bb29SDimitry Andric };
7916d97bb29SDimitry Andric 
792a580b014SDimitry Andric } // end anonymous namespace
793a580b014SDimitry Andric 
visitUnknown(DebugUnknownSubsectionRef & Unknown)7946d97bb29SDimitry Andric Error SubsectionConversionVisitor::visitUnknown(
7956d97bb29SDimitry Andric     DebugUnknownSubsectionRef &Unknown) {
7966d97bb29SDimitry Andric   return make_error<CodeViewError>(cv_error_code::operation_unsupported);
7976d97bb29SDimitry Andric }
7986d97bb29SDimitry Andric 
visitLines(DebugLinesSubsectionRef & Lines,const StringsAndChecksumsRef & State)799db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitLines(
80024d58133SDimitry Andric     DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
801db17bf38SDimitry Andric   auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
802db17bf38SDimitry Andric       State.strings(), State.checksums(), Lines);
8036d97bb29SDimitry Andric   if (!Result)
8046d97bb29SDimitry Andric     return Result.takeError();
8056d97bb29SDimitry Andric   Subsection.Subsection = *Result;
8066d97bb29SDimitry Andric   return Error::success();
8076d97bb29SDimitry Andric }
8086d97bb29SDimitry Andric 
visitFileChecksums(DebugChecksumsSubsectionRef & Checksums,const StringsAndChecksumsRef & State)8096d97bb29SDimitry Andric Error SubsectionConversionVisitor::visitFileChecksums(
81024d58133SDimitry Andric     DebugChecksumsSubsectionRef &Checksums,
81124d58133SDimitry Andric     const StringsAndChecksumsRef &State) {
812db17bf38SDimitry Andric   auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
813db17bf38SDimitry Andric                                                                 Checksums);
8146d97bb29SDimitry Andric   if (!Result)
8156d97bb29SDimitry Andric     return Result.takeError();
8166d97bb29SDimitry Andric   Subsection.Subsection = *Result;
8176d97bb29SDimitry Andric   return Error::success();
8186d97bb29SDimitry Andric }
8196d97bb29SDimitry Andric 
visitInlineeLines(DebugInlineeLinesSubsectionRef & Inlinees,const StringsAndChecksumsRef & State)8206d97bb29SDimitry Andric Error SubsectionConversionVisitor::visitInlineeLines(
821db17bf38SDimitry Andric     DebugInlineeLinesSubsectionRef &Inlinees,
82224d58133SDimitry Andric     const StringsAndChecksumsRef &State) {
8236d97bb29SDimitry Andric   auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
824db17bf38SDimitry Andric       State.strings(), State.checksums(), Inlinees);
825db17bf38SDimitry Andric   if (!Result)
826db17bf38SDimitry Andric     return Result.takeError();
827db17bf38SDimitry Andric   Subsection.Subsection = *Result;
828db17bf38SDimitry Andric   return Error::success();
829db17bf38SDimitry Andric }
830db17bf38SDimitry Andric 
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef & Exports,const StringsAndChecksumsRef & State)831db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleExports(
832db17bf38SDimitry Andric     DebugCrossModuleExportsSubsectionRef &Exports,
83324d58133SDimitry Andric     const StringsAndChecksumsRef &State) {
834db17bf38SDimitry Andric   auto Result =
835db17bf38SDimitry Andric       YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
836db17bf38SDimitry Andric   if (!Result)
837db17bf38SDimitry Andric     return Result.takeError();
838db17bf38SDimitry Andric   Subsection.Subsection = *Result;
839db17bf38SDimitry Andric   return Error::success();
840db17bf38SDimitry Andric }
841db17bf38SDimitry Andric 
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef & Imports,const StringsAndChecksumsRef & State)842db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleImports(
843db17bf38SDimitry Andric     DebugCrossModuleImportsSubsectionRef &Imports,
84424d58133SDimitry Andric     const StringsAndChecksumsRef &State) {
845db17bf38SDimitry Andric   auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
846db17bf38SDimitry Andric       State.strings(), Imports);
847db17bf38SDimitry Andric   if (!Result)
848db17bf38SDimitry Andric     return Result.takeError();
849db17bf38SDimitry Andric   Subsection.Subsection = *Result;
850db17bf38SDimitry Andric   return Error::success();
851db17bf38SDimitry Andric }
852db17bf38SDimitry Andric 
visitStringTable(DebugStringTableSubsectionRef & Strings,const StringsAndChecksumsRef & State)853db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitStringTable(
85424d58133SDimitry Andric     DebugStringTableSubsectionRef &Strings,
85524d58133SDimitry Andric     const StringsAndChecksumsRef &State) {
856db17bf38SDimitry Andric   auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
857db17bf38SDimitry Andric   if (!Result)
858db17bf38SDimitry Andric     return Result.takeError();
859db17bf38SDimitry Andric   Subsection.Subsection = *Result;
860db17bf38SDimitry Andric   return Error::success();
861db17bf38SDimitry Andric }
862db17bf38SDimitry Andric 
visitSymbols(DebugSymbolsSubsectionRef & Symbols,const StringsAndChecksumsRef & State)863db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitSymbols(
86424d58133SDimitry Andric     DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
865db17bf38SDimitry Andric   auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
866db17bf38SDimitry Andric   if (!Result)
867db17bf38SDimitry Andric     return Result.takeError();
868db17bf38SDimitry Andric   Subsection.Subsection = *Result;
869db17bf38SDimitry Andric   return Error::success();
870db17bf38SDimitry Andric }
871db17bf38SDimitry Andric 
visitFrameData(DebugFrameDataSubsectionRef & Frames,const StringsAndChecksumsRef & State)872db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitFrameData(
87324d58133SDimitry Andric     DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
874db17bf38SDimitry Andric   auto Result =
875db17bf38SDimitry Andric       YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
876db17bf38SDimitry Andric   if (!Result)
877db17bf38SDimitry Andric     return Result.takeError();
878db17bf38SDimitry Andric   Subsection.Subsection = *Result;
879db17bf38SDimitry Andric   return Error::success();
880db17bf38SDimitry Andric }
881db17bf38SDimitry Andric 
visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef & RVAs,const StringsAndChecksumsRef & State)882db17bf38SDimitry Andric Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
88324d58133SDimitry Andric     DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
884db17bf38SDimitry Andric   auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
8856d97bb29SDimitry Andric   if (!Result)
8866d97bb29SDimitry Andric     return Result.takeError();
8876d97bb29SDimitry Andric   Subsection.Subsection = *Result;
8886d97bb29SDimitry Andric   return Error::success();
8896d97bb29SDimitry Andric }
8906d97bb29SDimitry Andric 
89124d58133SDimitry Andric Expected<YAMLDebugSubsection>
fromCodeViewSubection(const StringsAndChecksumsRef & SC,const DebugSubsectionRecord & SS)89224d58133SDimitry Andric YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
8936d97bb29SDimitry Andric                                            const DebugSubsectionRecord &SS) {
894db17bf38SDimitry Andric   SubsectionConversionVisitor V;
89524d58133SDimitry Andric   if (auto EC = visitDebugSubsection(SS, V, SC))
8966d97bb29SDimitry Andric     return std::move(EC);
8976d97bb29SDimitry Andric 
8986d97bb29SDimitry Andric   return V.Subsection;
899f9448bf3SDimitry Andric }
900db17bf38SDimitry Andric 
90124d58133SDimitry Andric std::vector<YAMLDebugSubsection>
fromDebugS(ArrayRef<uint8_t> Data,const StringsAndChecksumsRef & SC)90224d58133SDimitry Andric llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data,
90324d58133SDimitry Andric                                const StringsAndChecksumsRef &SC) {
90424d58133SDimitry Andric   BinaryStreamReader Reader(Data, support::little);
90524d58133SDimitry Andric   uint32_t Magic;
90624d58133SDimitry Andric 
90724d58133SDimitry Andric   ExitOnError Err("Invalid .debug$S section!");
90824d58133SDimitry Andric   Err(Reader.readInteger(Magic));
90924d58133SDimitry Andric   assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
91024d58133SDimitry Andric 
91124d58133SDimitry Andric   DebugSubsectionArray Subsections;
91224d58133SDimitry Andric   Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
91324d58133SDimitry Andric 
91424d58133SDimitry Andric   std::vector<YAMLDebugSubsection> Result;
91524d58133SDimitry Andric 
91624d58133SDimitry Andric   for (const auto &SS : Subsections) {
91724d58133SDimitry Andric     auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
91824d58133SDimitry Andric     Result.push_back(YamlSS);
91924d58133SDimitry Andric   }
92024d58133SDimitry Andric   return Result;
92124d58133SDimitry Andric }
92224d58133SDimitry Andric 
initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections,codeview::StringsAndChecksums & SC)92324d58133SDimitry Andric void llvm::CodeViewYAML::initializeStringsAndChecksums(
92424d58133SDimitry Andric     ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) {
92524d58133SDimitry Andric   // String Table and Checksums subsections don't use the allocator.
92624d58133SDimitry Andric   BumpPtrAllocator Allocator;
92724d58133SDimitry Andric 
92824d58133SDimitry Andric   // It's possible for checksums and strings to even appear in different debug$S
92924d58133SDimitry Andric   // sections, so we have to make this a stateful function that can build up
93024d58133SDimitry Andric   // the strings and checksums field over multiple iterations.
93124d58133SDimitry Andric 
93224d58133SDimitry Andric   // File Checksums require the string table, but may become before it, so we
93324d58133SDimitry Andric   // have to scan for strings first, then scan for checksums again from the
93424d58133SDimitry Andric   // beginning.
93524d58133SDimitry Andric   if (!SC.hasStrings()) {
936db17bf38SDimitry Andric     for (const auto &SS : Sections) {
937db17bf38SDimitry Andric       if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
938db17bf38SDimitry Andric         continue;
939db17bf38SDimitry Andric 
94024d58133SDimitry Andric       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
94124d58133SDimitry Andric       SC.setStrings(
94224d58133SDimitry Andric           std::static_pointer_cast<DebugStringTableSubsection>(Result));
94324d58133SDimitry Andric       break;
944db17bf38SDimitry Andric     }
94524d58133SDimitry Andric   }
94624d58133SDimitry Andric 
94724d58133SDimitry Andric   if (SC.hasStrings() && !SC.hasChecksums()) {
94824d58133SDimitry Andric     for (const auto &SS : Sections) {
94924d58133SDimitry Andric       if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
95024d58133SDimitry Andric         continue;
95124d58133SDimitry Andric 
95224d58133SDimitry Andric       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
95324d58133SDimitry Andric       SC.setChecksums(
95424d58133SDimitry Andric           std::static_pointer_cast<DebugChecksumsSubsection>(Result));
95524d58133SDimitry Andric       break;
95624d58133SDimitry Andric     }
95724d58133SDimitry Andric   }
958db17bf38SDimitry Andric }
959