From bd2044c108655dc6409e2c724349219d3971b151 Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Wed, 29 Jun 2022 17:09:40 -0700 Subject: [PATCH] [CodeView] Call llvm::codeview::visitMemberRecordStream with the deserialized CVType whose kind is FieldListRecord. llvm::codeview::visitMemberRecordStream expects to receive an array ref that's FieldListRecord's Data not a CVType's data which has 4 more bytes preceeding. The first 2 bytes indicate the size of the FieldListRecord, and following 2 bytes is always 0x1203. Inside llvm::codeview::visitMemberRecordStream, it iterates to the data to check if first two bytes matching some type record kinds. If the size coincidentally matches one type kind, it will start parsing from there and causing crash. --- .../Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp | 35 ++++++++++++++-------- .../Plugins/SymbolFile/NativePDB/PdbUtil.cpp | 9 ++++-- llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp | 9 ++++-- llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp | 5 +++- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index daca398..6dcce73 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -401,10 +401,13 @@ void PdbAstBuilder::BuildParentMap() { } }; - CVType field_list = m_index.tpi().getType(tag.asTag().FieldList); + CVType field_list_cvt = m_index.tpi().getType(tag.asTag().FieldList); ProcessTpiStream process(m_index, *ti, tag, m_parent_types); - llvm::Error error = visitMemberRecordStream(field_list.data(), process); - if (error) + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + if (llvm::Error error = visitMemberRecordStream(field_list.Data, process)) llvm::consumeError(std::move(error)); } @@ -757,22 +760,26 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { CVType field_list_cvt = m_index.tpi().getType(field_list_ti); if (field_list_cvt.kind() != LF_FIELDLIST) return false; + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); // Visit all members of this class, then perform any finalization necessary // to complete the class. CompilerType ct = ToCompilerType(tag_qt); UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index, m_cxx_record_map); - auto error = - llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); + llvm::Error error = + llvm::codeview::visitMemberRecordStream(field_list.Data, completer); completer.complete(); status.resolved = true; - if (!error) - return true; - - llvm::consumeError(std::move(error)); - return false; + if (error) { + llvm::consumeError(std::move(error)); + return false; + } + return true; } clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { @@ -1118,10 +1125,14 @@ PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id, } } if (!tag_record.FieldList.isSimple()) { - CVType field_list = m_index.tpi().getType(tag_record.FieldList); + CVType field_list_cvt = m_index.tpi().getType(tag_record.FieldList); + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); CreateMethodDecl process(m_index, m_clang, func_ti, function_decl, parent_opaque_ty, func_name, func_ct); - if (llvm::Error err = visitMemberRecordStream(field_list.data(), process)) + if (llvm::Error err = visitMemberRecordStream(field_list.Data, process)) llvm::consumeError(std::move(err)); } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index 10e8cbd..ee1de24 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -733,9 +733,14 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( } if (IsTagRecord(class_cvt)) { TagRecord tag_record = CVTagRecord::create(class_cvt).asTag(); - CVType field_list = index.tpi().getType(tag_record.FieldList); + CVType field_list_cvt = index.tpi().getType(tag_record.FieldList); + FieldListRecord field_list; + if (llvm::Error error = + TypeDeserializer::deserializeAs( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); FindMembersSize find_members_size(members_info, index.tpi()); - if (llvm::Error err = visitMemberRecordStream(field_list.data(), + if (llvm::Error err = visitMemberRecordStream(field_list.Data, find_members_size)) { llvm::consumeError(std::move(err)); break; diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp index 645a996..ec37d27 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp @@ -67,10 +67,13 @@ NativeEnumEnumEnumerators::NativeEnumEnumEnumerators( ContinuationIndex = ClassParent.getEnumRecord().FieldList; while (ContinuationIndex) { - CVType FieldList = Types.getType(*ContinuationIndex); - assert(FieldList.kind() == LF_FIELDLIST); + CVType FieldListCVT = Types.getType(*ContinuationIndex); + assert(FieldListCVT.kind() == LF_FIELDLIST); ContinuationIndex.reset(); - cantFail(visitMemberRecordStream(FieldList.data(), *this)); + FieldListRecord FieldList; + cantFail(TypeDeserializer::deserializeAs(FieldListCVT, + FieldList)); + cantFail(visitMemberRecordStream(FieldList.Data, *this)); } } diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp index 49b24e2..e4e2b2a 100644 --- a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp +++ b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -490,7 +490,10 @@ private: Error LeafRecordImpl::fromCodeViewRecord(CVType Type) { MemberRecordConversionVisitor V(Members); - return visitMemberRecordStream(Type.content(), V); + FieldListRecord FieldList; + cantFail(TypeDeserializer::deserializeAs(Type, + FieldList)); + return visitMemberRecordStream(FieldList.Data, V); } CVType LeafRecordImpl::toCodeViewRecord( -- 2.7.4