[Lldb-commits] [lldb] r309581 - Fix LLDB crash accessing unknown DW_FORM_* attributes

Jan Kratochvil via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 31 10:02:52 PDT 2017


Author: jankratochvil
Date: Mon Jul 31 10:02:52 2017
New Revision: 309581

URL: http://llvm.org/viewvc/llvm-project?rev=309581&view=rev
Log:
Fix LLDB crash accessing unknown DW_FORM_* attributes

Current LLDB (that is without DWZ support) crashes accessing Fedora debug info:
READ of size 8 at 0x60200000ffc8 thread T0
    #0 in DWARFDebugInfoEntry::BuildAddressRangeTable(SymbolFileDWARF*, DWARFCompileUnit const*, DWARFDebugAranges*) const tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp:1336

Greg Clayton: We will need a warning to be emitted in
SymbolFileDWARF::CalculateAbilities() stating we won't parse the DWARF due to
"unsupported DW_FORM value of 0x1f20".

Patch has been mostly written by Greg Clayton.

Differential revision: https://reviews.llvm.org/D35622

Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp?rev=309581&r1=309580&r2=309581&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp Mon Jul 31 10:02:52 2017
@@ -98,6 +98,21 @@ dw_uleb128_t DWARFAbbreviationDeclaratio
 }
 
 //----------------------------------------------------------------------
+// DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
+//----------------------------------------------------------------------
+void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
+    std::set<dw_form_t> &invalid_forms) const {
+  for (const auto &abbr_decl : m_decls) {
+    const size_t num_attrs = abbr_decl.NumAttributes();
+    for (size_t i=0; i<num_attrs; ++i) {
+      dw_form_t form = abbr_decl.GetFormByIndex(i);
+      if (!DWARFFormValue::FormIsSupported(form))
+        invalid_forms.insert(form);
+    }
+  }
+}
+
+//----------------------------------------------------------------------
 // Encode
 //
 // Encode the abbreviation table onto the end of the buffer provided
@@ -175,3 +190,12 @@ DWARFDebugAbbrev::GetAbbreviationDeclara
     return &(pos->second);
   return NULL;
 }
+
+//----------------------------------------------------------------------
+// DWARFDebugAbbrev::GetUnsupportedForms()
+//----------------------------------------------------------------------
+void DWARFDebugAbbrev::GetUnsupportedForms(
+    std::set<dw_form_t> &invalid_forms) const {
+  for (const auto &pair : m_abbrevCollMap)
+    pair.second.GetUnsupportedForms(invalid_forms);
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h?rev=309581&r1=309580&r2=309581&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h Mon Jul 31 10:02:52 2017
@@ -41,6 +41,7 @@ public:
   // void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
   dw_uleb128_t
   AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration &abbrevDecl);
+  void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
 
   const DWARFAbbreviationDeclaration *
   GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const;
@@ -65,6 +66,7 @@ public:
   GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const;
   void Dump(lldb_private::Stream *s) const;
   void Parse(const lldb_private::DWARFDataExtractor &data);
+  void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const;
 
 protected:
   DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp?rev=309581&r1=309580&r2=309581&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp Mon Jul 31 10:02:52 2017
@@ -725,3 +725,39 @@ int DWARFFormValue::Compare(const DWARFF
   }
   return -1;
 }
+
+bool DWARFFormValue::FormIsSupported(dw_form_t form) {
+  switch (form) {
+    case DW_FORM_addr:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+    case DW_FORM_string:
+    case DW_FORM_block:
+    case DW_FORM_block1:
+    case DW_FORM_data1:
+    case DW_FORM_flag:
+    case DW_FORM_sdata:
+    case DW_FORM_strp:
+    case DW_FORM_udata:
+    case DW_FORM_ref_addr:
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_udata:
+    case DW_FORM_indirect:
+    case DW_FORM_sec_offset:
+    case DW_FORM_exprloc:
+    case DW_FORM_flag_present:
+    case DW_FORM_ref_sig8:
+    case DW_FORM_GNU_str_index:
+    case DW_FORM_GNU_addr_index:
+      return true;
+    default:
+      break;
+  }
+  return false;
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h?rev=309581&r1=309580&r2=309581&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h Mon Jul 31 10:02:52 2017
@@ -86,6 +86,7 @@ public:
                                                         bool is_dwarf64);
   static int Compare(const DWARFFormValue &a, const DWARFFormValue &b);
   void Clear();
+  static bool FormIsSupported(dw_form_t form);
 
 protected:
   const DWARFCompileUnit *m_cu; // Compile unit for this form

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=309581&r1=309580&r2=309581&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Jul 31 10:02:52 2017
@@ -532,6 +532,20 @@ uint32_t SymbolFileDWARF::CalculateAbili
       if (section)
         debug_abbrev_file_size = section->GetFileSize();
 
+      DWARFDebugAbbrev *abbrev = DebugAbbrev();
+      if (abbrev) {
+        std::set<dw_form_t> invalid_forms;
+        abbrev->GetUnsupportedForms(invalid_forms);
+        if (!invalid_forms.empty()) {
+          StreamString error;
+          error.Printf("unsupported DW_FORM value%s:", invalid_forms.size() > 1 ? "s" : "");
+          for (auto form : invalid_forms)
+            error.Printf(" %#x", form);
+          m_obj_file->GetModule()->ReportWarning("%s", error.GetString().str().c_str());
+          return 0;
+        }
+      }
+
       section =
           section_list->FindSectionByType(eSectionTypeDWARFDebugLine, true)
               .get();




More information about the lldb-commits mailing list