aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/dummy-frame.c149
-rw-r--r--gdb/dummy-frame.h2
-rw-r--r--gdb/frame-unwind.c2
4 files changed, 84 insertions, 79 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6d6ce0e4b83..b42caa51882 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2004-08-01 Andrew Cagney <cagney@gnu.org>
+ * dummy-frame.h (dummy_frame_unwind): Replace dummy_frame_sniffer.
+ * frame-unwind.c (frame_unwind_init): Use dummy_frame_unwind.
+ * dummy-frame.c (find_dummy_frame): Delete.
+ (struct dummy_frame_cache, dummy_frame_sniffer)
+ (dummy_frame_prev_register, dummy_frame_this_id)
+ (dummy_frame_unwinder, dummy_frame_unwind): Re-implement dummy
+ frame unwinder using a dummy_frame_cache.
+
+2004-08-01 Andrew Cagney <cagney@gnu.org>
+
* frame.h (frame_save_as_regcache): Declare.
* frame.c (frame_save_as_regcache): New function.
(do_frame_read_register): Replace do_frame_unwind_register.
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index d901214c37c..1945a00d966 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -32,10 +32,6 @@
#include "command.h"
#include "gdbcmd.h"
-static void dummy_frame_this_id (struct frame_info *next_frame,
- void **this_prologue_cache,
- struct frame_id *this_id);
-
static int pc_in_dummy_frame (CORE_ADDR pc);
/* Dummy frame. This saves the processor state just prior to setting
@@ -61,38 +57,6 @@ struct dummy_frame
static struct dummy_frame *dummy_frame_stack = NULL;
-/* Function: find_dummy_frame(pc, fp, sp)
-
- Search the stack of dummy frames for one matching the given PC and
- FP/SP. Unlike pc_in_dummy_frame(), this function doesn't need to
- adjust for DECR_PC_AFTER_BREAK. This is because it is only legal
- to call this function after the PC has been adjusted. */
-
-static struct dummy_frame *
-find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
-{
- struct dummy_frame *dummyframe;
-
- for (dummyframe = dummy_frame_stack; dummyframe != NULL;
- dummyframe = dummyframe->next)
- {
- /* Does the PC fall within the dummy frame's breakpoint
- instruction. If not, discard this one. */
- if (!(pc >= dummyframe->call_lo && pc < dummyframe->call_hi))
- continue;
- /* Does the FP match? */
- /* "infcall.c" explicitly saved the top-of-stack before the
- inferior function call, assume unwind_dummy_id() returns that
- same stack value. */
- if (fp != dummyframe->top)
- continue;
- /* The FP matches this dummy frame. */
- return dummyframe;
- }
-
- return NULL;
-}
-
/* Function: pc_in_call_dummy (pc)
Return true if the PC falls in a dummy frame created by gdb for an
@@ -185,6 +149,63 @@ generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi)
dummy_frame_stack->call_hi = hi;
}
+/* Return the dummy frame cache, it contains both the ID, and a
+ pointer to the regcache. */
+struct dummy_frame_cache
+{
+ struct frame_id this_id;
+ struct regcache *prev_regcache;
+};
+
+int
+dummy_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *next_frame,
+ void **this_prologue_cache)
+{
+ struct dummy_frame *dummyframe;
+ struct frame_id this_id;
+
+ /* When unwinding a normal frame, the stack structure is determined
+ by analyzing the frame's function's code (be it using brute force
+ prologue analysis, or the dwarf2 CFI). In the case of a dummy
+ frame, that simply isn't possible. The PC is either the program
+ entry point, or some random address on the stack. Trying to use
+ that PC to apply standard frame ID unwind techniques is just
+ asking for trouble. */
+ /* Use an architecture specific method to extract the prev's dummy
+ ID from the next frame. Note that this method uses
+ frame_register_unwind to obtain the register values needed to
+ determine the dummy frame's ID. */
+ this_id = gdbarch_unwind_dummy_id (get_frame_arch (next_frame), next_frame);
+
+ /* Use that ID to find the corresponding cache entry. */
+ for (dummyframe = dummy_frame_stack;
+ dummyframe != NULL;
+ dummyframe = dummyframe->next)
+ {
+ /* Does the PC fall within the dummy frame's breakpoint
+ instruction. If not, discard this one. */
+ if (!(this_id.code_addr >= dummyframe->call_lo
+ && this_id.code_addr < dummyframe->call_hi))
+ continue;
+ /* Does the FP match? "infcall.c" explicitly saved the
+ top-of-stack before the inferior function call, assume
+ unwind_dummy_id() returns that same stack value. */
+ if (this_id.stack_addr != dummyframe->top)
+ continue;
+ /* The FP matches this dummy frame. */
+ {
+ struct dummy_frame_cache *cache;
+ cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache);
+ cache->prev_regcache = dummyframe->regcache;
+ cache->this_id = this_id;
+ (*this_prologue_cache) = cache;
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* Given a call-dummy dummy-frame, return the registers. Here the
register value is taken from the local copy of the register buffer. */
@@ -195,14 +216,9 @@ dummy_frame_prev_register (struct frame_info *next_frame,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnum, void *bufferp)
{
- struct dummy_frame *dummy;
- struct frame_id id;
-
- /* Call the ID method which, if at all possible, will set the
- prologue cache. */
- dummy_frame_this_id (next_frame, this_prologue_cache, &id);
- dummy = (*this_prologue_cache);
- gdb_assert (dummy != NULL);
+ /* The dummy-frame sniffer always fills in the cache. */
+ struct dummy_frame_cache *cache = (*this_prologue_cache);
+ gdb_assert (cache != NULL);
/* Describe the register's location. Generic dummy frames always
have the register value in an ``expression''. */
@@ -218,7 +234,7 @@ dummy_frame_prev_register (struct frame_info *next_frame,
/* Use the regcache_cooked_read() method so that it, on the fly,
constructs either a raw or pseudo register from the raw
register cache. */
- regcache_cooked_read (dummy->regcache, regnum, bufferp);
+ regcache_cooked_read (cache->prev_regcache, regnum, bufferp);
}
}
@@ -233,45 +249,24 @@ dummy_frame_this_id (struct frame_info *next_frame,
void **this_prologue_cache,
struct frame_id *this_id)
{
- struct dummy_frame *dummy = (*this_prologue_cache);
- if (dummy != NULL)
- {
- (*this_id) = dummy->id;
- return;
- }
- /* When unwinding a normal frame, the stack structure is determined
- by analyzing the frame's function's code (be it using brute force
- prologue analysis, or the dwarf2 CFI). In the case of a dummy
- frame, that simply isn't possible. The PC is either the program
- entry point, or some random address on the stack. Trying to use
- that PC to apply standard frame ID unwind techniques is just
- asking for trouble. */
- /* Use an architecture specific method to extract the prev's dummy
- ID from the next frame. Note that this method uses
- frame_register_unwind to obtain the register values needed to
- determine the dummy frame's ID. */
- gdb_assert (gdbarch_unwind_dummy_id_p (current_gdbarch));
- (*this_id) = gdbarch_unwind_dummy_id (current_gdbarch, next_frame);
- (*this_prologue_cache) = find_dummy_frame ((*this_id).code_addr,
- (*this_id).stack_addr);
+ /* The dummy-frame sniffer always fills in the cache. */
+ struct dummy_frame_cache *cache = (*this_prologue_cache);
+ gdb_assert (cache != NULL);
+ (*this_id) = cache->this_id;
}
-static struct frame_unwind dummy_frame_unwind =
+static const struct frame_unwind dummy_frame_unwinder =
{
DUMMY_FRAME,
dummy_frame_this_id,
- dummy_frame_prev_register
+ dummy_frame_prev_register,
+ NULL,
+ dummy_frame_sniffer,
};
-const struct frame_unwind *
-dummy_frame_sniffer (struct frame_info *next_frame)
-{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
- if (pc_in_dummy_frame (pc))
- return &dummy_frame_unwind;
- else
- return NULL;
-}
+const struct frame_unwind *const dummy_frame_unwind = {
+ &dummy_frame_unwinder
+};
static void
fprint_dummy_frames (struct ui_file *file)
diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h
index 07f8f5a57fa..26c2522a7cf 100644
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -30,6 +30,6 @@ struct frame_id;
/* If the PC falls in a dummy frame, return a dummy frame
unwinder. */
-extern const struct frame_unwind *dummy_frame_sniffer (struct frame_info *next_frame);
+extern const struct frame_unwind *const dummy_frame_unwind;
#endif /* !defined (DUMMY_FRAME_H) */
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 166219ae544..9e30c7802fe 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -50,7 +50,7 @@ frame_unwind_init (struct obstack *obstack)
/* Start the table out with a few default sniffers. OSABI code
can't override this. */
table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
- table->list->sniffer = dummy_frame_sniffer;
+ table->list->unwinder = dummy_frame_unwind;
/* The insertion point for OSABI sniffers. */
table->osabi_head = &table->list->next;
return table;