mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-21 00:06:58 +00:00
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:
parent
11c89cad3e
commit
066ebbdf0e
@ -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)
|
||||
|
@ -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 \
|
||||
|
BIN
tests/data/test-types-stability/pr19204-libtcmalloc.so.4.2.6-xlc
Normal file
BIN
tests/data/test-types-stability/pr19204-libtcmalloc.so.4.2.6-xlc
Normal file
Binary file not shown.
@ -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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user