summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getlocation.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-05-08 03:22:59 -0700
committerRoland McGrath <roland@redhat.com>2010-05-08 03:22:59 -0700
commit688f7fcdb395cefef6a098b5ac9ddd167bb5fc3d (patch)
tree5c58beb134815682414b6fada8531e3020b4dcd8 /libdw/dwarf_getlocation.c
parent2716d81bf78a48cd94be309ed0c11b09f47231aa (diff)
Fix DW_OP_call_ref operand handling.
Diffstat (limited to 'libdw/dwarf_getlocation.c')
-rw-r--r--libdw/dwarf_getlocation.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index f362fe22..ede8c3c9 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -219,8 +219,8 @@ check_constant_offset (Dwarf_Attribute *attr,
int
internal_function
-__libdw_intern_expression (Dwarf *dbg,
- bool other_byte_order, unsigned int address_size,
+__libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
+ unsigned int address_size, unsigned int ref_size,
void **cache, const Dwarf_Block *block,
bool cfap, bool valuep,
Dwarf_Op **llbuf, size_t *listlen, int sec_index)
@@ -272,6 +272,13 @@ __libdw_intern_expression (Dwarf *dbg,
return -1;
break;
+ case DW_OP_call_ref:
+ /* DW_FORM_ref_addr, depends on offset size of CU. */
+ if (__libdw_read_offset_inc (dbg, sec_index, &data, ref_size,
+ &newloc->number, IDX_debug_info, 0))
+ return -1;
+ break;
+
case DW_OP_deref:
case DW_OP_dup:
case DW_OP_drop:
@@ -303,7 +310,6 @@ __libdw_intern_expression (Dwarf *dbg,
case DW_OP_reg0 ... DW_OP_reg31:
case DW_OP_nop:
case DW_OP_push_object_address:
- case DW_OP_call_ref:
case DW_OP_call_frame_cfa:
case DW_OP_form_tls_address:
case DW_OP_GNU_push_tls_address:
@@ -521,7 +527,10 @@ getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
Dwarf_Op **llbuf, size_t *listlen, int sec_index)
{
return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
- cu->address_size, &cu->locs, block,
+ cu->address_size, (cu->version == 2
+ ? cu->address_size
+ : cu->offset_size),
+ &cu->locs, block,
false, false,
llbuf, listlen, sec_index);
}