xref: /src/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1f382538dSDimitry Andric //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
2f382538dSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f382538dSDimitry Andric //
7f382538dSDimitry Andric //===----------------------------------------------------------------------===//
8f382538dSDimitry Andric //
9f382538dSDimitry Andric // This file defines classes for handling the YAML representation of CodeView
10f382538dSDimitry Andric // Debug Info.
11f382538dSDimitry Andric //
12f382538dSDimitry Andric //===----------------------------------------------------------------------===//
13f382538dSDimitry Andric 
14f382538dSDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
159df3605dSDimitry Andric #include "llvm/ADT/STLExtras.h"
16f382538dSDimitry Andric #include "llvm/ADT/StringExtras.h"
179df3605dSDimitry Andric #include "llvm/ADT/StringRef.h"
189df3605dSDimitry Andric #include "llvm/BinaryFormat/COFF.h"
199df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
20f382538dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
21d288ef4cSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
227ab83427SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
237ab83427SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
247ab83427SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
25d288ef4cSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
26d288ef4cSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
27d288ef4cSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
289df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
29d288ef4cSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
307ab83427SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
317ab83427SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
329df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h"
337c7aba6eSDimitry Andric #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
349df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
357ab83427SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
369df3605dSDimitry Andric #include "llvm/Support/Allocator.h"
379df3605dSDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
389df3605dSDimitry Andric #include "llvm/Support/Endian.h"
399df3605dSDimitry Andric #include "llvm/Support/Error.h"
409df3605dSDimitry Andric #include "llvm/Support/ErrorHandling.h"
419df3605dSDimitry Andric #include "llvm/Support/YAMLTraits.h"
429df3605dSDimitry Andric #include "llvm/Support/raw_ostream.h"
439df3605dSDimitry Andric #include <algorithm>
449df3605dSDimitry Andric #include <cassert>
459df3605dSDimitry Andric #include <cstdint>
469df3605dSDimitry Andric #include <memory>
479df3605dSDimitry Andric #include <string>
489df3605dSDimitry Andric #include <tuple>
499df3605dSDimitry Andric #include <vector>
509df3605dSDimitry Andric 
51f382538dSDimitry Andric using namespace llvm;
52f382538dSDimitry Andric using namespace llvm::codeview;
53f382538dSDimitry Andric using namespace llvm::CodeViewYAML;
54f382538dSDimitry Andric using namespace llvm::CodeViewYAML::detail;
55f382538dSDimitry Andric using namespace llvm::yaml;
56f382538dSDimitry Andric 
57f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry)
58f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry)
59f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry)
60f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock)
61f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo)
62f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite)
63f382538dSDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
647ab83427SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport)
657ab83427SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
667ab83427SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
67f382538dSDimitry Andric 
68044eb2f6SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
69d288ef4cSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
70f382538dSDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
71f382538dSDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
72f382538dSDimitry Andric 
737ab83427SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport)
747ab83427SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData)
757ab83427SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport)
767ab83427SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem)
77d288ef4cSDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry)
78d288ef4cSDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry)
79d288ef4cSDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry)
80d288ef4cSDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock)
81d288ef4cSDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite)
82d288ef4cSDimitry Andric 
83d288ef4cSDimitry Andric namespace llvm {
84d288ef4cSDimitry Andric namespace CodeViewYAML {
85d288ef4cSDimitry Andric namespace detail {
869df3605dSDimitry Andric 
87d288ef4cSDimitry Andric struct YAMLSubsectionBase {
YAMLSubsectionBasellvm::CodeViewYAML::detail::YAMLSubsectionBase88d288ef4cSDimitry Andric   explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {}
899df3605dSDimitry Andric   virtual ~YAMLSubsectionBase() = default;
90d288ef4cSDimitry Andric 
91d288ef4cSDimitry Andric   virtual void map(IO &IO) = 0;
927c7aba6eSDimitry Andric   virtual std::shared_ptr<DebugSubsection>
937ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
947c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const = 0;
959df3605dSDimitry Andric 
969df3605dSDimitry Andric   DebugSubsectionKind Kind;
97d288ef4cSDimitry Andric };
989df3605dSDimitry Andric 
999df3605dSDimitry Andric } // end namespace detail
1009df3605dSDimitry Andric } // end namespace CodeViewYAML
1019df3605dSDimitry Andric } // end namespace llvm
102d288ef4cSDimitry Andric 
103d288ef4cSDimitry Andric namespace {
1049df3605dSDimitry Andric 
105d288ef4cSDimitry Andric struct YAMLChecksumsSubsection : public YAMLSubsectionBase {
YAMLChecksumsSubsection__anon40e5bc160111::YAMLChecksumsSubsection106d288ef4cSDimitry Andric   YAMLChecksumsSubsection()
107d288ef4cSDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
108d288ef4cSDimitry Andric 
109d288ef4cSDimitry Andric   void map(IO &IO) override;
1107c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1117ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1127c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
113d288ef4cSDimitry Andric   static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
114d288ef4cSDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
115d288ef4cSDimitry Andric                          const DebugChecksumsSubsectionRef &FC);
116d288ef4cSDimitry Andric 
117d288ef4cSDimitry Andric   std::vector<SourceFileChecksumEntry> Checksums;
118d288ef4cSDimitry Andric };
119d288ef4cSDimitry Andric 
120d288ef4cSDimitry Andric struct YAMLLinesSubsection : public YAMLSubsectionBase {
YAMLLinesSubsection__anon40e5bc160111::YAMLLinesSubsection121d288ef4cSDimitry Andric   YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
122d288ef4cSDimitry Andric 
123d288ef4cSDimitry Andric   void map(IO &IO) override;
1247c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1257ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1267c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
127d288ef4cSDimitry Andric   static Expected<std::shared_ptr<YAMLLinesSubsection>>
128d288ef4cSDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
129d288ef4cSDimitry Andric                          const DebugChecksumsSubsectionRef &Checksums,
130d288ef4cSDimitry Andric                          const DebugLinesSubsectionRef &Lines);
131d288ef4cSDimitry Andric 
132d288ef4cSDimitry Andric   SourceLineInfo Lines;
133d288ef4cSDimitry Andric };
134d288ef4cSDimitry Andric 
135d288ef4cSDimitry Andric struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase {
YAMLInlineeLinesSubsection__anon40e5bc160111::YAMLInlineeLinesSubsection136d288ef4cSDimitry Andric   YAMLInlineeLinesSubsection()
137d288ef4cSDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
138d288ef4cSDimitry Andric 
139d288ef4cSDimitry Andric   void map(IO &IO) override;
1407c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1417ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1427c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
143d288ef4cSDimitry Andric   static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
144d288ef4cSDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
145d288ef4cSDimitry Andric                          const DebugChecksumsSubsectionRef &Checksums,
146d288ef4cSDimitry Andric                          const DebugInlineeLinesSubsectionRef &Lines);
147d288ef4cSDimitry Andric 
148d288ef4cSDimitry Andric   InlineeInfo InlineeLines;
149d288ef4cSDimitry Andric };
1507ab83427SDimitry Andric 
1517ab83427SDimitry Andric struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleExportsSubsection__anon40e5bc160111::YAMLCrossModuleExportsSubsection1527ab83427SDimitry Andric   YAMLCrossModuleExportsSubsection()
1537ab83427SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}
1547ab83427SDimitry Andric 
1557ab83427SDimitry Andric   void map(IO &IO) override;
1567c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1577ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1587c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1597ab83427SDimitry Andric   static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
1607ab83427SDimitry Andric   fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);
1617ab83427SDimitry Andric 
1627ab83427SDimitry Andric   std::vector<CrossModuleExport> Exports;
1637ab83427SDimitry Andric };
1647ab83427SDimitry Andric 
1657ab83427SDimitry Andric struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleImportsSubsection__anon40e5bc160111::YAMLCrossModuleImportsSubsection1667ab83427SDimitry Andric   YAMLCrossModuleImportsSubsection()
1677ab83427SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}
1687ab83427SDimitry Andric 
1697ab83427SDimitry Andric   void map(IO &IO) override;
1707c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1717ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1727c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1737ab83427SDimitry Andric   static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
1747ab83427SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1757ab83427SDimitry Andric                          const DebugCrossModuleImportsSubsectionRef &Imports);
1767ab83427SDimitry Andric 
1777ab83427SDimitry Andric   std::vector<YAMLCrossModuleImport> Imports;
1787ab83427SDimitry Andric };
1797ab83427SDimitry Andric 
1807ab83427SDimitry Andric struct YAMLSymbolsSubsection : public YAMLSubsectionBase {
YAMLSymbolsSubsection__anon40e5bc160111::YAMLSymbolsSubsection1817ab83427SDimitry Andric   YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}
1827ab83427SDimitry Andric 
1837ab83427SDimitry Andric   void map(IO &IO) override;
1847c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1857ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1867c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1877ab83427SDimitry Andric   static Expected<std::shared_ptr<YAMLSymbolsSubsection>>
1887ab83427SDimitry Andric   fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);
1897ab83427SDimitry Andric 
1907ab83427SDimitry Andric   std::vector<CodeViewYAML::SymbolRecord> Symbols;
1917ab83427SDimitry Andric };
1927ab83427SDimitry Andric 
1937ab83427SDimitry Andric struct YAMLStringTableSubsection : public YAMLSubsectionBase {
YAMLStringTableSubsection__anon40e5bc160111::YAMLStringTableSubsection1947ab83427SDimitry Andric   YAMLStringTableSubsection()
1957ab83427SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}
1967ab83427SDimitry Andric 
1977ab83427SDimitry Andric   void map(IO &IO) override;
1987c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
1997ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
2007c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
2017ab83427SDimitry Andric   static Expected<std::shared_ptr<YAMLStringTableSubsection>>
2027ab83427SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);
2037ab83427SDimitry Andric 
2047ab83427SDimitry Andric   std::vector<StringRef> Strings;
2057ab83427SDimitry Andric };
2067ab83427SDimitry Andric 
2077ab83427SDimitry Andric struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
YAMLFrameDataSubsection__anon40e5bc160111::YAMLFrameDataSubsection2087ab83427SDimitry Andric   YAMLFrameDataSubsection()
2097ab83427SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}
2107ab83427SDimitry Andric 
2117ab83427SDimitry Andric   void map(IO &IO) override;
2127c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
2137ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
2147c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
2157ab83427SDimitry Andric   static Expected<std::shared_ptr<YAMLFrameDataSubsection>>
2167ab83427SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
2177ab83427SDimitry Andric                          const DebugFrameDataSubsectionRef &Frames);
2187ab83427SDimitry Andric 
2197ab83427SDimitry Andric   std::vector<YAMLFrameData> Frames;
2207ab83427SDimitry Andric };
2217ab83427SDimitry Andric 
2227ab83427SDimitry Andric struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
YAMLCoffSymbolRVASubsection__anon40e5bc160111::YAMLCoffSymbolRVASubsection2237ab83427SDimitry Andric   YAMLCoffSymbolRVASubsection()
2247ab83427SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
2257ab83427SDimitry Andric 
2267ab83427SDimitry Andric   void map(IO &IO) override;
2277c7aba6eSDimitry Andric   std::shared_ptr<DebugSubsection>
2287ab83427SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
2297c7aba6eSDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
2307ab83427SDimitry Andric   static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
2317ab83427SDimitry Andric   fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
2327ab83427SDimitry Andric 
2337ab83427SDimitry Andric   std::vector<uint32_t> RVAs;
2347ab83427SDimitry Andric };
2359df3605dSDimitry Andric 
2369df3605dSDimitry Andric } // end anonymous namespace
237f382538dSDimitry Andric 
bitset(IO & io,LineFlags & Flags)238f382538dSDimitry Andric void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
239f382538dSDimitry Andric   io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
240f382538dSDimitry Andric   io.enumFallback<Hex16>(Flags);
241f382538dSDimitry Andric }
242f382538dSDimitry Andric 
enumeration(IO & io,FileChecksumKind & Kind)243f382538dSDimitry Andric void ScalarEnumerationTraits<FileChecksumKind>::enumeration(
244f382538dSDimitry Andric     IO &io, FileChecksumKind &Kind) {
245f382538dSDimitry Andric   io.enumCase(Kind, "None", FileChecksumKind::None);
246f382538dSDimitry Andric   io.enumCase(Kind, "MD5", FileChecksumKind::MD5);
247f382538dSDimitry Andric   io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1);
248f382538dSDimitry Andric   io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256);
249f382538dSDimitry Andric }
250f382538dSDimitry Andric 
output(const HexFormattedString & Value,void * ctx,raw_ostream & Out)251f382538dSDimitry Andric void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
252f382538dSDimitry Andric                                               void *ctx, raw_ostream &Out) {
253f382538dSDimitry Andric   StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
254f382538dSDimitry Andric                   Value.Bytes.size());
255f382538dSDimitry Andric   Out << toHex(Bytes);
256f382538dSDimitry Andric }
257f382538dSDimitry Andric 
input(StringRef Scalar,void * ctxt,HexFormattedString & Value)258f382538dSDimitry Andric StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
259f382538dSDimitry Andric                                                   HexFormattedString &Value) {
260f382538dSDimitry Andric   std::string H = fromHex(Scalar);
261f382538dSDimitry Andric   Value.Bytes.assign(H.begin(), H.end());
262f382538dSDimitry Andric   return StringRef();
263f382538dSDimitry Andric }
264f382538dSDimitry Andric 
mapping(IO & IO,SourceLineEntry & Obj)265f382538dSDimitry Andric void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) {
266f382538dSDimitry Andric   IO.mapRequired("Offset", Obj.Offset);
267f382538dSDimitry Andric   IO.mapRequired("LineStart", Obj.LineStart);
268f382538dSDimitry Andric   IO.mapRequired("IsStatement", Obj.IsStatement);
269f382538dSDimitry Andric   IO.mapRequired("EndDelta", Obj.EndDelta);
270f382538dSDimitry Andric }
271f382538dSDimitry Andric 
mapping(IO & IO,SourceColumnEntry & Obj)272f382538dSDimitry Andric void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) {
273f382538dSDimitry Andric   IO.mapRequired("StartColumn", Obj.StartColumn);
274f382538dSDimitry Andric   IO.mapRequired("EndColumn", Obj.EndColumn);
275f382538dSDimitry Andric }
276f382538dSDimitry Andric 
mapping(IO & IO,SourceLineBlock & Obj)277f382538dSDimitry Andric void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) {
278f382538dSDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
279f382538dSDimitry Andric   IO.mapRequired("Lines", Obj.Lines);
280f382538dSDimitry Andric   IO.mapRequired("Columns", Obj.Columns);
281f382538dSDimitry Andric }
282f382538dSDimitry Andric 
mapping(IO & IO,CrossModuleExport & Obj)2837ab83427SDimitry Andric void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) {
2847ab83427SDimitry Andric   IO.mapRequired("LocalId", Obj.Local);
2857ab83427SDimitry Andric   IO.mapRequired("GlobalId", Obj.Global);
2867ab83427SDimitry Andric }
2877ab83427SDimitry Andric 
mapping(IO & IO,YAMLCrossModuleImport & Obj)2887ab83427SDimitry Andric void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO,
2897ab83427SDimitry Andric                                                    YAMLCrossModuleImport &Obj) {
2907ab83427SDimitry Andric   IO.mapRequired("Module", Obj.ModuleName);
2917ab83427SDimitry Andric   IO.mapRequired("Imports", Obj.ImportIds);
2927ab83427SDimitry Andric }
2937ab83427SDimitry Andric 
mapping(IO & IO,SourceFileChecksumEntry & Obj)294f382538dSDimitry Andric void MappingTraits<SourceFileChecksumEntry>::mapping(
295f382538dSDimitry Andric     IO &IO, SourceFileChecksumEntry &Obj) {
296f382538dSDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
297f382538dSDimitry Andric   IO.mapRequired("Kind", Obj.Kind);
298f382538dSDimitry Andric   IO.mapRequired("Checksum", Obj.ChecksumBytes);
299f382538dSDimitry Andric }
300f382538dSDimitry Andric 
mapping(IO & IO,InlineeSite & Obj)301f382538dSDimitry Andric void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
302f382538dSDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
303f382538dSDimitry Andric   IO.mapRequired("LineNum", Obj.SourceLineNum);
304f382538dSDimitry Andric   IO.mapRequired("Inlinee", Obj.Inlinee);
305f382538dSDimitry Andric   IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
306f382538dSDimitry Andric }
307f382538dSDimitry Andric 
mapping(IO & IO,YAMLFrameData & Obj)3087ab83427SDimitry Andric void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) {
3097ab83427SDimitry Andric   IO.mapRequired("CodeSize", Obj.CodeSize);
3107ab83427SDimitry Andric   IO.mapRequired("FrameFunc", Obj.FrameFunc);
3117ab83427SDimitry Andric   IO.mapRequired("LocalSize", Obj.LocalSize);
3127ab83427SDimitry Andric   IO.mapOptional("MaxStackSize", Obj.MaxStackSize);
3137ab83427SDimitry Andric   IO.mapOptional("ParamsSize", Obj.ParamsSize);
3147ab83427SDimitry Andric   IO.mapOptional("PrologSize", Obj.PrologSize);
3157ab83427SDimitry Andric   IO.mapOptional("RvaStart", Obj.RvaStart);
3167ab83427SDimitry Andric   IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize);
3177ab83427SDimitry Andric }
3187ab83427SDimitry Andric 
map(IO & IO)319d288ef4cSDimitry Andric void YAMLChecksumsSubsection::map(IO &IO) {
320d288ef4cSDimitry Andric   IO.mapTag("!FileChecksums", true);
321d288ef4cSDimitry Andric   IO.mapRequired("Checksums", Checksums);
322d288ef4cSDimitry Andric }
323d288ef4cSDimitry Andric 
map(IO & IO)324d288ef4cSDimitry Andric void YAMLLinesSubsection::map(IO &IO) {
325d288ef4cSDimitry Andric   IO.mapTag("!Lines", true);
326d288ef4cSDimitry Andric   IO.mapRequired("CodeSize", Lines.CodeSize);
327d288ef4cSDimitry Andric 
328d288ef4cSDimitry Andric   IO.mapRequired("Flags", Lines.Flags);
329d288ef4cSDimitry Andric   IO.mapRequired("RelocOffset", Lines.RelocOffset);
330d288ef4cSDimitry Andric   IO.mapRequired("RelocSegment", Lines.RelocSegment);
331d288ef4cSDimitry Andric   IO.mapRequired("Blocks", Lines.Blocks);
332d288ef4cSDimitry Andric }
333d288ef4cSDimitry Andric 
map(IO & IO)334d288ef4cSDimitry Andric void YAMLInlineeLinesSubsection::map(IO &IO) {
335d288ef4cSDimitry Andric   IO.mapTag("!InlineeLines", true);
336d288ef4cSDimitry Andric   IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles);
337d288ef4cSDimitry Andric   IO.mapRequired("Sites", InlineeLines.Sites);
338d288ef4cSDimitry Andric }
339d288ef4cSDimitry Andric 
map(IO & IO)3407ab83427SDimitry Andric void YAMLCrossModuleExportsSubsection::map(IO &IO) {
3417ab83427SDimitry Andric   IO.mapTag("!CrossModuleExports", true);
3427ab83427SDimitry Andric   IO.mapOptional("Exports", Exports);
3437ab83427SDimitry Andric }
3447ab83427SDimitry Andric 
map(IO & IO)3457ab83427SDimitry Andric void YAMLCrossModuleImportsSubsection::map(IO &IO) {
3467ab83427SDimitry Andric   IO.mapTag("!CrossModuleImports", true);
3477ab83427SDimitry Andric   IO.mapOptional("Imports", Imports);
3487ab83427SDimitry Andric }
3497ab83427SDimitry Andric 
map(IO & IO)3507ab83427SDimitry Andric void YAMLSymbolsSubsection::map(IO &IO) {
3517ab83427SDimitry Andric   IO.mapTag("!Symbols", true);
3527ab83427SDimitry Andric   IO.mapRequired("Records", Symbols);
3537ab83427SDimitry Andric }
3547ab83427SDimitry Andric 
map(IO & IO)3557ab83427SDimitry Andric void YAMLStringTableSubsection::map(IO &IO) {
3567ab83427SDimitry Andric   IO.mapTag("!StringTable", true);
3577ab83427SDimitry Andric   IO.mapRequired("Strings", Strings);
3587ab83427SDimitry Andric }
3597ab83427SDimitry Andric 
map(IO & IO)3607ab83427SDimitry Andric void YAMLFrameDataSubsection::map(IO &IO) {
3617ab83427SDimitry Andric   IO.mapTag("!FrameData", true);
3627ab83427SDimitry Andric   IO.mapRequired("Frames", Frames);
3637ab83427SDimitry Andric }
3647ab83427SDimitry Andric 
map(IO & IO)3657ab83427SDimitry Andric void YAMLCoffSymbolRVASubsection::map(IO &IO) {
3667ab83427SDimitry Andric   IO.mapTag("!COFFSymbolRVAs", true);
3677ab83427SDimitry Andric   IO.mapRequired("RVAs", RVAs);
3687ab83427SDimitry Andric }
3697ab83427SDimitry Andric 
mapping(IO & IO,YAMLDebugSubsection & Subsection)370d288ef4cSDimitry Andric void MappingTraits<YAMLDebugSubsection>::mapping(
371d288ef4cSDimitry Andric     IO &IO, YAMLDebugSubsection &Subsection) {
372d288ef4cSDimitry Andric   if (!IO.outputting()) {
373d288ef4cSDimitry Andric     if (IO.mapTag("!FileChecksums")) {
374d288ef4cSDimitry Andric       auto SS = std::make_shared<YAMLChecksumsSubsection>();
375d288ef4cSDimitry Andric       Subsection.Subsection = SS;
376d288ef4cSDimitry Andric     } else if (IO.mapTag("!Lines")) {
377d288ef4cSDimitry Andric       Subsection.Subsection = std::make_shared<YAMLLinesSubsection>();
378d288ef4cSDimitry Andric     } else if (IO.mapTag("!InlineeLines")) {
379d288ef4cSDimitry Andric       Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>();
3807ab83427SDimitry Andric     } else if (IO.mapTag("!CrossModuleExports")) {
3817ab83427SDimitry Andric       Subsection.Subsection =
3827ab83427SDimitry Andric           std::make_shared<YAMLCrossModuleExportsSubsection>();
3837ab83427SDimitry Andric     } else if (IO.mapTag("!CrossModuleImports")) {
3847ab83427SDimitry Andric       Subsection.Subsection =
3857ab83427SDimitry Andric           std::make_shared<YAMLCrossModuleImportsSubsection>();
3867ab83427SDimitry Andric     } else if (IO.mapTag("!Symbols")) {
3877ab83427SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>();
3887ab83427SDimitry Andric     } else if (IO.mapTag("!StringTable")) {
3897ab83427SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
3907ab83427SDimitry Andric     } else if (IO.mapTag("!FrameData")) {
3917ab83427SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
3927ab83427SDimitry Andric     } else if (IO.mapTag("!COFFSymbolRVAs")) {
3937ab83427SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
394d288ef4cSDimitry Andric     } else {
395d288ef4cSDimitry Andric       llvm_unreachable("Unexpected subsection tag!");
396d288ef4cSDimitry Andric     }
397d288ef4cSDimitry Andric   }
398d288ef4cSDimitry Andric   Subsection.Subsection->map(IO);
399d288ef4cSDimitry Andric }
400d288ef4cSDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4017c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
4027c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
4037c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4047c7aba6eSDimitry Andric   assert(SC.hasStrings());
4057c7aba6eSDimitry Andric   auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings());
406d288ef4cSDimitry Andric   for (const auto &CS : Checksums) {
407d288ef4cSDimitry Andric     Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
408d288ef4cSDimitry Andric   }
4097c7aba6eSDimitry Andric   return Result;
410d288ef4cSDimitry Andric }
411d288ef4cSDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4127c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
4137c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
4147c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4157c7aba6eSDimitry Andric   assert(SC.hasStrings() && SC.hasChecksums());
416d288ef4cSDimitry Andric   auto Result =
4177c7aba6eSDimitry Andric       std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings());
418d288ef4cSDimitry Andric   Result->setCodeSize(Lines.CodeSize);
419d288ef4cSDimitry Andric   Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
420d288ef4cSDimitry Andric   Result->setFlags(Lines.Flags);
421d288ef4cSDimitry Andric   for (const auto &LC : Lines.Blocks) {
422d288ef4cSDimitry Andric     Result->createBlock(LC.FileName);
423d288ef4cSDimitry Andric     if (Result->hasColumnInfo()) {
424706b4fc4SDimitry Andric       for (auto Item : zip(LC.Lines, LC.Columns)) {
425d288ef4cSDimitry Andric         auto &L = std::get<0>(Item);
426d288ef4cSDimitry Andric         auto &C = std::get<1>(Item);
427d288ef4cSDimitry Andric         uint32_t LE = L.LineStart + L.EndDelta;
428d288ef4cSDimitry Andric         Result->addLineAndColumnInfo(L.Offset,
429d288ef4cSDimitry Andric                                      LineInfo(L.LineStart, LE, L.IsStatement),
430d288ef4cSDimitry Andric                                      C.StartColumn, C.EndColumn);
431d288ef4cSDimitry Andric       }
432d288ef4cSDimitry Andric     } else {
433d288ef4cSDimitry Andric       for (const auto &L : LC.Lines) {
434d288ef4cSDimitry Andric         uint32_t LE = L.LineStart + L.EndDelta;
435d288ef4cSDimitry Andric         Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement));
436d288ef4cSDimitry Andric       }
437d288ef4cSDimitry Andric     }
438d288ef4cSDimitry Andric   }
4397c7aba6eSDimitry Andric   return Result;
440d288ef4cSDimitry Andric }
441d288ef4cSDimitry Andric 
4427c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const443d288ef4cSDimitry Andric YAMLInlineeLinesSubsection::toCodeViewSubsection(
4447c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
4457c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4467c7aba6eSDimitry Andric   assert(SC.hasChecksums());
4477c7aba6eSDimitry Andric   auto Result = std::make_shared<DebugInlineeLinesSubsection>(
4487c7aba6eSDimitry Andric       *SC.checksums(), InlineeLines.HasExtraFiles);
449d288ef4cSDimitry Andric 
450d288ef4cSDimitry Andric   for (const auto &Site : InlineeLines.Sites) {
451d288ef4cSDimitry Andric     Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
452d288ef4cSDimitry Andric                           Site.SourceLineNum);
453d288ef4cSDimitry Andric     if (!InlineeLines.HasExtraFiles)
454d288ef4cSDimitry Andric       continue;
455d288ef4cSDimitry Andric 
456d288ef4cSDimitry Andric     for (auto EF : Site.ExtraFiles) {
457d288ef4cSDimitry Andric       Result->addExtraFile(EF);
458d288ef4cSDimitry Andric     }
459d288ef4cSDimitry Andric   }
4607c7aba6eSDimitry Andric   return Result;
461d288ef4cSDimitry Andric }
462d288ef4cSDimitry Andric 
4637c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4647ab83427SDimitry Andric YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
4657c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
4667c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4677c7aba6eSDimitry Andric   auto Result = std::make_shared<DebugCrossModuleExportsSubsection>();
4687ab83427SDimitry Andric   for (const auto &M : Exports)
4697ab83427SDimitry Andric     Result->addMapping(M.Local, M.Global);
4707c7aba6eSDimitry Andric   return Result;
4717ab83427SDimitry Andric }
4727ab83427SDimitry Andric 
4737c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4747ab83427SDimitry Andric YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
4757c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
4767c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4777c7aba6eSDimitry Andric   assert(SC.hasStrings());
4787c7aba6eSDimitry Andric 
4797c7aba6eSDimitry Andric   auto Result =
4807c7aba6eSDimitry Andric       std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings());
4817ab83427SDimitry Andric   for (const auto &M : Imports) {
4827ab83427SDimitry Andric     for (const auto Id : M.ImportIds)
4837ab83427SDimitry Andric       Result->addImport(M.ModuleName, Id);
4847ab83427SDimitry Andric   }
4857c7aba6eSDimitry Andric   return Result;
4867ab83427SDimitry Andric }
4877ab83427SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4887c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
4897c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
4907c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4917c7aba6eSDimitry Andric   auto Result = std::make_shared<DebugSymbolsSubsection>();
4927ab83427SDimitry Andric   for (const auto &Sym : Symbols)
4937ab83427SDimitry Andric     Result->addSymbol(
4947ab83427SDimitry Andric         Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
4957c7aba6eSDimitry Andric   return Result;
4967ab83427SDimitry Andric }
4977ab83427SDimitry Andric 
4987c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4997ab83427SDimitry Andric YAMLStringTableSubsection::toCodeViewSubsection(
5007c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
5017c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
5027c7aba6eSDimitry Andric   auto Result = std::make_shared<DebugStringTableSubsection>();
5037ab83427SDimitry Andric   for (const auto &Str : this->Strings)
5047ab83427SDimitry Andric     Result->insert(Str);
5057c7aba6eSDimitry Andric   return Result;
5067ab83427SDimitry Andric }
5077ab83427SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const5087c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
5097c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
5107c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
5117c7aba6eSDimitry Andric   assert(SC.hasStrings());
5127c7aba6eSDimitry Andric 
513d8e91e46SDimitry Andric   auto Result = std::make_shared<DebugFrameDataSubsection>(true);
5147ab83427SDimitry Andric   for (const auto &YF : Frames) {
5157ab83427SDimitry Andric     codeview::FrameData F;
5167ab83427SDimitry Andric     F.CodeSize = YF.CodeSize;
5177ab83427SDimitry Andric     F.Flags = YF.Flags;
5187ab83427SDimitry Andric     F.LocalSize = YF.LocalSize;
5197ab83427SDimitry Andric     F.MaxStackSize = YF.MaxStackSize;
5207ab83427SDimitry Andric     F.ParamsSize = YF.ParamsSize;
5217ab83427SDimitry Andric     F.PrologSize = YF.PrologSize;
5227ab83427SDimitry Andric     F.RvaStart = YF.RvaStart;
5237ab83427SDimitry Andric     F.SavedRegsSize = YF.SavedRegsSize;
5247c7aba6eSDimitry Andric     F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
5257ab83427SDimitry Andric     Result->addFrameData(F);
5267ab83427SDimitry Andric   }
5277c7aba6eSDimitry Andric   return Result;
5287ab83427SDimitry Andric }
5297ab83427SDimitry Andric 
5307c7aba6eSDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const5317ab83427SDimitry Andric YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
5327c7aba6eSDimitry Andric     BumpPtrAllocator &Allocator,
5337c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) const {
5347c7aba6eSDimitry Andric   auto Result = std::make_shared<DebugSymbolRVASubsection>();
5357ab83427SDimitry Andric   for (const auto &RVA : RVAs)
5367ab83427SDimitry Andric     Result->addRVA(RVA);
5377c7aba6eSDimitry Andric   return Result;
5387ab83427SDimitry Andric }
5397ab83427SDimitry Andric 
540d288ef4cSDimitry Andric static Expected<SourceFileChecksumEntry>
convertOneChecksum(const DebugStringTableSubsectionRef & Strings,const FileChecksumEntry & CS)541d288ef4cSDimitry Andric convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
542d288ef4cSDimitry Andric                    const FileChecksumEntry &CS) {
543d288ef4cSDimitry Andric   auto ExpectedString = Strings.getString(CS.FileNameOffset);
544d288ef4cSDimitry Andric   if (!ExpectedString)
545d288ef4cSDimitry Andric     return ExpectedString.takeError();
546d288ef4cSDimitry Andric 
547d288ef4cSDimitry Andric   SourceFileChecksumEntry Result;
548d288ef4cSDimitry Andric   Result.ChecksumBytes.Bytes = CS.Checksum;
549d288ef4cSDimitry Andric   Result.Kind = CS.Kind;
550d288ef4cSDimitry Andric   Result.FileName = *ExpectedString;
551d288ef4cSDimitry Andric   return Result;
552d288ef4cSDimitry Andric }
553d288ef4cSDimitry Andric 
554d288ef4cSDimitry Andric static Expected<StringRef>
getFileName(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,uint32_t FileID)555d288ef4cSDimitry Andric getFileName(const DebugStringTableSubsectionRef &Strings,
556d288ef4cSDimitry Andric             const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
557d288ef4cSDimitry Andric   auto Iter = Checksums.getArray().at(FileID);
558d288ef4cSDimitry Andric   if (Iter == Checksums.getArray().end())
559d288ef4cSDimitry Andric     return make_error<CodeViewError>(cv_error_code::no_records);
560d288ef4cSDimitry Andric   uint32_t Offset = Iter->FileNameOffset;
561d288ef4cSDimitry Andric   return Strings.getString(Offset);
562d288ef4cSDimitry Andric }
563d288ef4cSDimitry Andric 
564d288ef4cSDimitry Andric Expected<std::shared_ptr<YAMLChecksumsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & FC)565d288ef4cSDimitry Andric YAMLChecksumsSubsection::fromCodeViewSubsection(
566d288ef4cSDimitry Andric     const DebugStringTableSubsectionRef &Strings,
567d288ef4cSDimitry Andric     const DebugChecksumsSubsectionRef &FC) {
568d288ef4cSDimitry Andric   auto Result = std::make_shared<YAMLChecksumsSubsection>();
569d288ef4cSDimitry Andric 
570d288ef4cSDimitry Andric   for (const auto &CS : FC) {
571d288ef4cSDimitry Andric     auto ConvertedCS = convertOneChecksum(Strings, CS);
572d288ef4cSDimitry Andric     if (!ConvertedCS)
573d288ef4cSDimitry Andric       return ConvertedCS.takeError();
574d288ef4cSDimitry Andric     Result->Checksums.push_back(*ConvertedCS);
575d288ef4cSDimitry Andric   }
576d288ef4cSDimitry Andric   return Result;
577d288ef4cSDimitry Andric }
578d288ef4cSDimitry Andric 
579d288ef4cSDimitry Andric Expected<std::shared_ptr<YAMLLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugLinesSubsectionRef & Lines)580d288ef4cSDimitry Andric YAMLLinesSubsection::fromCodeViewSubsection(
581d288ef4cSDimitry Andric     const DebugStringTableSubsectionRef &Strings,
582d288ef4cSDimitry Andric     const DebugChecksumsSubsectionRef &Checksums,
583d288ef4cSDimitry Andric     const DebugLinesSubsectionRef &Lines) {
584d288ef4cSDimitry Andric   auto Result = std::make_shared<YAMLLinesSubsection>();
585d288ef4cSDimitry Andric   Result->Lines.CodeSize = Lines.header()->CodeSize;
586d288ef4cSDimitry Andric   Result->Lines.RelocOffset = Lines.header()->RelocOffset;
587d288ef4cSDimitry Andric   Result->Lines.RelocSegment = Lines.header()->RelocSegment;
588d288ef4cSDimitry Andric   Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags));
589d288ef4cSDimitry Andric   for (const auto &L : Lines) {
590d288ef4cSDimitry Andric     SourceLineBlock Block;
591d288ef4cSDimitry Andric     auto EF = getFileName(Strings, Checksums, L.NameIndex);
592d288ef4cSDimitry Andric     if (!EF)
593d288ef4cSDimitry Andric       return EF.takeError();
594d288ef4cSDimitry Andric     Block.FileName = *EF;
595d288ef4cSDimitry Andric     if (Lines.hasColumnInfo()) {
596d288ef4cSDimitry Andric       for (const auto &C : L.Columns) {
597d288ef4cSDimitry Andric         SourceColumnEntry SCE;
598d288ef4cSDimitry Andric         SCE.EndColumn = C.EndColumn;
599d288ef4cSDimitry Andric         SCE.StartColumn = C.StartColumn;
600d288ef4cSDimitry Andric         Block.Columns.push_back(SCE);
601d288ef4cSDimitry Andric       }
602d288ef4cSDimitry Andric     }
603d288ef4cSDimitry Andric     for (const auto &LN : L.LineNumbers) {
604d288ef4cSDimitry Andric       SourceLineEntry SLE;
605d288ef4cSDimitry Andric       LineInfo LI(LN.Flags);
606d288ef4cSDimitry Andric       SLE.Offset = LN.Offset;
607d288ef4cSDimitry Andric       SLE.LineStart = LI.getStartLine();
608d288ef4cSDimitry Andric       SLE.EndDelta = LI.getLineDelta();
609d288ef4cSDimitry Andric       SLE.IsStatement = LI.isStatement();
610d288ef4cSDimitry Andric       Block.Lines.push_back(SLE);
611d288ef4cSDimitry Andric     }
612d288ef4cSDimitry Andric     Result->Lines.Blocks.push_back(Block);
613d288ef4cSDimitry Andric   }
614d288ef4cSDimitry Andric   return Result;
615d288ef4cSDimitry Andric }
616d288ef4cSDimitry Andric 
617d288ef4cSDimitry Andric Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugInlineeLinesSubsectionRef & Lines)618d288ef4cSDimitry Andric YAMLInlineeLinesSubsection::fromCodeViewSubsection(
619d288ef4cSDimitry Andric     const DebugStringTableSubsectionRef &Strings,
620d288ef4cSDimitry Andric     const DebugChecksumsSubsectionRef &Checksums,
621d288ef4cSDimitry Andric     const DebugInlineeLinesSubsectionRef &Lines) {
622d288ef4cSDimitry Andric   auto Result = std::make_shared<YAMLInlineeLinesSubsection>();
623d288ef4cSDimitry Andric 
624d288ef4cSDimitry Andric   Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles();
625d288ef4cSDimitry Andric   for (const auto &IL : Lines) {
626d288ef4cSDimitry Andric     InlineeSite Site;
627d288ef4cSDimitry Andric     auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID);
628d288ef4cSDimitry Andric     if (!ExpF)
629d288ef4cSDimitry Andric       return ExpF.takeError();
630d288ef4cSDimitry Andric     Site.FileName = *ExpF;
631d288ef4cSDimitry Andric     Site.Inlinee = IL.Header->Inlinee.getIndex();
632d288ef4cSDimitry Andric     Site.SourceLineNum = IL.Header->SourceLineNum;
633d288ef4cSDimitry Andric     if (Lines.hasExtraFiles()) {
634d288ef4cSDimitry Andric       for (const auto EF : IL.ExtraFiles) {
635d288ef4cSDimitry Andric         auto ExpF2 = getFileName(Strings, Checksums, EF);
636d288ef4cSDimitry Andric         if (!ExpF2)
637d288ef4cSDimitry Andric           return ExpF2.takeError();
638d288ef4cSDimitry Andric         Site.ExtraFiles.push_back(*ExpF2);
639d288ef4cSDimitry Andric       }
640d288ef4cSDimitry Andric     }
641d288ef4cSDimitry Andric     Result->InlineeLines.Sites.push_back(Site);
642d288ef4cSDimitry Andric   }
643d288ef4cSDimitry Andric   return Result;
644d288ef4cSDimitry Andric }
645d288ef4cSDimitry Andric 
6467ab83427SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef & Exports)6477ab83427SDimitry Andric YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(
6487ab83427SDimitry Andric     const DebugCrossModuleExportsSubsectionRef &Exports) {
6497ab83427SDimitry Andric   auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>();
6507ab83427SDimitry Andric   Result->Exports.assign(Exports.begin(), Exports.end());
6517ab83427SDimitry Andric   return Result;
6527ab83427SDimitry Andric }
6537ab83427SDimitry Andric 
6547ab83427SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugCrossModuleImportsSubsectionRef & Imports)6557ab83427SDimitry Andric YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
6567ab83427SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
6577ab83427SDimitry Andric     const DebugCrossModuleImportsSubsectionRef &Imports) {
6587ab83427SDimitry Andric   auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>();
6597ab83427SDimitry Andric   for (const auto &CMI : Imports) {
6607ab83427SDimitry Andric     YAMLCrossModuleImport YCMI;
6617ab83427SDimitry Andric     auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset);
6627ab83427SDimitry Andric     if (!ExpectedStr)
6637ab83427SDimitry Andric       return ExpectedStr.takeError();
6647ab83427SDimitry Andric     YCMI.ModuleName = *ExpectedStr;
6657ab83427SDimitry Andric     YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end());
6667ab83427SDimitry Andric     Result->Imports.push_back(YCMI);
6677ab83427SDimitry Andric   }
6687ab83427SDimitry Andric   return Result;
6697ab83427SDimitry Andric }
6707ab83427SDimitry Andric 
6717ab83427SDimitry Andric Expected<std::shared_ptr<YAMLSymbolsSubsection>>
fromCodeViewSubsection(const DebugSymbolsSubsectionRef & Symbols)6727ab83427SDimitry Andric YAMLSymbolsSubsection::fromCodeViewSubsection(
6737ab83427SDimitry Andric     const DebugSymbolsSubsectionRef &Symbols) {
6747ab83427SDimitry Andric   auto Result = std::make_shared<YAMLSymbolsSubsection>();
6757ab83427SDimitry Andric   for (const auto &Sym : Symbols) {
6767ab83427SDimitry Andric     auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
6777ab83427SDimitry Andric     if (!S)
6787ab83427SDimitry Andric       return joinErrors(make_error<CodeViewError>(
6797ab83427SDimitry Andric                             cv_error_code::corrupt_record,
6807ab83427SDimitry Andric                             "Invalid CodeView Symbol Record in SymbolRecord "
6817ab83427SDimitry Andric                             "subsection of .debug$S while converting to YAML!"),
6827ab83427SDimitry Andric                         S.takeError());
6837ab83427SDimitry Andric 
6847ab83427SDimitry Andric     Result->Symbols.push_back(*S);
6857ab83427SDimitry Andric   }
6867ab83427SDimitry Andric   return Result;
6877ab83427SDimitry Andric }
6887ab83427SDimitry Andric 
6897ab83427SDimitry Andric Expected<std::shared_ptr<YAMLStringTableSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings)6907ab83427SDimitry Andric YAMLStringTableSubsection::fromCodeViewSubsection(
6917ab83427SDimitry Andric     const DebugStringTableSubsectionRef &Strings) {
6927ab83427SDimitry Andric   auto Result = std::make_shared<YAMLStringTableSubsection>();
6937ab83427SDimitry Andric   BinaryStreamReader Reader(Strings.getBuffer());
6947ab83427SDimitry Andric   StringRef S;
6957ab83427SDimitry Andric   // First item is a single null string, skip it.
6967ab83427SDimitry Andric   if (auto EC = Reader.readCString(S))
6977ab83427SDimitry Andric     return std::move(EC);
6987ab83427SDimitry Andric   assert(S.empty());
6997ab83427SDimitry Andric   while (Reader.bytesRemaining() > 0) {
7007ab83427SDimitry Andric     if (auto EC = Reader.readCString(S))
7017ab83427SDimitry Andric       return std::move(EC);
7027ab83427SDimitry Andric     Result->Strings.push_back(S);
7037ab83427SDimitry Andric   }
7047ab83427SDimitry Andric   return Result;
7057ab83427SDimitry Andric }
7067ab83427SDimitry Andric 
7077ab83427SDimitry Andric Expected<std::shared_ptr<YAMLFrameDataSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugFrameDataSubsectionRef & Frames)7087ab83427SDimitry Andric YAMLFrameDataSubsection::fromCodeViewSubsection(
7097ab83427SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
7107ab83427SDimitry Andric     const DebugFrameDataSubsectionRef &Frames) {
7117ab83427SDimitry Andric   auto Result = std::make_shared<YAMLFrameDataSubsection>();
7127ab83427SDimitry Andric   for (const auto &F : Frames) {
7137ab83427SDimitry Andric     YAMLFrameData YF;
7147ab83427SDimitry Andric     YF.CodeSize = F.CodeSize;
7157ab83427SDimitry Andric     YF.Flags = F.Flags;
7167ab83427SDimitry Andric     YF.LocalSize = F.LocalSize;
7177ab83427SDimitry Andric     YF.MaxStackSize = F.MaxStackSize;
7187ab83427SDimitry Andric     YF.ParamsSize = F.ParamsSize;
7197ab83427SDimitry Andric     YF.PrologSize = F.PrologSize;
7207ab83427SDimitry Andric     YF.RvaStart = F.RvaStart;
7217ab83427SDimitry Andric     YF.SavedRegsSize = F.SavedRegsSize;
7227ab83427SDimitry Andric 
7237ab83427SDimitry Andric     auto ES = Strings.getString(F.FrameFunc);
7247ab83427SDimitry Andric     if (!ES)
7257ab83427SDimitry Andric       return joinErrors(
7267ab83427SDimitry Andric           make_error<CodeViewError>(
7277ab83427SDimitry Andric               cv_error_code::no_records,
7287ab83427SDimitry Andric               "Could not find string for string id while mapping FrameData!"),
7297ab83427SDimitry Andric           ES.takeError());
7307ab83427SDimitry Andric     YF.FrameFunc = *ES;
7317ab83427SDimitry Andric     Result->Frames.push_back(YF);
7327ab83427SDimitry Andric   }
7337ab83427SDimitry Andric   return Result;
7347ab83427SDimitry Andric }
7357ab83427SDimitry Andric 
7367ab83427SDimitry Andric Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
fromCodeViewSubsection(const DebugSymbolRVASubsectionRef & Section)7377ab83427SDimitry Andric YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
7387ab83427SDimitry Andric     const DebugSymbolRVASubsectionRef &Section) {
7397ab83427SDimitry Andric   auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
7407ab83427SDimitry Andric   for (const auto &RVA : Section) {
7417ab83427SDimitry Andric     Result->RVAs.push_back(RVA);
7427ab83427SDimitry Andric   }
7437ab83427SDimitry Andric   return Result;
7447ab83427SDimitry Andric }
7457ab83427SDimitry Andric 
7467c7aba6eSDimitry Andric Expected<std::vector<std::shared_ptr<DebugSubsection>>>
toCodeViewSubsectionList(BumpPtrAllocator & Allocator,ArrayRef<YAMLDebugSubsection> Subsections,const codeview::StringsAndChecksums & SC)7477ab83427SDimitry Andric llvm::CodeViewYAML::toCodeViewSubsectionList(
7487ab83427SDimitry Andric     BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
7497c7aba6eSDimitry Andric     const codeview::StringsAndChecksums &SC) {
7507c7aba6eSDimitry Andric   std::vector<std::shared_ptr<DebugSubsection>> Result;
751d288ef4cSDimitry Andric   if (Subsections.empty())
752d288ef4cSDimitry Andric     return std::move(Result);
753d288ef4cSDimitry Andric 
754d288ef4cSDimitry Andric   for (const auto &SS : Subsections) {
7557c7aba6eSDimitry Andric     std::shared_ptr<DebugSubsection> CVS;
7567c7aba6eSDimitry Andric     CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
7577ab83427SDimitry Andric     assert(CVS != nullptr);
758d288ef4cSDimitry Andric     Result.push_back(std::move(CVS));
759d288ef4cSDimitry Andric   }
760d288ef4cSDimitry Andric   return std::move(Result);
761d288ef4cSDimitry Andric }
762d288ef4cSDimitry Andric 
763d288ef4cSDimitry Andric namespace {
7649df3605dSDimitry Andric 
765d288ef4cSDimitry Andric struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
7669df3605dSDimitry Andric   SubsectionConversionVisitor() = default;
767d288ef4cSDimitry Andric 
768d288ef4cSDimitry Andric   Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
7697ab83427SDimitry Andric   Error visitLines(DebugLinesSubsectionRef &Lines,
7707c7aba6eSDimitry Andric                    const StringsAndChecksumsRef &State) override;
7717ab83427SDimitry Andric   Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
7727c7aba6eSDimitry Andric                            const StringsAndChecksumsRef &State) override;
7737ab83427SDimitry Andric   Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
7747c7aba6eSDimitry Andric                           const StringsAndChecksumsRef &State) override;
7757ab83427SDimitry Andric   Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
7767c7aba6eSDimitry Andric                                 const StringsAndChecksumsRef &State) override;
7777ab83427SDimitry Andric   Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
7787c7aba6eSDimitry Andric                                 const StringsAndChecksumsRef &State) override;
7797ab83427SDimitry Andric   Error visitStringTable(DebugStringTableSubsectionRef &ST,
7807c7aba6eSDimitry Andric                          const StringsAndChecksumsRef &State) override;
7817ab83427SDimitry Andric   Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
7827c7aba6eSDimitry Andric                      const StringsAndChecksumsRef &State) override;
7837ab83427SDimitry Andric   Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
7847c7aba6eSDimitry Andric                        const StringsAndChecksumsRef &State) override;
7857ab83427SDimitry Andric   Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
7867c7aba6eSDimitry Andric                             const StringsAndChecksumsRef &State) override;
787d288ef4cSDimitry Andric 
788d288ef4cSDimitry Andric   YAMLDebugSubsection Subsection;
789d288ef4cSDimitry Andric };
790d288ef4cSDimitry Andric 
7919df3605dSDimitry Andric } // end anonymous namespace
7929df3605dSDimitry Andric 
visitUnknown(DebugUnknownSubsectionRef & Unknown)793d288ef4cSDimitry Andric Error SubsectionConversionVisitor::visitUnknown(
794d288ef4cSDimitry Andric     DebugUnknownSubsectionRef &Unknown) {
795d288ef4cSDimitry Andric   return make_error<CodeViewError>(cv_error_code::operation_unsupported);
796d288ef4cSDimitry Andric }
797d288ef4cSDimitry Andric 
visitLines(DebugLinesSubsectionRef & Lines,const StringsAndChecksumsRef & State)7987ab83427SDimitry Andric Error SubsectionConversionVisitor::visitLines(
7997c7aba6eSDimitry Andric     DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
8007ab83427SDimitry Andric   auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
8017ab83427SDimitry Andric       State.strings(), State.checksums(), Lines);
802d288ef4cSDimitry Andric   if (!Result)
803d288ef4cSDimitry Andric     return Result.takeError();
804d288ef4cSDimitry Andric   Subsection.Subsection = *Result;
805d288ef4cSDimitry Andric   return Error::success();
806d288ef4cSDimitry Andric }
807d288ef4cSDimitry Andric 
visitFileChecksums(DebugChecksumsSubsectionRef & Checksums,const StringsAndChecksumsRef & State)808d288ef4cSDimitry Andric Error SubsectionConversionVisitor::visitFileChecksums(
8097c7aba6eSDimitry Andric     DebugChecksumsSubsectionRef &Checksums,
8107c7aba6eSDimitry Andric     const StringsAndChecksumsRef &State) {
8117ab83427SDimitry Andric   auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
8127ab83427SDimitry Andric                                                                 Checksums);
813d288ef4cSDimitry Andric   if (!Result)
814d288ef4cSDimitry Andric     return Result.takeError();
815d288ef4cSDimitry Andric   Subsection.Subsection = *Result;
816d288ef4cSDimitry Andric   return Error::success();
817d288ef4cSDimitry Andric }
818d288ef4cSDimitry Andric 
visitInlineeLines(DebugInlineeLinesSubsectionRef & Inlinees,const StringsAndChecksumsRef & State)819d288ef4cSDimitry Andric Error SubsectionConversionVisitor::visitInlineeLines(
8207ab83427SDimitry Andric     DebugInlineeLinesSubsectionRef &Inlinees,
8217c7aba6eSDimitry Andric     const StringsAndChecksumsRef &State) {
822d288ef4cSDimitry Andric   auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
8237ab83427SDimitry Andric       State.strings(), State.checksums(), Inlinees);
8247ab83427SDimitry Andric   if (!Result)
8257ab83427SDimitry Andric     return Result.takeError();
8267ab83427SDimitry Andric   Subsection.Subsection = *Result;
8277ab83427SDimitry Andric   return Error::success();
8287ab83427SDimitry Andric }
8297ab83427SDimitry Andric 
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef & Exports,const StringsAndChecksumsRef & State)8307ab83427SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleExports(
8317ab83427SDimitry Andric     DebugCrossModuleExportsSubsectionRef &Exports,
8327c7aba6eSDimitry Andric     const StringsAndChecksumsRef &State) {
8337ab83427SDimitry Andric   auto Result =
8347ab83427SDimitry Andric       YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
8357ab83427SDimitry Andric   if (!Result)
8367ab83427SDimitry Andric     return Result.takeError();
8377ab83427SDimitry Andric   Subsection.Subsection = *Result;
8387ab83427SDimitry Andric   return Error::success();
8397ab83427SDimitry Andric }
8407ab83427SDimitry Andric 
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef & Imports,const StringsAndChecksumsRef & State)8417ab83427SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleImports(
8427ab83427SDimitry Andric     DebugCrossModuleImportsSubsectionRef &Imports,
8437c7aba6eSDimitry Andric     const StringsAndChecksumsRef &State) {
8447ab83427SDimitry Andric   auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
8457ab83427SDimitry Andric       State.strings(), Imports);
8467ab83427SDimitry Andric   if (!Result)
8477ab83427SDimitry Andric     return Result.takeError();
8487ab83427SDimitry Andric   Subsection.Subsection = *Result;
8497ab83427SDimitry Andric   return Error::success();
8507ab83427SDimitry Andric }
8517ab83427SDimitry Andric 
visitStringTable(DebugStringTableSubsectionRef & Strings,const StringsAndChecksumsRef & State)8527ab83427SDimitry Andric Error SubsectionConversionVisitor::visitStringTable(
8537c7aba6eSDimitry Andric     DebugStringTableSubsectionRef &Strings,
8547c7aba6eSDimitry Andric     const StringsAndChecksumsRef &State) {
8557ab83427SDimitry Andric   auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
8567ab83427SDimitry Andric   if (!Result)
8577ab83427SDimitry Andric     return Result.takeError();
8587ab83427SDimitry Andric   Subsection.Subsection = *Result;
8597ab83427SDimitry Andric   return Error::success();
8607ab83427SDimitry Andric }
8617ab83427SDimitry Andric 
visitSymbols(DebugSymbolsSubsectionRef & Symbols,const StringsAndChecksumsRef & State)8627ab83427SDimitry Andric Error SubsectionConversionVisitor::visitSymbols(
8637c7aba6eSDimitry Andric     DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
8647ab83427SDimitry Andric   auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
8657ab83427SDimitry Andric   if (!Result)
8667ab83427SDimitry Andric     return Result.takeError();
8677ab83427SDimitry Andric   Subsection.Subsection = *Result;
8687ab83427SDimitry Andric   return Error::success();
8697ab83427SDimitry Andric }
8707ab83427SDimitry Andric 
visitFrameData(DebugFrameDataSubsectionRef & Frames,const StringsAndChecksumsRef & State)8717ab83427SDimitry Andric Error SubsectionConversionVisitor::visitFrameData(
8727c7aba6eSDimitry Andric     DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
8737ab83427SDimitry Andric   auto Result =
8747ab83427SDimitry Andric       YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
8757ab83427SDimitry Andric   if (!Result)
8767ab83427SDimitry Andric     return Result.takeError();
8777ab83427SDimitry Andric   Subsection.Subsection = *Result;
8787ab83427SDimitry Andric   return Error::success();
8797ab83427SDimitry Andric }
8807ab83427SDimitry Andric 
visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef & RVAs,const StringsAndChecksumsRef & State)8817ab83427SDimitry Andric Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
8827c7aba6eSDimitry Andric     DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
8837ab83427SDimitry Andric   auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
884d288ef4cSDimitry Andric   if (!Result)
885d288ef4cSDimitry Andric     return Result.takeError();
886d288ef4cSDimitry Andric   Subsection.Subsection = *Result;
887d288ef4cSDimitry Andric   return Error::success();
888d288ef4cSDimitry Andric }
889d288ef4cSDimitry Andric 
8907c7aba6eSDimitry Andric Expected<YAMLDebugSubsection>
fromCodeViewSubection(const StringsAndChecksumsRef & SC,const DebugSubsectionRecord & SS)8917c7aba6eSDimitry Andric YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
892d288ef4cSDimitry Andric                                            const DebugSubsectionRecord &SS) {
8937ab83427SDimitry Andric   SubsectionConversionVisitor V;
8947c7aba6eSDimitry Andric   if (auto EC = visitDebugSubsection(SS, V, SC))
895d288ef4cSDimitry Andric     return std::move(EC);
896d288ef4cSDimitry Andric 
897d288ef4cSDimitry Andric   return V.Subsection;
898f382538dSDimitry Andric }
8997ab83427SDimitry Andric 
9007c7aba6eSDimitry Andric std::vector<YAMLDebugSubsection>
fromDebugS(ArrayRef<uint8_t> Data,const StringsAndChecksumsRef & SC)9017c7aba6eSDimitry Andric llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data,
9027c7aba6eSDimitry Andric                                const StringsAndChecksumsRef &SC) {
903b1c73532SDimitry Andric   BinaryStreamReader Reader(Data, llvm::endianness::little);
9047c7aba6eSDimitry Andric   uint32_t Magic;
9057c7aba6eSDimitry Andric 
9067c7aba6eSDimitry Andric   ExitOnError Err("Invalid .debug$S section!");
9077c7aba6eSDimitry Andric   Err(Reader.readInteger(Magic));
9087c7aba6eSDimitry Andric   assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
9097c7aba6eSDimitry Andric 
9107c7aba6eSDimitry Andric   DebugSubsectionArray Subsections;
9117c7aba6eSDimitry Andric   Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
9127c7aba6eSDimitry Andric 
9137c7aba6eSDimitry Andric   std::vector<YAMLDebugSubsection> Result;
9147c7aba6eSDimitry Andric 
9157c7aba6eSDimitry Andric   for (const auto &SS : Subsections) {
9167c7aba6eSDimitry Andric     auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
9177c7aba6eSDimitry Andric     Result.push_back(YamlSS);
9187c7aba6eSDimitry Andric   }
9197c7aba6eSDimitry Andric   return Result;
9207c7aba6eSDimitry Andric }
9217c7aba6eSDimitry Andric 
initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections,codeview::StringsAndChecksums & SC)9227c7aba6eSDimitry Andric void llvm::CodeViewYAML::initializeStringsAndChecksums(
9237c7aba6eSDimitry Andric     ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) {
9247c7aba6eSDimitry Andric   // String Table and Checksums subsections don't use the allocator.
9257c7aba6eSDimitry Andric   BumpPtrAllocator Allocator;
9267c7aba6eSDimitry Andric 
9277c7aba6eSDimitry Andric   // It's possible for checksums and strings to even appear in different debug$S
9287c7aba6eSDimitry Andric   // sections, so we have to make this a stateful function that can build up
9297c7aba6eSDimitry Andric   // the strings and checksums field over multiple iterations.
9307c7aba6eSDimitry Andric 
9317c7aba6eSDimitry Andric   // File Checksums require the string table, but may become before it, so we
9327c7aba6eSDimitry Andric   // have to scan for strings first, then scan for checksums again from the
9337c7aba6eSDimitry Andric   // beginning.
9347c7aba6eSDimitry Andric   if (!SC.hasStrings()) {
9357ab83427SDimitry Andric     for (const auto &SS : Sections) {
9367ab83427SDimitry Andric       if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
9377ab83427SDimitry Andric         continue;
9387ab83427SDimitry Andric 
9397c7aba6eSDimitry Andric       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
9407c7aba6eSDimitry Andric       SC.setStrings(
9417c7aba6eSDimitry Andric           std::static_pointer_cast<DebugStringTableSubsection>(Result));
9427c7aba6eSDimitry Andric       break;
9437ab83427SDimitry Andric     }
9447c7aba6eSDimitry Andric   }
9457c7aba6eSDimitry Andric 
9467c7aba6eSDimitry Andric   if (SC.hasStrings() && !SC.hasChecksums()) {
9477c7aba6eSDimitry Andric     for (const auto &SS : Sections) {
9487c7aba6eSDimitry Andric       if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
9497c7aba6eSDimitry Andric         continue;
9507c7aba6eSDimitry Andric 
9517c7aba6eSDimitry Andric       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
9527c7aba6eSDimitry Andric       SC.setChecksums(
9537c7aba6eSDimitry Andric           std::static_pointer_cast<DebugChecksumsSubsection>(Result));
9547c7aba6eSDimitry Andric       break;
9557c7aba6eSDimitry Andric     }
9567c7aba6eSDimitry Andric   }
9577ab83427SDimitry Andric }
958