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
llvm-svn: 309581
This commit is contained in:
parent
02c602e18c
commit
b14f1da23c
|
|
@ -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
|
||||
//
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue