summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getlocation.c
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/dwarf_getlocation.c
parent76aec244dcdf41c690aee001d2ce0783322734ab (diff)
Fix dwarf_getlocation braino in constant-form case handling.
Diffstat (limited to 'libdw/dwarf_getlocation.c')
-rw-r--r--libdw/dwarf_getlocation.c24
1 files changed, 21 insertions, 3 deletions
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);