summaryrefslogtreecommitdiff
path: root/libdw
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2009-11-21 17:03:34 -0800
committerRoland McGrath <roland@redhat.com>2009-11-21 17:03:53 -0800
commit888381b9ace5251b9feaad14f9bfa8c9d85cb1fd (patch)
tree41979d130cbd925d1caa3f3617c6e8cb47bfcf08 /libdw
parent76aec244dcdf41c690aee001d2ce0783322734ab (diff)
downloadelfutils-888381b9ace5251b9feaad14f9bfa8c9d85cb1fd.tar.gz
Fix dwarf_getlocation braino in constant-form case handling.
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/dwarf_getlocation.c24
2 files changed, 26 insertions, 3 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 33a18baf..9506daea 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-21 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getlocation.c (check_constant_offset): Return 1 for all
+ non-constant forms.
+
2009-10-15 Roland McGrath <roland@redhat.com>
* libdw_form.c (__libdw_form_val_len): Grok DW_FORM_sec_offset,
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 17df8fe9..720b20f4 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -154,11 +154,29 @@ static int
check_constant_offset (Dwarf_Attribute *attr,
Dwarf_Op **llbuf, size_t *listlen)
{
- if (attr->code != DW_AT_data_member_location
- || attr->form == DW_FORM_data4
- || attr->form == DW_FORM_data8)
+ if (attr->code != DW_AT_data_member_location)
return 1;
+ switch (attr->form)
+ {
+ /* Punt for any non-constant form. */
+ default:
+ return 1;
+
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ break;
+
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ /* These are loclistptr, not constants.
+ XXX check cu->version > 3???
+ */
+ return 1;
+ }
+
/* Check whether we already cached this location. */
struct loc_s fake = { .addr = attr->valp };
struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);