Author: markj
Date: Wed Dec 28 21:54:33 2016
New Revision: 310724
URL: https://svnweb.freebsd.org/changeset/base/310724

Log:
  Follow DW_AT_specification when looking up DW_AT_type attributes.
  
  dwarf_attrval_*() will search the parent DIE referenced by a
  DW_AT_abstract_origin attribute for the value of the DW_AT_type attribute.
  Do the same thing for the DW_AT_specification attributes in variable
  definitions emitted by GCC 6.2, and ensure that we return an error rather
  than crashing if neither DW_AT_abstract_origin or DW_AT_specification is
  found when looking for the value of the DW_AT_type attribute.
  
  PR:           215350, 215395
  Reviewed by:  emaste
  MFC after:    2 weeks
  Differential Revision:        https://reviews.freebsd.org/D8920

Modified:
  head/contrib/elftoolchain/libdwarf/dwarf_attrval.c
  head/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3

Modified: head/contrib/elftoolchain/libdwarf/dwarf_attrval.c
==============================================================================
--- head/contrib/elftoolchain/libdwarf/dwarf_attrval.c  Wed Dec 28 21:45:41 
2016        (r310723)
+++ head/contrib/elftoolchain/libdwarf/dwarf_attrval.c  Wed Dec 28 21:54:33 
2016        (r310724)
@@ -145,6 +145,7 @@ dwarf_attrval_unsigned(Dwarf_Die die, Dw
        Dwarf_Die die1;
        Dwarf_Unsigned val;
        Dwarf_Debug dbg;
+       int first;
 
        dbg = die != NULL ? die->die_dbg : NULL;
 
@@ -155,14 +156,16 @@ dwarf_attrval_unsigned(Dwarf_Die die, Dw
 
        *valp = 0;
 
-       if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) {
-               DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
-               return (DW_DLV_NO_ENTRY);
-       }
-
        die1 = NULL;
-       if (at == NULL &&
-           (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) {
+       for (;;) {
+               if ((at = _dwarf_attr_find(die, attr)) != NULL ||
+                   attr != DW_AT_type)
+                       break;
+               if ((at = _dwarf_attr_find(die, DW_AT_abstract_origin)) ==
+                   NULL &&
+                   (at = _dwarf_attr_find(die, DW_AT_specification)) == NULL)
+                       break;
+
                switch (at->at_form) {
                case DW_FORM_ref1:
                case DW_FORM_ref2:
@@ -170,13 +173,15 @@ dwarf_attrval_unsigned(Dwarf_Die die, Dw
                case DW_FORM_ref8:
                case DW_FORM_ref_udata:
                        val = at->u[0].u64;
-                       if ((die1 = _dwarf_die_find(die, val)) == NULL ||
-                           (at = _dwarf_attr_find(die1, attr)) == NULL) {
-                               if (die1 != NULL)
-                                       dwarf_dealloc(dbg, die1, DW_DLA_DIE);
+                       first = (die1 == NULL);
+                       die1 = _dwarf_die_find(die, val);
+                       if (!first)
+                               dwarf_dealloc(dbg, die, DW_DLA_DIE);
+                       if (die1 == NULL) {
                                DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
                                return (DW_DLV_NO_ENTRY);
                        }
+                       die = die1;
                        break;
                default:
                        DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
@@ -184,6 +189,11 @@ dwarf_attrval_unsigned(Dwarf_Die die, Dw
                }
        }
 
+       if (at == NULL) {
+               DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
+               return (DW_DLV_NO_ENTRY);
+       }
+
        switch (at->at_form) {
        case DW_FORM_addr:
        case DW_FORM_data1:

Modified: head/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3
==============================================================================
--- head/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3   Wed Dec 28 
21:45:41 2016        (r310723)
+++ head/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3   Wed Dec 28 
21:54:33 2016        (r310724)
@@ -24,7 +24,7 @@
 .\"
 .\" $Id: dwarf_attrval_signed.3 2980 2014-01-21 20:15:54Z kaiwang27 $
 .\"
-.Dd January 18, 2014
+.Dd December 26, 2016
 .Os
 .Dt DWARF_ATTRVAL_SIGNED 3
 .Sh NAME
@@ -168,17 +168,22 @@ or
 .Pp
 If the attribute named by argument
 .Ar attr
-is not present in the debugging information entry referenced by
-argument
+is
+.Dv DW_AT_type
+and is not present in the debugging information entry referenced by argument
 .Ar die ,
 and if a
 .Dv DW_AT_abstract_origin
+or
+.Dv DW_AT_specification
 attribute is present in the debugging information entry,
 function
 .Fn dwarf_attrval_unsigned
 will search for the named attribute in the debugging information entry
 referenced by the
 .Dv DW_AT_abstract_origin
+or
+.Dv DW_AT_specification
 attribute.
 .Sh RETURN VALUES
 On success, these functions returns
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to