diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2021-03-17 16:48:25 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2021-03-22 14:34:53 +0000 |
commit | 702cf3f5df18818eb62da7ffbd70544fa98da3c7 (patch) | |
tree | 6bfe50fd3c8410defe99271d207617e94f727cff /gdb/dwarf2 | |
parent | 46fec6428ef7504be486ebd57e2509bde4382918 (diff) | |
download | gdb-702cf3f5df18818eb62da7ffbd70544fa98da3c7.zip gdb-702cf3f5df18818eb62da7ffbd70544fa98da3c7.tar.gz gdb-702cf3f5df18818eb62da7ffbd70544fa98da3c7.tar.bz2 |
gdb: handle invalid DWARF when compilation unit is missing
Replace an abort call in process_psymtab_comp_unit with a real error,
and add a test to cover this case. The case is question is when badly
formed DWARF is missing a DW_TAG_compile_unit, DW_TAG_partial_unit, or
DW_TAG_type_unit as its top level tag.
I then tested with --target_board=readnow and added additional code to
also validate the top-level tag in this case.
I added an assert that would trigger for the readnow case before I
added the fix. I suspect there's lots of places where badly formed
DWARF could result in the builder being nullptr when it shouldn't be,
but I only added this one assert, as this is the one that would have
helped me in this case.
gdb/ChangeLog:
* dwarf2/read.c (process_psymtab_comp_unit): Replace abort with an
error.
(process_full_comp_unit): Validate the top-level tag before
processing the first DIE.
(read_func_scope): Ensure we have a valid builder.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-missing-cu-tag.c: New file.
* gdb.dwarf2/dw2-missing-cu-tag.exp: New file.
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/read.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index acbc5fa..2bfb13d 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -7737,7 +7737,10 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu, this_cu->unit_type = DW_UT_type; break; default: - abort (); + error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"), + dwarf_tag_name (reader.comp_unit_die->tag), + sect_offset_str (reader.cu->per_cu->sect_off), + objfile_name (per_objfile->objfile)); } if (reader.dummy_p) @@ -9994,6 +9997,21 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language) dwarf2_find_base_address (cu->dies, cu); + /* Before we start reading the top-level DIE, ensure it has a valid tag + type. */ + switch (cu->dies->tag) + { + case DW_TAG_compile_unit: + case DW_TAG_partial_unit: + case DW_TAG_type_unit: + break; + default: + error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"), + dwarf_tag_name (cu->dies->tag), + sect_offset_str (cu->per_cu->sect_off), + objfile_name (per_objfile->objfile)); + } + /* Do line number decoding in read_file_scope () */ process_die (cu->dies, cu); @@ -13628,6 +13646,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) } } + gdb_assert (cu->get_builder () != nullptr); newobj = cu->get_builder ()->push_context (0, lowpc); newobj->name = new_symbol (die, read_type_die (die, cu), cu, (struct symbol *) templ_func); |