[Lldb-commits] [lldb] bd2044c - [CodeView] Call llvm::codeview::visitMemberRecordStream with the deserialized CVType whose kind is FieldListRecord.

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 29 17:19:05 PDT 2022


Author: Zequan Wu
Date: 2022-06-29T17:18:56-07:00
New Revision: bd2044c108655dc6409e2c724349219d3971b151

URL: https://github.com/llvm/llvm-project/commit/bd2044c108655dc6409e2c724349219d3971b151
DIFF: https://github.com/llvm/llvm-project/commit/bd2044c108655dc6409e2c724349219d3971b151.diff

LOG: [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.

Added: 
    

Modified: 
    lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
    llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
    llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index daca3988f7646..6dcce738b79f5 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<FieldListRecord>(
+            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<FieldListRecord>(
+          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<FieldListRecord>(
+              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 10e8cbd11482d..ee1de24383d6a 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<FieldListRecord>(
+                      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 645a9963084b9..ec37d276e66b4 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<FieldListRecord>(FieldListCVT,
+                                                              FieldList));
+    cantFail(visitMemberRecordStream(FieldList.Data, *this));
   }
 }
 

diff  --git a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
index 49b24e21cf60c..e4e2b2a6d21a6 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp
@@ -490,7 +490,10 @@ class MemberRecordConversionVisitor : public TypeVisitorCallbacks {
 
 Error LeafRecordImpl<FieldListRecord>::fromCodeViewRecord(CVType Type) {
   MemberRecordConversionVisitor V(Members);
-  return visitMemberRecordStream(Type.content(), V);
+  FieldListRecord FieldList;
+  cantFail(TypeDeserializer::deserializeAs<FieldListRecord>(Type,
+                                                            FieldList));
+  return visitMemberRecordStream(FieldList.Data, V);
 }
 
 CVType LeafRecordImpl<FieldListRecord>::toCodeViewRecord(


        


More information about the lldb-commits mailing list