diff options
21 files changed, 549 insertions, 335 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h b/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h index e7036033d2d..c958a95ee6d 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h +++ b/llvm/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h @@ -60,8 +60,8 @@ public: Error initialize(BinaryStreamReader Reader); Error initialize(BinaryStreamRef Stream); - Iterator begin() { return Checksums.begin(); } - Iterator end() { return Checksums.end(); } + Iterator begin() const { return Checksums.begin(); } + Iterator end() const { return Checksums.end(); } const FileChecksumArray &getArray() const { return Checksums; } diff --git a/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h index e2cfc3c9923..60440700c26 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h +++ b/llvm/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h @@ -74,8 +74,13 @@ private: class DebugInlineeLinesSubsection final : public DebugSubsection { public: + struct Entry { + std::vector<support::ulittle32_t> ExtraFiles; + InlineeSourceLineHeader Header; + }; + DebugInlineeLinesSubsection(DebugChecksumsSubsection &Checksums, - bool HasExtraFiles); + bool HasExtraFiles = false); static bool classof(const DebugSubsection *S) { return S->kind() == DebugSubsectionKind::InlineeLines; @@ -87,16 +92,18 @@ public: void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine); void addExtraFile(StringRef FileName); + bool hasExtraFiles() const { return HasExtraFiles; } + void setHasExtraFiles(bool Has) { HasExtraFiles = Has; } + + std::vector<Entry>::const_iterator begin() const { return Entries.begin(); } + std::vector<Entry>::const_iterator end() const { return Entries.end(); } + private: DebugChecksumsSubsection &Checksums; bool HasExtraFiles = false; uint32_t ExtraFileCount = 0; - struct Entry { - std::vector<support::ulittle32_t> ExtraFiles; - InlineeSourceLineHeader Header; - }; std::vector<Entry> Entries; }; } diff --git a/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h index 3058157590e..847259c5cea 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h +++ b/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h @@ -49,15 +49,14 @@ private: class DebugSubsectionRecordBuilder { public: - DebugSubsectionRecordBuilder(DebugSubsectionKind Kind, DebugSubsection &Frag, + DebugSubsectionRecordBuilder(std::unique_ptr<DebugSubsection> Subsection, CodeViewContainer Container); uint32_t calculateSerializedLength(); Error commit(BinaryStreamWriter &Writer); private: + std::unique_ptr<DebugSubsection> Subsection; CodeViewContainer Container; - DebugSubsectionKind Kind; - DebugSubsection &Frag; }; } // namespace codeview diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h index e5858d0f45e..2ff166b24e6 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -49,11 +49,8 @@ public: void setObjFileName(StringRef Name); void addSymbol(codeview::CVSymbol Symbol); - void addC13Fragment(std::unique_ptr<codeview::DebugLinesSubsection> Lines); - void addC13Fragment( - std::unique_ptr<codeview::DebugInlineeLinesSubsection> Inlinees); - void setC13FileChecksums( - std::unique_ptr<codeview::DebugChecksumsSubsection> Checksums); + void + addDebugSubsection(std::unique_ptr<codeview::DebugSubsection> Subsection); uint16_t getStreamIndex() const; StringRef getModuleName() const { return ModuleName; } @@ -83,10 +80,6 @@ private: std::vector<std::string> SourceFiles; std::vector<codeview::CVSymbol> Symbols; - std::unique_ptr<codeview::DebugChecksumsSubsection> ChecksumInfo; - std::vector<std::unique_ptr<codeview::DebugLinesSubsection>> LineInfo; - std::vector<std::unique_ptr<codeview::DebugInlineeLinesSubsection>> Inlinees; - std::vector<std::unique_ptr<codeview::DebugSubsectionRecordBuilder>> C13Builders; diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h index 822ce3ce13d..a8121978d88 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -12,6 +12,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" +#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" @@ -25,7 +26,7 @@ class PDBFile; class DbiModuleDescriptor; class ModuleDebugStreamRef { - typedef codeview::DebugSubsectionArray::Iterator LinesAndChecksumsIterator; + typedef codeview::DebugSubsectionArray::Iterator DebugSubsectionIterator; public: ModuleDebugStreamRef(const DbiModuleDescriptor &Module, @@ -39,12 +40,15 @@ public: iterator_range<codeview::CVSymbolArray::Iterator> symbols(bool *HadError) const; - llvm::iterator_range<LinesAndChecksumsIterator> linesAndChecksums() const; + llvm::iterator_range<DebugSubsectionIterator> subsections() const; - bool hasLineInfo() const; + bool hasDebugSubsections() const; Error commit(); + Expected<codeview::DebugChecksumsSubsectionRef> + findChecksumsSubsection() const; + private: const DbiModuleDescriptor &Mod; @@ -57,7 +61,7 @@ private: BinaryStreamRef C13LinesSubstream; BinaryStreamRef GlobalRefsSubstream; - codeview::DebugSubsectionArray LinesAndChecksums; + codeview::DebugSubsectionArray Subsections; }; } } diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h b/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h index 6aeb0a5479c..28a14d7356d 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h @@ -45,6 +45,8 @@ public: FixedStreamArray<support::ulittle32_t> name_ids() const; + codeview::DebugStringTableSubsectionRef getStringTable() const; + private: Error readHeader(BinaryStreamReader &Reader); Error readStrings(BinaryStreamReader &Reader); diff --git a/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h b/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h index 6ddae2e2b41..a6d4d404415 100644 --- a/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h +++ b/llvm/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h @@ -17,12 +17,20 @@ #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/ObjectYAML/YAML.h" namespace llvm { + +namespace codeview { +class DebugStringTableSubsection; +class DebugStringTableSubsectionRef; +class DebugChecksumsSubsectionRef; +} namespace CodeViewYAML { + namespace detail { -struct C13FragmentBase; +struct YAMLSubsectionBase; } struct SourceLineEntry { @@ -74,18 +82,24 @@ struct InlineeInfo { std::vector<InlineeSite> Sites; }; -struct SourceFileInfo { - std::vector<SourceFileChecksumEntry> FileChecksums; - std::vector<SourceLineInfo> LineFragments; - std::vector<InlineeInfo> Inlinees; -}; +struct YAMLDebugSubsection { + static Expected<YAMLDebugSubsection> + fromCodeViewSubection(const codeview::DebugStringTableSubsectionRef &Strings, + const codeview::DebugChecksumsSubsectionRef &Checksums, + const codeview::DebugSubsectionRecord &SS); -struct C13DebugSection { - std::vector<detail::C13FragmentBase> Fragments; + std::shared_ptr<detail::YAMLSubsectionBase> Subsection; }; + +Expected<std::vector<std::unique_ptr<codeview::DebugSubsection>>> +convertSubsectionList(ArrayRef<YAMLDebugSubsection> Subsections, + codeview::DebugStringTableSubsection &Strings); + } // namespace CodeViewYAML } // namespace llvm -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileInfo) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::YAMLDebugSubsection) + +LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::YAMLDebugSubsection) #endif diff --git a/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp index b8741eb0b67..2e72242181b 100644 --- a/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp +++ b/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp @@ -72,7 +72,7 @@ Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { uint32_t DebugStringTableSubsection::size() const { return Strings.size(); } uint32_t DebugStringTableSubsection::getStringId(StringRef S) const { - auto P = Strings.find(S); - assert(P != Strings.end()); - return P->second; + auto Iter = Strings.find(S); + assert(Iter != Strings.end()); + return Iter->second; } diff --git a/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp b/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp index 5ecfaf2f23a..cfd1c5d3ab0 100644 --- a/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp +++ b/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp @@ -60,13 +60,13 @@ DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; } BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; } DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder( - DebugSubsectionKind Kind, DebugSubsection &Frag, - CodeViewContainer Container) - : Container(Container), Kind(Kind), Frag(Frag) {} + std::unique_ptr<DebugSubsection> Subsection, CodeViewContainer Container) + : Subsection(std::move(Subsection)), Container(Container) {} uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() { - uint32_t Size = sizeof(DebugSubsectionHeader) + - alignTo(Frag.calculateSerializedSize(), alignOf(Container)); + uint32_t Size = + sizeof(DebugSubsectionHeader) + + alignTo(Subsection->calculateSerializedSize(), alignOf(Container)); return Size; } @@ -75,12 +75,12 @@ Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) { "Debug Subsection not properly aligned"); DebugSubsectionHeader Header; - Header.Kind = uint32_t(Kind); + Header.Kind = uint32_t(Subsection->kind()); Header.Length = calculateSerializedLength() - sizeof(DebugSubsectionHeader); if (auto EC = Writer.writeObject(Header)) return EC; - if (auto EC = Frag.commit(Writer)) + if (auto EC = Subsection->commit(Writer)) return EC; if (auto EC = Writer.padToAlignment(alignOf(Container))) return EC; diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp index bf3f83741ae..9aea4acb74a 100644 --- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp @@ -174,42 +174,9 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter, return Error::success(); } -void DbiModuleDescriptorBuilder::addC13Fragment( - std::unique_ptr<DebugLinesSubsection> Lines) { - DebugLinesSubsection &Frag = *Lines; - - // File Checksums have to come first, so push an empty entry on if this - // is the first. - if (C13Builders.empty()) - C13Builders.push_back(nullptr); - - this->LineInfo.push_back(std::move(Lines)); +void DbiModuleDescriptorBuilder::addDebugSubsection( + std::unique_ptr<DebugSubsection> Subsection) { + assert(Subsection); C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>( - Frag.kind(), Frag, CodeViewContainer::Pdb)); -} - -void DbiModuleDescriptorBuilder::addC13Fragment( - std::unique_ptr<codeview::DebugInlineeLinesSubsection> Inlinees) { - DebugInlineeLinesSubsection &Frag = *Inlinees; - - // File Checksums have to come first, so push an empty entry on if this - // is the first. - if (C13Builders.empty()) - C13Builders.push_back(nullptr); - - this->Inlinees.push_back(std::move(Inlinees)); - C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>( - Frag.kind(), Frag, CodeViewContainer::Pdb)); -} - -void DbiModuleDescriptorBuilder::setC13FileChecksums( - std::unique_ptr<DebugChecksumsSubsection> Checksums) { - assert(!ChecksumInfo && "Can't have more than one checksum info!"); - - if (C13Builders.empty()) - C13Builders.push_back(nullptr); - - ChecksumInfo = std::move(Checksums); - C13Builders[0] = llvm::make_unique<DebugSubsectionRecordBuilder>( - ChecksumInfo->kind(), *ChecksumInfo, CodeViewContainer::Pdb); + std::move(Subsection), CodeViewContainer::Pdb)); } diff --git a/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp index d7a203746a0..c4ff30011a1 100644 --- a/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp @@ -55,9 +55,9 @@ Error ModuleDebugStreamRef::reload() { if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size)) return EC; - BinaryStreamReader LineReader(C13LinesSubstream); - if (auto EC = - LineReader.readArray(LinesAndChecksums, LineReader.bytesRemaining())) + BinaryStreamReader SubsectionsReader(C13LinesSubstream); + if (auto EC = SubsectionsReader.readArray(Subsections, + SubsectionsReader.bytesRemaining())) return EC; uint32_t GlobalRefsSize; @@ -77,13 +77,27 @@ ModuleDebugStreamRef::symbols(bool *HadError) const { return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end()); } -llvm::iterator_range<ModuleDebugStreamRef::LinesAndChecksumsIterator> -ModuleDebugStreamRef::linesAndChecksums() const { - return make_range(LinesAndChecksums.begin(), LinesAndChecksums.end()); +llvm::iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator> +ModuleDebugStreamRef::subsections() const { + return make_range(Subsections.begin(), Subsections.end()); } -bool ModuleDebugStreamRef::hasLineInfo() const { +bool ModuleDebugStreamRef::hasDebugSubsections() const { return C13LinesSubstream.getLength() > 0; } Error ModuleDebugStreamRef::commit() { return Error::success(); } + +Expected<codeview::DebugChecksumsSubsectionRef> +ModuleDebugStreamRef::findChecksumsSubsection() const { + for (const auto &SS : subsections()) { + if (SS.kind() != DebugSubsectionKind::FileChecksums) + continue; + + codeview::DebugChecksumsSubsectionRef Result; + if (auto EC = Result.initialize(SS.getRecordData())) + return std::move(EC); + return Result; + } + return make_error<RawError>(raw_error_code::no_entry); +} diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp index e84573fe07b..6013c342cf0 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTable.cpp @@ -56,6 +56,10 @@ Error PDBStringTable::readStrings(BinaryStreamReader &Reader) { return Error::success(); } +codeview::DebugStringTableSubsectionRef PDBStringTable::getStringTable() const { + return Strings; +} + Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) { const support::ulittle32_t *HashCount; if (auto EC = Reader.readObject(HashCount)) diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp index f652ff57f30..1d62d1b2621 100644 --- a/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp +++ b/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp @@ -17,6 +17,11 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" @@ -36,16 +41,80 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false) +LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind) LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineEntry) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceColumnEntry) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileChecksumEntry) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineInfo) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineBlock) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeInfo) -LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeSite) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock) +LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite) + +namespace llvm { +namespace CodeViewYAML { +namespace detail { +struct YAMLSubsectionBase { + explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {} + DebugSubsectionKind Kind; + virtual ~YAMLSubsectionBase() {} + + virtual void map(IO &IO) = 0; + virtual std::unique_ptr<DebugSubsection> + toCodeViewSubsection(DebugStringTableSubsection *UseStrings, + DebugChecksumsSubsection *UseChecksums) const = 0; +}; +} +} +} + +namespace { +struct YAMLChecksumsSubsection : public YAMLSubsectionBase { + YAMLChecksumsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} + + void map(IO &IO) override; + std::unique_ptr<DebugSubsection> + toCodeViewSubsection(DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const override; + static Expected<std::shared_ptr<YAMLChecksumsSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &FC); + + std::vector<SourceFileChecksumEntry> Checksums; +}; + +struct YAMLLinesSubsection : public YAMLSubsectionBase { + YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} + + void map(IO &IO) override; + std::unique_ptr<DebugSubsection> + toCodeViewSubsection(DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const override; + static Expected<std::shared_ptr<YAMLLinesSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugLinesSubsectionRef &Lines); + + SourceLineInfo Lines; +}; + +struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { + YAMLInlineeLinesSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} + + void map(IO &IO) override; + std::unique_ptr<DebugSubsection> + toCodeViewSubsection(DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const override; + static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugInlineeLinesSubsectionRef &Lines); + + InlineeInfo InlineeLines; +}; +} void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) { io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); @@ -99,21 +168,6 @@ void MappingTraits<SourceFileChecksumEntry>::mapping( IO.mapRequired("Checksum", Obj.ChecksumBytes); } -void MappingTraits<SourceLineInfo>::mapping(IO &IO, SourceLineInfo &Obj) { - IO.mapRequired("CodeSize", Obj.CodeSize); - - IO.mapRequired("Flags", Obj.Flags); - IO.mapRequired("RelocOffset", Obj.RelocOffset); - IO.mapRequired("RelocSegment", Obj.RelocSegment); - IO.mapRequired("Blocks", Obj.Blocks); -} - -void MappingTraits<SourceFileInfo>::mapping(IO &IO, SourceFileInfo &Obj) { - IO.mapOptional("Checksums", Obj.FileChecksums); - IO.mapOptional("Lines", Obj.LineFragments); - IO.mapOptional("InlineeLines", Obj.Inlinees); -} - void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { IO.mapRequired("FileName", Obj.FileName); IO.mapRequired("LineNum", Obj.SourceLineNum); @@ -121,7 +175,310 @@ void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { IO.mapOptional("ExtraFiles", Obj.ExtraFiles); } -void MappingTraits<InlineeInfo>::mapping(IO &IO, InlineeInfo &Obj) { - IO.mapRequired("HasExtraFiles", Obj.HasExtraFiles); - IO.mapRequired("Sites", Obj.Sites); +void YAMLChecksumsSubsection::map(IO &IO) { + IO.mapTag("!FileChecksums", true); + IO.mapRequired("Checksums", Checksums); +} + +void YAMLLinesSubsection::map(IO &IO) { + IO.mapTag("!Lines", true); + IO.mapRequired("CodeSize", Lines.CodeSize); + + IO.mapRequired("Flags", Lines.Flags); + IO.mapRequired("RelocOffset", Lines.RelocOffset); + IO.mapRequired("RelocSegment", Lines.RelocSegment); + IO.mapRequired("Blocks", Lines.Blocks); +} + +void YAMLInlineeLinesSubsection::map(IO &IO) { + IO.mapTag("!InlineeLines", true); + IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles); + IO.mapRequired("Sites", InlineeLines.Sites); +} + +void MappingTraits<YAMLDebugSubsection>::mapping( + IO &IO, YAMLDebugSubsection &Subsection) { + if (!IO.outputting()) { + if (IO.mapTag("!FileChecksums")) { + auto SS = std::make_shared<YAMLChecksumsSubsection>(); + Subsection.Subsection = SS; + } else if (IO.mapTag("!Lines")) { + Subsection.Subsection = std::make_shared<YAMLLinesSubsection>(); + } else if (IO.mapTag("!InlineeLines")) { + Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>(); + } else { + llvm_unreachable("Unexpected subsection tag!"); + } + } + Subsection.Subsection->map(IO); +} + +static Expected<const YAMLChecksumsSubsection &> +findChecksums(ArrayRef<YAMLDebugSubsection> Subsections) { + for (const auto &SS : Subsections) { + if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) { + return static_cast<const YAMLChecksumsSubsection &>(*SS.Subsection); + } + } + return make_error<CodeViewError>(cv_error_code::no_records); +} + +std::unique_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection( + DebugStringTableSubsection *UseStrings, + DebugChecksumsSubsection *UseChecksums) const { + assert(UseStrings && !UseChecksums); + auto Result = llvm::make_unique<DebugChecksumsSubsection>(*UseStrings); + for (const auto &CS : Checksums) { + Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); + } + return std::move(Result); +} + +std::unique_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection( + DebugStringTableSubsection *UseStrings, + DebugChecksumsSubsection *UseChecksums) const { + assert(UseStrings && UseChecksums); + auto Result = + llvm::make_unique<DebugLinesSubsection>(*UseChecksums, *UseStrings); + Result->setCodeSize(Lines.CodeSize); + Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); + Result->setFlags(Lines.Flags); + for (const auto &LC : Lines.Blocks) { + Result->createBlock(LC.FileName); + if (Result->hasColumnInfo()) { + for (const auto &Item : zip(LC.Lines, LC.Columns)) { + auto &L = std::get<0>(Item); + auto &C = std::get<1>(Item); + uint32_t LE = L.LineStart + L.EndDelta; + Result->addLineAndColumnInfo(L.Offset, + LineInfo(L.LineStart, LE, L.IsStatement), + C.StartColumn, C.EndColumn); + } + } else { + for (const auto &L : LC.Lines) { + uint32_t LE = L.LineStart + L.EndDelta; + Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement)); + } + } + } + return Result; +} + +std::unique_ptr<DebugSubsection> +YAMLInlineeLinesSubsection::toCodeViewSubsection( + DebugStringTableSubsection *UseStrings, + DebugChecksumsSubsection *UseChecksums) const { + assert(UseChecksums); + auto Result = llvm::make_unique<DebugInlineeLinesSubsection>( + *UseChecksums, InlineeLines.HasExtraFiles); + + for (const auto &Site : InlineeLines.Sites) { + Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, + Site.SourceLineNum); + if (!InlineeLines.HasExtraFiles) + continue; + + for (auto EF : Site.ExtraFiles) { + Result->addExtraFile(EF); + } + } + return Result; +} + +static Expected<SourceFileChecksumEntry> +convertOneChecksum(const DebugStringTableSubsectionRef &Strings, + const FileChecksumEntry &CS) { + auto ExpectedString = Strings.getString(CS.FileNameOffset); + if (!ExpectedString) + return ExpectedString.takeError(); + + SourceFileChecksumEntry Result; + Result.ChecksumBytes.Bytes = CS.Checksum; + Result.Kind = CS.Kind; + Result.FileName = *ExpectedString; + return Result; +} + +static Expected<StringRef> +getFileName(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { + auto Iter = Checksums.getArray().at(FileID); + if (Iter == Checksums.getArray().end()) + return make_error<CodeViewError>(cv_error_code::no_records); + uint32_t Offset = Iter->FileNameOffset; + return Strings.getString(Offset); +} + +Expected<std::shared_ptr<YAMLChecksumsSubsection>> +YAMLChecksumsSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &FC) { + auto Result = std::make_shared<YAMLChecksumsSubsection>(); + + for (const auto &CS : FC) { + auto ConvertedCS = convertOneChecksum(Strings, CS); + if (!ConvertedCS) + return ConvertedCS.takeError(); + Result->Checksums.push_back(*ConvertedCS); + } + return Result; +} + +Expected<std::shared_ptr<YAMLLinesSubsection>> +YAMLLinesSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugLinesSubsectionRef &Lines) { + auto Result = std::make_shared<YAMLLinesSubsection>(); + Result->Lines.CodeSize = Lines.header()->CodeSize; + Result->Lines.RelocOffset = Lines.header()->RelocOffset; + Result->Lines.RelocSegment = Lines.header()->RelocSegment; + Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags)); + for (const auto &L : Lines) { + SourceLineBlock Block; + auto EF = getFileName(Strings, Checksums, L.NameIndex); + if (!EF) + return EF.takeError(); + Block.FileName = *EF; + if (Lines.hasColumnInfo()) { + for (const auto &C : L.Columns) { + SourceColumnEntry SCE; + SCE.EndColumn = C.EndColumn; + SCE.StartColumn = C.StartColumn; + Block.Columns.push_back(SCE); + } + } + for (const auto &LN : L.LineNumbers) { + SourceLineEntry SLE; + LineInfo LI(LN.Flags); + SLE.Offset = LN.Offset; + SLE.LineStart = LI.getStartLine(); + SLE.EndDelta = LI.getLineDelta(); + SLE.IsStatement = LI.isStatement(); + Block.Lines.push_back(SLE); + } + Result->Lines.Blocks.push_back(Block); + } + return Result; +} + +Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> +YAMLInlineeLinesSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugInlineeLinesSubsectionRef &Lines) { + auto Result = std::make_shared<YAMLInlineeLinesSubsection>(); + + Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles(); + for (const auto &IL : Lines) { + InlineeSite Site; + auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID); + if (!ExpF) + return ExpF.takeError(); + Site.FileName = *ExpF; + Site.Inlinee = IL.Header->Inlinee.getIndex(); + Site.SourceLineNum = IL.Header->SourceLineNum; + if (Lines.hasExtraFiles()) { + for (const auto EF : IL.ExtraFiles) { + auto ExpF2 = getFileName(Strings, Checksums, EF); + if (!ExpF2) + return ExpF2.takeError(); + Site.ExtraFiles.push_back(*ExpF2); + } + } + Result->InlineeLines.Sites.push_back(Site); + } + return Result; +} + +Expected<std::vector<std::unique_ptr<DebugSubsection>>> +llvm::CodeViewYAML::convertSubsectionList( + ArrayRef<YAMLDebugSubsection> Subsections, + DebugStringTableSubsection &Strings) { + std::vector<std::unique_ptr<DebugSubsection>> Result; + if (Subsections.empty()) + return Result; + + auto Checksums = findChecksums(Subsections); + if (!Checksums) + return Checksums.takeError(); + auto ChecksumsBase = Checksums->toCodeViewSubsection(&Strings, nullptr); + DebugChecksumsSubsection &CS = + llvm::cast<DebugChecksumsSubsection>(*ChecksumsBase); + for (const auto &SS : Subsections) { + // We've already converted the checksums subsection, don't do it + // twice. + std::unique_ptr<DebugSubsection> CVS; + if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) + CVS = std::move(ChecksumsBase); + else + CVS = SS.Subsection->toCodeViewSubsection(&Strings, &CS); + Result.push_back(std::move(CVS)); + } + return std::move(Result); +} + +namespace { +struct SubsectionConversionVisitor : public DebugSubsectionVisitor { + explicit SubsectionConversionVisitor( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums) + : Strings(Strings), Checksums(Checksums) {} + + Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; + Error visitLines(DebugLinesSubsectionRef &Lines) override; + Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums) override; + Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees) override; + + YAMLDebugSubsection Subsection; + +private: + const DebugStringTableSubsectionRef &Strings; + const DebugChecksumsSubsectionRef &Checksums; +}; + +Error SubsectionConversionVisitor::visitUnknown( + DebugUnknownSubsectionRef &Unknown) { + return make_error<CodeViewError>(cv_error_code::operation_unsupported); +} + +Error SubsectionConversionVisitor::visitLines(DebugLinesSubsectionRef &Lines) { + auto Result = + YAMLLinesSubsection::fromCodeViewSubsection(Strings, Checksums, Lines); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitFileChecksums( + DebugChecksumsSubsectionRef &Checksums) { + auto Result = + YAMLChecksumsSubsection::fromCodeViewSubsection(Strings, Checksums); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitInlineeLines( + DebugInlineeLinesSubsectionRef &Inlinees) { + auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( + Strings, Checksums, Inlinees); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} +} + +Expected<YAMLDebugSubsection> YAMLDebugSubsection::fromCodeViewSubection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugSubsectionRecord &SS) { + SubsectionConversionVisitor V(Strings, Checksums); + if (auto EC = visitDebugSubsection(SS, V)) + return std::move(EC); + + return V.Subsection; } diff --git a/llvm/test/DebugInfo/PDB/Inputs/simple-line-info.yaml b/llvm/test/DebugInfo/PDB/Inputs/simple-line-info.yaml index 66030020f8f..d1324d26d8b 100644 --- a/llvm/test/DebugInfo/PDB/Inputs/simple-line-info.yaml +++ b/llvm/test/DebugInfo/PDB/Inputs/simple-line-info.yaml @@ -5,39 +5,40 @@ DbiStream: ObjFile: 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj' SourceFiles: - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' - LineInfo: - Checksums: - - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' - Kind: MD5 - Checksum: A0A5BD0D3ECD93FC29D19DE826FBF4BC - - FileName: 'f:\dd\externalapis\windows\10\sdk\inc\winerror.h' - Kind: MD5 - Checksum: 1154D69F5B2650196E1FC34F4134E56B - Lines: - - CodeSize: 10 - Flags: [ ] - RelocOffset: 16 - RelocSegment: 1 - Blocks: - - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' - Lines: - - Offset: 0 - LineStart: 5 - IsStatement: true - EndDelta: 0 - - Offset: 3 - LineStart: 6 - IsStatement: true - EndDelta: 0 - - Offset: 8 - LineStart: 7 - IsStatement: true - EndDelta: 0 - Columns: - InlineeLines: - - HasExtraFiles: false - Sites: - - FileName: 'f:\dd\externalapis\windows\10\sdk\inc\winerror.h' - LineNum: 26950 - Inlinee: 22767 + Subsections: + - !FileChecksums + Checksums: + - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' + Kind: MD5 + Checksum: A0A5BD0D3ECD93FC29D19DE826FBF4BC + - FileName: 'f:\dd\externalapis\windows\10\sdk\inc\winerror.h' + Kind: MD5 + Checksum: 1154D69F5B2650196E1FC34F4134E56B + - !Lines + CodeSize: 10 + Flags: [ ] + RelocOffset: 16 + RelocSegment: 1 + Blocks: + - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' + Lines: + - Offset: 0 + LineStart: 5 + IsStatement: true + EndDelta: 0 + - Offset: 3 + LineStart: 6 + IsStatement: true + EndDelta: 0 + - Offset: 8 + LineStart: 7 + IsStatement: true + EndDelta: 0 + Columns: + - !InlineeLines + HasExtraFiles: false + Sites: + - FileName: 'f:\dd\externalapis\windows\10\sdk\inc\winerror.h' + LineNum: 26950 + Inlinee: 22767 ... diff --git a/llvm/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test b/llvm/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test index ca7427c0099..f959805c747 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test @@ -28,12 +28,8 @@ YAML: - Module: 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj' YAML: ObjFile: 'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj' YAML: SourceFiles: YAML: - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' -YAML: LineInfo: -YAML: Checksums: -YAML: - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' -YAML: Kind: MD5 -YAML: Checksum: A0A5BD0D3ECD93FC29D19DE826FBF4BC -YAML: Lines: +YAML: Subsections: +YAML: - !Lines YAML: CodeSize: 10 YAML: Flags: [ ] YAML: RelocOffset: 16 @@ -54,6 +50,11 @@ YAML: LineStart: 7 YAML: IsStatement: true YAML: EndDelta: 0 YAML: Columns: +YAML: - !FileChecksums +YAML: Checksums: +YAML: - FileName: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' +YAML: Kind: MD5 +YAML: Checksum: A0A5BD0D3ECD93FC29D19DE826FBF4BC YAML: - Module: '* Linker *' YAML: ObjFile: '' YAML: ...
\ No newline at end of file diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp index 6a9fb25dda3..7268d0b888d 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -831,8 +831,7 @@ Error LLVMOutputStyle::dumpDbiStream() { return ExpectedTypes.takeError(); auto &IpiItems = *ExpectedTypes; C13RawVisitor V(P, File, IpiItems); - if (auto EC = - codeview::visitDebugSubsections(ModS.linesAndChecksums(), V)) + if (auto EC = codeview::visitDebugSubsections(ModS.subsections(), V)) return EC; } } diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.cpp b/llvm/tools/llvm-pdbdump/PdbYaml.cpp index e288063e2af..b4a41fbfdb8 100644 --- a/llvm/tools/llvm-pdbdump/PdbYaml.cpp +++ b/llvm/tools/llvm-pdbdump/PdbYaml.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" #include "llvm/DebugInfo/CodeView/TypeSerializer.h" @@ -21,6 +22,7 @@ #include "llvm/DebugInfo/PDB/Native/TpiHashing.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" #include "llvm/ObjectYAML/CodeViewYAMLTypes.h" using namespace llvm; @@ -220,6 +222,6 @@ void MappingTraits<PdbDbiModuleInfo>::mapping(IO &IO, PdbDbiModuleInfo &Obj) { IO.mapRequired("Module", Obj.Mod); IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod); IO.mapOptional("SourceFiles", Obj.SourceFiles); - IO.mapOptional("LineInfo", Obj.FileLineInfo); + IO.mapOptional("Subsections", Obj.Subsections); IO.mapOptional("Modi", Obj.Modi); } diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.h b/llvm/tools/llvm-pdbdump/PdbYaml.h index deb500ec207..62ed608916f 100644 --- a/llvm/tools/llvm-pdbdump/PdbYaml.h +++ b/llvm/tools/llvm-pdbdump/PdbYaml.h @@ -28,6 +28,9 @@ #include <vector> namespace llvm { +namespace codeview { +class DebugStringTableSubsection; +} namespace pdb { namespace yaml { @@ -68,7 +71,7 @@ struct PdbDbiModuleInfo { StringRef Obj; StringRef Mod; std::vector<StringRef> SourceFiles; - Optional<CodeViewYAML::SourceFileInfo> FileLineInfo; + std::vector<CodeViewYAML::YAMLDebugSubsection> Subsections; Optional<PdbModiStream> Modi; }; diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp index 18839a7679d..610b288c9ba 100644 --- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -101,117 +101,6 @@ Error YAMLOutputStyle::dump() { return Error::success(); } -namespace { -class C13YamlVisitor : public C13DebugFragmentVisitor { -public: - C13YamlVisitor(CodeViewYAML::SourceFileInfo &Info, PDBFile &F) - : C13DebugFragmentVisitor(F), Info(Info) {} - - Error handleFileChecksums() override { - for (const auto &C : *Checksums) { - CodeViewYAML::SourceFileChecksumEntry Entry; - if (auto Result = getNameFromStringTable(C.FileNameOffset)) - Entry.FileName = *Result; - else - return Result.takeError(); - - Entry.Kind = C.Kind; - Entry.ChecksumBytes.Bytes = C.Checksum; - Info.FileChecksums.push_back(Entry); - } - return Error::success(); - } - - Error handleLines() override { - for (const auto &LF : Lines) { - Info.LineFragments.emplace_back(); - auto &Fragment = Info.LineFragments.back(); - - Fragment.CodeSize = LF.header()->CodeSize; - Fragment.Flags = - static_cast<codeview::LineFlags>(uint16_t(LF.header()->Flags)); - Fragment.RelocOffset = LF.header()->RelocOffset; - Fragment.RelocSegment = LF.header()->RelocSegment; - - for (const auto &L : LF) { - Fragment.Blocks.emplace_back(); - auto &Block = Fragment.Blocks.back(); - - if (auto Result = getNameFromChecksumsBuffer(L.NameIndex)) - Block.FileName = *Result; - else - return Result.takeError(); - - for (const auto &N : L.LineNumbers) { - CodeViewYAML::SourceLineEntry Line; - Line.Offset = N.Offset; - codeview::LineInfo LI(N.Flags); - Line.LineStart = LI.getStartLine(); - Line.EndDelta = LI.getLineDelta(); - Line.IsStatement = LI.isStatement(); - Block.Lines.push_back(Line); - } - - if (LF.hasColumnInfo()) { - for (const auto &C : L.Columns) { - CodeViewYAML::SourceColumnEntry Column; - Column.StartColumn = C.StartColumn; - Column.EndColumn = C.EndColumn; - Block.Columns.push_back(Column); - } - } - } - } - return Error::success(); - } - - Error handleInlineeLines() override { - for (const auto &ILF : InlineeLines) { - Info.Inlinees.emplace_back(); - auto &Inlinee = Info.Inlinees.back(); - - Inlinee.HasExtraFiles = ILF.hasExtraFiles(); - for (const auto &IL : ILF) { - Inlinee.Sites.emplace_back(); - auto &Site = Inlinee.Sites.back(); - if (auto Result = getNameFromChecksumsBuffer(IL.Header->FileID)) - Site.FileName = *Result; - else - return Result.takeError(); - - Site.Inlinee = IL.Header->Inlinee.getIndex(); - Site.SourceLineNum = IL.Header->SourceLineNum; - if (ILF.hasExtraFiles()) { - for (const auto &EF : IL.ExtraFiles) { - if (auto Result = getNameFromChecksumsBuffer(EF)) - Site.ExtraFiles.push_back(*Result); - else - return Result.takeError(); - } - } - } - } - return Error::success(); - } - -private: - CodeViewYAML::SourceFileInfo &Info; -}; -} - -Expected<Optional<CodeViewYAML::SourceFileInfo>> -YAMLOutputStyle::getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS) { - if (!ModS.hasLineInfo()) - return None; - - CodeViewYAML::SourceFileInfo Info; - C13YamlVisitor Visitor(Info, File); - if (auto EC = - codeview::visitDebugSubsections(ModS.linesAndChecksums(), Visitor)) - return std::move(EC); - - return Info; -} Error YAMLOutputStyle::dumpFileHeaders() { if (opts::pdb2yaml::NoFileHeaders) @@ -236,14 +125,17 @@ Error YAMLOutputStyle::dumpFileHeaders() { } Error YAMLOutputStyle::dumpStringTable() { - if (!opts::pdb2yaml::StringTable) + bool RequiresStringTable = opts::pdb2yaml::DbiModuleSourceFileInfo || + opts::pdb2yaml::DbiModuleSourceLineInfo; + bool RequestedStringTable = opts::pdb2yaml::StringTable; + if (!RequiresStringTable && !RequestedStringTable) return Error::success(); - Obj.StringTable.emplace(); auto ExpectedST = File.getStringTable(); if (!ExpectedST) return ExpectedST.takeError(); + Obj.StringTable.emplace(); const auto &ST = ExpectedST.get(); for (auto ID : ST.name_ids()) { auto S = ST.getStringForID(ID); @@ -343,11 +235,23 @@ Error YAMLOutputStyle::dumpDbiStream() { if (auto EC = ModS.reload()) return EC; - if (opts::pdb2yaml::DbiModuleSourceLineInfo) { - auto ExpectedInfo = getFileLineInfo(ModS); - if (!ExpectedInfo) - return ExpectedInfo.takeError(); - DMI.FileLineInfo = *ExpectedInfo; + auto ExpectedST = File.getStringTable(); + if (!ExpectedST) + return ExpectedST.takeError(); + if (opts::pdb2yaml::DbiModuleSourceLineInfo && + ModS.hasDebugSubsections()) { + auto ExpectedChecksums = ModS.findChecksumsSubsection(); + if (!ExpectedChecksums) + return ExpectedChecksums.takeError(); + + for (const auto &SS : ModS.subsections()) { + auto Converted = + CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection( + ExpectedST->getStringTable(), *ExpectedChecksums, SS); + if (!Converted) + return Converted.takeError(); + DMI.Subsections.push_back(*Converted); + } } if (opts::pdb2yaml::DbiModuleSyms) { diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h index 6e4067c48f8..3690e3529d4 100644 --- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h +++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -27,9 +27,6 @@ public: Error dump() override; private: - Expected<Optional<CodeViewYAML::SourceFileInfo>> - getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS); - Error dumpStringTable(); Error dumpFileHeaders(); Error dumpStreamMetadata(); diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index 7534790254d..4626de9c444 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -476,7 +476,6 @@ static void yamlToPdb(StringRef Path) { std::unique_ptr<MemoryBuffer> &Buffer = ErrorOrBuffer.get(); llvm::yaml::Input In(Buffer->getBuffer()); - In.setContext(&Allocator); pdb::yaml::PdbObject YamlObj(Allocator); In >> YamlObj; @@ -540,64 +539,11 @@ static void yamlToPdb(StringRef Path) { Symbol.toCodeViewSymbol(Allocator, CodeViewContainer::Pdb)); } } - if (MI.FileLineInfo.hasValue()) { - const auto &FLI = *MI.FileLineInfo; - - // File Checksums must be emitted before line information, because line - // info records use offsets into the checksum buffer to reference a file's - // source file name. - auto Checksums = llvm::make_unique<DebugChecksumsSubsection>(Strings); - auto &ChecksumRef = *Checksums; - if (!FLI.FileChecksums.empty()) { - for (auto &FC : FLI.FileChecksums) - Checksums->addChecksum(FC.FileName, FC.Kind, FC.ChecksumBytes.Bytes); - } - ModiBuilder.setC13FileChecksums(std::move(Checksums)); - - for (const auto &Fragment : FLI.LineFragments) { - auto Lines = - llvm::make_unique<DebugLinesSubsection>(ChecksumRef, Strings); - Lines->setCodeSize(Fragment.CodeSize); - Lines->setRelocationAddress(Fragment.RelocSegment, - Fragment.RelocOffset); - Lines->setFlags(Fragment.Flags); - for (const auto &LC : Fragment.Blocks) { - Lines->createBlock(LC.FileName); - if (Lines->hasColumnInfo()) { - for (const auto &Item : zip(LC.Lines, LC.Columns)) { - auto &L = std::get<0>(Item); - auto &C = std::get<1>(Item); - uint32_t LE = L.LineStart + L.EndDelta; - Lines->addLineAndColumnInfo( - L.Offset, LineInfo(L.LineStart, LE, L.IsStatement), - C.StartColumn, C.EndColumn); - } - } else { - for (const auto &L : LC.Lines) { - uint32_t LE = L.LineStart + L.EndDelta; - Lines->addLineInfo(L.Offset, - LineInfo(L.LineStart, LE, L.IsStatement)); - } - } - } - ModiBuilder.addC13Fragment(std::move(Lines)); - } - for (const auto &Inlinee : FLI.Inlinees) { - auto Inlinees = llvm::make_unique<DebugInlineeLinesSubsection>( - ChecksumRef, Inlinee.HasExtraFiles); - for (const auto &Site : Inlinee.Sites) { - Inlinees->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, - Site.SourceLineNum); - if (!Inlinee.HasExtraFiles) - continue; - - for (auto EF : Site.ExtraFiles) { - Inlinees->addExtraFile(EF); - } - } - ModiBuilder.addC13Fragment(std::move(Inlinees)); - } + auto CodeViewSubsections = + ExitOnErr(CodeViewYAML::convertSubsectionList(MI.Subsections, Strings)); + for (auto &SS : CodeViewSubsections) { + ModiBuilder.addDebugSubsection(std::move(SS)); } } |