summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getlocation.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-04-26 11:50:27 -0700
committerRoland McGrath <roland@redhat.com>2010-04-26 11:50:27 -0700
commit0ab97839da3c382ab8799ebdbf5eb0a79bf20bdc (patch)
tree2963526d4fc6fa261584cc2a514cc00ff968b983 /libdw/dwarf_getlocation.c
parent3c6ee4b62787738d4524e4a83c97f1a64ce15379 (diff)
Translate DW_CFA_expression/DW_CFA_val_expression properly to imply pushing CFA before given expression.
Diffstat (limited to 'libdw/dwarf_getlocation.c')
-rw-r--r--libdw/dwarf_getlocation.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c
index 720b20f4..f362fe22 100644
--- a/libdw/dwarf_getlocation.c
+++ b/libdw/dwarf_getlocation.c
@@ -1,5 +1,5 @@
/* Return location expression list.
- Copyright (C) 2000-2009 Red Hat, Inc.
+ Copyright (C) 2000-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2000.
@@ -221,7 +221,8 @@ int
internal_function
__libdw_intern_expression (Dwarf *dbg,
bool other_byte_order, unsigned int address_size,
- void **cache, const Dwarf_Block *block, bool valuep,
+ void **cache, const Dwarf_Block *block,
+ bool cfap, bool valuep,
Dwarf_Op **llbuf, size_t *listlen, int sec_index)
{
/* Check whether we already looked at this list. */
@@ -444,6 +445,9 @@ __libdw_intern_expression (Dwarf *dbg,
++n;
}
+ if (cfap)
+ ++n;
+
/* Allocate the array. */
Dwarf_Op *result;
if (dbg != NULL)
@@ -463,6 +467,16 @@ __libdw_intern_expression (Dwarf *dbg,
*llbuf = result;
*listlen = n;
+ if (cfap)
+ {
+ /* Synthesize the operation to push the CFA before the expression. */
+ --n;
+ result[0].atom = DW_OP_call_frame_cfa;
+ result[0].number = 0;
+ result[0].number2 = 0;
+ result[0].offset = -1;
+ }
+
do
{
/* We populate the array from the back since the list is backwards. */
@@ -507,7 +521,8 @@ 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, false,
+ cu->address_size, &cu->locs, block,
+ false, false,
llbuf, listlen, sec_index);
}