summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdw/ChangeLog9
-rw-r--r--libdw/dwarf_frame_cfa.c2
-rw-r--r--libdw/dwarf_frame_register.c4
-rw-r--r--libdw/dwarf_getlocation.c21
-rw-r--r--libdw/libdwP.h4
5 files changed, 32 insertions, 8 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 5fa75151..f927032e 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-26 Roland McGrath <roland@redhat.com>
+
+ * dwarf_getlocation.c (__libdw_intern_expression): Take new arg CFAP.
+ Prepend DW_OP_call_frame_cfa if true.
+ (getlocation): Update caller.
+ * dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise.
+ * dwarf_frame_register.c (dwarf_frame_register): Likewise.
+ * libdwP.h: Update decl.
+
2010-04-22 Roland McGrath <roland@redhat.com>
* cfi.c (execute_cfi): Track last-set CFA regno and offset even
diff --git a/libdw/dwarf_frame_cfa.c b/libdw/dwarf_frame_cfa.c
index d1c57108..03c5fbd2 100644
--- a/libdw/dwarf_frame_cfa.c
+++ b/libdw/dwarf_frame_cfa.c
@@ -84,7 +84,7 @@ dwarf_frame_cfa (fs, ops, nops)
result = __libdw_intern_expression
(NULL, fs->cache->other_byte_order,
fs->cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8,
- &fs->cache->expr_tree, &fs->cfa_data.expr, false,
+ &fs->cache->expr_tree, &fs->cfa_data.expr, false, false,
ops, nops, IDX_debug_frame);
break;
diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c
index 3d232e95..e42b76bf 100644
--- a/libdw/dwarf_frame_register.c
+++ b/libdw/dwarf_frame_register.c
@@ -1,5 +1,5 @@
/* Get register location expression for frame.
- Copyright (C) 2009 Red Hat, Inc.
+ Copyright (C) 2009-2010 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -131,7 +131,7 @@ dwarf_frame_register (fs, regno, ops_mem, ops, nops)
fs->cache->other_byte_order,
address_size,
&fs->cache->expr_tree, &block,
- reg->rule == reg_val_expression,
+ true, reg->rule == reg_val_expression,
ops, nops, IDX_debug_frame) < 0)
return -1;
break;
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);
}
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 248a58d5..44beac67 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -433,10 +433,10 @@ extern int __libdw_intern_expression (Dwarf *dbg,
bool other_byte_order,
unsigned int address_size,
void **cache, const Dwarf_Block *block,
- bool valuep,
+ bool cfap, bool valuep,
Dwarf_Op **llbuf, size_t *listlen,
int sec_index)
- __nonnull_attribute__ (4, 5, 7, 8) internal_function;
+ __nonnull_attribute__ (4, 5, 8, 9) internal_function;
/* Return error code of last failing function call. This value is kept