summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-01-20 00:38:14 +0000
committerAndrew Cagney <cagney@redhat.com>2003-01-20 00:38:14 +0000
commit52fd4aea56936792d4404e3050d8b1e2d1d774ad (patch)
tree6080fa94bf4797b551bf7075bc137b322e7fee2a
parent5099a23f897d755cfef2d88458049d3565c23032 (diff)
downloadgdb-52fd4aea56936792d4404e3050d8b1e2d1d774ad.tar.gz
Merge branch with mainline:
POP_FRAME_P; frame-unwind.h.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/d10v-frame.c17
-rw-r--r--gdb/d10v-tdep.c13
-rw-r--r--gdb/dummy-frame.c106
-rw-r--r--gdb/dummy-frame.h35
-rw-r--r--gdb/frame-unwind.h71
-rw-r--r--gdb/frame.c195
-rw-r--r--gdb/frame.h27
-rw-r--r--gdb/gdbarch.c20
-rw-r--r--gdb/gdbarch.h26
-rwxr-xr-xgdb/gdbarch.sh10
-rw-r--r--gdb/infrun.c12
-rw-r--r--gdb/legacy-frame.c22
-rw-r--r--gdb/legacy-frame.h39
-rw-r--r--gdb/mi/mi-main.c8
-rw-r--r--gdb/sentinel-frame.c18
-rw-r--r--gdb/sentinel-frame.h31
-rw-r--r--gdb/stack.c170
-rw-r--r--gdb/thread.c4
-rw-r--r--gdb/valops.c5
21 files changed, 405 insertions, 437 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1029e8564c8..7c8fe9cfdbc 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
2003-01-19 Andrew Cagney <ac131313@redhat.com>
+ * Makefile.in: Update.
+ * d10v-frame.c, d10v-tdep.c: Update.
+ * infrun.c, stack.c, thread.c, valops.c, mi/mi-main.c: Ditto.
+ * legacy-frame.c, legacy-frame.h, sentinel-frame.c: Ditto.
+ * sentinel-frame.h: Ditto.
+ * dummy-frame.c, dummy-frame.h, frame-unwind.h: Ditto.
+ * frame.c, frame.h: Ditto.
+ * gdbarch.c, gdbarch.h, gdbarch.sh: Ditto.
+
+2003-01-19 Andrew Cagney <ac131313@redhat.com>
+
* d10v-frame.c: Use D10V_RET1_REGNUM.
(saved_regs_unwinder): Don't use get_frame_saved_regs.
* frame.c (get_prev_frame): Always initialize frame.frame.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 4f130510c35..4c89fd71247 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1688,7 +1688,7 @@ frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \
$(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(builtin_regs_h) \
$(gdb_obstack_h) $(dummy_frame_h) $(sentinel_frame_h) \
$(legacy_frame_h) $(gdbcore_h) $(annotate_h) $(language_h) \
- $(ui_out_h)
+ $(command_h) $(gdbcmd_h)
frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \
$(gdb_assert_h) $(dummy_frame_h) $(legacy_frame_h)
frv-tdep.o: frv-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \
diff --git a/gdb/d10v-frame.c b/gdb/d10v-frame.c
index 45e2dd9417f..4a8ba9b483c 100644
--- a/gdb/d10v-frame.c
+++ b/gdb/d10v-frame.c
@@ -109,7 +109,7 @@ prologue_find_regs (unsigned short op, struct frame_unwind_cache *info,
struct frame_unwind_cache *
d10v_frame_unwind_cache (struct frame_info *fi,
- struct frame_unwind_cache **cache)
+ void **cache)
{
CORE_ADDR fp, pc;
unsigned long op;
@@ -230,7 +230,7 @@ d10v_frame_unwind_cache (struct frame_info *fi,
static CORE_ADDR
d10v_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache)
+ void **cache)
{
struct frame_unwind_cache *info = d10v_frame_unwind_cache (frame, cache);
return info->return_pc;
@@ -238,7 +238,7 @@ d10v_frame_pc_unwind (struct frame_info *frame,
static void
d10v_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
+ void **cache,
struct frame_id *id)
{
struct frame_unwind_cache *info = d10v_frame_unwind_cache (frame, cache);
@@ -329,7 +329,7 @@ saved_regs_unwinder (struct frame_info *frame,
static void
d10v_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
+ void **cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnump, void *bufferp)
@@ -340,11 +340,11 @@ d10v_frame_register_unwind (struct frame_info *frame,
}
-void
-do_d10v_pop_frame (struct frame_info *fi)
+static void
+d10v_frame_pop (struct frame_info *fi, void **unwind_cache,
+ struct regcache *regcache)
{
- struct frame_unwind_cache *info =
- d10v_frame_unwind_cache (fi, &fi->unwind_cache);
+ struct frame_unwind_cache *info = d10v_frame_unwind_cache (fi, unwind_cache);
CORE_ADDR fp;
int regnum;
char raw_buffer[8];
@@ -380,6 +380,7 @@ do_d10v_pop_frame (struct frame_info *fi)
}
static struct frame_unwind d10v_frame_unwind = {
+ d10v_frame_pop,
d10v_frame_pc_unwind,
d10v_frame_id_unwind,
d10v_frame_register_unwind
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c
index 353efe25b5d..6a7073f22b9 100644
--- a/gdb/d10v-tdep.c
+++ b/gdb/d10v-tdep.c
@@ -84,8 +84,6 @@ static int prologue_find_regs (unsigned short op, struct frame_info *fi,
static void d10v_frame_init_saved_regs (struct frame_info *);
-void do_d10v_pop_frame (struct frame_info *fi);
-
static int
d10v_frame_chain_valid (CORE_ADDR chain, struct frame_info *frame)
{
@@ -510,15 +508,6 @@ d10v_saved_pc_after_call (struct frame_info *frame)
| D10V_IMEM_START);
}
-/* Discard from the stack the innermost frame, restoring all saved
- registers. */
-
-static void
-d10v_pop_frame (void)
-{
- generic_pop_current_frame (do_d10v_pop_frame);
-}
-
static int
check_prologue (unsigned short op)
{
@@ -1552,8 +1541,6 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_frame_init_saved_regs (gdbarch, d10v_frame_init_saved_regs);
- set_gdbarch_pop_frame (gdbarch, d10v_pop_frame);
-
set_gdbarch_skip_prologue (gdbarch, d10v_skip_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_decr_pc_after_break (gdbarch, 4);
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index 83748127d07..5b638306fd3 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -24,19 +24,19 @@
#include "defs.h"
#include "dummy-frame.h"
-#include "frame-unwind.h"
#include "regcache.h"
#include "frame.h"
#include "inferior.h"
#include "gdb_assert.h"
+#include "frame-unwind.h"
/* Dummy frame. This saves the processor state just prior to setting
up the inferior function call. Older targets save the registers
on the target stack (but that really slows down function calls). */
-struct frame_unwind_cache
+struct dummy_frame
{
- struct frame_unwind_cache *next;
+ struct dummy_frame *next;
/* These values belong to the caller (the previous frame, the frame
that this unwinds back to). */
@@ -53,7 +53,7 @@ struct frame_unwind_cache
CORE_ADDR call_hi;
};
-static struct frame_unwind_cache *dummy_frame_stack = NULL;
+static struct dummy_frame *dummy_frame_stack = NULL;
/* Function: find_dummy_frame(pc, fp, sp)
@@ -62,10 +62,10 @@ static struct frame_unwind_cache *dummy_frame_stack = NULL;
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 frame_unwind_cache *
+static struct dummy_frame *
find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
{
- struct frame_unwind_cache *dummyframe;
+ struct dummy_frame *dummyframe;
for (dummyframe = dummy_frame_stack; dummyframe != NULL;
dummyframe = dummyframe->next)
@@ -104,9 +104,8 @@ find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
return NULL;
}
-struct frame_unwind_cache *
-cached_find_dummy_frame (struct frame_info *frame,
- struct frame_unwind_cache **cache)
+struct dummy_frame *
+cached_find_dummy_frame (struct frame_info *frame, void **cache)
{
if ((*cache) == NULL)
(*cache) = find_dummy_frame (get_frame_pc (frame), get_frame_base (frame));
@@ -116,7 +115,7 @@ cached_find_dummy_frame (struct frame_info *frame,
struct regcache *
generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
{
- struct frame_unwind_cache *dummy = find_dummy_frame (pc, fp);
+ struct dummy_frame *dummy = find_dummy_frame (pc, fp);
if (dummy != NULL)
return dummy->regcache;
else
@@ -160,7 +159,7 @@ generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
int
pc_in_dummy_frame (CORE_ADDR pc)
{
- struct frame_unwind_cache *dummyframe;
+ struct dummy_frame *dummyframe;
for (dummyframe = dummy_frame_stack;
dummyframe != NULL;
dummyframe = dummyframe->next)
@@ -209,7 +208,7 @@ deprecated_read_register_dummy (CORE_ADDR pc, CORE_ADDR fp, int regno)
void
generic_push_dummy_frame (void)
{
- struct frame_unwind_cache *dummy_frame;
+ struct dummy_frame *dummy_frame;
CORE_ADDR fp = get_frame_base (get_current_frame ());
/* check to see if there are stale dummy frames,
@@ -228,7 +227,7 @@ generic_push_dummy_frame (void)
else
dummy_frame = dummy_frame->next;
- dummy_frame = XMALLOC (struct frame_unwind_cache);
+ dummy_frame = xmalloc (sizeof (struct dummy_frame));
dummy_frame->regcache = regcache_xmalloc (current_gdbarch);
dummy_frame->pc = read_pc ();
@@ -271,25 +270,63 @@ generic_pop_current_frame (void (*popper) (struct frame_info * frame))
(*popper) (frame);
}
-/* Function: pop_dummy_frame
- Restore the machine state from a saved dummy stack frame. */
+/* Discard the innermost dummy frame from the dummy frame stack
+ (passed in as a parameter). */
+
+static void
+discard_innermost_dummy (struct dummy_frame **stack)
+{
+ struct dummy_frame *tbd = (*stack);
+ (*stack) = (*stack)->next;
+ regcache_xfree (tbd->regcache);
+ xfree (tbd);
+}
+
+/* Function: dummy_frame_pop. Restore the machine state from a saved
+ dummy stack frame. */
+
+static void
+dummy_frame_pop (struct frame_info *fi, void **cache,
+ struct regcache *regcache)
+{
+ struct dummy_frame *dummy = cached_find_dummy_frame (fi, cache);
+
+ /* If it isn't, what are we even doing here? */
+ gdb_assert (get_frame_type (fi) == DUMMY_FRAME);
+
+ if (dummy == NULL)
+ error ("Can't pop dummy frame!");
+
+ /* Discard all dummy frames up-to but not including this one. */
+ while (dummy_frame_stack != dummy)
+ discard_innermost_dummy (&dummy_frame_stack);
+
+ /* Restore this one. */
+ regcache_cpy (regcache, dummy->regcache);
+ flush_cached_frames ();
+
+ /* Now discard it. */
+ discard_innermost_dummy (&dummy_frame_stack);
+
+ /* Note: target changed would be better. Registers, memory and
+ frame are all invalid. */
+ flush_cached_frames ();
+}
void
generic_pop_dummy_frame (void)
{
- struct frame_unwind_cache *dummy_frame = dummy_frame_stack;
+ struct dummy_frame *dummy_frame = dummy_frame_stack;
/* FIXME: what if the first frame isn't the right one, eg..
because one call-by-hand function has done a longjmp into another one? */
if (!dummy_frame)
error ("Can't pop dummy frame!");
- dummy_frame_stack = dummy_frame->next;
regcache_cpy (current_regcache, dummy_frame->regcache);
flush_cached_frames ();
- regcache_xfree (dummy_frame->regcache);
- xfree (dummy_frame);
+ discard_innermost_dummy (&dummy_frame_stack);
}
/* Function: fix_call_dummy
@@ -306,14 +343,13 @@ generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
/* Given a call-dummy dummy-frame, return the registers. Here the
register value is taken from the local copy of the register buffer. */
-void
-dummy_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
+static void
+dummy_frame_register_unwind (struct frame_info *frame, void **cache,
int regnum, int *optimized,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnum, void *bufferp)
{
- struct frame_unwind_cache *dummy = cached_find_dummy_frame (frame, cache);
+ struct dummy_frame *dummy = cached_find_dummy_frame (frame, cache);
gdb_assert (dummy != NULL);
/* Describe the register's location. Generic dummy frames always
@@ -334,11 +370,14 @@ dummy_frame_register_unwind (struct frame_info *frame,
}
}
-CORE_ADDR
+/* Assuming that FRAME is a dummy, return the resume address for the
+ previous frame. */
+
+static CORE_ADDR
dummy_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache)
+ void **cache)
{
- struct frame_unwind_cache *dummy = cached_find_dummy_frame (frame, cache);
+ struct dummy_frame *dummy = cached_find_dummy_frame (frame, cache);
/* Oops! In a dummy-frame but can't find the stack dummy. Pretend
that the frame doesn't unwind. Should this function instead
return a has-no-caller indication? */
@@ -348,23 +387,27 @@ dummy_frame_pc_unwind (struct frame_info *frame,
}
-void
+/* Assuming that FRAME is a dummy, return the ID of the calling frame
+ (the frame that the dummy has the saved state of). */
+
+static void
dummy_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
+ void **cache,
struct frame_id *id)
{
- struct frame_unwind_cache *dummy = cached_find_dummy_frame (frame, cache);
+ struct dummy_frame *dummy = cached_find_dummy_frame (frame, cache);
/* Oops! In a dummy-frame but can't find the stack dummy. Pretend
that the frame doesn't unwind. Should this function instead
return a has-no-caller indication? */
if (dummy == NULL)
- *id = null_frame_id;
+ (*id) = null_frame_id;
else
- *id = dummy->id;
+ (*id) = dummy->id;
}
static struct frame_unwind dummy_frame_unwind =
{
+ dummy_frame_pop,
dummy_frame_pc_unwind,
dummy_frame_id_unwind,
dummy_frame_register_unwind
@@ -380,4 +423,3 @@ dummy_frame_p (CORE_ADDR pc)
else
return NULL;
}
-
diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h
index 39bf1a9faf6..2d0342115a2 100644
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -22,17 +22,10 @@
#if !defined (DUMMY_FRAME_H)
#define DUMMY_FRAME_H 1
-/* Does the PC belong to a dummy frame? If it does, return a dummy
- frame unwind descriptor. */
-
-struct frame_unwind;
-extern const struct frame_unwind *dummy_frame_p (CORE_ADDR pc);
-
-
struct frame_info;
struct regcache;
+struct frame_unwind;
struct frame_id;
-struct frame_unwind_cache;
/* GENERIC DUMMY FRAMES
@@ -51,30 +44,10 @@ struct frame_unwind_cache;
generic_{file,func}_frame_chain_valid and FIX_CALL_DUMMY as
generic_fix_call_dummy. */
-/* Assuming that FRAME is a dummy, return a register value for the
- previous frame. */
+/* If the PC falls in a dummy frame, return a dummy frame
+ unwinder. */
-extern void dummy_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- int regnum,
- int *optimized,
- enum lval_type *lvalp,
- CORE_ADDR *addrp,
- int *realnump,
- void *valuep);
-
-/* Assuming that FRAME is a dummy, return the resume address for the
- previous frame. */
-
-extern CORE_ADDR dummy_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache);
-
-/* Assuming that FRAME is a dummy, return the ID of the calling frame
- (the frame that the dummy has the saved state of). */
-
-extern void dummy_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- struct frame_id *id);
+extern const struct frame_unwind *dummy_frame_p (CORE_ADDR pc);
/* Does the PC fall in a dummy frame?
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 5c82b6dda28..2c67c969fb1 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -23,26 +23,28 @@
#define FRAME_UNWIND_H 1
struct frame_info;
-struct frame_unwind_cache;
-struct frame_unwind;
struct frame_id;
+struct frame_unwind;
struct gdbarch;
+struct regcache;
-/* Return the corresponding frame descriptor this method is capable of
- unwinding the frame containing PC. */
+/* Return the frame unwind methods for the function that contains PC,
+ or NULL if this this unwinder can't handle this frame. */
typedef const struct frame_unwind *(frame_unwind_p_ftype) (CORE_ADDR pc);
-/* Append a descriptor predicate. Descriptors are polled in append
- order. The list is initialized with just the dummy frame. */
+/* Add a frame unwinder to the list. The predicates are polled in the
+ order that they are appended. The initial list contains the dummy
+ frame's predicate. */
extern void frame_unwind_append_predicate (struct gdbarch *gdbarch,
frame_unwind_p_ftype *p);
-/* Iterate through the list of frame descriptor predicates for the
- first one to return a frame descriptor. */
+/* Iterate through the list of frame unwinders until one returns an
+ implementation. */
-extern const struct frame_unwind *frame_unwind_find_by_pc (struct gdbarch *gdbarch,
+extern const struct frame_unwind *frame_unwind_find_by_pc (struct gdbarch
+ *gdbarch,
CORE_ADDR pc);
/* Return the location (and possibly value) of REGNUM for the previous
@@ -59,34 +61,51 @@ extern const struct frame_unwind *frame_unwind_find_by_pc (struct gdbarch *gdbar
request for the value of "o1" for the previous frame would be found
in the register "i1" in this FRAME. */
-typedef void (frame_register_unwind_ftype) (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- int regnum,
- int *optimized,
- enum lval_type *lvalp,
- CORE_ADDR *addrp,
- int *realnump,
- void *valuep);
+typedef void (frame_unwind_reg_ftype) (struct frame_info * frame,
+ void **unwind_cache,
+ int regnum,
+ int *optimized,
+ enum lval_type * lvalp,
+ CORE_ADDR *addrp,
+ int *realnump, void *valuep);
/* Same as for registers above, but return the address at which the
calling frame would resume. */
-typedef CORE_ADDR (frame_pc_unwind_ftype) (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache);
+typedef CORE_ADDR (frame_unwind_pc_ftype) (struct frame_info * frame,
+ void **unwind_cache);
/* Same as for registers above, but return the ID of the frame that
called this one. */
-typedef void (frame_id_unwind_ftype) (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- struct frame_id *id);
+typedef void (frame_unwind_id_ftype) (struct frame_info * frame,
+ void **unwind_cache,
+ struct frame_id * id);
+
+/* Discard the frame by restoring the registers (in regcache) back to
+ that of the caller. */
+/* NOTE: cagney/2003-01-19: While at present the callers all pop each
+ frame in turn, the implementor should try to code things so that
+ any frame can be popped directly. */
+/* FIXME: cagney/2003-01-19: Since both FRAME and REGCACHE refer to a
+ common register cache, care must be taken when restoring the
+ registers. The `correct fix' is to first first save the registers
+ in a scratch cache, and second write that scratch cache back to to
+ the real register cache. */
+
+typedef void (frame_unwind_pop_ftype) (struct frame_info *frame,
+ void **unwind_cache,
+ struct regcache *regcache);
struct frame_unwind
{
- /* FIXME: Should the frame's type go here? */
- frame_pc_unwind_ftype *pc;
- frame_id_unwind_ftype *id;
- frame_register_unwind_ftype *reg;
+ /* Should the frame's type go here? */
+ /* Should an attribute indicating the frame's address-in-block go
+ here? */
+ frame_unwind_pop_ftype *pop;
+ frame_unwind_pc_ftype *pc;
+ frame_unwind_id_ftype *id;
+ frame_unwind_reg_ftype *reg;
};
#endif
diff --git a/gdb/frame.c b/gdb/frame.c
index bcad061eed5..40bf17643c9 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -36,7 +36,13 @@
#include "gdbcore.h"
#include "annotate.h"
#include "language.h"
-#include "ui-out.h"
+#include "frame-unwind.h"
+#include "command.h"
+#include "gdbcmd.h"
+
+/* Flag to indicate whether backtraces should stop at main. */
+
+static int backtrace_below_main;
/* Return a frame uniq ID that can be used to, later, re-find the
frame. */
@@ -57,29 +63,6 @@ get_frame_id (struct frame_info *fi)
}
}
-struct frame_id
-frame_id_unwind (struct frame_info *frame)
-{
- if (!frame->id_unwind_cache_p)
- {
- frame->unwind->id (frame, &frame->unwind_cache, &frame->id_unwind_cache);
- frame->id_unwind_cache_p = 1;
- }
- return frame->id_unwind_cache;
-}
-
-void
-deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base)
-{
- /* See comment in "frame.h". */
- frame->frame = base;
- gdb_assert (frame->next != NULL);
- gdb_assert (frame->next->id_unwind_cache_p);
- gdb_assert (frame->next->pc_unwind_cache_p);
- frame->next->id_unwind_cache.base = base;
- frame->next->id_unwind_cache.pc = frame->next->pc_unwind_cache;
-}
-
const struct frame_id null_frame_id; /* All zeros. */
struct frame_id
@@ -148,6 +131,40 @@ frame_find_by_id (struct frame_id id)
return NULL;
}
+CORE_ADDR
+frame_pc_unwind (struct frame_info *frame)
+{
+ if (!frame->pc_unwind_cache_p)
+ {
+ frame->pc_unwind_cache = frame->unwind->pc (frame, &frame->unwind_cache);
+ frame->pc_unwind_cache_p = 1;
+ }
+ return frame->pc_unwind_cache;
+}
+
+struct frame_id
+frame_id_unwind (struct frame_info *frame)
+{
+ if (!frame->id_unwind_cache_p)
+ {
+ frame->unwind->id (frame, &frame->unwind_cache, &frame->id_unwind_cache);
+ frame->id_unwind_cache_p = 1;
+ }
+ return frame->id_unwind_cache;
+}
+
+void
+frame_pop (struct frame_info *frame)
+{
+ /* FIXME: cagney/2003-01-18: There is probably a chicken-egg problem
+ with passing in current_regcache. The pop function needs to be
+ written carefully so as to not overwrite registers whose [old]
+ values are needed to restore other registers. Instead, this code
+ should pass in a scratch cache and, as a second step, restore the
+ registers using that. */
+ frame->unwind->pop (frame, &frame->unwind_cache, current_regcache);
+ flush_cached_frames ();
+}
void
frame_register_unwind (struct frame_info *frame, int regnum,
@@ -644,8 +661,8 @@ reinit_frame_cache (void)
}
}
-/* Create the previous frame using the original INIT_EXTRA_INFO
- method. */
+/* Create the previous frame using the deprecated methods
+ INIT_EXTRA_INFO, INIT_FRAME_PC and INIT_FRAME_PC_FIRST. */
static struct frame_info *
legacy_get_prev_frame (struct frame_info *next_frame)
@@ -654,7 +671,8 @@ legacy_get_prev_frame (struct frame_info *next_frame)
struct frame_info *prev;
int fromleaf;
- /* This code doesn't work with the sentinal frame. */
+ /* This code only works on normal frames. A sentinel frame, where
+ the level is -1, should never reach this code. */
gdb_assert (next_frame->level >= 0);
/* On some machines it is possible to call a function without
@@ -666,7 +684,7 @@ legacy_get_prev_frame (struct frame_info *next_frame)
/* Still don't want to worry about this except on the innermost
frame. This macro will set FROMLEAF if NEXT_FRAME is a frameless
function invocation. */
- if (get_next_frame (next_frame) == NULL)
+ if (next_frame->level == 0)
/* FIXME: 2002-11-09: Frameless functions can occure anywhere in
the frame chain, not just the inner most frame! The generic,
per-architecture, frame code should handle this and the below
@@ -909,13 +927,13 @@ get_prev_frame (struct frame_info *next_frame)
gdb_assert (next_frame != NULL);
if (next_frame->level >= 0
- /* && !backtrace_below_main */
+ && !backtrace_below_main
&& inside_main_func (get_frame_pc (next_frame)))
- /* Don't unwind past main(), always unwind the sentinel frame.
+ /* Don't unwind past main(), bug always unwind the sentinel frame.
Note, this is done _before_ the frame has been marked as
previously unwound. That way if the user later decides to
- allow unwinds past main(), they can just happen. */
- return 0;
+ allow unwinds past main(), that just happens. */
+ return NULL;
/* Only try to do the unwind once. */
if (next_frame->prev_p)
@@ -933,16 +951,26 @@ get_prev_frame (struct frame_info *next_frame)
if (inside_entry_file (get_frame_pc (next_frame)))
return NULL;
+ /* If any of the old frame initialization methods are around, use
+ the legacy get_prev_frame method. Just don't try to unwind a
+ sentinel frame using that method - it doesn't work. All sentinal
+ frames use the new unwind code. */
if ((DEPRECATED_INIT_FRAME_PC_P ()
- || DEPRECATED_INIT_FRAME_PC_FIRST_P ())
+ || DEPRECATED_INIT_FRAME_PC_FIRST_P ()
+ || INIT_EXTRA_FRAME_INFO_P ())
&& next_frame->level >= 0)
- /* Don't try to unwind the sentinal frame using the old code. */
return legacy_get_prev_frame (next_frame);
- /* Allocate the new frame but do not wire it in. Some (bad) code in
- INIT_EXTRA_FRAME_INFO tries to look along frame->next to pull
- some fancy tricks (of course such code is, by definition,
- recursive). Try to prevent it. */
+ /* Allocate the new frame but do not wire it in to the frame chain.
+ Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along
+ frame->next to pull some fancy tricks (of course such code is, by
+ definition, recursive). Try to prevent it.
+
+ There is no reason to worry about memory leaks, should the
+ remainder of the function fail. The allocated memory will be
+ quickly reclaimed when the frame cache is flushed, and the `we've
+ been here before' check above will stop repeated memory
+ allocation calls. */
prev_frame = FRAME_OBSTACK_ZALLOC (struct frame_info);
prev_frame->level = next_frame->level + 1;
@@ -989,16 +1017,18 @@ get_prev_frame (struct frame_info *next_frame)
next_frame->prev = prev_frame;
prev_frame->next = next_frame;
- /* NOTE: cagney/2002-12-18: Eventually this call will go away.
- Instead of initializing extra info, all frames will use the
- frame_cache (passed to the unwind functions) to store extra frame
- info. */
- /* NOTE: cagney/2003-01-11: Legacy targets, when having the sentinel
- frame unwound, rely on this call. */
+ /* FIXME: cagney/2002-01-19: This call will go away. Instead of
+ initializing extra info, all frames will use the frame_cache
+ (passed to the unwind functions) to store additional frame info.
+ Unfortunatly legacy targets can't use legacy_get_prev_frame() to
+ unwind the sentinel frame and, consequently, are forced to take
+ this code path and rely on the below call to INIT_EXTR_FRAME_INFO
+ to initialize the inner-most frame. */
if (INIT_EXTRA_FRAME_INFO_P ())
- /* NOTE: This code doesn't bother trying to sort out frameless
- functions. That is left to the target. */
- INIT_EXTRA_FRAME_INFO (0, prev_frame);
+ {
+ gdb_assert (prev_frame->level == 0);
+ INIT_EXTRA_FRAME_INFO (0, prev_frame);
+ }
return prev_frame;
}
@@ -1010,35 +1040,6 @@ get_frame_pc (struct frame_info *frame)
return frame->pc;
}
-CORE_ADDR
-frame_pc_unwind (struct frame_info *frame)
-{
- if (!frame->pc_unwind_cache_p)
- {
- frame->pc_unwind_cache = frame->unwind->pc (frame, &frame->unwind_cache);
- frame->pc_unwind_cache_p = 1;
- }
- return frame->pc_unwind_cache;
-}
-
-void
-deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
-{
- /* See comment in "frame.h". */
- frame->pc = pc;
- gdb_assert (frame->next != NULL);
- /* Got a bucket? Legacy code that handles dummy frames directly
- doesn't always use the unwind function to determine the dummy
- frame's PC. Consequently, it is possible for this function to be
- called when the next frame's pc unwind cache isn't valid. */
- if (frame->next->pc_unwind_cache_p)
- frame->next->pc_unwind_cache = pc;
- /* Since the PC is unwound before the frame ID, only need to update
- the frame ID's PC when it has been unwound. */
- if (frame->next->id_unwind_cache_p)
- frame->next->id_unwind_cache.pc = pc;
-}
-
static int
pc_notcurrent (struct frame_info *frame)
{
@@ -1149,6 +1150,31 @@ frame_extra_info_zalloc (struct frame_info *fi, long size)
}
void
+deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
+{
+ /* See comment in "frame.h". */
+ frame->pc = pc;
+ gdb_assert (frame->next != NULL);
+ /* Got a bucket? Legacy code that handles dummy frames directly
+ doesn't always use the unwind function to determine the dummy
+ frame's PC. Consequently, it is possible for this function to be
+ called when the next frame's pc unwind cache isn't valid. */
+ if (frame->next->pc_unwind_cache_p)
+ frame->next->pc_unwind_cache = pc;
+ /* Since the PC is unwound before the frame ID, only need to update
+ the frame ID's PC when it has been unwound. */
+ if (frame->next->id_unwind_cache_p)
+ frame->next->id_unwind_cache.pc = pc;
+}
+
+void
+deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base)
+{
+ /* See comment in "frame.h". */
+ frame->frame = base;
+}
+
+void
deprecated_set_frame_saved_regs_hack (struct frame_info *frame,
CORE_ADDR *saved_regs)
{
@@ -1220,4 +1246,21 @@ void
_initialize_frame (void)
{
obstack_init (&frame_cache_obstack);
+
+ /* FIXME: cagney/2003-01-19: This command needs a rename. Suggest
+ `set backtrace {past,beyond,...}-main'. Also suggest adding `set
+ backtrace ...-start' to control backtraces past start. The
+ problem with `below' is that it stops the `up' command. */
+
+ add_setshow_boolean_cmd ("backtrace-below-main", class_obscure,
+ &backtrace_below_main, "\
+Set whether backtraces should continue past \"main\".\n\
+Normally the caller of \"main\" is not of interest, so GDB will terminate\n\
+the backtrace at \"main\". Set this variable if you need to see the rest\n\
+of the stack trace.", "\
+Show whether backtraces should continue past \"main\".\n\
+Normally the caller of \"main\" is not of interest, so GDB will terminate\n\
+the backtrace at \"main\". Set this variable if you need to see the rest\n\
+of the stack trace.",
+ NULL, NULL, &setlist, &showlist);
}
diff --git a/gdb/frame.h b/gdb/frame.h
index 6b80afc3136..260a817712b 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -24,14 +24,12 @@
#define FRAME_H 1
struct symtab_and_line;
+struct frame_unwind;
/* The frame object. */
struct frame_info;
-/* The frame unwind cache object. */
-struct frame_unwind_cache;
-
/* The frame object's ID. This provides a per-frame unique identifier
that can be used to relocate a `struct frame_info' after a target
resume or a frame cache destruct. It of course assumes that the
@@ -308,10 +306,9 @@ extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
caller's frame. */
extern struct frame_id frame_id_unwind (struct frame_info *frame);
-
-/* FIXME: cagney/2003-01-12: Once `struct frame_info' has been made
- opaque, this include can go. */
-#include "frame-unwind.h"
+/* Discard the specified frame. Restoring the registers to the state
+ of the caller. */
+extern void frame_pop (struct frame_info *frame);
/* Describe the saved registers of a frame. */
@@ -398,14 +395,16 @@ struct frame_info
/* Unwind cache shared between the unwind functions - they had
better all agree as to the contents. */
- struct frame_unwind_cache *unwind_cache;
+ void *unwind_cache;
+
+ /* The frame's unwinder. */
const struct frame_unwind *unwind;
- /* Cache for the unwound PC value. */
+ /* Cached copy of the previous frame's resume address. */
int pc_unwind_cache_p;
CORE_ADDR pc_unwind_cache;
- /* Cache for the unwound frame ID value. */
+ /* Cached copy of the previous frame's ID. */
int id_unwind_cache_p;
struct frame_id id_unwind_cache;
@@ -516,8 +515,6 @@ extern void show_and_print_stack_frame (struct frame_info *fi, int level,
extern void print_stack_frame (struct frame_info *, int, int);
-extern void print_only_stack_frame (struct frame_info *, int, int);
-
extern void show_stack_frame (struct frame_info *);
extern void print_frame_info (struct frame_info *, int, int, int);
@@ -641,6 +638,12 @@ extern CORE_ADDR *get_frame_saved_regs (struct frame_info *);
overhead of unnecessary prologue analysis. */
extern void deprecated_update_frame_pc_hack (struct frame_info *frame,
CORE_ADDR pc);
+
+/* FIXME: cagney/2002-12-18: Has the frame's base changed? Or to be
+ more exact, whas that initial guess at the frame's base as returned
+ by read_fp() wrong. If it was, fix it. This shouldn't be
+ necessary since the code should be getting the frame's base correct
+ from the outset. */
extern void deprecated_update_frame_base_hack (struct frame_info *frame,
CORE_ADDR base);
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 069e56666e1..bd19793ff15 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -728,9 +728,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
&& (gdbarch->push_dummy_frame == 0))
fprintf_unfiltered (log, "\n\tpush_dummy_frame");
/* Skip verify of push_return_address, has predicate */
- if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
- && (gdbarch->pop_frame == 0))
- fprintf_unfiltered (log, "\n\tpop_frame");
+ /* Skip verify of pop_frame, has predicate */
if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
&& (gdbarch->store_struct_return == 0))
fprintf_unfiltered (log, "\n\tstore_struct_return");
@@ -1761,6 +1759,15 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
(long) current_gdbarch->pointer_to_address
/*POINTER_TO_ADDRESS ()*/);
#endif
+#ifdef POP_FRAME_P
+ fprintf_unfiltered (file,
+ "gdbarch_dump: %s # %s\n",
+ "POP_FRAME_P()",
+ XSTRING (POP_FRAME_P ()));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: POP_FRAME_P() = %d\n",
+ POP_FRAME_P ());
+#endif
#ifdef POP_FRAME
#if GDB_MULTI_ARCH
/* Macro might contain `[{}]' when not multi-arch */
@@ -4178,6 +4185,13 @@ set_gdbarch_push_return_address (struct gdbarch *gdbarch,
gdbarch->push_return_address = push_return_address;
}
+int
+gdbarch_pop_frame_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->pop_frame != 0;
+}
+
void
gdbarch_pop_frame (struct gdbarch *gdbarch)
{
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 336f6ca5abe..303477c0d4d 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1577,6 +1577,32 @@ extern void set_gdbarch_push_return_address (struct gdbarch *gdbarch, gdbarch_pu
#endif
#endif
+#if defined (POP_FRAME)
+/* Legacy for systems yet to multi-arch POP_FRAME */
+#if !defined (POP_FRAME_P)
+#define POP_FRAME_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (POP_FRAME_P)
+#define POP_FRAME_P() (0)
+#endif
+
+extern int gdbarch_pop_frame_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (POP_FRAME_P)
+#error "Non multi-arch definition of POP_FRAME"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (POP_FRAME_P)
+#define POP_FRAME_P() (gdbarch_pop_frame_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (POP_FRAME)
+#define POP_FRAME (internal_error (__FILE__, __LINE__, "POP_FRAME"), 0)
+#define POP_FRAME (gdbarch_pop_frame (current_gdbarch))
+#endif
+
typedef void (gdbarch_pop_frame_ftype) (void);
extern void gdbarch_pop_frame (struct gdbarch *gdbarch);
extern void set_gdbarch_pop_frame (struct gdbarch *gdbarch, gdbarch_pop_frame_ftype *pop_frame);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 9efadfe2495..fd9ddd52605 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -538,7 +538,7 @@ f:2:RETURN_VALUE_ON_STACK:int:return_value_on_stack:struct type *type:type:::gen
f:2:PUSH_ARGUMENTS:CORE_ADDR:push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr:::default_push_arguments::0
f:2:PUSH_DUMMY_FRAME:void:push_dummy_frame:void:-:::0
F:2:PUSH_RETURN_ADDRESS:CORE_ADDR:push_return_address:CORE_ADDR pc, CORE_ADDR sp:pc, sp:::0
-f:2:POP_FRAME:void:pop_frame:void:-:::0
+F:2:POP_FRAME:void:pop_frame:void:-:::0
#
f:2:STORE_STRUCT_RETURN:void:store_struct_return:CORE_ADDR addr, CORE_ADDR sp:addr, sp:::0
#
@@ -907,7 +907,13 @@ do
printf "#if (!GDB_MULTI_ARCH) && !defined (${macro})\n"
if [ "x${fallbackdefault}" = "x0" ]
then
- printf "#define ${macro}(${actual}) (internal_error (__FILE__, __LINE__, \"${macro}\"), 0)\n"
+ if [ "x${actual}" = "x-" ]
+ then
+ printf "#define ${macro} (internal_error (__FILE__, __LINE__, \"${macro}\"), 0)\n"
+ printf "#define ${macro} (gdbarch_${function} (current_gdbarch))\n"
+ else
+ printf "#define ${macro}(${actual}) (internal_error (__FILE__, __LINE__, \"${macro}\"), 0)\n"
+ fi
else
# FIXME: Should be passing current_gdbarch through!
echo "#define ${macro}(${actual}) (${fallbackdefault} (${actual}))" \
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 704e0338fb3..29ebf4413b5 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2,7 +2,7 @@
process.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
Foundation, Inc.
This file is part of GDB.
@@ -3093,7 +3093,7 @@ normal_stop (void)
LOCATION: Print only location
SRC_AND_LOC: Print location and source line */
if (do_frame_printing)
- show_and_print_stack_frame (deprecated_selected_frame, -1, source_flag);
+ print_stack_frame (deprecated_selected_frame, -1, source_flag);
/* Display the auto-display expressions. */
do_displays ();
@@ -3109,10 +3109,10 @@ normal_stop (void)
if (stop_stack_dummy)
{
- /* Pop the empty frame that contains the stack dummy.
- POP_FRAME ends with a setting of the current frame, so we
- can use that next. */
- POP_FRAME;
+ /* Pop the empty frame that contains the stack dummy. POP_FRAME
+ ends with a setting of the current frame, so we can use that
+ next. */
+ frame_pop (get_current_frame ());
/* Set stop_pc to what it was before we called the function.
Can't rely on restore_inferior_status because that only gets
called if we don't stop in the called function. */
diff --git a/gdb/legacy-frame.c b/gdb/legacy-frame.c
index fc974fd729c..a961efca9a7 100644
--- a/gdb/legacy-frame.c
+++ b/gdb/legacy-frame.c
@@ -46,10 +46,10 @@ struct frame_unwind_cache
void
legacy_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *bufferp)
+ void **unwind_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *bufferp)
{
/* There is always a frame at this point. And THIS is the frame
we're interested in. */
@@ -93,7 +93,7 @@ legacy_frame_register_unwind (struct frame_info *frame,
*realnump = -1;
if (bufferp != NULL)
{
-#if 1
+#if 0
/* Save each register value, as it is read in, in a
frame based cache. */
if ((*cache) == NULL)
@@ -142,14 +142,14 @@ legacy_frame_register_unwind (struct frame_info *frame,
CORE_ADDR
legacy_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache)
+ void **unwind_cache)
{
return FRAME_SAVED_PC (frame);
}
void
legacy_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
+ void **unwind_cache,
struct frame_id *id)
{
int fromleaf;
@@ -306,9 +306,17 @@ deprecated_generic_get_saved_register (char *raw_buffer, int *optimized,
deprecated_read_register_gen (regnum, raw_buffer);
}
+static void
+legacy_frame_pop (struct frame_info *fi, void **unwind_cache,
+ struct regcache *regcache)
+{
+ gdb_assert (POP_FRAME_P ());
+ POP_FRAME;
+}
const struct frame_unwind legacy_frame_unwind =
{
+ legacy_frame_pop,
legacy_frame_pc_unwind,
legacy_frame_id_unwind,
legacy_frame_register_unwind
diff --git a/gdb/legacy-frame.h b/gdb/legacy-frame.h
index 909893a440f..2be8d1a93e2 100644
--- a/gdb/legacy-frame.h
+++ b/gdb/legacy-frame.h
@@ -22,45 +22,10 @@
#if !defined (LEGACY_FRAME_H)
#define LEGACY_FRAME_H 1
+struct frame_unwind;
+
/* Frame unwinder for legacy code. */
const struct frame_unwind *legacy_frame_unwind_p (CORE_ADDR pc);
-
-struct frame_info;
-struct regcache;
-struct frame_id;
-struct frame_unwind_cache;
-
-/* LEGACY FRAMES
-
- The original extra frame info implementation of the`struct
- frame_info' object. These frames always initialize the entire
- frame object using extra frame info. */
-
-/* Assuming that FRAME is a legacy, return a register value for the
- previous frame. */
-
-extern void legacy_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- int regnum,
- int *optimized,
- enum lval_type *lvalp,
- CORE_ADDR *addrp,
- int *realnump,
- void *valuep);
-
-/* Assuming that FRAME is a legacy, return the resume address for the
- previous frame. */
-
-extern CORE_ADDR legacy_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache);
-
-/* Assuming that FRAME is a legacy, return the ID of the calling frame
- (the frame that the legacy has the saved state of). */
-
-extern void legacy_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- struct frame_id *id);
-
#endif
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 536e8a5b054..96030b71ab6 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1,5 +1,5 @@
/* MI Command Set.
- Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Solutions (a Red Hat company).
This file is part of GDB.
@@ -183,9 +183,9 @@ mi_cmd_exec_return (char *args, int from_tty)
/* Because we have called return_command with from_tty = 0, we need
to print the frame here. */
- show_and_print_stack_frame (deprecated_selected_frame,
- frame_relative_level (deprecated_selected_frame),
- LOC_AND_ADDRESS);
+ print_stack_frame (deprecated_selected_frame,
+ frame_relative_level (deprecated_selected_frame),
+ LOC_AND_ADDRESS);
return MI_CMD_DONE;
}
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 036c318b014..8aeef62656e 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -26,13 +26,14 @@
#include "regcache.h"
#include "sentinel-frame.h"
#include "inferior.h"
+#include "frame-unwind.h"
struct frame_unwind_cache
{
struct regcache *regcache;
};
-struct frame_unwind_cache *
+void *
sentinel_frame_cache (struct regcache *regcache)
{
struct frame_unwind_cache *cache =
@@ -45,7 +46,7 @@ sentinel_frame_cache (struct regcache *regcache)
void
sentinel_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
+ void **unwind_cache,
int regnum, int *optimized,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnum, void *bufferp)
@@ -71,7 +72,7 @@ sentinel_frame_register_unwind (struct frame_info *frame,
CORE_ADDR
sentinel_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache)
+ void **cache)
{
/* FIXME: cagney/2003-01-08: This should be using a per-architecture
method that doesn't suffer from DECR_PC_AFTER_BREAK problems.
@@ -82,7 +83,7 @@ sentinel_frame_pc_unwind (struct frame_info *frame,
void
sentinel_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **cache,
+ void **cache,
struct frame_id *id)
{
/* FIXME: cagney/2003-01-08: This should be using a per-architecture
@@ -93,8 +94,17 @@ sentinel_frame_id_unwind (struct frame_info *frame,
id->pc = read_pc ();
}
+static void
+sentinel_frame_pop (struct frame_info *frame,
+ void **cache,
+ struct regcache *regcache)
+{
+ internal_error (__FILE__, __LINE__, "Function sentinal_frame_pop called");
+}
+
const struct frame_unwind sentinel_frame_unwind =
{
+ sentinel_frame_pop,
sentinel_frame_pc_unwind,
sentinel_frame_id_unwind,
sentinel_frame_register_unwind
diff --git a/gdb/sentinel-frame.h b/gdb/sentinel-frame.h
index a7d218731ae..f52e1e2a3d0 100644
--- a/gdb/sentinel-frame.h
+++ b/gdb/sentinel-frame.h
@@ -23,8 +23,8 @@
#define SENTINEL_FRAME_H 1
struct frame_info;
-struct frame_id;
-struct frame_unwind_cache;
+struct frame_unwind;
+struct regcache;
/* Implement the sentinel frame. The sentinel frame terminates the
inner most end of the frame chain. If unwound, it returns the
@@ -33,32 +33,7 @@ struct frame_unwind_cache;
/* Pump prime the sentinel frame's cache. Since this needs the
REGCACHE provide that here. */
-struct frame_unwind_cache *sentinel_frame_cache (struct regcache *regcache);
-
-/* Return the previous frames register value. For a sentinel-frame,
- it is the value found in the register cache. */
-
-extern void sentinel_frame_register_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- int regnum,
- int *optimized,
- enum lval_type *lvalp,
- CORE_ADDR *addrp,
- int *realnump,
- void *valuep);
-
-/* Return the resume address of the previous frame. For the
- sentinel-frame, it is the threads resume address. */
-
-extern CORE_ADDR sentinel_frame_pc_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache);
-
-/* Return the frame ID of the previous frame. For the sentinel-frame,
- it is the ID of the inner most frame. */
-
-extern void sentinel_frame_id_unwind (struct frame_info *frame,
- struct frame_unwind_cache **unwind_cache,
- struct frame_id *id);
+void *sentinel_frame_cache (struct regcache *regcache);
extern const struct frame_unwind *sentinel_frame_unwind_p (CORE_ADDR pc);
diff --git a/gdb/stack.c b/gdb/stack.c
index a3a55c2f161..405a5e42666 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1,7 +1,7 @@
/* Print and select stack frames for GDB, the GNU debugger.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
Foundation, Inc.
This file is part of GDB.
@@ -98,10 +98,6 @@ static void print_frame (struct frame_info *fi,
int args,
struct symtab_and_line sal);
-static void print_frame_info_base (struct frame_info *, int, int, int);
-
-static void print_stack_frame_base (struct frame_info *, int, int);
-
static void backtrace_command (char *, int);
struct frame_info *parse_frame_specification (char *);
@@ -127,21 +123,6 @@ struct print_stack_frame_args
int args;
};
-static int print_stack_frame_base_stub (char *);
-
-/* Show and print the frame arguments.
- Pass the args the way catch_errors wants them. */
-static int show_and_print_stack_frame_stub (void *args);
-static int
-show_and_print_stack_frame_stub (void *args)
-{
- struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
-
- print_frame_info (p->fi, p->level, p->source, p->args);
-
- return 0;
-}
-
/* Show or print the frame arguments.
Pass the args the way catch_errors wants them. */
static int print_stack_frame_stub (void *args);
@@ -150,83 +131,10 @@ print_stack_frame_stub (void *args)
{
struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
- print_frame_info_base (p->fi, p->level, p->source, p->args);
- return 0;
-}
-
-/* Print a stack frame briefly. FRAME_INFI should be the frame info
- and LEVEL should be its level in the stack (or -1 for level not
- defined). */
-
-/* Pass the args the way catch_errors wants them. */
-static int
-print_stack_frame_base_stub (char *args)
-{
- struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
-
- print_frame_info_base (p->fi, p->level, p->source, p->args);
- return 0;
-}
-
-/* print the frame arguments to the terminal.
- Pass the args the way catch_errors wants them. */
-static int print_only_stack_frame_stub (void *);
-static int
-print_only_stack_frame_stub (void *args)
-{
- struct print_stack_frame_args *p = (struct print_stack_frame_args *) args;
-
- print_frame_info_base (p->fi, p->level, p->source, p->args);
+ print_frame_info (p->fi, p->level, p->source, p->args);
return 0;
}
-/* Print a stack frame briefly. FRAME_INFI should be the frame info
- and LEVEL should be its level in the stack (or -1 for level not defined).
- This prints the level, the function executing, the arguments,
- and the file name and line number.
- If the pc is not at the beginning of the source line,
- the actual pc is printed at the beginning.
-
- If SOURCE is 1, print the source line as well.
- If SOURCE is -1, print ONLY the source line. */
-
-static void
-print_stack_frame_base (struct frame_info *fi, int level, int source)
-{
- struct print_stack_frame_args args;
-
- args.fi = fi;
- args.level = level;
- args.source = source;
- args.args = 1;
-
- catch_errors (print_stack_frame_stub, &args, "", RETURN_MASK_ALL);
-}
-
-/* Show and print a stack frame briefly. FRAME_INFI should be the frame info
- and LEVEL should be its level in the stack (or -1 for level not defined).
- This prints the level, the function executing, the arguments,
- and the file name and line number.
- If the pc is not at the beginning of the source line,
- the actual pc is printed at the beginning.
-
- If SOURCE is 1, print the source line as well.
- If SOURCE is -1, print ONLY the source line. */
-
-void
-show_and_print_stack_frame (struct frame_info *fi, int level, int source)
-{
- struct print_stack_frame_args args;
-
- args.fi = fi;
- args.level = level;
- args.source = source;
- args.args = 1;
-
- catch_errors (show_and_print_stack_frame_stub, &args, "", RETURN_MASK_ALL);
-}
-
-
/* Show or print a stack frame briefly. FRAME_INFI should be the frame info
and LEVEL should be its level in the stack (or -1 for level not defined).
This prints the level, the function executing, the arguments,
@@ -248,30 +156,7 @@ print_stack_frame (struct frame_info *fi, int level, int source)
args.args = 1;
catch_errors (print_stack_frame_stub, (char *) &args, "", RETURN_MASK_ALL);
-}
-
-/* Print a stack frame briefly. FRAME_INFI should be the frame info
- and LEVEL should be its level in the stack (or -1 for level not defined).
- This prints the level, the function executing, the arguments,
- and the file name and line number.
- If the pc is not at the beginning of the source line,
- the actual pc is printed at the beginning.
-
- If SOURCE is 1, print the source line as well.
- If SOURCE is -1, print ONLY the source line. */
-
-void
-print_only_stack_frame (struct frame_info *fi, int level, int source)
-{
- struct print_stack_frame_args args;
-
- args.fi = fi;
- args.level = level;
- args.source = source;
- args.args = 1;
-
- catch_errors (print_only_stack_frame_stub, &args, "", RETURN_MASK_ALL);
-}
+}
struct print_args_args
{
@@ -280,12 +165,12 @@ struct print_args_args
struct ui_file *stream;
};
-static int print_args_stub (PTR);
+static int print_args_stub (void *);
/* Pass the args the way catch_errors wants them. */
static int
-print_args_stub (PTR args)
+print_args_stub (void *args)
{
int numargs;
struct print_args_args *p = (struct print_args_args *) args;
@@ -305,8 +190,8 @@ print_args_stub (PTR args)
LOCATION: Print only location
LOC_AND_SRC: Print location and source line. */
-static void
-print_frame_info_base (struct frame_info *fi, int level, int source, int args)
+void
+print_frame_info (struct frame_info *fi, int level, int source, int args)
{
struct symtab_and_line sal;
int source_print;
@@ -581,16 +466,6 @@ print_frame (struct frame_info *fi,
do_cleanups (old_chain);
}
-
-/* Show or print the frame info. If this is the tui, it will be shown in
- the source display */
-void
-print_frame_info (struct frame_info *fi, register int level, int source,
- int args)
-{
- print_frame_info_base (fi, level, source, args);
-}
-
/* Show the frame info. If this is the tui, it will be shown in
the source display otherwise, nothing is done */
void
@@ -1099,7 +974,7 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
means further attempts to backtrace would fail (on the other
hand, perhaps the code does or could be fixed to make sure
the frame->prev field gets set to NULL in that case). */
- print_frame_info_base (fi, trailing_level + i, 0, 1);
+ print_frame_info (fi, trailing_level + i, 0, 1);
if (show_locals)
print_frame_local_vars (fi, 1, gdb_stdout);
}
@@ -1599,8 +1474,8 @@ void
frame_command (char *level_exp, int from_tty)
{
select_frame_command (level_exp, from_tty);
- show_and_print_stack_frame (deprecated_selected_frame,
- frame_relative_level (deprecated_selected_frame), 1);
+ print_stack_frame (deprecated_selected_frame,
+ frame_relative_level (deprecated_selected_frame), 1);
}
/* The XDB Compatibility command to print the current frame. */
@@ -1610,7 +1485,7 @@ current_frame_command (char *level_exp, int from_tty)
{
if (target_has_stack == 0 || deprecated_selected_frame == 0)
error ("No stack.");
- print_only_stack_frame (deprecated_selected_frame,
+ print_stack_frame (deprecated_selected_frame,
frame_relative_level (deprecated_selected_frame), 1);
}
@@ -1647,8 +1522,8 @@ static void
up_command (char *count_exp, int from_tty)
{
up_silently_base (count_exp);
- show_and_print_stack_frame (deprecated_selected_frame,
- frame_relative_level (deprecated_selected_frame), 1);
+ print_stack_frame (deprecated_selected_frame,
+ frame_relative_level (deprecated_selected_frame), 1);
}
/* Select the frame down one or COUNT stack levels
@@ -1694,8 +1569,8 @@ static void
down_command (char *count_exp, int from_tty)
{
down_silently_base (count_exp);
- show_and_print_stack_frame (deprecated_selected_frame,
- frame_relative_level (deprecated_selected_frame), 1);
+ print_stack_frame (deprecated_selected_frame,
+ frame_relative_level (deprecated_selected_frame), 1);
}
void
@@ -1750,6 +1625,10 @@ return_command (char *retval_exp, int from_tty)
error ("Not confirmed.");
}
+ /* FIXME: cagney/2003-01-18: Rather than pop each frame in turn,
+ this code should just go straight to the relevant frame and pop
+ that. */
+
/* Do the real work. Pop until the specified frame is current. We
use this method because the deprecated_selected_frame is not valid after
a POP_FRAME. The pc comparison makes this work even if the
@@ -1757,11 +1636,11 @@ return_command (char *retval_exp, int from_tty)
while (selected_frame_addr != get_frame_base (frame = get_current_frame ())
|| selected_frame_pc != get_frame_pc (frame))
- POP_FRAME;
+ frame_pop (get_current_frame ());
/* Then pop that frame. */
- POP_FRAME;
+ frame_pop (get_current_frame ());
/* Compute the return value (if any) and store in the place
for return values. */
@@ -1771,9 +1650,14 @@ return_command (char *retval_exp, int from_tty)
/* If we are at the end of a call dummy now, pop the dummy frame too. */
+ /* FIXME: cagney/2003-01-18: This is silly. Instead of popping all
+ the frames except the dummy, and then, as an afterthought,
+ popping the dummy frame, this code should just pop through to the
+ dummy frame. */
+
if (CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (),
get_frame_base (get_current_frame ())))
- POP_FRAME;
+ frame_pop (get_current_frame ());
/* If interactive, print the frame that is now current. */
diff --git a/gdb/thread.c b/gdb/thread.c
index 6ef484078ef..f36def1f279 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1,7 +1,7 @@
/* Multi-process/thread control for GDB, the GNU debugger.
Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
@@ -457,7 +457,7 @@ info_threads_command (char *arg, int from_tty)
switch_to_thread (tp->ptid);
if (deprecated_selected_frame)
- print_only_stack_frame (deprecated_selected_frame, -1, 0);
+ print_stack_frame (deprecated_selected_frame, -1, 0);
else
printf_filtered ("[No stack.]\n");
}
diff --git a/gdb/valops.c b/gdb/valops.c
index d3906f9faee..d1a18774f96 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1711,8 +1711,9 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
{
/* The user wants the context restored. */
- /* We must get back to the frame we were before the dummy call. */
- POP_FRAME;
+ /* We must get back to the frame we were before the dummy
+ call. */
+ frame_pop (get_current_frame ());
/* FIXME: Insert a bunch of wrap_here; name can be very long if it's
a C++ name with arguments and stuff. */