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
This commit is contained in:
parent
47abdb10a0
commit
2ef476c9a2
@ -145,6 +145,7 @@ dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwa
|
||||
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, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwa
|
||||
|
||||
*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, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwa
|
||||
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, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwa
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user