From ab44768b23cf653c93a1578d9685fb16d0d29cff Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Mon, 12 Jun 2017 23:10:31 +0000 Subject: [PATCH] [pdb] Don't choke on unknown symbol types. When we get an unknown symbol type, we might as well at least dump it. Same goes for round-tripping through YAML, we can dump the record contents as raw bytes even if we don't know how to interpret it semantically. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305248 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 54 ++++++++++++++++--- test/DebugInfo/PDB/Inputs/unknown-symbol.yaml | 10 ++++ test/DebugInfo/PDB/pdb-unknown-symbol.test | 6 +++ 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 test/DebugInfo/PDB/Inputs/unknown-symbol.yaml create mode 100644 test/DebugInfo/PDB/pdb-unknown-symbol.test diff --git a/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/lib/ObjectYAML/CodeViewYAMLSymbols.cpp index fa3f1e0b60a..21e0229a7f8 100644 --- a/lib/ObjectYAML/CodeViewYAMLSymbols.cpp +++ b/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -183,8 +183,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 +500,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 +511,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 +526,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 +540,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/test/DebugInfo/PDB/Inputs/unknown-symbol.yaml b/test/DebugInfo/PDB/Inputs/unknown-symbol.yaml new file mode 100644 index 00000000000..c7a4136b88c --- /dev/null +++ b/test/DebugInfo/PDB/Inputs/unknown-symbol.yaml @@ -0,0 +1,10 @@ +--- +DbiStream: + Modules: + - Module: unknown-symbol.yaml + Modi: + Records: + - Kind: S_ANNOTATION + UnknownSym: + Data: 123456789ABCDEF0 +... diff --git a/test/DebugInfo/PDB/pdb-unknown-symbol.test b/test/DebugInfo/PDB/pdb-unknown-symbol.test new file mode 100644 index 00000000000..3ef889750bc --- /dev/null +++ b/test/DebugInfo/PDB/pdb-unknown-symbol.test @@ -0,0 +1,6 @@ +; RUN: llvm-pdbutil yaml2pdb -pdb=%t.pdb %p/Inputs/unknown-symbol.yaml +; RUN: llvm-pdbutil pdb2yaml -minimal -module-syms -no-file-headers %t.pdb | FileCheck %s + +CHECK: - Kind: S_ANNOTATION +CHECK: UnknownSym: +CHECK: Data: 123456789ABCDEF0 -- 2.50.1