Skip to content

Commit

Permalink
Fix LLDB crash accessing unknown DW_FORM_* attributes
Browse files Browse the repository at this point in the history
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

llvm-svn: 309581
  • Loading branch information
jankratochvil committed Jul 31, 2017
1 parent 02c602e commit b14f1da
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 0 deletions.
24 changes: 24 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
Expand Up @@ -97,6 +97,21 @@ dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
return code; // return the new abbreviation code!
}

//----------------------------------------------------------------------
// 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
//
Expand Down Expand Up @@ -175,3 +190,12 @@ DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
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);
}
2 changes: 2 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
Expand Up @@ -41,6 +41,7 @@ class DWARFAbbreviationDeclarationSet {
// 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;
Expand All @@ -65,6 +66,7 @@ class DWARFDebugAbbrev {
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;
Expand Down
36 changes: 36 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
Expand Up @@ -725,3 +725,39 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
}
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;
}
1 change: 1 addition & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
Expand Up @@ -86,6 +86,7 @@ class DWARFFormValue {
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
Expand Down
14 changes: 14 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Expand Up @@ -532,6 +532,20 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
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();
Expand Down

0 comments on commit b14f1da

Please sign in to comment.