Try harder to detect a DWARF attribute pointing into alternate DWARF section

This is bug https://sourceware.org/bugzilla/show_bug.cgi?id=17655.
There are several issues conflated into that one problem report.  This
patch addresses one of them.

The value of a DW_AT_type attribute on a DW_TAG_subprogram DIE can be
a type that lies in an alternate DWARF section.  The link from the
DW_TAG_subprogram die to the attribute value can be very much
indirect; for instance, the DW_TAG_subprogram might be linked to an
abstract origin function through a DW_AT_abstract_origin, which itself
can be linked to a function specification that lies in the alternate
DWARF section through a DW_AT_specification attribute.  It's that last
function specification (in the alternate DWARF section) that would
have the DW_AT_type that points to the return type of the function,
defined in the alternate DWARF section.  In this specific case, we
were failing to detect that the DW_AT_type was inside the alternate
debug info section; note that detecting that is not obvious because
the elfutils function dwarf_attr_integrate that we use to get the
value of the DW_AT_type magically does the walking through all the
hops, but doesn't tell us if the resulting type is in the alternate
debug info section or not.  So we do have our own function that does
the detection.

This patch makes the detection work in this case.

	* src/abg-dwarf-reader.cc
	(is_die_attribute_resolved_through_gnu_ref_alt): Support the case
	of the origin function itself having a specification function
	link.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2014-12-11 13:48:43 +01:00
parent 04abbd1d44
commit 1176c1c4ed

View File

@ -3057,12 +3057,31 @@ is_die_attribute_resolved_through_gnu_ref_alt(Dwarf_Die* die,
if (r)
is_in_alternate_debug_info = (attr.form == DW_FORM_GNU_ref_alt);
// Now let's see if we got to the attribute attr_name by looking
// through either DW_AT_abstract_origin or DW_AT_specification, or
// even DW_AT_abstract_origin *and then* DW_AT_specification. Would
// then be looking at a function which definition is in the
// alternate debug info file.
if (r && !is_in_alternate_debug_info && thru_abstract_origin)
{
Dwarf_Die origin_die;
Dwarf_Attribute mem;
Dwarf_Attribute* a = dwarf_attr(die, DW_AT_abstract_origin, &mem);
if (a == NULL)
a = dwarf_attr(die, DW_AT_specification, &mem);
if (a == NULL || a->form != DW_FORM_GNU_ref_alt)
{
if (a == NULL)
a = dwarf_attr(die, DW_AT_specification, &mem);
else
{
// so we looked through a DW_AT_abstract_origin
// attribute. So let's get that origin DIE and see if
// it has an DW_AT_specification attribute ...
assert(dwarf_formref_die(a, &origin_die));
a = dwarf_attr(&origin_die, DW_AT_specification, &mem);
}
}
// Now if the final function we got by jumping through hoops is
// inside an alternate debug info file, we are good.
if (a && a->form == DW_FORM_GNU_ref_alt)
is_in_alternate_debug_info = true;
}