summaryrefslogtreecommitdiff
path: root/gdb/dwarf2-frame.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2009-09-02 14:53:52 +0000
committerTom Tromey <tromey@redhat.com>2009-09-02 14:53:52 +0000
commiteb6eb0c014f9de9f5e4c6909291e8a6c96f1b1d9 (patch)
treeeea8a6d2c52ce03258d2e969e1f96ca9bbf5ab6b /gdb/dwarf2-frame.c
parent18111055212657a23aabfa4ebe33914546eeefc6 (diff)
downloadgdb-eb6eb0c014f9de9f5e4c6909291e8a6c96f1b1d9.tar.gz
gdb
* frame.h (frame_unwinder_is): Declare. * frame.c (frame_unwinder_is): New function. * dwarf2loc.c: Include dwarf2-frame.h. (dwarf_expr_frame_cfa): New function. (dwarf2_evaluate_loc_desc): Use it. (needs_frame_frame_cfa): New function. (dwarf2_loc_desc_needs_frame): Use it. * dwarf2expr.h (struct dwarf_expr_context) <get_frame_cfa>: New field. * dwarf2expr.c (execute_stack_op) <DW_OP_call_frame_cfa>: New case. * dwarf2-frame.h (dwarf2_frame_cfa): Declare. * dwarf2-frame.c (no_get_frame_cfa): New function. (execute_stack_op): Use it. (dwarf2_frame_cfa): New function. gdb/testsuite * gdb.dwarf2/callframecfa.exp: New file. * gdb.dwarf2/callframecfa.S: New file.
Diffstat (limited to 'gdb/dwarf2-frame.c')
-rw-r--r--gdb/dwarf2-frame.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 427f58f5cd4..f9ca067dfe1 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -309,6 +309,15 @@ no_get_frame_base (void *baton, gdb_byte **start, size_t *length)
_("Support for DW_OP_fbreg is unimplemented"));
}
+/* Helper function for execute_stack_op. */
+
+static CORE_ADDR
+no_get_frame_cfa (void *baton)
+{
+ internal_error (__FILE__, __LINE__,
+ _("Support for DW_OP_call_frame_cfa is unimplemented"));
+}
+
static CORE_ADDR
no_get_tls_address (void *baton, CORE_ADDR offset)
{
@@ -363,6 +372,7 @@ execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
ctx->read_reg = read_reg;
ctx->read_mem = read_mem;
ctx->get_frame_base = no_get_frame_base;
+ ctx->get_frame_cfa = no_get_frame_cfa;
ctx->get_tls_address = no_get_tls_address;
dwarf_expr_push (ctx, initial);
@@ -1250,6 +1260,23 @@ dwarf2_frame_base_sniffer (struct frame_info *this_frame)
return NULL;
}
+
+/* Compute the CFA for THIS_FRAME, but only if THIS_FRAME came from
+ the DWARF unwinder. This is used to implement
+ DW_OP_call_frame_cfa. */
+
+CORE_ADDR
+dwarf2_frame_cfa (struct frame_info *this_frame)
+{
+ while (get_frame_type (this_frame) == INLINE_FRAME)
+ this_frame = get_prev_frame (this_frame);
+ /* This restriction could be lifted if other unwinders are known to
+ compute the frame base in a way compatible with the DWARF
+ unwinder. */
+ if (! frame_unwinder_is (this_frame, &dwarf2_frame_unwind))
+ error (_("can't compute CFA for this frame"));
+ return get_frame_base (this_frame);
+}
const struct objfile_data *dwarf2_frame_objfile_data;