diff options
-rw-r--r-- | libdw/ChangeLog | 9 | ||||
-rw-r--r-- | libdw/dwarf_frame_cfa.c | 2 | ||||
-rw-r--r-- | libdw/dwarf_frame_register.c | 4 | ||||
-rw-r--r-- | libdw/dwarf_getlocation.c | 21 | ||||
-rw-r--r-- | libdw/libdwP.h | 4 |
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 |