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