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