diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-01-20 00:38:14 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-01-20 00:38:14 +0000 |
commit | a8ba5982475d4da9afea823bb2de439f434946a6 (patch) | |
tree | 6e5d082ccb08b0bea770cac014cbf9a3909646f3 | |
parent | 102a6c5ab462bb4625f9f812d05566bd72b11e8d (diff) | |
download | gdb-a8ba5982475d4da9afea823bb2de439f434946a6.zip gdb-a8ba5982475d4da9afea823bb2de439f434946a6.tar.gz gdb-a8ba5982475d4da9afea823bb2de439f434946a6.tar.bz2 |
Merge branch with mainline:
POP_FRAME_P;
frame-unwind.h.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/d10v-frame.c | 17 | ||||
-rw-r--r-- | gdb/d10v-tdep.c | 13 | ||||
-rw-r--r-- | gdb/dummy-frame.c | 106 | ||||
-rw-r--r-- | gdb/dummy-frame.h | 35 | ||||
-rw-r--r-- | gdb/frame-unwind.h | 71 | ||||
-rw-r--r-- | gdb/frame.c | 195 | ||||
-rw-r--r-- | gdb/frame.h | 27 | ||||
-rw-r--r-- | gdb/gdbarch.c | 20 | ||||
-rw-r--r-- | gdb/gdbarch.h | 26 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 10 | ||||
-rw-r--r-- | gdb/infrun.c | 12 | ||||
-rw-r--r-- | gdb/legacy-frame.c | 22 | ||||
-rw-r--r-- | gdb/legacy-frame.h | 39 | ||||
-rw-r--r-- | gdb/mi/mi-main.c | 8 | ||||
-rw-r--r-- | gdb/sentinel-frame.c | 18 | ||||
-rw-r--r-- | gdb/sentinel-frame.h | 31 | ||||
-rw-r--r-- | gdb/stack.c | 170 | ||||
-rw-r--r-- | gdb/thread.c | 4 | ||||
-rw-r--r-- | gdb/valops.c | 5 |
21 files changed, 405 insertions, 437 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1029e85..7c8fe9c 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 4f13051..4c89fd7 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 45e2dd9..4a8ba9b 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 353efe2..6a7073f 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 8374812..5b63830 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 39bf1a9..2d03421 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 5c82b6d..2c67c96 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 bcad061..40bf176 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 6b80afc..260a817 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 069e566..bd19793 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 336f6ca..303477c 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 9efadfe..fd9ddd5 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 704e033..29ebf44 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 fc974fd..a961efc 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 909893a..2be8d1a 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 536e8a5..96030b7 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 036c318..8aeef62 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 a7d2187..f52e1e2 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 a3a55c2..405a5e4 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 6ef4840..f36def1 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 d3906f9f..d1a1877 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. */ |