summaryrefslogtreecommitdiffstats
path: root/contrib/elftoolchain
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2017-02-03 01:32:04 +0000
committermarkj <markj@FreeBSD.org>2017-02-03 01:32:04 +0000
commita7273418b837d781ff68bd6fda9772bf2cdbff8b (patch)
tree6a07b07b80e3e753e1887499c590392227659020 /contrib/elftoolchain
parent2aaa4fe248dde393e885dd046425c1a319b045c1 (diff)
downloadFreeBSD-src-a7273418b837d781ff68bd6fda9772bf2cdbff8b.zip
FreeBSD-src-a7273418b837d781ff68bd6fda9772bf2cdbff8b.tar.gz
MFC r310724:
Follow DW_AT_specification when looking up DW_AT_type attributes. PR: 215350, 215395
Diffstat (limited to 'contrib/elftoolchain')
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_attrval.c32
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_attrval_signed.311
2 files changed, 29 insertions, 14 deletions
diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval.c b/contrib/elftoolchain/libdwarf/dwarf_attrval.c
index 0dd38a4..19a4fd9 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_attrval.c
+++ b/contrib/elftoolchain/libdwarf/dwarf_attrval.c
@@ -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:
diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3
index 93d4ae0..4c129dc 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3
+++ b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3
@@ -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
OpenPOWER on IntegriCloud