From: Tom Tromey <tromey@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: RFC: DW_OP_call_frame_cfa, again
Date: Tue, 01 Sep 2009 18:08:00 -0000 [thread overview]
Message-ID: <m3skf6tu5i.fsf@fleche.redhat.com> (raw)
In-Reply-To: <m37hxauldt.fsf@fleche.redhat.com> (Tom Tromey's message of "Tue, 11 Aug 2009 14:49:02 -0600")
>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:
Tom> Here is a new version of my patch to implement DW_OP_call_frame_cfa.
Tom> Previous thread here:
Tom> http://sourceware.org/ml/gdb-patches/2009-06/msg00191.html
Tom> With followup the next month (I wish our mailing list archive handled
Tom> this more nicely):
Tom> http://sourceware.org/ml/gdb-patches/2009-07/msg00570.html
Here is an updated version. This fixes a couple of bugs found by
testing it in Fedora rawhide.
I'm happy with this version, so I plan to check it in next week or so.
Comment soon if you think it needs some change.
Tom
2009-09-01 Tom Tromey <tromey@redhat.com>
* 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.
2009-09-01 Tom Tromey <tromey@redhat.com>
* gdb.dwarf2/callframecfa.exp: New file.
* gdb.dwarf2/callframecfa.S: New file.
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 427f58f..f32a44f 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -309,6 +309,14 @@ 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 +371,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 +1259,20 @@ 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);
+ if (! frame_unwinder_is (this_frame, &dwarf2_frame_unwind))
+ error (_("can't compute CFA for this frame"));
+ return get_frame_base (this_frame);
+}
\f
const struct objfile_data *dwarf2_frame_objfile_data;
diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h
index b203661..dd03d59 100644
--- a/gdb/dwarf2-frame.h
+++ b/gdb/dwarf2-frame.h
@@ -118,4 +118,8 @@ extern const struct frame_base *
void dwarf2_frame_build_info (struct objfile *objfile);
+/* Compute the DWARF CFA for a frame. */
+
+CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame);
+
#endif /* dwarf2-frame.h */
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 2721065..6401e72 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -716,6 +716,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
}
break;
+ case DW_OP_call_frame_cfa:
+ result = (ctx->get_frame_cfa) (ctx->baton);
+ break;
+
case DW_OP_GNU_push_tls_address:
/* Variable is at a constant offset in the thread-local
storage block into the objfile for the current thread and
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 2306e49..6b3a068 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -55,6 +55,9 @@ struct dwarf_expr_context
expression evaluation is complete. */
void (*get_frame_base) (void *baton, gdb_byte **start, size_t *length);
+ /* Return the CFA for the frame. */
+ CORE_ADDR (*get_frame_cfa) (void *baton);
+
/* Return the thread-local storage address for
DW_OP_GNU_push_tls_address. */
CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset);
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index b6c9b11..95ee2f5 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -36,6 +36,7 @@
#include "dwarf2.h"
#include "dwarf2expr.h"
#include "dwarf2loc.h"
+#include "dwarf2-frame.h"
#include "gdb_string.h"
#include "gdb_assert.h"
@@ -194,6 +195,15 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
SYMBOL_NATURAL_NAME (framefunc));
}
+/* Helper function for dwarf2_evaluate_loc_desc. Computes the CFA for
+ the frame in BATON. */
+static CORE_ADDR
+dwarf_expr_frame_cfa (void *baton)
+{
+ struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+ return dwarf2_frame_cfa (debaton->frame);
+}
+
/* Using the objfile specified in BATON, find the address for the
current thread's thread-local storage with offset OFFSET. */
static CORE_ADDR
@@ -237,6 +247,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
ctx->read_reg = dwarf_expr_read_reg;
ctx->read_mem = dwarf_expr_read_mem;
ctx->get_frame_base = dwarf_expr_frame_base;
+ ctx->get_frame_cfa = dwarf_expr_frame_cfa;
ctx->get_tls_address = dwarf_expr_tls_address;
dwarf_expr_eval (ctx, data, size);
@@ -331,6 +342,15 @@ needs_frame_frame_base (void *baton, gdb_byte **start, size_t * length)
nf_baton->needs_frame = 1;
}
+/* CFA accesses require a frame. */
+static CORE_ADDR
+needs_frame_frame_cfa (void *baton)
+{
+ struct needs_frame_baton *nf_baton = baton;
+ nf_baton->needs_frame = 1;
+ return 1;
+}
+
/* Thread-local accesses do require a frame. */
static CORE_ADDR
needs_frame_tls_address (void *baton, CORE_ADDR offset)
@@ -363,6 +383,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
ctx->read_reg = needs_frame_read_reg;
ctx->read_mem = needs_frame_read_mem;
ctx->get_frame_base = needs_frame_frame_base;
+ ctx->get_frame_cfa = needs_frame_frame_cfa;
ctx->get_tls_address = needs_frame_tls_address;
dwarf_expr_eval (ctx, data, size);
diff --git a/gdb/frame.c b/gdb/frame.c
index 67e0607..3f32471 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1843,6 +1843,17 @@ get_frame_args_address (struct frame_info *fi)
return fi->base->this_args (fi, &fi->base_cache);
}
+/* Return true if the frame base for frame FI is BASE; false
+ otherwise. */
+
+int
+frame_unwinder_is (struct frame_info *fi, const struct frame_unwind *unwinder)
+{
+ if (fi->unwind == NULL)
+ fi->unwind = frame_unwind_find_by_frame (fi, &fi->prologue_cache);
+ return fi->unwind == unwinder;
+}
+
/* Level of the selected frame: 0 for innermost, 1 for its caller, ...
or -1 for a NULL frame. */
diff --git a/gdb/frame.h b/gdb/frame.h
index febef5c..611c6d3 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -696,4 +696,10 @@ extern struct frame_info *deprecated_safe_get_selected_frame (void);
extern struct frame_info *create_new_frame (CORE_ADDR base, CORE_ADDR pc);
+/* Return true if the frame unwinder for frame FI is UNWINDER; false
+ otherwise. */
+
+extern int frame_unwinder_is (struct frame_info *fi,
+ const struct frame_unwind *unwinder);
+
#endif /* !defined (FRAME_H) */
next prev parent reply other threads:[~2009-09-01 18:08 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-12 0:52 Tom Tromey
2009-09-01 18:08 ` Tom Tromey [this message]
2009-09-01 23:07 ` Doug Evans
2009-09-01 23:41 ` Tom Tromey
2009-09-01 23:24 ` Pedro Alves
2009-09-01 23:47 ` Tom Tromey
2009-09-02 14:53 ` Tom Tromey
2009-09-02 14:59 ` Pedro Alves
2009-09-02 16:48 ` Tom Tromey
2009-09-02 17:01 ` Pedro Alves
2009-09-01 22:50 ` Daniel Jacobowitz
2009-09-01 23:51 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3skf6tu5i.fsf@fleche.redhat.com \
--to=tromey@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox