]> sourceware.org Git - libabigail.git/commitdiff
Try harder to detect a DWARF attribute pointing into alternate DWARF section
authorDodji Seketeli <dodji@redhat.com>
Thu, 11 Dec 2014 12:48:43 +0000 (13:48 +0100)
committerDodji Seketeli <dodji@redhat.com>
Thu, 11 Dec 2014 12:48:43 +0000 (13:48 +0100)
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>
src/abg-dwarf-reader.cc

index 36b16c1396a09b98c636f31c5d5306aa2e6c081d..ffabd5ccb46f0c7ee78bc4a63b9f38a7edec7351 100644 (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;
     }
This page took 0.042139 seconds and 5 git commands to generate.