diff options
Diffstat (limited to 'lib/ObjectYAML/CodeViewYAMLSymbols.cpp')
-rw-r--r-- | lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 64 |
1 files changed, 58 insertions, 6 deletions
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<ThunkOrdinal>::enumeration(IO &io, } } +void ScalarEnumerationTraits<FrameCookieKind>::enumeration( + IO &io, FrameCookieKind &FC) { + auto ThunkNames = getFrameCookieKindNames(); + for (const auto &E : ThunkNames) { + io.enumCase(FC, E.Name.str().c_str(), + static_cast<FrameCookieKind>(E.Value)); + } +} + namespace llvm { namespace CodeViewYAML { namespace detail { @@ -183,8 +193,47 @@ template <typename T> 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<uint8_t>(TotalLen); + ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); + ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); + return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen)); + } + Error fromCodeViewSymbol(CVSymbol CVS) override { + this->Kind = CVS.kind(); + Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); + return Error::success(); + } + + std::vector<uint8_t> Data; +}; + template <> void SymbolRecordImpl<ScopeEndSym>::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<Thunk32Sym>::map(IO &IO) { IO.mapRequired("Parent", Symbol.Parent); IO.mapRequired("End", Symbol.End); @@ -461,7 +510,7 @@ static inline Expected<CodeViewYAML::SymbolRecord> fromCodeViewSymbolImpl(CVSymbol Symbol) { CodeViewYAML::SymbolRecord Result; - auto Impl = std::make_shared<SymbolRecordImpl<SymbolType>>(Symbol.kind()); + auto Impl = std::make_shared<SymbolType>(Symbol.kind()); if (auto EC = Impl->fromCodeViewSymbol(Symbol)) return std::move(EC); Result.Symbol = Impl; @@ -472,12 +521,13 @@ Expected<CodeViewYAML::SymbolRecord> CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ case EnumName: \ - return fromCodeViewSymbolImpl<ClassName>(Symbol); + return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(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<UnknownSymbolRecord>(Symbol); } return make_error<CodeViewError>(cv_error_code::corrupt_record); } @@ -486,7 +536,7 @@ template <typename ConcreteType> static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, CodeViewYAML::SymbolRecord &Obj) { if (!IO.outputting()) - Obj.Symbol = std::make_shared<SymbolRecordImpl<ConcreteType>>(Kind); + Obj.Symbol = std::make_shared<ConcreteType>(Kind); IO.mapRequired(Class, *Obj.Symbol); } @@ -500,12 +550,14 @@ void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ case EnumName: \ - mapSymbolRecordImpl<ClassName>(IO, #ClassName, Kind, Obj); \ + mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(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<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); } } |