xref: /freebsd-src/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines classes for handling the YAML representation of CodeView
100b57cec5SDimitry Andric // Debug Info.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
180b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
190b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
200b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h"
210b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
220b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
230b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
240b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
250b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
260b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
270b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
280b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
290b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
300b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
310b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
320b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h"
330b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
340b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
350b57cec5SDimitry Andric #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
360b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
370b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
380b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
390b57cec5SDimitry Andric #include "llvm/Support/Error.h"
400b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
410b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h"
420b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
430b57cec5SDimitry Andric #include <algorithm>
440b57cec5SDimitry Andric #include <cassert>
450b57cec5SDimitry Andric #include <cstdint>
460b57cec5SDimitry Andric #include <memory>
470b57cec5SDimitry Andric #include <string>
480b57cec5SDimitry Andric #include <tuple>
490b57cec5SDimitry Andric #include <vector>
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric using namespace llvm;
520b57cec5SDimitry Andric using namespace llvm::codeview;
530b57cec5SDimitry Andric using namespace llvm::CodeViewYAML;
540b57cec5SDimitry Andric using namespace llvm::CodeViewYAML::detail;
550b57cec5SDimitry Andric using namespace llvm::yaml;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry)
580b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry)
590b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry)
600b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock)
610b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo)
620b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite)
630b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
640b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport)
650b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
660b57cec5SDimitry Andric LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
690b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
700b57cec5SDimitry Andric LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
710b57cec5SDimitry Andric LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport)
740b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData)
750b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport)
760b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem)
770b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry)
780b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry)
790b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry)
800b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock)
810b57cec5SDimitry Andric LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite)
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric namespace llvm {
840b57cec5SDimitry Andric namespace CodeViewYAML {
850b57cec5SDimitry Andric namespace detail {
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric struct YAMLSubsectionBase {
YAMLSubsectionBasellvm::CodeViewYAML::detail::YAMLSubsectionBase880b57cec5SDimitry Andric   explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {}
890b57cec5SDimitry Andric   virtual ~YAMLSubsectionBase() = default;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   virtual void map(IO &IO) = 0;
920b57cec5SDimitry Andric   virtual std::shared_ptr<DebugSubsection>
930b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
940b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const = 0;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   DebugSubsectionKind Kind;
970b57cec5SDimitry Andric };
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric } // end namespace detail
1000b57cec5SDimitry Andric } // end namespace CodeViewYAML
1010b57cec5SDimitry Andric } // end namespace llvm
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric namespace {
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric struct YAMLChecksumsSubsection : public YAMLSubsectionBase {
YAMLChecksumsSubsection__anonc290efd30111::YAMLChecksumsSubsection1060b57cec5SDimitry Andric   YAMLChecksumsSubsection()
1070b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   void map(IO &IO) override;
1100b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1110b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1120b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1130b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
1140b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1150b57cec5SDimitry Andric                          const DebugChecksumsSubsectionRef &FC);
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   std::vector<SourceFileChecksumEntry> Checksums;
1180b57cec5SDimitry Andric };
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric struct YAMLLinesSubsection : public YAMLSubsectionBase {
YAMLLinesSubsection__anonc290efd30111::YAMLLinesSubsection1210b57cec5SDimitry Andric   YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   void map(IO &IO) override;
1240b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1250b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1260b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1270b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLLinesSubsection>>
1280b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1290b57cec5SDimitry Andric                          const DebugChecksumsSubsectionRef &Checksums,
1300b57cec5SDimitry Andric                          const DebugLinesSubsectionRef &Lines);
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   SourceLineInfo Lines;
1330b57cec5SDimitry Andric };
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase {
YAMLInlineeLinesSubsection__anonc290efd30111::YAMLInlineeLinesSubsection1360b57cec5SDimitry Andric   YAMLInlineeLinesSubsection()
1370b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   void map(IO &IO) override;
1400b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1410b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1420b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1430b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
1440b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1450b57cec5SDimitry Andric                          const DebugChecksumsSubsectionRef &Checksums,
1460b57cec5SDimitry Andric                          const DebugInlineeLinesSubsectionRef &Lines);
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   InlineeInfo InlineeLines;
1490b57cec5SDimitry Andric };
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleExportsSubsection__anonc290efd30111::YAMLCrossModuleExportsSubsection1520b57cec5SDimitry Andric   YAMLCrossModuleExportsSubsection()
1530b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {}
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   void map(IO &IO) override;
1560b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1570b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1580b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1590b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
1600b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports);
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   std::vector<CrossModuleExport> Exports;
1630b57cec5SDimitry Andric };
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase {
YAMLCrossModuleImportsSubsection__anonc290efd30111::YAMLCrossModuleImportsSubsection1660b57cec5SDimitry Andric   YAMLCrossModuleImportsSubsection()
1670b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {}
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   void map(IO &IO) override;
1700b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1710b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1720b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1730b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
1740b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
1750b57cec5SDimitry Andric                          const DebugCrossModuleImportsSubsectionRef &Imports);
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   std::vector<YAMLCrossModuleImport> Imports;
1780b57cec5SDimitry Andric };
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric struct YAMLSymbolsSubsection : public YAMLSubsectionBase {
YAMLSymbolsSubsection__anonc290efd30111::YAMLSymbolsSubsection1810b57cec5SDimitry Andric   YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {}
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   void map(IO &IO) override;
1840b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1850b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
1860b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
1870b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLSymbolsSubsection>>
1880b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols);
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   std::vector<CodeViewYAML::SymbolRecord> Symbols;
1910b57cec5SDimitry Andric };
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric struct YAMLStringTableSubsection : public YAMLSubsectionBase {
YAMLStringTableSubsection__anonc290efd30111::YAMLStringTableSubsection1940b57cec5SDimitry Andric   YAMLStringTableSubsection()
1950b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {}
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   void map(IO &IO) override;
1980b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
1990b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
2000b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
2010b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLStringTableSubsection>>
2020b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings);
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   std::vector<StringRef> Strings;
2050b57cec5SDimitry Andric };
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric struct YAMLFrameDataSubsection : public YAMLSubsectionBase {
YAMLFrameDataSubsection__anonc290efd30111::YAMLFrameDataSubsection2080b57cec5SDimitry Andric   YAMLFrameDataSubsection()
2090b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {}
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   void map(IO &IO) override;
2120b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
2130b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
2140b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
2150b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLFrameDataSubsection>>
2160b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
2170b57cec5SDimitry Andric                          const DebugFrameDataSubsectionRef &Frames);
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   std::vector<YAMLFrameData> Frames;
2200b57cec5SDimitry Andric };
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase {
YAMLCoffSymbolRVASubsection__anonc290efd30111::YAMLCoffSymbolRVASubsection2230b57cec5SDimitry Andric   YAMLCoffSymbolRVASubsection()
2240b57cec5SDimitry Andric       : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {}
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   void map(IO &IO) override;
2270b57cec5SDimitry Andric   std::shared_ptr<DebugSubsection>
2280b57cec5SDimitry Andric   toCodeViewSubsection(BumpPtrAllocator &Allocator,
2290b57cec5SDimitry Andric                        const codeview::StringsAndChecksums &SC) const override;
2300b57cec5SDimitry Andric   static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
2310b57cec5SDimitry Andric   fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs);
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   std::vector<uint32_t> RVAs;
2340b57cec5SDimitry Andric };
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric } // end anonymous namespace
2370b57cec5SDimitry Andric 
bitset(IO & io,LineFlags & Flags)2380b57cec5SDimitry Andric void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
2390b57cec5SDimitry Andric   io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
2400b57cec5SDimitry Andric   io.enumFallback<Hex16>(Flags);
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
enumeration(IO & io,FileChecksumKind & Kind)2430b57cec5SDimitry Andric void ScalarEnumerationTraits<FileChecksumKind>::enumeration(
2440b57cec5SDimitry Andric     IO &io, FileChecksumKind &Kind) {
2450b57cec5SDimitry Andric   io.enumCase(Kind, "None", FileChecksumKind::None);
2460b57cec5SDimitry Andric   io.enumCase(Kind, "MD5", FileChecksumKind::MD5);
2470b57cec5SDimitry Andric   io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1);
2480b57cec5SDimitry Andric   io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256);
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
output(const HexFormattedString & Value,void * ctx,raw_ostream & Out)2510b57cec5SDimitry Andric void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
2520b57cec5SDimitry Andric                                               void *ctx, raw_ostream &Out) {
2530b57cec5SDimitry Andric   StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
2540b57cec5SDimitry Andric                   Value.Bytes.size());
2550b57cec5SDimitry Andric   Out << toHex(Bytes);
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
input(StringRef Scalar,void * ctxt,HexFormattedString & Value)2580b57cec5SDimitry Andric StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
2590b57cec5SDimitry Andric                                                   HexFormattedString &Value) {
2600b57cec5SDimitry Andric   std::string H = fromHex(Scalar);
2610b57cec5SDimitry Andric   Value.Bytes.assign(H.begin(), H.end());
2620b57cec5SDimitry Andric   return StringRef();
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric 
mapping(IO & IO,SourceLineEntry & Obj)2650b57cec5SDimitry Andric void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) {
2660b57cec5SDimitry Andric   IO.mapRequired("Offset", Obj.Offset);
2670b57cec5SDimitry Andric   IO.mapRequired("LineStart", Obj.LineStart);
2680b57cec5SDimitry Andric   IO.mapRequired("IsStatement", Obj.IsStatement);
2690b57cec5SDimitry Andric   IO.mapRequired("EndDelta", Obj.EndDelta);
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
mapping(IO & IO,SourceColumnEntry & Obj)2720b57cec5SDimitry Andric void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) {
2730b57cec5SDimitry Andric   IO.mapRequired("StartColumn", Obj.StartColumn);
2740b57cec5SDimitry Andric   IO.mapRequired("EndColumn", Obj.EndColumn);
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric 
mapping(IO & IO,SourceLineBlock & Obj)2770b57cec5SDimitry Andric void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) {
2780b57cec5SDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
2790b57cec5SDimitry Andric   IO.mapRequired("Lines", Obj.Lines);
2800b57cec5SDimitry Andric   IO.mapRequired("Columns", Obj.Columns);
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric 
mapping(IO & IO,CrossModuleExport & Obj)2830b57cec5SDimitry Andric void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) {
2840b57cec5SDimitry Andric   IO.mapRequired("LocalId", Obj.Local);
2850b57cec5SDimitry Andric   IO.mapRequired("GlobalId", Obj.Global);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
mapping(IO & IO,YAMLCrossModuleImport & Obj)2880b57cec5SDimitry Andric void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO,
2890b57cec5SDimitry Andric                                                    YAMLCrossModuleImport &Obj) {
2900b57cec5SDimitry Andric   IO.mapRequired("Module", Obj.ModuleName);
2910b57cec5SDimitry Andric   IO.mapRequired("Imports", Obj.ImportIds);
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
mapping(IO & IO,SourceFileChecksumEntry & Obj)2940b57cec5SDimitry Andric void MappingTraits<SourceFileChecksumEntry>::mapping(
2950b57cec5SDimitry Andric     IO &IO, SourceFileChecksumEntry &Obj) {
2960b57cec5SDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
2970b57cec5SDimitry Andric   IO.mapRequired("Kind", Obj.Kind);
2980b57cec5SDimitry Andric   IO.mapRequired("Checksum", Obj.ChecksumBytes);
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric 
mapping(IO & IO,InlineeSite & Obj)3010b57cec5SDimitry Andric void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
3020b57cec5SDimitry Andric   IO.mapRequired("FileName", Obj.FileName);
3030b57cec5SDimitry Andric   IO.mapRequired("LineNum", Obj.SourceLineNum);
3040b57cec5SDimitry Andric   IO.mapRequired("Inlinee", Obj.Inlinee);
3050b57cec5SDimitry Andric   IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric 
mapping(IO & IO,YAMLFrameData & Obj)3080b57cec5SDimitry Andric void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) {
3090b57cec5SDimitry Andric   IO.mapRequired("CodeSize", Obj.CodeSize);
3100b57cec5SDimitry Andric   IO.mapRequired("FrameFunc", Obj.FrameFunc);
3110b57cec5SDimitry Andric   IO.mapRequired("LocalSize", Obj.LocalSize);
3120b57cec5SDimitry Andric   IO.mapOptional("MaxStackSize", Obj.MaxStackSize);
3130b57cec5SDimitry Andric   IO.mapOptional("ParamsSize", Obj.ParamsSize);
3140b57cec5SDimitry Andric   IO.mapOptional("PrologSize", Obj.PrologSize);
3150b57cec5SDimitry Andric   IO.mapOptional("RvaStart", Obj.RvaStart);
3160b57cec5SDimitry Andric   IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize);
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
map(IO & IO)3190b57cec5SDimitry Andric void YAMLChecksumsSubsection::map(IO &IO) {
3200b57cec5SDimitry Andric   IO.mapTag("!FileChecksums", true);
3210b57cec5SDimitry Andric   IO.mapRequired("Checksums", Checksums);
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric 
map(IO & IO)3240b57cec5SDimitry Andric void YAMLLinesSubsection::map(IO &IO) {
3250b57cec5SDimitry Andric   IO.mapTag("!Lines", true);
3260b57cec5SDimitry Andric   IO.mapRequired("CodeSize", Lines.CodeSize);
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   IO.mapRequired("Flags", Lines.Flags);
3290b57cec5SDimitry Andric   IO.mapRequired("RelocOffset", Lines.RelocOffset);
3300b57cec5SDimitry Andric   IO.mapRequired("RelocSegment", Lines.RelocSegment);
3310b57cec5SDimitry Andric   IO.mapRequired("Blocks", Lines.Blocks);
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
map(IO & IO)3340b57cec5SDimitry Andric void YAMLInlineeLinesSubsection::map(IO &IO) {
3350b57cec5SDimitry Andric   IO.mapTag("!InlineeLines", true);
3360b57cec5SDimitry Andric   IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles);
3370b57cec5SDimitry Andric   IO.mapRequired("Sites", InlineeLines.Sites);
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
map(IO & IO)3400b57cec5SDimitry Andric void YAMLCrossModuleExportsSubsection::map(IO &IO) {
3410b57cec5SDimitry Andric   IO.mapTag("!CrossModuleExports", true);
3420b57cec5SDimitry Andric   IO.mapOptional("Exports", Exports);
3430b57cec5SDimitry Andric }
3440b57cec5SDimitry Andric 
map(IO & IO)3450b57cec5SDimitry Andric void YAMLCrossModuleImportsSubsection::map(IO &IO) {
3460b57cec5SDimitry Andric   IO.mapTag("!CrossModuleImports", true);
3470b57cec5SDimitry Andric   IO.mapOptional("Imports", Imports);
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
map(IO & IO)3500b57cec5SDimitry Andric void YAMLSymbolsSubsection::map(IO &IO) {
3510b57cec5SDimitry Andric   IO.mapTag("!Symbols", true);
3520b57cec5SDimitry Andric   IO.mapRequired("Records", Symbols);
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
map(IO & IO)3550b57cec5SDimitry Andric void YAMLStringTableSubsection::map(IO &IO) {
3560b57cec5SDimitry Andric   IO.mapTag("!StringTable", true);
3570b57cec5SDimitry Andric   IO.mapRequired("Strings", Strings);
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric 
map(IO & IO)3600b57cec5SDimitry Andric void YAMLFrameDataSubsection::map(IO &IO) {
3610b57cec5SDimitry Andric   IO.mapTag("!FrameData", true);
3620b57cec5SDimitry Andric   IO.mapRequired("Frames", Frames);
3630b57cec5SDimitry Andric }
3640b57cec5SDimitry Andric 
map(IO & IO)3650b57cec5SDimitry Andric void YAMLCoffSymbolRVASubsection::map(IO &IO) {
3660b57cec5SDimitry Andric   IO.mapTag("!COFFSymbolRVAs", true);
3670b57cec5SDimitry Andric   IO.mapRequired("RVAs", RVAs);
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
mapping(IO & IO,YAMLDebugSubsection & Subsection)3700b57cec5SDimitry Andric void MappingTraits<YAMLDebugSubsection>::mapping(
3710b57cec5SDimitry Andric     IO &IO, YAMLDebugSubsection &Subsection) {
3720b57cec5SDimitry Andric   if (!IO.outputting()) {
3730b57cec5SDimitry Andric     if (IO.mapTag("!FileChecksums")) {
3740b57cec5SDimitry Andric       auto SS = std::make_shared<YAMLChecksumsSubsection>();
3750b57cec5SDimitry Andric       Subsection.Subsection = SS;
3760b57cec5SDimitry Andric     } else if (IO.mapTag("!Lines")) {
3770b57cec5SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLLinesSubsection>();
3780b57cec5SDimitry Andric     } else if (IO.mapTag("!InlineeLines")) {
3790b57cec5SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>();
3800b57cec5SDimitry Andric     } else if (IO.mapTag("!CrossModuleExports")) {
3810b57cec5SDimitry Andric       Subsection.Subsection =
3820b57cec5SDimitry Andric           std::make_shared<YAMLCrossModuleExportsSubsection>();
3830b57cec5SDimitry Andric     } else if (IO.mapTag("!CrossModuleImports")) {
3840b57cec5SDimitry Andric       Subsection.Subsection =
3850b57cec5SDimitry Andric           std::make_shared<YAMLCrossModuleImportsSubsection>();
3860b57cec5SDimitry Andric     } else if (IO.mapTag("!Symbols")) {
3870b57cec5SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>();
3880b57cec5SDimitry Andric     } else if (IO.mapTag("!StringTable")) {
3890b57cec5SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>();
3900b57cec5SDimitry Andric     } else if (IO.mapTag("!FrameData")) {
3910b57cec5SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>();
3920b57cec5SDimitry Andric     } else if (IO.mapTag("!COFFSymbolRVAs")) {
3930b57cec5SDimitry Andric       Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>();
3940b57cec5SDimitry Andric     } else {
3950b57cec5SDimitry Andric       llvm_unreachable("Unexpected subsection tag!");
3960b57cec5SDimitry Andric     }
3970b57cec5SDimitry Andric   }
3980b57cec5SDimitry Andric   Subsection.Subsection->map(IO);
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4010b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
4020b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
4030b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4040b57cec5SDimitry Andric   assert(SC.hasStrings());
4050b57cec5SDimitry Andric   auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings());
4060b57cec5SDimitry Andric   for (const auto &CS : Checksums) {
4070b57cec5SDimitry Andric     Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric   return Result;
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4120b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
4130b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
4140b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4150b57cec5SDimitry Andric   assert(SC.hasStrings() && SC.hasChecksums());
4160b57cec5SDimitry Andric   auto Result =
4170b57cec5SDimitry Andric       std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings());
4180b57cec5SDimitry Andric   Result->setCodeSize(Lines.CodeSize);
4190b57cec5SDimitry Andric   Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
4200b57cec5SDimitry Andric   Result->setFlags(Lines.Flags);
4210b57cec5SDimitry Andric   for (const auto &LC : Lines.Blocks) {
4220b57cec5SDimitry Andric     Result->createBlock(LC.FileName);
4230b57cec5SDimitry Andric     if (Result->hasColumnInfo()) {
424480093f4SDimitry Andric       for (auto Item : zip(LC.Lines, LC.Columns)) {
4250b57cec5SDimitry Andric         auto &L = std::get<0>(Item);
4260b57cec5SDimitry Andric         auto &C = std::get<1>(Item);
4270b57cec5SDimitry Andric         uint32_t LE = L.LineStart + L.EndDelta;
4280b57cec5SDimitry Andric         Result->addLineAndColumnInfo(L.Offset,
4290b57cec5SDimitry Andric                                      LineInfo(L.LineStart, LE, L.IsStatement),
4300b57cec5SDimitry Andric                                      C.StartColumn, C.EndColumn);
4310b57cec5SDimitry Andric       }
4320b57cec5SDimitry Andric     } else {
4330b57cec5SDimitry Andric       for (const auto &L : LC.Lines) {
4340b57cec5SDimitry Andric         uint32_t LE = L.LineStart + L.EndDelta;
4350b57cec5SDimitry Andric         Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement));
4360b57cec5SDimitry Andric       }
4370b57cec5SDimitry Andric     }
4380b57cec5SDimitry Andric   }
4390b57cec5SDimitry Andric   return Result;
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4430b57cec5SDimitry Andric YAMLInlineeLinesSubsection::toCodeViewSubsection(
4440b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
4450b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4460b57cec5SDimitry Andric   assert(SC.hasChecksums());
4470b57cec5SDimitry Andric   auto Result = std::make_shared<DebugInlineeLinesSubsection>(
4480b57cec5SDimitry Andric       *SC.checksums(), InlineeLines.HasExtraFiles);
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   for (const auto &Site : InlineeLines.Sites) {
4510b57cec5SDimitry Andric     Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
4520b57cec5SDimitry Andric                           Site.SourceLineNum);
4530b57cec5SDimitry Andric     if (!InlineeLines.HasExtraFiles)
4540b57cec5SDimitry Andric       continue;
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric     for (auto EF : Site.ExtraFiles) {
4570b57cec5SDimitry Andric       Result->addExtraFile(EF);
4580b57cec5SDimitry Andric     }
4590b57cec5SDimitry Andric   }
4600b57cec5SDimitry Andric   return Result;
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4640b57cec5SDimitry Andric YAMLCrossModuleExportsSubsection::toCodeViewSubsection(
4650b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
4660b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4670b57cec5SDimitry Andric   auto Result = std::make_shared<DebugCrossModuleExportsSubsection>();
4680b57cec5SDimitry Andric   for (const auto &M : Exports)
4690b57cec5SDimitry Andric     Result->addMapping(M.Local, M.Global);
4700b57cec5SDimitry Andric   return Result;
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4740b57cec5SDimitry Andric YAMLCrossModuleImportsSubsection::toCodeViewSubsection(
4750b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
4760b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4770b57cec5SDimitry Andric   assert(SC.hasStrings());
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   auto Result =
4800b57cec5SDimitry Andric       std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings());
4810b57cec5SDimitry Andric   for (const auto &M : Imports) {
4820b57cec5SDimitry Andric     for (const auto Id : M.ImportIds)
4830b57cec5SDimitry Andric       Result->addImport(M.ModuleName, Id);
4840b57cec5SDimitry Andric   }
4850b57cec5SDimitry Andric   return Result;
4860b57cec5SDimitry Andric }
4870b57cec5SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4880b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection(
4890b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
4900b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
4910b57cec5SDimitry Andric   auto Result = std::make_shared<DebugSymbolsSubsection>();
4920b57cec5SDimitry Andric   for (const auto &Sym : Symbols)
4930b57cec5SDimitry Andric     Result->addSymbol(
4940b57cec5SDimitry Andric         Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile));
4950b57cec5SDimitry Andric   return Result;
4960b57cec5SDimitry Andric }
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const4990b57cec5SDimitry Andric YAMLStringTableSubsection::toCodeViewSubsection(
5000b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
5010b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
5020b57cec5SDimitry Andric   auto Result = std::make_shared<DebugStringTableSubsection>();
5030b57cec5SDimitry Andric   for (const auto &Str : this->Strings)
5040b57cec5SDimitry Andric     Result->insert(Str);
5050b57cec5SDimitry Andric   return Result;
5060b57cec5SDimitry Andric }
5070b57cec5SDimitry Andric 
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const5080b57cec5SDimitry Andric std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection(
5090b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
5100b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
5110b57cec5SDimitry Andric   assert(SC.hasStrings());
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   auto Result = std::make_shared<DebugFrameDataSubsection>(true);
5140b57cec5SDimitry Andric   for (const auto &YF : Frames) {
5150b57cec5SDimitry Andric     codeview::FrameData F;
5160b57cec5SDimitry Andric     F.CodeSize = YF.CodeSize;
5170b57cec5SDimitry Andric     F.Flags = YF.Flags;
5180b57cec5SDimitry Andric     F.LocalSize = YF.LocalSize;
5190b57cec5SDimitry Andric     F.MaxStackSize = YF.MaxStackSize;
5200b57cec5SDimitry Andric     F.ParamsSize = YF.ParamsSize;
5210b57cec5SDimitry Andric     F.PrologSize = YF.PrologSize;
5220b57cec5SDimitry Andric     F.RvaStart = YF.RvaStart;
5230b57cec5SDimitry Andric     F.SavedRegsSize = YF.SavedRegsSize;
5240b57cec5SDimitry Andric     F.FrameFunc = SC.strings()->insert(YF.FrameFunc);
5250b57cec5SDimitry Andric     Result->addFrameData(F);
5260b57cec5SDimitry Andric   }
5270b57cec5SDimitry Andric   return Result;
5280b57cec5SDimitry Andric }
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric std::shared_ptr<DebugSubsection>
toCodeViewSubsection(BumpPtrAllocator & Allocator,const codeview::StringsAndChecksums & SC) const5310b57cec5SDimitry Andric YAMLCoffSymbolRVASubsection::toCodeViewSubsection(
5320b57cec5SDimitry Andric     BumpPtrAllocator &Allocator,
5330b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) const {
5340b57cec5SDimitry Andric   auto Result = std::make_shared<DebugSymbolRVASubsection>();
5350b57cec5SDimitry Andric   for (const auto &RVA : RVAs)
5360b57cec5SDimitry Andric     Result->addRVA(RVA);
5370b57cec5SDimitry Andric   return Result;
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric static Expected<SourceFileChecksumEntry>
convertOneChecksum(const DebugStringTableSubsectionRef & Strings,const FileChecksumEntry & CS)5410b57cec5SDimitry Andric convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
5420b57cec5SDimitry Andric                    const FileChecksumEntry &CS) {
5430b57cec5SDimitry Andric   auto ExpectedString = Strings.getString(CS.FileNameOffset);
5440b57cec5SDimitry Andric   if (!ExpectedString)
5450b57cec5SDimitry Andric     return ExpectedString.takeError();
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   SourceFileChecksumEntry Result;
5480b57cec5SDimitry Andric   Result.ChecksumBytes.Bytes = CS.Checksum;
5490b57cec5SDimitry Andric   Result.Kind = CS.Kind;
5500b57cec5SDimitry Andric   Result.FileName = *ExpectedString;
5510b57cec5SDimitry Andric   return Result;
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric static Expected<StringRef>
getFileName(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,uint32_t FileID)5550b57cec5SDimitry Andric getFileName(const DebugStringTableSubsectionRef &Strings,
5560b57cec5SDimitry Andric             const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
5570b57cec5SDimitry Andric   auto Iter = Checksums.getArray().at(FileID);
5580b57cec5SDimitry Andric   if (Iter == Checksums.getArray().end())
5590b57cec5SDimitry Andric     return make_error<CodeViewError>(cv_error_code::no_records);
5600b57cec5SDimitry Andric   uint32_t Offset = Iter->FileNameOffset;
5610b57cec5SDimitry Andric   return Strings.getString(Offset);
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLChecksumsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & FC)5650b57cec5SDimitry Andric YAMLChecksumsSubsection::fromCodeViewSubsection(
5660b57cec5SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
5670b57cec5SDimitry Andric     const DebugChecksumsSubsectionRef &FC) {
5680b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLChecksumsSubsection>();
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric   for (const auto &CS : FC) {
5710b57cec5SDimitry Andric     auto ConvertedCS = convertOneChecksum(Strings, CS);
5720b57cec5SDimitry Andric     if (!ConvertedCS)
5730b57cec5SDimitry Andric       return ConvertedCS.takeError();
5740b57cec5SDimitry Andric     Result->Checksums.push_back(*ConvertedCS);
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric   return Result;
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugLinesSubsectionRef & Lines)5800b57cec5SDimitry Andric YAMLLinesSubsection::fromCodeViewSubsection(
5810b57cec5SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
5820b57cec5SDimitry Andric     const DebugChecksumsSubsectionRef &Checksums,
5830b57cec5SDimitry Andric     const DebugLinesSubsectionRef &Lines) {
5840b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLLinesSubsection>();
5850b57cec5SDimitry Andric   Result->Lines.CodeSize = Lines.header()->CodeSize;
5860b57cec5SDimitry Andric   Result->Lines.RelocOffset = Lines.header()->RelocOffset;
5870b57cec5SDimitry Andric   Result->Lines.RelocSegment = Lines.header()->RelocSegment;
5880b57cec5SDimitry Andric   Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags));
5890b57cec5SDimitry Andric   for (const auto &L : Lines) {
5900b57cec5SDimitry Andric     SourceLineBlock Block;
5910b57cec5SDimitry Andric     auto EF = getFileName(Strings, Checksums, L.NameIndex);
5920b57cec5SDimitry Andric     if (!EF)
5930b57cec5SDimitry Andric       return EF.takeError();
5940b57cec5SDimitry Andric     Block.FileName = *EF;
5950b57cec5SDimitry Andric     if (Lines.hasColumnInfo()) {
5960b57cec5SDimitry Andric       for (const auto &C : L.Columns) {
5970b57cec5SDimitry Andric         SourceColumnEntry SCE;
5980b57cec5SDimitry Andric         SCE.EndColumn = C.EndColumn;
5990b57cec5SDimitry Andric         SCE.StartColumn = C.StartColumn;
6000b57cec5SDimitry Andric         Block.Columns.push_back(SCE);
6010b57cec5SDimitry Andric       }
6020b57cec5SDimitry Andric     }
6030b57cec5SDimitry Andric     for (const auto &LN : L.LineNumbers) {
6040b57cec5SDimitry Andric       SourceLineEntry SLE;
6050b57cec5SDimitry Andric       LineInfo LI(LN.Flags);
6060b57cec5SDimitry Andric       SLE.Offset = LN.Offset;
6070b57cec5SDimitry Andric       SLE.LineStart = LI.getStartLine();
6080b57cec5SDimitry Andric       SLE.EndDelta = LI.getLineDelta();
6090b57cec5SDimitry Andric       SLE.IsStatement = LI.isStatement();
6100b57cec5SDimitry Andric       Block.Lines.push_back(SLE);
6110b57cec5SDimitry Andric     }
6120b57cec5SDimitry Andric     Result->Lines.Blocks.push_back(Block);
6130b57cec5SDimitry Andric   }
6140b57cec5SDimitry Andric   return Result;
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugChecksumsSubsectionRef & Checksums,const DebugInlineeLinesSubsectionRef & Lines)6180b57cec5SDimitry Andric YAMLInlineeLinesSubsection::fromCodeViewSubsection(
6190b57cec5SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
6200b57cec5SDimitry Andric     const DebugChecksumsSubsectionRef &Checksums,
6210b57cec5SDimitry Andric     const DebugInlineeLinesSubsectionRef &Lines) {
6220b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLInlineeLinesSubsection>();
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric   Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles();
6250b57cec5SDimitry Andric   for (const auto &IL : Lines) {
6260b57cec5SDimitry Andric     InlineeSite Site;
6270b57cec5SDimitry Andric     auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID);
6280b57cec5SDimitry Andric     if (!ExpF)
6290b57cec5SDimitry Andric       return ExpF.takeError();
6300b57cec5SDimitry Andric     Site.FileName = *ExpF;
6310b57cec5SDimitry Andric     Site.Inlinee = IL.Header->Inlinee.getIndex();
6320b57cec5SDimitry Andric     Site.SourceLineNum = IL.Header->SourceLineNum;
6330b57cec5SDimitry Andric     if (Lines.hasExtraFiles()) {
6340b57cec5SDimitry Andric       for (const auto EF : IL.ExtraFiles) {
6350b57cec5SDimitry Andric         auto ExpF2 = getFileName(Strings, Checksums, EF);
6360b57cec5SDimitry Andric         if (!ExpF2)
6370b57cec5SDimitry Andric           return ExpF2.takeError();
6380b57cec5SDimitry Andric         Site.ExtraFiles.push_back(*ExpF2);
6390b57cec5SDimitry Andric       }
6400b57cec5SDimitry Andric     }
6410b57cec5SDimitry Andric     Result->InlineeLines.Sites.push_back(Site);
6420b57cec5SDimitry Andric   }
6430b57cec5SDimitry Andric   return Result;
6440b57cec5SDimitry Andric }
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>>
fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef & Exports)6470b57cec5SDimitry Andric YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(
6480b57cec5SDimitry Andric     const DebugCrossModuleExportsSubsectionRef &Exports) {
6490b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>();
6500b57cec5SDimitry Andric   Result->Exports.assign(Exports.begin(), Exports.end());
6510b57cec5SDimitry Andric   return Result;
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugCrossModuleImportsSubsectionRef & Imports)6550b57cec5SDimitry Andric YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
6560b57cec5SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
6570b57cec5SDimitry Andric     const DebugCrossModuleImportsSubsectionRef &Imports) {
6580b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>();
6590b57cec5SDimitry Andric   for (const auto &CMI : Imports) {
6600b57cec5SDimitry Andric     YAMLCrossModuleImport YCMI;
6610b57cec5SDimitry Andric     auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset);
6620b57cec5SDimitry Andric     if (!ExpectedStr)
6630b57cec5SDimitry Andric       return ExpectedStr.takeError();
6640b57cec5SDimitry Andric     YCMI.ModuleName = *ExpectedStr;
6650b57cec5SDimitry Andric     YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end());
6660b57cec5SDimitry Andric     Result->Imports.push_back(YCMI);
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric   return Result;
6690b57cec5SDimitry Andric }
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLSymbolsSubsection>>
fromCodeViewSubsection(const DebugSymbolsSubsectionRef & Symbols)6720b57cec5SDimitry Andric YAMLSymbolsSubsection::fromCodeViewSubsection(
6730b57cec5SDimitry Andric     const DebugSymbolsSubsectionRef &Symbols) {
6740b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLSymbolsSubsection>();
6750b57cec5SDimitry Andric   for (const auto &Sym : Symbols) {
6760b57cec5SDimitry Andric     auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
6770b57cec5SDimitry Andric     if (!S)
6780b57cec5SDimitry Andric       return joinErrors(make_error<CodeViewError>(
6790b57cec5SDimitry Andric                             cv_error_code::corrupt_record,
6800b57cec5SDimitry Andric                             "Invalid CodeView Symbol Record in SymbolRecord "
6810b57cec5SDimitry Andric                             "subsection of .debug$S while converting to YAML!"),
6820b57cec5SDimitry Andric                         S.takeError());
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric     Result->Symbols.push_back(*S);
6850b57cec5SDimitry Andric   }
6860b57cec5SDimitry Andric   return Result;
6870b57cec5SDimitry Andric }
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLStringTableSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings)6900b57cec5SDimitry Andric YAMLStringTableSubsection::fromCodeViewSubsection(
6910b57cec5SDimitry Andric     const DebugStringTableSubsectionRef &Strings) {
6920b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLStringTableSubsection>();
6930b57cec5SDimitry Andric   BinaryStreamReader Reader(Strings.getBuffer());
6940b57cec5SDimitry Andric   StringRef S;
6950b57cec5SDimitry Andric   // First item is a single null string, skip it.
6960b57cec5SDimitry Andric   if (auto EC = Reader.readCString(S))
6970b57cec5SDimitry Andric     return std::move(EC);
6980b57cec5SDimitry Andric   assert(S.empty());
6990b57cec5SDimitry Andric   while (Reader.bytesRemaining() > 0) {
7000b57cec5SDimitry Andric     if (auto EC = Reader.readCString(S))
7010b57cec5SDimitry Andric       return std::move(EC);
7020b57cec5SDimitry Andric     Result->Strings.push_back(S);
7030b57cec5SDimitry Andric   }
7040b57cec5SDimitry Andric   return Result;
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLFrameDataSubsection>>
fromCodeViewSubsection(const DebugStringTableSubsectionRef & Strings,const DebugFrameDataSubsectionRef & Frames)7080b57cec5SDimitry Andric YAMLFrameDataSubsection::fromCodeViewSubsection(
7090b57cec5SDimitry Andric     const DebugStringTableSubsectionRef &Strings,
7100b57cec5SDimitry Andric     const DebugFrameDataSubsectionRef &Frames) {
7110b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLFrameDataSubsection>();
7120b57cec5SDimitry Andric   for (const auto &F : Frames) {
7130b57cec5SDimitry Andric     YAMLFrameData YF;
7140b57cec5SDimitry Andric     YF.CodeSize = F.CodeSize;
7150b57cec5SDimitry Andric     YF.Flags = F.Flags;
7160b57cec5SDimitry Andric     YF.LocalSize = F.LocalSize;
7170b57cec5SDimitry Andric     YF.MaxStackSize = F.MaxStackSize;
7180b57cec5SDimitry Andric     YF.ParamsSize = F.ParamsSize;
7190b57cec5SDimitry Andric     YF.PrologSize = F.PrologSize;
7200b57cec5SDimitry Andric     YF.RvaStart = F.RvaStart;
7210b57cec5SDimitry Andric     YF.SavedRegsSize = F.SavedRegsSize;
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric     auto ES = Strings.getString(F.FrameFunc);
7240b57cec5SDimitry Andric     if (!ES)
7250b57cec5SDimitry Andric       return joinErrors(
7260b57cec5SDimitry Andric           make_error<CodeViewError>(
7270b57cec5SDimitry Andric               cv_error_code::no_records,
7280b57cec5SDimitry Andric               "Could not find string for string id while mapping FrameData!"),
7290b57cec5SDimitry Andric           ES.takeError());
7300b57cec5SDimitry Andric     YF.FrameFunc = *ES;
7310b57cec5SDimitry Andric     Result->Frames.push_back(YF);
7320b57cec5SDimitry Andric   }
7330b57cec5SDimitry Andric   return Result;
7340b57cec5SDimitry Andric }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>>
fromCodeViewSubsection(const DebugSymbolRVASubsectionRef & Section)7370b57cec5SDimitry Andric YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(
7380b57cec5SDimitry Andric     const DebugSymbolRVASubsectionRef &Section) {
7390b57cec5SDimitry Andric   auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>();
7400b57cec5SDimitry Andric   for (const auto &RVA : Section) {
7410b57cec5SDimitry Andric     Result->RVAs.push_back(RVA);
7420b57cec5SDimitry Andric   }
7430b57cec5SDimitry Andric   return Result;
7440b57cec5SDimitry Andric }
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric Expected<std::vector<std::shared_ptr<DebugSubsection>>>
toCodeViewSubsectionList(BumpPtrAllocator & Allocator,ArrayRef<YAMLDebugSubsection> Subsections,const codeview::StringsAndChecksums & SC)7470b57cec5SDimitry Andric llvm::CodeViewYAML::toCodeViewSubsectionList(
7480b57cec5SDimitry Andric     BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections,
7490b57cec5SDimitry Andric     const codeview::StringsAndChecksums &SC) {
7500b57cec5SDimitry Andric   std::vector<std::shared_ptr<DebugSubsection>> Result;
7510b57cec5SDimitry Andric   if (Subsections.empty())
7520b57cec5SDimitry Andric     return std::move(Result);
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric   for (const auto &SS : Subsections) {
7550b57cec5SDimitry Andric     std::shared_ptr<DebugSubsection> CVS;
7560b57cec5SDimitry Andric     CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC);
7570b57cec5SDimitry Andric     assert(CVS != nullptr);
7580b57cec5SDimitry Andric     Result.push_back(std::move(CVS));
7590b57cec5SDimitry Andric   }
7600b57cec5SDimitry Andric   return std::move(Result);
7610b57cec5SDimitry Andric }
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric namespace {
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
7660b57cec5SDimitry Andric   SubsectionConversionVisitor() = default;
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
7690b57cec5SDimitry Andric   Error visitLines(DebugLinesSubsectionRef &Lines,
7700b57cec5SDimitry Andric                    const StringsAndChecksumsRef &State) override;
7710b57cec5SDimitry Andric   Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
7720b57cec5SDimitry Andric                            const StringsAndChecksumsRef &State) override;
7730b57cec5SDimitry Andric   Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
7740b57cec5SDimitry Andric                           const StringsAndChecksumsRef &State) override;
7750b57cec5SDimitry Andric   Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums,
7760b57cec5SDimitry Andric                                 const StringsAndChecksumsRef &State) override;
7770b57cec5SDimitry Andric   Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees,
7780b57cec5SDimitry Andric                                 const StringsAndChecksumsRef &State) override;
7790b57cec5SDimitry Andric   Error visitStringTable(DebugStringTableSubsectionRef &ST,
7800b57cec5SDimitry Andric                          const StringsAndChecksumsRef &State) override;
7810b57cec5SDimitry Andric   Error visitSymbols(DebugSymbolsSubsectionRef &Symbols,
7820b57cec5SDimitry Andric                      const StringsAndChecksumsRef &State) override;
7830b57cec5SDimitry Andric   Error visitFrameData(DebugFrameDataSubsectionRef &Symbols,
7840b57cec5SDimitry Andric                        const StringsAndChecksumsRef &State) override;
7850b57cec5SDimitry Andric   Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols,
7860b57cec5SDimitry Andric                             const StringsAndChecksumsRef &State) override;
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric   YAMLDebugSubsection Subsection;
7890b57cec5SDimitry Andric };
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric } // end anonymous namespace
7920b57cec5SDimitry Andric 
visitUnknown(DebugUnknownSubsectionRef & Unknown)7930b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitUnknown(
7940b57cec5SDimitry Andric     DebugUnknownSubsectionRef &Unknown) {
7950b57cec5SDimitry Andric   return make_error<CodeViewError>(cv_error_code::operation_unsupported);
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric 
visitLines(DebugLinesSubsectionRef & Lines,const StringsAndChecksumsRef & State)7980b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitLines(
7990b57cec5SDimitry Andric     DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) {
8000b57cec5SDimitry Andric   auto Result = YAMLLinesSubsection::fromCodeViewSubsection(
8010b57cec5SDimitry Andric       State.strings(), State.checksums(), Lines);
8020b57cec5SDimitry Andric   if (!Result)
8030b57cec5SDimitry Andric     return Result.takeError();
8040b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8050b57cec5SDimitry Andric   return Error::success();
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric 
visitFileChecksums(DebugChecksumsSubsectionRef & Checksums,const StringsAndChecksumsRef & State)8080b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitFileChecksums(
8090b57cec5SDimitry Andric     DebugChecksumsSubsectionRef &Checksums,
8100b57cec5SDimitry Andric     const StringsAndChecksumsRef &State) {
8110b57cec5SDimitry Andric   auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(),
8120b57cec5SDimitry Andric                                                                 Checksums);
8130b57cec5SDimitry Andric   if (!Result)
8140b57cec5SDimitry Andric     return Result.takeError();
8150b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8160b57cec5SDimitry Andric   return Error::success();
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric 
visitInlineeLines(DebugInlineeLinesSubsectionRef & Inlinees,const StringsAndChecksumsRef & State)8190b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitInlineeLines(
8200b57cec5SDimitry Andric     DebugInlineeLinesSubsectionRef &Inlinees,
8210b57cec5SDimitry Andric     const StringsAndChecksumsRef &State) {
8220b57cec5SDimitry Andric   auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
8230b57cec5SDimitry Andric       State.strings(), State.checksums(), Inlinees);
8240b57cec5SDimitry Andric   if (!Result)
8250b57cec5SDimitry Andric     return Result.takeError();
8260b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8270b57cec5SDimitry Andric   return Error::success();
8280b57cec5SDimitry Andric }
8290b57cec5SDimitry Andric 
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef & Exports,const StringsAndChecksumsRef & State)8300b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleExports(
8310b57cec5SDimitry Andric     DebugCrossModuleExportsSubsectionRef &Exports,
8320b57cec5SDimitry Andric     const StringsAndChecksumsRef &State) {
8330b57cec5SDimitry Andric   auto Result =
8340b57cec5SDimitry Andric       YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports);
8350b57cec5SDimitry Andric   if (!Result)
8360b57cec5SDimitry Andric     return Result.takeError();
8370b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8380b57cec5SDimitry Andric   return Error::success();
8390b57cec5SDimitry Andric }
8400b57cec5SDimitry Andric 
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef & Imports,const StringsAndChecksumsRef & State)8410b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitCrossModuleImports(
8420b57cec5SDimitry Andric     DebugCrossModuleImportsSubsectionRef &Imports,
8430b57cec5SDimitry Andric     const StringsAndChecksumsRef &State) {
8440b57cec5SDimitry Andric   auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection(
8450b57cec5SDimitry Andric       State.strings(), Imports);
8460b57cec5SDimitry Andric   if (!Result)
8470b57cec5SDimitry Andric     return Result.takeError();
8480b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8490b57cec5SDimitry Andric   return Error::success();
8500b57cec5SDimitry Andric }
8510b57cec5SDimitry Andric 
visitStringTable(DebugStringTableSubsectionRef & Strings,const StringsAndChecksumsRef & State)8520b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitStringTable(
8530b57cec5SDimitry Andric     DebugStringTableSubsectionRef &Strings,
8540b57cec5SDimitry Andric     const StringsAndChecksumsRef &State) {
8550b57cec5SDimitry Andric   auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings);
8560b57cec5SDimitry Andric   if (!Result)
8570b57cec5SDimitry Andric     return Result.takeError();
8580b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8590b57cec5SDimitry Andric   return Error::success();
8600b57cec5SDimitry Andric }
8610b57cec5SDimitry Andric 
visitSymbols(DebugSymbolsSubsectionRef & Symbols,const StringsAndChecksumsRef & State)8620b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitSymbols(
8630b57cec5SDimitry Andric     DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) {
8640b57cec5SDimitry Andric   auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols);
8650b57cec5SDimitry Andric   if (!Result)
8660b57cec5SDimitry Andric     return Result.takeError();
8670b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8680b57cec5SDimitry Andric   return Error::success();
8690b57cec5SDimitry Andric }
8700b57cec5SDimitry Andric 
visitFrameData(DebugFrameDataSubsectionRef & Frames,const StringsAndChecksumsRef & State)8710b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitFrameData(
8720b57cec5SDimitry Andric     DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) {
8730b57cec5SDimitry Andric   auto Result =
8740b57cec5SDimitry Andric       YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames);
8750b57cec5SDimitry Andric   if (!Result)
8760b57cec5SDimitry Andric     return Result.takeError();
8770b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8780b57cec5SDimitry Andric   return Error::success();
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric 
visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef & RVAs,const StringsAndChecksumsRef & State)8810b57cec5SDimitry Andric Error SubsectionConversionVisitor::visitCOFFSymbolRVAs(
8820b57cec5SDimitry Andric     DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) {
8830b57cec5SDimitry Andric   auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs);
8840b57cec5SDimitry Andric   if (!Result)
8850b57cec5SDimitry Andric     return Result.takeError();
8860b57cec5SDimitry Andric   Subsection.Subsection = *Result;
8870b57cec5SDimitry Andric   return Error::success();
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric Expected<YAMLDebugSubsection>
fromCodeViewSubection(const StringsAndChecksumsRef & SC,const DebugSubsectionRecord & SS)8910b57cec5SDimitry Andric YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC,
8920b57cec5SDimitry Andric                                            const DebugSubsectionRecord &SS) {
8930b57cec5SDimitry Andric   SubsectionConversionVisitor V;
8940b57cec5SDimitry Andric   if (auto EC = visitDebugSubsection(SS, V, SC))
8950b57cec5SDimitry Andric     return std::move(EC);
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric   return V.Subsection;
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric std::vector<YAMLDebugSubsection>
fromDebugS(ArrayRef<uint8_t> Data,const StringsAndChecksumsRef & SC)9010b57cec5SDimitry Andric llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data,
9020b57cec5SDimitry Andric                                const StringsAndChecksumsRef &SC) {
903*5f757f3fSDimitry Andric   BinaryStreamReader Reader(Data, llvm::endianness::little);
9040b57cec5SDimitry Andric   uint32_t Magic;
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   ExitOnError Err("Invalid .debug$S section!");
9070b57cec5SDimitry Andric   Err(Reader.readInteger(Magic));
9080b57cec5SDimitry Andric   assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric   DebugSubsectionArray Subsections;
9110b57cec5SDimitry Andric   Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric   std::vector<YAMLDebugSubsection> Result;
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   for (const auto &SS : Subsections) {
9160b57cec5SDimitry Andric     auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS));
9170b57cec5SDimitry Andric     Result.push_back(YamlSS);
9180b57cec5SDimitry Andric   }
9190b57cec5SDimitry Andric   return Result;
9200b57cec5SDimitry Andric }
9210b57cec5SDimitry Andric 
initializeStringsAndChecksums(ArrayRef<YAMLDebugSubsection> Sections,codeview::StringsAndChecksums & SC)9220b57cec5SDimitry Andric void llvm::CodeViewYAML::initializeStringsAndChecksums(
9230b57cec5SDimitry Andric     ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) {
9240b57cec5SDimitry Andric   // String Table and Checksums subsections don't use the allocator.
9250b57cec5SDimitry Andric   BumpPtrAllocator Allocator;
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric   // It's possible for checksums and strings to even appear in different debug$S
9280b57cec5SDimitry Andric   // sections, so we have to make this a stateful function that can build up
9290b57cec5SDimitry Andric   // the strings and checksums field over multiple iterations.
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   // File Checksums require the string table, but may become before it, so we
9320b57cec5SDimitry Andric   // have to scan for strings first, then scan for checksums again from the
9330b57cec5SDimitry Andric   // beginning.
9340b57cec5SDimitry Andric   if (!SC.hasStrings()) {
9350b57cec5SDimitry Andric     for (const auto &SS : Sections) {
9360b57cec5SDimitry Andric       if (SS.Subsection->Kind != DebugSubsectionKind::StringTable)
9370b57cec5SDimitry Andric         continue;
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
9400b57cec5SDimitry Andric       SC.setStrings(
9410b57cec5SDimitry Andric           std::static_pointer_cast<DebugStringTableSubsection>(Result));
9420b57cec5SDimitry Andric       break;
9430b57cec5SDimitry Andric     }
9440b57cec5SDimitry Andric   }
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric   if (SC.hasStrings() && !SC.hasChecksums()) {
9470b57cec5SDimitry Andric     for (const auto &SS : Sections) {
9480b57cec5SDimitry Andric       if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums)
9490b57cec5SDimitry Andric         continue;
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric       auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC);
9520b57cec5SDimitry Andric       SC.setChecksums(
9530b57cec5SDimitry Andric           std::static_pointer_cast<DebugChecksumsSubsection>(Result));
9540b57cec5SDimitry Andric       break;
9550b57cec5SDimitry Andric     }
9560b57cec5SDimitry Andric   }
9570b57cec5SDimitry Andric }
958