Bug 19204 - libabigail aborts on DWARF referencing non-existing DIE

In this bug the DWARF reader tries to get the parent of a DIE
(referred-to by its offset) which is not defined in the debug info.
The DIE is not defined, but it's referred-to by another DIE of the
debug info.  This definitely looks like a faulty DWARF.

The DWARF reader aborts because, obviously, it cannot get the parent
DIE of a DIE that is not defined.

This patch changes the behaviour of the DWARF reader in this case.
Rather than aborting, the DWARF reader just drops the DIE (which
refers to a non-existing DIE) on the floor.  It thus do not abort on
such faulty DWARF anymore.

	* src/abg-dwarf-reader.cc (get_parent_die): If we couldn't find
	the parent of a given DIE, return false, do not abort.  Also,
	assert that if we don't find the parent of a DIE in the main debug
	info, we don't find it in the alternate debug info either (and
	vice versa).  This is because I'd like to abort on cases where we
	look for a DIE in the wrong debug info; those cases are likely to
	be hint that the DWARF reader is doing something wrong which ought
	to be investigated and fixed.
	(get_scope_for_die): If we couldn't get the parent of the DIE,
	then return a nil scope.
	* tests/data/test-types-stability/pr19204-libtcmalloc.so.4.2.6-xlc:
	New test binary input.
	* tests/data/Makefile.am: Add the new binary test input to the
	source distribution.
	* tests/test-types-stability.cc (elf_paths): Account for the new
	binary input.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2016-01-21 10:48:32 +01:00
parent 11c89cad3e
commit 066ebbdf0e
4 changed files with 51 additions and 10 deletions

View File

@ -6188,7 +6188,10 @@ find_import_unit_point_before_die(read_context& ctxt,
/// positionned at, in the DIE tree. This is useful when @p die is
/// e.g, DW_TAG_partial_unit that can be included in several places in
/// the DIE tree.
static void
///
/// @return true if the function could get a parent DIE, false
/// otherwise.
static bool
get_parent_die(read_context& ctxt,
Dwarf_Die* die,
bool die_is_from_alt_di,
@ -6204,13 +6207,45 @@ get_parent_die(read_context& ctxt,
if (die_is_from_alt_di)
{
assert(i != ctxt.alternate_die_parent_map().end());
assert(dwarf_offdie(ctxt.alt_dwarf(), i->second, &parent_die));
if (i == ctxt.alternate_die_parent_map().end())
{
// We haven't found the DIE in the alternate debug info.
//
// This could a problem in the debug info (the DIE doesn't
// exist in it).
//
// But first let's make sure the DIE we are looking for is
// not in the main debug info either; if it is, it might
// mean that we are looking for the DIE in the wrong debug
// info. And that would most likely argue for a wrongdoing
// on our part that ought fixing.
assert(ctxt.die_parent_map().find(dwarf_dieoffset(die))
== ctxt.die_parent_map().end());
return false;
}
else
assert(dwarf_offdie(ctxt.alt_dwarf(), i->second, &parent_die));
}
else
{
assert(i != ctxt.die_parent_map().end());
assert(dwarf_offdie(ctxt.dwarf(), i->second, &parent_die));
if (i == ctxt.die_parent_map().end())
{
// We haven't found the DIE in the main debug info.
//
// This could a problem in the debug info (the DIE doesn't
// exist in it).
//
// But first let's make sure the DIE we are looking for is not
// in the alternate debug info either; if it is, it might mean
// that we are looking for the DIE int the wrong debug info.
// And that would most likely argue for a wrongdoing on our
// part that ought fixing.
assert(ctxt.alternate_die_parent_map().find(dwarf_dieoffset(die))
== ctxt.alternate_die_parent_map().end());
return false;
}
else
assert(dwarf_offdie(ctxt.dwarf(), i->second, &parent_die));
}
if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
@ -6235,11 +6270,13 @@ get_parent_die(read_context& ctxt,
assert(dwarf_offdie(ctxt.dwarf(),
import_point_offset,
&import_point_die));
get_parent_die(ctxt, &import_point_die,
/*die_is_from_alt_di=*/false,
parent_die, where_offset);
return get_parent_die(ctxt, &import_point_die,
/*die_is_from_alt_di=*/false,
parent_die, where_offset);
}
}
return true;
}
/// Return the abigail IR node representing the scope of a given DIE.
@ -6284,8 +6321,10 @@ get_scope_for_die(read_context& ctxt,
where_offset);
Dwarf_Die parent_die;
get_parent_die(ctxt, die, die_is_from_alt_di,
parent_die, where_offset);
if (!get_parent_die(ctxt, die, die_is_from_alt_di,
parent_die, where_offset))
return scope_decl_sptr();
if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
|| dwarf_tag(&parent_die) == DW_TAG_partial_unit)

View File

@ -322,6 +322,7 @@ test-types-stability/pr19138-elf0 \
test-types-stability/pr19433-custom0 \
test-types-stability/pr19141-get5d.o \
test-types-stability/pr19142-topo.o \
test-types-stability/pr19204-libtcmalloc.so.4.2.6-xlc \
\
test-diff-filter/test0-v0.cc \
test-diff-filter/test0-v1.cc \

View File

@ -61,6 +61,7 @@ const char* elf_paths[] =
"data/test-types-stability/pr19433-custom0",
"data/test-types-stability/pr19141-get5d.o",
"data/test-types-stability/pr19142-topo.o",
"data/test-types-stability/pr19204-libtcmalloc.so.4.2.6-xlc",
// The below should always be the last element of array.
0
};