11b88f4f3SZachary Turner //===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===// 21b88f4f3SZachary Turner // 31b88f4f3SZachary Turner // The LLVM Compiler Infrastructure 41b88f4f3SZachary Turner // 51b88f4f3SZachary Turner // This file is distributed under the University of Illinois Open Source 61b88f4f3SZachary Turner // License. See LICENSE.TXT for details. 71b88f4f3SZachary Turner // 81b88f4f3SZachary Turner //===----------------------------------------------------------------------===// 91b88f4f3SZachary Turner // 101b88f4f3SZachary Turner // This file defines classes for handling the YAML representation of CodeView 111b88f4f3SZachary Turner // Debug Info. 121b88f4f3SZachary Turner // 131b88f4f3SZachary Turner //===----------------------------------------------------------------------===// 141b88f4f3SZachary Turner 151b88f4f3SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" 161b88f4f3SZachary Turner 171b88f4f3SZachary Turner #include "llvm/ADT/StringExtras.h" 181b88f4f3SZachary Turner #include "llvm/ADT/StringSwitch.h" 191b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 2092dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" 2192dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" 2292dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 2392dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 2492dcdda6SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" 251b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/EnumTables.h" 261b88f4f3SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 271b88f4f3SZachary Turner 281b88f4f3SZachary Turner using namespace llvm; 291b88f4f3SZachary Turner using namespace llvm::codeview; 301b88f4f3SZachary Turner using namespace llvm::CodeViewYAML; 311b88f4f3SZachary Turner using namespace llvm::CodeViewYAML::detail; 321b88f4f3SZachary Turner using namespace llvm::yaml; 331b88f4f3SZachary Turner 341b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry) 351b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry) 361b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry) 371b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock) 381b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo) 391b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite) 401b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) 411b88f4f3SZachary Turner LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) 421b88f4f3SZachary Turner 431b88f4f3SZachary Turner LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false) 4492dcdda6SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind) 451b88f4f3SZachary Turner LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) 461b88f4f3SZachary Turner LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) 471b88f4f3SZachary Turner 4892dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) 4992dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry) 5092dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry) 5192dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock) 5292dcdda6SZachary Turner LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite) 5392dcdda6SZachary Turner 5492dcdda6SZachary Turner namespace llvm { 5592dcdda6SZachary Turner namespace CodeViewYAML { 5692dcdda6SZachary Turner namespace detail { 5792dcdda6SZachary Turner struct YAMLSubsectionBase { 5892dcdda6SZachary Turner explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {} 5992dcdda6SZachary Turner DebugSubsectionKind Kind; 6092dcdda6SZachary Turner virtual ~YAMLSubsectionBase() {} 6192dcdda6SZachary Turner 6292dcdda6SZachary Turner virtual void map(IO &IO) = 0; 6392dcdda6SZachary Turner virtual std::unique_ptr<DebugSubsection> 6492dcdda6SZachary Turner toCodeViewSubsection(DebugStringTableSubsection *UseStrings, 6592dcdda6SZachary Turner DebugChecksumsSubsection *UseChecksums) const = 0; 6692dcdda6SZachary Turner }; 6792dcdda6SZachary Turner } 6892dcdda6SZachary Turner } 6992dcdda6SZachary Turner } 7092dcdda6SZachary Turner 7192dcdda6SZachary Turner namespace { 7292dcdda6SZachary Turner struct YAMLChecksumsSubsection : public YAMLSubsectionBase { 7392dcdda6SZachary Turner YAMLChecksumsSubsection() 7492dcdda6SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} 7592dcdda6SZachary Turner 7692dcdda6SZachary Turner void map(IO &IO) override; 7792dcdda6SZachary Turner std::unique_ptr<DebugSubsection> 7892dcdda6SZachary Turner toCodeViewSubsection(DebugStringTableSubsection *Strings, 7992dcdda6SZachary Turner DebugChecksumsSubsection *Checksums) const override; 8092dcdda6SZachary Turner static Expected<std::shared_ptr<YAMLChecksumsSubsection>> 8192dcdda6SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 8292dcdda6SZachary Turner const DebugChecksumsSubsectionRef &FC); 8392dcdda6SZachary Turner 8492dcdda6SZachary Turner std::vector<SourceFileChecksumEntry> Checksums; 8592dcdda6SZachary Turner }; 8692dcdda6SZachary Turner 8792dcdda6SZachary Turner struct YAMLLinesSubsection : public YAMLSubsectionBase { 8892dcdda6SZachary Turner YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} 8992dcdda6SZachary Turner 9092dcdda6SZachary Turner void map(IO &IO) override; 9192dcdda6SZachary Turner std::unique_ptr<DebugSubsection> 9292dcdda6SZachary Turner toCodeViewSubsection(DebugStringTableSubsection *Strings, 9392dcdda6SZachary Turner DebugChecksumsSubsection *Checksums) const override; 9492dcdda6SZachary Turner static Expected<std::shared_ptr<YAMLLinesSubsection>> 9592dcdda6SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 9692dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 9792dcdda6SZachary Turner const DebugLinesSubsectionRef &Lines); 9892dcdda6SZachary Turner 9992dcdda6SZachary Turner SourceLineInfo Lines; 10092dcdda6SZachary Turner }; 10192dcdda6SZachary Turner 10292dcdda6SZachary Turner struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { 10392dcdda6SZachary Turner YAMLInlineeLinesSubsection() 10492dcdda6SZachary Turner : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} 10592dcdda6SZachary Turner 10692dcdda6SZachary Turner void map(IO &IO) override; 10792dcdda6SZachary Turner std::unique_ptr<DebugSubsection> 10892dcdda6SZachary Turner toCodeViewSubsection(DebugStringTableSubsection *Strings, 10992dcdda6SZachary Turner DebugChecksumsSubsection *Checksums) const override; 11092dcdda6SZachary Turner static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> 11192dcdda6SZachary Turner fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, 11292dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 11392dcdda6SZachary Turner const DebugInlineeLinesSubsectionRef &Lines); 11492dcdda6SZachary Turner 11592dcdda6SZachary Turner InlineeInfo InlineeLines; 11692dcdda6SZachary Turner }; 11792dcdda6SZachary Turner } 1181b88f4f3SZachary Turner 1191b88f4f3SZachary Turner void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) { 1201b88f4f3SZachary Turner io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); 1211b88f4f3SZachary Turner io.enumFallback<Hex16>(Flags); 1221b88f4f3SZachary Turner } 1231b88f4f3SZachary Turner 1241b88f4f3SZachary Turner void ScalarEnumerationTraits<FileChecksumKind>::enumeration( 1251b88f4f3SZachary Turner IO &io, FileChecksumKind &Kind) { 1261b88f4f3SZachary Turner io.enumCase(Kind, "None", FileChecksumKind::None); 1271b88f4f3SZachary Turner io.enumCase(Kind, "MD5", FileChecksumKind::MD5); 1281b88f4f3SZachary Turner io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1); 1291b88f4f3SZachary Turner io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256); 1301b88f4f3SZachary Turner } 1311b88f4f3SZachary Turner 1321b88f4f3SZachary Turner void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value, 1331b88f4f3SZachary Turner void *ctx, raw_ostream &Out) { 1341b88f4f3SZachary Turner StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()), 1351b88f4f3SZachary Turner Value.Bytes.size()); 1361b88f4f3SZachary Turner Out << toHex(Bytes); 1371b88f4f3SZachary Turner } 1381b88f4f3SZachary Turner 1391b88f4f3SZachary Turner StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt, 1401b88f4f3SZachary Turner HexFormattedString &Value) { 1411b88f4f3SZachary Turner std::string H = fromHex(Scalar); 1421b88f4f3SZachary Turner Value.Bytes.assign(H.begin(), H.end()); 1431b88f4f3SZachary Turner return StringRef(); 1441b88f4f3SZachary Turner } 1451b88f4f3SZachary Turner 1461b88f4f3SZachary Turner void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) { 1471b88f4f3SZachary Turner IO.mapRequired("Offset", Obj.Offset); 1481b88f4f3SZachary Turner IO.mapRequired("LineStart", Obj.LineStart); 1491b88f4f3SZachary Turner IO.mapRequired("IsStatement", Obj.IsStatement); 1501b88f4f3SZachary Turner IO.mapRequired("EndDelta", Obj.EndDelta); 1511b88f4f3SZachary Turner } 1521b88f4f3SZachary Turner 1531b88f4f3SZachary Turner void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) { 1541b88f4f3SZachary Turner IO.mapRequired("StartColumn", Obj.StartColumn); 1551b88f4f3SZachary Turner IO.mapRequired("EndColumn", Obj.EndColumn); 1561b88f4f3SZachary Turner } 1571b88f4f3SZachary Turner 1581b88f4f3SZachary Turner void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) { 1591b88f4f3SZachary Turner IO.mapRequired("FileName", Obj.FileName); 1601b88f4f3SZachary Turner IO.mapRequired("Lines", Obj.Lines); 1611b88f4f3SZachary Turner IO.mapRequired("Columns", Obj.Columns); 1621b88f4f3SZachary Turner } 1631b88f4f3SZachary Turner 1641b88f4f3SZachary Turner void MappingTraits<SourceFileChecksumEntry>::mapping( 1651b88f4f3SZachary Turner IO &IO, SourceFileChecksumEntry &Obj) { 1661b88f4f3SZachary Turner IO.mapRequired("FileName", Obj.FileName); 1671b88f4f3SZachary Turner IO.mapRequired("Kind", Obj.Kind); 1681b88f4f3SZachary Turner IO.mapRequired("Checksum", Obj.ChecksumBytes); 1691b88f4f3SZachary Turner } 1701b88f4f3SZachary Turner 1711b88f4f3SZachary Turner void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { 1721b88f4f3SZachary Turner IO.mapRequired("FileName", Obj.FileName); 1731b88f4f3SZachary Turner IO.mapRequired("LineNum", Obj.SourceLineNum); 1741b88f4f3SZachary Turner IO.mapRequired("Inlinee", Obj.Inlinee); 1751b88f4f3SZachary Turner IO.mapOptional("ExtraFiles", Obj.ExtraFiles); 1761b88f4f3SZachary Turner } 1771b88f4f3SZachary Turner 17892dcdda6SZachary Turner void YAMLChecksumsSubsection::map(IO &IO) { 17992dcdda6SZachary Turner IO.mapTag("!FileChecksums", true); 18092dcdda6SZachary Turner IO.mapRequired("Checksums", Checksums); 18192dcdda6SZachary Turner } 18292dcdda6SZachary Turner 18392dcdda6SZachary Turner void YAMLLinesSubsection::map(IO &IO) { 18492dcdda6SZachary Turner IO.mapTag("!Lines", true); 18592dcdda6SZachary Turner IO.mapRequired("CodeSize", Lines.CodeSize); 18692dcdda6SZachary Turner 18792dcdda6SZachary Turner IO.mapRequired("Flags", Lines.Flags); 18892dcdda6SZachary Turner IO.mapRequired("RelocOffset", Lines.RelocOffset); 18992dcdda6SZachary Turner IO.mapRequired("RelocSegment", Lines.RelocSegment); 19092dcdda6SZachary Turner IO.mapRequired("Blocks", Lines.Blocks); 19192dcdda6SZachary Turner } 19292dcdda6SZachary Turner 19392dcdda6SZachary Turner void YAMLInlineeLinesSubsection::map(IO &IO) { 19492dcdda6SZachary Turner IO.mapTag("!InlineeLines", true); 19592dcdda6SZachary Turner IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles); 19692dcdda6SZachary Turner IO.mapRequired("Sites", InlineeLines.Sites); 19792dcdda6SZachary Turner } 19892dcdda6SZachary Turner 19992dcdda6SZachary Turner void MappingTraits<YAMLDebugSubsection>::mapping( 20092dcdda6SZachary Turner IO &IO, YAMLDebugSubsection &Subsection) { 20192dcdda6SZachary Turner if (!IO.outputting()) { 20292dcdda6SZachary Turner if (IO.mapTag("!FileChecksums")) { 20392dcdda6SZachary Turner auto SS = std::make_shared<YAMLChecksumsSubsection>(); 20492dcdda6SZachary Turner Subsection.Subsection = SS; 20592dcdda6SZachary Turner } else if (IO.mapTag("!Lines")) { 20692dcdda6SZachary Turner Subsection.Subsection = std::make_shared<YAMLLinesSubsection>(); 20792dcdda6SZachary Turner } else if (IO.mapTag("!InlineeLines")) { 20892dcdda6SZachary Turner Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>(); 20992dcdda6SZachary Turner } else { 21092dcdda6SZachary Turner llvm_unreachable("Unexpected subsection tag!"); 21192dcdda6SZachary Turner } 21292dcdda6SZachary Turner } 21392dcdda6SZachary Turner Subsection.Subsection->map(IO); 21492dcdda6SZachary Turner } 21592dcdda6SZachary Turner 21692dcdda6SZachary Turner static Expected<const YAMLChecksumsSubsection &> 21792dcdda6SZachary Turner findChecksums(ArrayRef<YAMLDebugSubsection> Subsections) { 21892dcdda6SZachary Turner for (const auto &SS : Subsections) { 21992dcdda6SZachary Turner if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) { 22092dcdda6SZachary Turner return static_cast<const YAMLChecksumsSubsection &>(*SS.Subsection); 22192dcdda6SZachary Turner } 22292dcdda6SZachary Turner } 22392dcdda6SZachary Turner return make_error<CodeViewError>(cv_error_code::no_records); 22492dcdda6SZachary Turner } 22592dcdda6SZachary Turner 22692dcdda6SZachary Turner std::unique_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection( 22792dcdda6SZachary Turner DebugStringTableSubsection *UseStrings, 22892dcdda6SZachary Turner DebugChecksumsSubsection *UseChecksums) const { 22992dcdda6SZachary Turner assert(UseStrings && !UseChecksums); 23092dcdda6SZachary Turner auto Result = llvm::make_unique<DebugChecksumsSubsection>(*UseStrings); 23192dcdda6SZachary Turner for (const auto &CS : Checksums) { 23292dcdda6SZachary Turner Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); 23392dcdda6SZachary Turner } 23492dcdda6SZachary Turner return std::move(Result); 23592dcdda6SZachary Turner } 23692dcdda6SZachary Turner 23792dcdda6SZachary Turner std::unique_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection( 23892dcdda6SZachary Turner DebugStringTableSubsection *UseStrings, 23992dcdda6SZachary Turner DebugChecksumsSubsection *UseChecksums) const { 24092dcdda6SZachary Turner assert(UseStrings && UseChecksums); 24192dcdda6SZachary Turner auto Result = 24292dcdda6SZachary Turner llvm::make_unique<DebugLinesSubsection>(*UseChecksums, *UseStrings); 24392dcdda6SZachary Turner Result->setCodeSize(Lines.CodeSize); 24492dcdda6SZachary Turner Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); 24592dcdda6SZachary Turner Result->setFlags(Lines.Flags); 24692dcdda6SZachary Turner for (const auto &LC : Lines.Blocks) { 24792dcdda6SZachary Turner Result->createBlock(LC.FileName); 24892dcdda6SZachary Turner if (Result->hasColumnInfo()) { 24992dcdda6SZachary Turner for (const auto &Item : zip(LC.Lines, LC.Columns)) { 25092dcdda6SZachary Turner auto &L = std::get<0>(Item); 25192dcdda6SZachary Turner auto &C = std::get<1>(Item); 25292dcdda6SZachary Turner uint32_t LE = L.LineStart + L.EndDelta; 25392dcdda6SZachary Turner Result->addLineAndColumnInfo(L.Offset, 25492dcdda6SZachary Turner LineInfo(L.LineStart, LE, L.IsStatement), 25592dcdda6SZachary Turner C.StartColumn, C.EndColumn); 25692dcdda6SZachary Turner } 25792dcdda6SZachary Turner } else { 25892dcdda6SZachary Turner for (const auto &L : LC.Lines) { 25992dcdda6SZachary Turner uint32_t LE = L.LineStart + L.EndDelta; 26092dcdda6SZachary Turner Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement)); 26192dcdda6SZachary Turner } 26292dcdda6SZachary Turner } 26392dcdda6SZachary Turner } 264*4bedb5fdSZachary Turner return llvm::cast<DebugSubsection>(std::move(Result)); 26592dcdda6SZachary Turner } 26692dcdda6SZachary Turner 26792dcdda6SZachary Turner std::unique_ptr<DebugSubsection> 26892dcdda6SZachary Turner YAMLInlineeLinesSubsection::toCodeViewSubsection( 26992dcdda6SZachary Turner DebugStringTableSubsection *UseStrings, 27092dcdda6SZachary Turner DebugChecksumsSubsection *UseChecksums) const { 27192dcdda6SZachary Turner assert(UseChecksums); 27292dcdda6SZachary Turner auto Result = llvm::make_unique<DebugInlineeLinesSubsection>( 27392dcdda6SZachary Turner *UseChecksums, InlineeLines.HasExtraFiles); 27492dcdda6SZachary Turner 27592dcdda6SZachary Turner for (const auto &Site : InlineeLines.Sites) { 27692dcdda6SZachary Turner Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, 27792dcdda6SZachary Turner Site.SourceLineNum); 27892dcdda6SZachary Turner if (!InlineeLines.HasExtraFiles) 27992dcdda6SZachary Turner continue; 28092dcdda6SZachary Turner 28192dcdda6SZachary Turner for (auto EF : Site.ExtraFiles) { 28292dcdda6SZachary Turner Result->addExtraFile(EF); 28392dcdda6SZachary Turner } 28492dcdda6SZachary Turner } 285*4bedb5fdSZachary Turner return llvm::cast<DebugSubsection>(std::move(Result)); 28692dcdda6SZachary Turner } 28792dcdda6SZachary Turner 28892dcdda6SZachary Turner static Expected<SourceFileChecksumEntry> 28992dcdda6SZachary Turner convertOneChecksum(const DebugStringTableSubsectionRef &Strings, 29092dcdda6SZachary Turner const FileChecksumEntry &CS) { 29192dcdda6SZachary Turner auto ExpectedString = Strings.getString(CS.FileNameOffset); 29292dcdda6SZachary Turner if (!ExpectedString) 29392dcdda6SZachary Turner return ExpectedString.takeError(); 29492dcdda6SZachary Turner 29592dcdda6SZachary Turner SourceFileChecksumEntry Result; 29692dcdda6SZachary Turner Result.ChecksumBytes.Bytes = CS.Checksum; 29792dcdda6SZachary Turner Result.Kind = CS.Kind; 29892dcdda6SZachary Turner Result.FileName = *ExpectedString; 29992dcdda6SZachary Turner return Result; 30092dcdda6SZachary Turner } 30192dcdda6SZachary Turner 30292dcdda6SZachary Turner static Expected<StringRef> 30392dcdda6SZachary Turner getFileName(const DebugStringTableSubsectionRef &Strings, 30492dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { 30592dcdda6SZachary Turner auto Iter = Checksums.getArray().at(FileID); 30692dcdda6SZachary Turner if (Iter == Checksums.getArray().end()) 30792dcdda6SZachary Turner return make_error<CodeViewError>(cv_error_code::no_records); 30892dcdda6SZachary Turner uint32_t Offset = Iter->FileNameOffset; 30992dcdda6SZachary Turner return Strings.getString(Offset); 31092dcdda6SZachary Turner } 31192dcdda6SZachary Turner 31292dcdda6SZachary Turner Expected<std::shared_ptr<YAMLChecksumsSubsection>> 31392dcdda6SZachary Turner YAMLChecksumsSubsection::fromCodeViewSubsection( 31492dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 31592dcdda6SZachary Turner const DebugChecksumsSubsectionRef &FC) { 31692dcdda6SZachary Turner auto Result = std::make_shared<YAMLChecksumsSubsection>(); 31792dcdda6SZachary Turner 31892dcdda6SZachary Turner for (const auto &CS : FC) { 31992dcdda6SZachary Turner auto ConvertedCS = convertOneChecksum(Strings, CS); 32092dcdda6SZachary Turner if (!ConvertedCS) 32192dcdda6SZachary Turner return ConvertedCS.takeError(); 32292dcdda6SZachary Turner Result->Checksums.push_back(*ConvertedCS); 32392dcdda6SZachary Turner } 32492dcdda6SZachary Turner return Result; 32592dcdda6SZachary Turner } 32692dcdda6SZachary Turner 32792dcdda6SZachary Turner Expected<std::shared_ptr<YAMLLinesSubsection>> 32892dcdda6SZachary Turner YAMLLinesSubsection::fromCodeViewSubsection( 32992dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 33092dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 33192dcdda6SZachary Turner const DebugLinesSubsectionRef &Lines) { 33292dcdda6SZachary Turner auto Result = std::make_shared<YAMLLinesSubsection>(); 33392dcdda6SZachary Turner Result->Lines.CodeSize = Lines.header()->CodeSize; 33492dcdda6SZachary Turner Result->Lines.RelocOffset = Lines.header()->RelocOffset; 33592dcdda6SZachary Turner Result->Lines.RelocSegment = Lines.header()->RelocSegment; 33692dcdda6SZachary Turner Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags)); 33792dcdda6SZachary Turner for (const auto &L : Lines) { 33892dcdda6SZachary Turner SourceLineBlock Block; 33992dcdda6SZachary Turner auto EF = getFileName(Strings, Checksums, L.NameIndex); 34092dcdda6SZachary Turner if (!EF) 34192dcdda6SZachary Turner return EF.takeError(); 34292dcdda6SZachary Turner Block.FileName = *EF; 34392dcdda6SZachary Turner if (Lines.hasColumnInfo()) { 34492dcdda6SZachary Turner for (const auto &C : L.Columns) { 34592dcdda6SZachary Turner SourceColumnEntry SCE; 34692dcdda6SZachary Turner SCE.EndColumn = C.EndColumn; 34792dcdda6SZachary Turner SCE.StartColumn = C.StartColumn; 34892dcdda6SZachary Turner Block.Columns.push_back(SCE); 34992dcdda6SZachary Turner } 35092dcdda6SZachary Turner } 35192dcdda6SZachary Turner for (const auto &LN : L.LineNumbers) { 35292dcdda6SZachary Turner SourceLineEntry SLE; 35392dcdda6SZachary Turner LineInfo LI(LN.Flags); 35492dcdda6SZachary Turner SLE.Offset = LN.Offset; 35592dcdda6SZachary Turner SLE.LineStart = LI.getStartLine(); 35692dcdda6SZachary Turner SLE.EndDelta = LI.getLineDelta(); 35792dcdda6SZachary Turner SLE.IsStatement = LI.isStatement(); 35892dcdda6SZachary Turner Block.Lines.push_back(SLE); 35992dcdda6SZachary Turner } 36092dcdda6SZachary Turner Result->Lines.Blocks.push_back(Block); 36192dcdda6SZachary Turner } 36292dcdda6SZachary Turner return Result; 36392dcdda6SZachary Turner } 36492dcdda6SZachary Turner 36592dcdda6SZachary Turner Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> 36692dcdda6SZachary Turner YAMLInlineeLinesSubsection::fromCodeViewSubsection( 36792dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 36892dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 36992dcdda6SZachary Turner const DebugInlineeLinesSubsectionRef &Lines) { 37092dcdda6SZachary Turner auto Result = std::make_shared<YAMLInlineeLinesSubsection>(); 37192dcdda6SZachary Turner 37292dcdda6SZachary Turner Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles(); 37392dcdda6SZachary Turner for (const auto &IL : Lines) { 37492dcdda6SZachary Turner InlineeSite Site; 37592dcdda6SZachary Turner auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID); 37692dcdda6SZachary Turner if (!ExpF) 37792dcdda6SZachary Turner return ExpF.takeError(); 37892dcdda6SZachary Turner Site.FileName = *ExpF; 37992dcdda6SZachary Turner Site.Inlinee = IL.Header->Inlinee.getIndex(); 38092dcdda6SZachary Turner Site.SourceLineNum = IL.Header->SourceLineNum; 38192dcdda6SZachary Turner if (Lines.hasExtraFiles()) { 38292dcdda6SZachary Turner for (const auto EF : IL.ExtraFiles) { 38392dcdda6SZachary Turner auto ExpF2 = getFileName(Strings, Checksums, EF); 38492dcdda6SZachary Turner if (!ExpF2) 38592dcdda6SZachary Turner return ExpF2.takeError(); 38692dcdda6SZachary Turner Site.ExtraFiles.push_back(*ExpF2); 38792dcdda6SZachary Turner } 38892dcdda6SZachary Turner } 38992dcdda6SZachary Turner Result->InlineeLines.Sites.push_back(Site); 39092dcdda6SZachary Turner } 39192dcdda6SZachary Turner return Result; 39292dcdda6SZachary Turner } 39392dcdda6SZachary Turner 39492dcdda6SZachary Turner Expected<std::vector<std::unique_ptr<DebugSubsection>>> 39592dcdda6SZachary Turner llvm::CodeViewYAML::convertSubsectionList( 39692dcdda6SZachary Turner ArrayRef<YAMLDebugSubsection> Subsections, 39792dcdda6SZachary Turner DebugStringTableSubsection &Strings) { 39892dcdda6SZachary Turner std::vector<std::unique_ptr<DebugSubsection>> Result; 39992dcdda6SZachary Turner if (Subsections.empty()) 40092dcdda6SZachary Turner return Result; 40192dcdda6SZachary Turner 40292dcdda6SZachary Turner auto Checksums = findChecksums(Subsections); 40392dcdda6SZachary Turner if (!Checksums) 40492dcdda6SZachary Turner return Checksums.takeError(); 40592dcdda6SZachary Turner auto ChecksumsBase = Checksums->toCodeViewSubsection(&Strings, nullptr); 40692dcdda6SZachary Turner DebugChecksumsSubsection &CS = 40792dcdda6SZachary Turner llvm::cast<DebugChecksumsSubsection>(*ChecksumsBase); 40892dcdda6SZachary Turner for (const auto &SS : Subsections) { 40992dcdda6SZachary Turner // We've already converted the checksums subsection, don't do it 41092dcdda6SZachary Turner // twice. 41192dcdda6SZachary Turner std::unique_ptr<DebugSubsection> CVS; 41292dcdda6SZachary Turner if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) 41392dcdda6SZachary Turner CVS = std::move(ChecksumsBase); 41492dcdda6SZachary Turner else 41592dcdda6SZachary Turner CVS = SS.Subsection->toCodeViewSubsection(&Strings, &CS); 41692dcdda6SZachary Turner Result.push_back(std::move(CVS)); 41792dcdda6SZachary Turner } 41892dcdda6SZachary Turner return std::move(Result); 41992dcdda6SZachary Turner } 42092dcdda6SZachary Turner 42192dcdda6SZachary Turner namespace { 42292dcdda6SZachary Turner struct SubsectionConversionVisitor : public DebugSubsectionVisitor { 42392dcdda6SZachary Turner explicit SubsectionConversionVisitor( 42492dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 42592dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums) 42692dcdda6SZachary Turner : Strings(Strings), Checksums(Checksums) {} 42792dcdda6SZachary Turner 42892dcdda6SZachary Turner Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; 42992dcdda6SZachary Turner Error visitLines(DebugLinesSubsectionRef &Lines) override; 43092dcdda6SZachary Turner Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums) override; 43192dcdda6SZachary Turner Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees) override; 43292dcdda6SZachary Turner 43392dcdda6SZachary Turner YAMLDebugSubsection Subsection; 43492dcdda6SZachary Turner 43592dcdda6SZachary Turner private: 43692dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings; 43792dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums; 43892dcdda6SZachary Turner }; 43992dcdda6SZachary Turner 44092dcdda6SZachary Turner Error SubsectionConversionVisitor::visitUnknown( 44192dcdda6SZachary Turner DebugUnknownSubsectionRef &Unknown) { 44292dcdda6SZachary Turner return make_error<CodeViewError>(cv_error_code::operation_unsupported); 44392dcdda6SZachary Turner } 44492dcdda6SZachary Turner 44592dcdda6SZachary Turner Error SubsectionConversionVisitor::visitLines(DebugLinesSubsectionRef &Lines) { 44692dcdda6SZachary Turner auto Result = 44792dcdda6SZachary Turner YAMLLinesSubsection::fromCodeViewSubsection(Strings, Checksums, Lines); 44892dcdda6SZachary Turner if (!Result) 44992dcdda6SZachary Turner return Result.takeError(); 45092dcdda6SZachary Turner Subsection.Subsection = *Result; 45192dcdda6SZachary Turner return Error::success(); 45292dcdda6SZachary Turner } 45392dcdda6SZachary Turner 45492dcdda6SZachary Turner Error SubsectionConversionVisitor::visitFileChecksums( 45592dcdda6SZachary Turner DebugChecksumsSubsectionRef &Checksums) { 45692dcdda6SZachary Turner auto Result = 45792dcdda6SZachary Turner YAMLChecksumsSubsection::fromCodeViewSubsection(Strings, Checksums); 45892dcdda6SZachary Turner if (!Result) 45992dcdda6SZachary Turner return Result.takeError(); 46092dcdda6SZachary Turner Subsection.Subsection = *Result; 46192dcdda6SZachary Turner return Error::success(); 46292dcdda6SZachary Turner } 46392dcdda6SZachary Turner 46492dcdda6SZachary Turner Error SubsectionConversionVisitor::visitInlineeLines( 46592dcdda6SZachary Turner DebugInlineeLinesSubsectionRef &Inlinees) { 46692dcdda6SZachary Turner auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( 46792dcdda6SZachary Turner Strings, Checksums, Inlinees); 46892dcdda6SZachary Turner if (!Result) 46992dcdda6SZachary Turner return Result.takeError(); 47092dcdda6SZachary Turner Subsection.Subsection = *Result; 47192dcdda6SZachary Turner return Error::success(); 47292dcdda6SZachary Turner } 47392dcdda6SZachary Turner } 47492dcdda6SZachary Turner 47592dcdda6SZachary Turner Expected<YAMLDebugSubsection> YAMLDebugSubsection::fromCodeViewSubection( 47692dcdda6SZachary Turner const DebugStringTableSubsectionRef &Strings, 47792dcdda6SZachary Turner const DebugChecksumsSubsectionRef &Checksums, 47892dcdda6SZachary Turner const DebugSubsectionRecord &SS) { 47992dcdda6SZachary Turner SubsectionConversionVisitor V(Strings, Checksums); 48092dcdda6SZachary Turner if (auto EC = visitDebugSubsection(SS, V)) 48192dcdda6SZachary Turner return std::move(EC); 48292dcdda6SZachary Turner 48392dcdda6SZachary Turner return V.Subsection; 4841b88f4f3SZachary Turner } 485