From 7c7aba6e5fef47a01a136be655b0a92cfd7090f6 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 16 Jun 2017 21:03:24 +0000 Subject: Vendor import of llvm trunk r305575: https://llvm.org/svn/llvm-project/llvm/trunk@305575 --- lib/ObjectYAML/COFFYAML.cpp | 11 +- lib/ObjectYAML/CodeViewYAMLDebugSections.cpp | 338 +++++++++++++-------------- lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 64 ++++- lib/ObjectYAML/CodeViewYAMLTypes.cpp | 40 ++++ lib/ObjectYAML/ELFYAML.cpp | 1 + 5 files changed, 269 insertions(+), 185 deletions(-) (limited to 'lib/ObjectYAML') diff --git a/lib/ObjectYAML/COFFYAML.cpp b/lib/ObjectYAML/COFFYAML.cpp index 7f9f4c1f8c2c..c8cbea1490f6 100644 --- a/lib/ObjectYAML/COFFYAML.cpp +++ b/lib/ObjectYAML/COFFYAML.cpp @@ -488,7 +488,16 @@ void MappingTraits::mapping(IO &IO, COFFYAML::Section &Sec) { IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U); IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U); IO.mapOptional("Alignment", Sec.Alignment, 0U); - IO.mapRequired("SectionData", Sec.SectionData); + + // If this is a .debug$S or .debug$T section parse the semantic representation + // of the symbols/types. If it is any other kind of section, just deal in raw + // bytes. + IO.mapOptional("SectionData", Sec.SectionData); + if (Sec.Name == ".debug$S") + IO.mapOptional("Subsections", Sec.DebugS); + else if (Sec.Name == ".debug$T") + IO.mapOptional("Types", Sec.DebugT); + IO.mapOptional("Relocations", Sec.Relocations); } diff --git a/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp index 08a4bb715fac..d194420d5ef4 100644 --- a/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp +++ b/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp @@ -28,6 +28,7 @@ #include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h" #include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" @@ -75,10 +76,9 @@ struct YAMLSubsectionBase { virtual ~YAMLSubsectionBase() {} virtual void map(IO &IO) = 0; - virtual std::unique_ptr + virtual std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *UseStrings, - DebugChecksumsSubsection *UseChecksums) const = 0; + const codeview::StringsAndChecksums &SC) const = 0; }; } } @@ -90,10 +90,9 @@ struct YAMLChecksumsSubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &FC); @@ -105,10 +104,9 @@ struct YAMLLinesSubsection : public YAMLSubsectionBase { YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, @@ -122,10 +120,9 @@ struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, @@ -139,10 +136,9 @@ struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports); @@ -154,10 +150,9 @@ struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, const DebugCrossModuleImportsSubsectionRef &Imports); @@ -169,10 +164,9 @@ struct YAMLSymbolsSubsection : public YAMLSubsectionBase { YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols); @@ -184,10 +178,9 @@ struct YAMLStringTableSubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings); @@ -199,10 +192,9 @@ struct YAMLFrameDataSubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, const DebugFrameDataSubsectionRef &Frames); @@ -215,10 +207,9 @@ struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase { : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {} void map(IO &IO) override; - std::unique_ptr + std::shared_ptr toCodeViewSubsection(BumpPtrAllocator &Allocator, - DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const override; + const codeview::StringsAndChecksums &SC) const override; static Expected> fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs); @@ -389,34 +380,23 @@ void MappingTraits::mapping( Subsection.Subsection->map(IO); } -static std::shared_ptr -findChecksums(ArrayRef Subsections) { - for (const auto &SS : Subsections) { - if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) { - return std::static_pointer_cast(SS.Subsection); - } - } - - return nullptr; -} - -std::unique_ptr YAMLChecksumsSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings, - DebugChecksumsSubsection *UseChecksums) const { - assert(UseStrings && !UseChecksums); - auto Result = llvm::make_unique(*UseStrings); +std::shared_ptr YAMLChecksumsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + auto Result = std::make_shared(*SC.strings()); for (const auto &CS : Checksums) { Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); } - return std::move(Result); + return Result; } -std::unique_ptr YAMLLinesSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings, - DebugChecksumsSubsection *UseChecksums) const { - assert(UseStrings && UseChecksums); +std::shared_ptr YAMLLinesSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings() && SC.hasChecksums()); auto Result = - llvm::make_unique(*UseChecksums, *UseStrings); + std::make_shared(*SC.checksums(), *SC.strings()); Result->setCodeSize(Lines.CodeSize); Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); Result->setFlags(Lines.Flags); @@ -438,16 +418,16 @@ std::unique_ptr YAMLLinesSubsection::toCodeViewSubsection( } } } - return llvm::cast(std::move(Result)); + return Result; } -std::unique_ptr +std::shared_ptr YAMLInlineeLinesSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings, - DebugChecksumsSubsection *UseChecksums) const { - assert(UseChecksums); - auto Result = llvm::make_unique( - *UseChecksums, InlineeLines.HasExtraFiles); + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasChecksums()); + auto Result = std::make_shared( + *SC.checksums(), InlineeLines.HasExtraFiles); for (const auto &Site : InlineeLines.Sites) { Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, @@ -459,56 +439,60 @@ YAMLInlineeLinesSubsection::toCodeViewSubsection( Result->addExtraFile(EF); } } - return llvm::cast(std::move(Result)); + return Result; } -std::unique_ptr +std::shared_ptr YAMLCrossModuleExportsSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const { - auto Result = llvm::make_unique(); + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared(); for (const auto &M : Exports) Result->addMapping(M.Local, M.Global); - return llvm::cast(std::move(Result)); + return Result; } -std::unique_ptr +std::shared_ptr YAMLCrossModuleImportsSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const { - auto Result = llvm::make_unique(*Strings); + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + + auto Result = + std::make_shared(*SC.strings()); for (const auto &M : Imports) { for (const auto Id : M.ImportIds) Result->addImport(M.ModuleName, Id); } - return llvm::cast(std::move(Result)); + return Result; } -std::unique_ptr YAMLSymbolsSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const { - auto Result = llvm::make_unique(); +std::shared_ptr YAMLSymbolsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared(); for (const auto &Sym : Symbols) Result->addSymbol( Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile)); - return std::move(Result); + return Result; } -std::unique_ptr +std::shared_ptr YAMLStringTableSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const { - auto Result = llvm::make_unique(); + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared(); for (const auto &Str : this->Strings) Result->insert(Str); - return std::move(Result); + return Result; } -std::unique_ptr YAMLFrameDataSubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const { - assert(Strings); - auto Result = llvm::make_unique(); +std::shared_ptr YAMLFrameDataSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + + auto Result = std::make_shared(); for (const auto &YF : Frames) { codeview::FrameData F; F.CodeSize = YF.CodeSize; @@ -519,20 +503,20 @@ std::unique_ptr YAMLFrameDataSubsection::toCodeViewSubsection( F.PrologSize = YF.PrologSize; F.RvaStart = YF.RvaStart; F.SavedRegsSize = YF.SavedRegsSize; - F.FrameFunc = Strings->insert(YF.FrameFunc); + F.FrameFunc = SC.strings()->insert(YF.FrameFunc); Result->addFrameData(F); } - return std::move(Result); + return Result; } -std::unique_ptr +std::shared_ptr YAMLCoffSymbolRVASubsection::toCodeViewSubsection( - BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, - DebugChecksumsSubsection *Checksums) const { - auto Result = llvm::make_unique(); + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared(); for (const auto &RVA : RVAs) Result->addRVA(RVA); - return std::move(Result); + return Result; } static Expected @@ -741,63 +725,17 @@ YAMLCoffSymbolRVASubsection::fromCodeViewSubsection( return Result; } -Expected>> +Expected>> llvm::CodeViewYAML::toCodeViewSubsectionList( BumpPtrAllocator &Allocator, ArrayRef Subsections, - DebugStringTableSubsection &Strings) { - std::vector> Result; + const codeview::StringsAndChecksums &SC) { + std::vector> Result; if (Subsections.empty()) return std::move(Result); - auto Checksums = findChecksums(Subsections); - std::unique_ptr ChecksumsBase; - if (Checksums) - ChecksumsBase = - Checksums->toCodeViewSubsection(Allocator, &Strings, nullptr); - DebugChecksumsSubsection *CS = - static_cast(ChecksumsBase.get()); for (const auto &SS : Subsections) { - // We've already converted the checksums subsection, don't do it - // twice. - std::unique_ptr CVS; - if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) - CVS = std::move(ChecksumsBase); - else - CVS = SS.Subsection->toCodeViewSubsection(Allocator, &Strings, CS); - assert(CVS != nullptr); - Result.push_back(std::move(CVS)); - } - return std::move(Result); -} - -Expected>> -llvm::CodeViewYAML::toCodeViewSubsectionList( - BumpPtrAllocator &Allocator, ArrayRef Subsections, - std::unique_ptr &TakeStrings, - DebugStringTableSubsection *StringsRef) { - std::vector> Result; - if (Subsections.empty()) - return std::move(Result); - - auto Checksums = findChecksums(Subsections); - - std::unique_ptr ChecksumsBase; - if (Checksums) - ChecksumsBase = - Checksums->toCodeViewSubsection(Allocator, StringsRef, nullptr); - DebugChecksumsSubsection *CS = - static_cast(ChecksumsBase.get()); - for (const auto &SS : Subsections) { - // We've already converted the checksums and string table subsection, don't - // do it twice. - std::unique_ptr CVS; - if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) - CVS = std::move(ChecksumsBase); - else if (SS.Subsection->Kind == DebugSubsectionKind::StringTable) { - assert(TakeStrings && "No string table!"); - CVS = std::move(TakeStrings); - } else - CVS = SS.Subsection->toCodeViewSubsection(Allocator, StringsRef, CS); + std::shared_ptr CVS; + CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC); assert(CVS != nullptr); Result.push_back(std::move(CVS)); } @@ -810,23 +748,23 @@ struct SubsectionConversionVisitor : public DebugSubsectionVisitor { Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; Error visitLines(DebugLinesSubsectionRef &Lines, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitStringTable(DebugStringTableSubsectionRef &ST, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitSymbols(DebugSymbolsSubsectionRef &Symbols, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitFrameData(DebugFrameDataSubsectionRef &Symbols, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols, - const DebugSubsectionState &State) override; + const StringsAndChecksumsRef &State) override; YAMLDebugSubsection Subsection; }; @@ -837,7 +775,7 @@ Error SubsectionConversionVisitor::visitUnknown( } Error SubsectionConversionVisitor::visitLines( - DebugLinesSubsectionRef &Lines, const DebugSubsectionState &State) { + DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) { auto Result = YAMLLinesSubsection::fromCodeViewSubsection( State.strings(), State.checksums(), Lines); if (!Result) @@ -847,7 +785,8 @@ Error SubsectionConversionVisitor::visitLines( } Error SubsectionConversionVisitor::visitFileChecksums( - DebugChecksumsSubsectionRef &Checksums, const DebugSubsectionState &State) { + DebugChecksumsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) { auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(), Checksums); if (!Result) @@ -858,7 +797,7 @@ Error SubsectionConversionVisitor::visitFileChecksums( Error SubsectionConversionVisitor::visitInlineeLines( DebugInlineeLinesSubsectionRef &Inlinees, - const DebugSubsectionState &State) { + const StringsAndChecksumsRef &State) { auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( State.strings(), State.checksums(), Inlinees); if (!Result) @@ -869,7 +808,7 @@ Error SubsectionConversionVisitor::visitInlineeLines( Error SubsectionConversionVisitor::visitCrossModuleExports( DebugCrossModuleExportsSubsectionRef &Exports, - const DebugSubsectionState &State) { + const StringsAndChecksumsRef &State) { auto Result = YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports); if (!Result) @@ -880,7 +819,7 @@ Error SubsectionConversionVisitor::visitCrossModuleExports( Error SubsectionConversionVisitor::visitCrossModuleImports( DebugCrossModuleImportsSubsectionRef &Imports, - const DebugSubsectionState &State) { + const StringsAndChecksumsRef &State) { auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( State.strings(), Imports); if (!Result) @@ -890,7 +829,8 @@ Error SubsectionConversionVisitor::visitCrossModuleImports( } Error SubsectionConversionVisitor::visitStringTable( - DebugStringTableSubsectionRef &Strings, const DebugSubsectionState &State) { + DebugStringTableSubsectionRef &Strings, + const StringsAndChecksumsRef &State) { auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings); if (!Result) return Result.takeError(); @@ -899,7 +839,7 @@ Error SubsectionConversionVisitor::visitStringTable( } Error SubsectionConversionVisitor::visitSymbols( - DebugSymbolsSubsectionRef &Symbols, const DebugSubsectionState &State) { + DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) { auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols); if (!Result) return Result.takeError(); @@ -908,7 +848,7 @@ Error SubsectionConversionVisitor::visitSymbols( } Error SubsectionConversionVisitor::visitFrameData( - DebugFrameDataSubsectionRef &Frames, const DebugSubsectionState &State) { + DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) { auto Result = YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames); if (!Result) @@ -918,7 +858,7 @@ Error SubsectionConversionVisitor::visitFrameData( } Error SubsectionConversionVisitor::visitCOFFSymbolRVAs( - DebugSymbolRVASubsectionRef &RVAs, const DebugSubsectionState &State) { + DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) { auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs); if (!Result) return Result.takeError(); @@ -927,29 +867,71 @@ Error SubsectionConversionVisitor::visitCOFFSymbolRVAs( } } -Expected YAMLDebugSubsection::fromCodeViewSubection( - const DebugStringTableSubsectionRef &Strings, - const DebugChecksumsSubsectionRef &Checksums, - const DebugSubsectionRecord &SS) { - DebugSubsectionState State(Strings, Checksums); +Expected +YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC, + const DebugSubsectionRecord &SS) { SubsectionConversionVisitor V; - if (auto EC = visitDebugSubsection(SS, V, State)) + if (auto EC = visitDebugSubsection(SS, V, SC)) return std::move(EC); return V.Subsection; } -std::unique_ptr -llvm::CodeViewYAML::findStringTable(ArrayRef Sections) { - for (const auto &SS : Sections) { - if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) - continue; +std::vector +llvm::CodeViewYAML::fromDebugS(ArrayRef Data, + const StringsAndChecksumsRef &SC) { + BinaryStreamReader Reader(Data, support::little); + uint32_t Magic; + + ExitOnError Err("Invalid .debug$S section!"); + Err(Reader.readInteger(Magic)); + assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!"); + + DebugSubsectionArray Subsections; + Err(Reader.readArray(Subsections, Reader.bytesRemaining())); + + std::vector Result; - // String Table doesn't use the allocator. - BumpPtrAllocator Allocator; - auto Result = - SS.Subsection->toCodeViewSubsection(Allocator, nullptr, nullptr); - return llvm::cast(std::move(Result)); + for (const auto &SS : Subsections) { + auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS)); + Result.push_back(YamlSS); + } + return Result; +} + +void llvm::CodeViewYAML::initializeStringsAndChecksums( + ArrayRef Sections, codeview::StringsAndChecksums &SC) { + // String Table and Checksums subsections don't use the allocator. + BumpPtrAllocator Allocator; + + // It's possible for checksums and strings to even appear in different debug$S + // sections, so we have to make this a stateful function that can build up + // the strings and checksums field over multiple iterations. + + // File Checksums require the string table, but may become before it, so we + // have to scan for strings first, then scan for checksums again from the + // beginning. + if (!SC.hasStrings()) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) + continue; + + auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); + SC.setStrings( + std::static_pointer_cast(Result)); + break; + } + } + + if (SC.hasStrings() && !SC.hasChecksums()) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums) + continue; + + auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); + SC.setChecksums( + std::static_pointer_cast(Result)); + break; + } } - return nullptr; } diff --git a/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/lib/ObjectYAML/CodeViewYAMLSymbols.cpp index fa3f1e0b60aa..ba3a2abe2097 100644 --- a/lib/ObjectYAML/CodeViewYAMLSymbols.cpp +++ b/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -35,6 +35,7 @@ LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind) LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) @@ -149,6 +150,15 @@ void ScalarEnumerationTraits::enumeration(IO &io, } } +void ScalarEnumerationTraits::enumeration( + IO &io, FrameCookieKind &FC) { + auto ThunkNames = getFrameCookieKindNames(); + for (const auto &E : ThunkNames) { + io.enumCase(FC, E.Name.str().c_str(), + static_cast(E.Value)); + } +} + namespace llvm { namespace CodeViewYAML { namespace detail { @@ -183,8 +193,47 @@ template struct SymbolRecordImpl : public SymbolRecordBase { mutable T Symbol; }; +struct UnknownSymbolRecord : public SymbolRecordBase { + explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} + + void map(yaml::IO &io) override; + + CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const override { + RecordPrefix Prefix; + uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); + Prefix.RecordKind = Kind; + Prefix.RecordLen = TotalLen - 2; + uint8_t *Buffer = Allocator.Allocate(TotalLen); + ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); + ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); + return CVSymbol(Kind, ArrayRef(Buffer, TotalLen)); + } + Error fromCodeViewSymbol(CVSymbol CVS) override { + this->Kind = CVS.kind(); + Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); + return Error::success(); + } + + std::vector Data; +}; + template <> void SymbolRecordImpl::map(IO &IO) {} +void UnknownSymbolRecord::map(yaml::IO &io) { + yaml::BinaryRef Binary; + if (io.outputting()) + Binary = yaml::BinaryRef(Data); + io.mapRequired("Data", Binary); + if (!io.outputting()) { + std::string Str; + raw_string_ostream OS(Str); + Binary.writeAsBinary(OS); + OS.flush(); + Data.assign(Str.begin(), Str.end()); + } +} + template <> void SymbolRecordImpl::map(IO &IO) { IO.mapRequired("Parent", Symbol.Parent); IO.mapRequired("End", Symbol.End); @@ -461,7 +510,7 @@ static inline Expected fromCodeViewSymbolImpl(CVSymbol Symbol) { CodeViewYAML::SymbolRecord Result; - auto Impl = std::make_shared>(Symbol.kind()); + auto Impl = std::make_shared(Symbol.kind()); if (auto EC = Impl->fromCodeViewSymbol(Symbol)) return std::move(EC); Result.Symbol = Impl; @@ -472,12 +521,13 @@ Expected CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ case EnumName: \ - return fromCodeViewSymbolImpl(Symbol); + return fromCodeViewSymbolImpl>(Symbol); #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ SYMBOL_RECORD(EnumName, EnumVal, ClassName) switch (Symbol.kind()) { #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" - default: { llvm_unreachable("Unknown symbol kind!"); } + default: + return fromCodeViewSymbolImpl(Symbol); } return make_error(cv_error_code::corrupt_record); } @@ -486,7 +536,7 @@ template static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, CodeViewYAML::SymbolRecord &Obj) { if (!IO.outputting()) - Obj.Symbol = std::make_shared>(Kind); + Obj.Symbol = std::make_shared(Kind); IO.mapRequired(Class, *Obj.Symbol); } @@ -500,12 +550,14 @@ void MappingTraits::mapping( #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ case EnumName: \ - mapSymbolRecordImpl(IO, #ClassName, Kind, Obj); \ + mapSymbolRecordImpl>(IO, #ClassName, Kind, \ + Obj); \ break; #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ SYMBOL_RECORD(EnumName, EnumVal, ClassName) switch (Kind) { #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" - default: { llvm_unreachable("Unknown symbol kind!"); } + default: + mapSymbolRecordImpl(IO, "UnknownSym", Kind, Obj); } } diff --git a/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/lib/ObjectYAML/CodeViewYAMLTypes.cpp index 1302b0713d0e..a03b9cd50faa 100644 --- a/lib/ObjectYAML/CodeViewYAMLTypes.cpp +++ b/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -714,3 +714,43 @@ void MappingTraits::mapping(IO &IO, MemberRecord &Obj) { default: { llvm_unreachable("Unknown member kind!"); } } } + +std::vector +llvm::CodeViewYAML::fromDebugT(ArrayRef DebugT) { + ExitOnError Err("Invalid .debug$T section!"); + BinaryStreamReader Reader(DebugT, support::little); + CVTypeArray Types; + uint32_t Magic; + + Err(Reader.readInteger(Magic)); + assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$T section!"); + + std::vector Result; + Err(Reader.readArray(Types, Reader.bytesRemaining())); + for (const auto &T : Types) { + auto CVT = Err(LeafRecord::fromCodeViewRecord(T)); + Result.push_back(CVT); + } + return Result; +} + +ArrayRef llvm::CodeViewYAML::toDebugT(ArrayRef Leafs, + BumpPtrAllocator &Alloc) { + TypeTableBuilder TTB(Alloc, false); + uint32_t Size = sizeof(uint32_t); + for (const auto &Leaf : Leafs) { + CVType T = Leaf.toCodeViewRecord(TTB); + Size += T.length(); + assert(T.length() % 4 == 0 && "Improper type record alignment!"); + } + uint8_t *ResultBuffer = Alloc.Allocate(Size); + MutableArrayRef Output(ResultBuffer, Size); + BinaryStreamWriter Writer(Output, support::little); + ExitOnError Err("Error writing type record to .debug$T section"); + Err(Writer.writeInteger(COFF::DEBUG_SECTION_MAGIC)); + for (const auto &R : TTB.records()) { + Err(Writer.writeBytes(R)); + } + assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!"); + return Output; +} diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp index 70e25ea504a0..dbd5498e003d 100644 --- a/lib/ObjectYAML/ELFYAML.cpp +++ b/lib/ObjectYAML/ELFYAML.cpp @@ -372,6 +372,7 @@ void ScalarEnumerationTraits::enumeration( ECase(SHT_GROUP); ECase(SHT_SYMTAB_SHNDX); ECase(SHT_LOOS); + ECase(SHT_LLVM_ODRTAB); ECase(SHT_GNU_ATTRIBUTES); ECase(SHT_GNU_HASH); ECase(SHT_GNU_verdef); -- cgit v1.3