diff options
author | Tom Tromey <tromey@redhat.com> | 2009-09-02 14:53:57 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2009-09-02 14:53:57 +0000 |
commit | e78022079ce4c50f042bb5287665a4f38704a71b (patch) | |
tree | 76c5d22b601a7a3ab15067483733204fe114f9db /gdb/dwarf2-frame.c | |
parent | d34089166b3e7b60151752997db33c3f28016349 (diff) | |
download | gdb-e78022079ce4c50f042bb5287665a4f38704a71b.zip gdb-e78022079ce4c50f042bb5287665a4f38704a71b.tar.gz gdb-e78022079ce4c50f042bb5287665a4f38704a71b.tar.bz2 |
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.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 427f58f..f9ca067 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; |