From 4443bd8373866e76ec700a8bb3f5df8a50ba3714 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Tue, 8 Apr 2003 21:56:10 +0000 Subject: [PATCH] 2003-04-08 Andrew Cagney * gdbarch.sh (SAVED_PC_AFTER_CALL): Add a predicate. * gdbarch.h, gdbarch.c: Re-generate. * d10v-tdep.c (d10v_saved_pc_after_call): Delete function. (d10v_gdbarch_init): Do not set saved_pc_after_call. * infrun.c (step_over_function): Call SAVED_PC_AFTER_CALL_P conditionally, use frame_pc_unwind as an alternative. Add comments. * arch-utils.c (init_frame_pc_default): Only call SAVED_PC_AFTER_CALL when available. --- gdb/ChangeLog | 12 ++++++++++++ gdb/arch-utils.c | 2 +- gdb/d10v-tdep.c | 12 ------------ gdb/gdbarch.c | 20 +++++++++++++++++--- gdb/gdbarch.h | 25 +++++++++++++++++++++++++ gdb/gdbarch.sh | 2 +- gdb/infrun.c | 39 ++++++++++++++++++++++++++++++++++++++- 7 files changed, 94 insertions(+), 18 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c1ba5bb019..a86fe644a7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2003-04-08 Andrew Cagney + + * gdbarch.sh (SAVED_PC_AFTER_CALL): Add a predicate. + * gdbarch.h, gdbarch.c: Re-generate. + * d10v-tdep.c (d10v_saved_pc_after_call): Delete function. + (d10v_gdbarch_init): Do not set saved_pc_after_call. + * infrun.c (step_over_function): Call SAVED_PC_AFTER_CALL_P + conditionally, use frame_pc_unwind as an alternative. Add + comments. + * arch-utils.c (init_frame_pc_default): Only call + SAVED_PC_AFTER_CALL when available. + 2003-04-08 Elena Zannoni * infrun.c (stop_soon): Rename from stop_soon_quietly. diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 712b03ebcc..cba0175709 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -383,7 +383,7 @@ init_frame_pc_noop (int fromleaf, struct frame_info *prev) CORE_ADDR init_frame_pc_default (int fromleaf, struct frame_info *prev) { - if (fromleaf) + if (fromleaf && SAVED_PC_AFTER_CALL_P ()) return SAVED_PC_AFTER_CALL (get_next_frame (prev)); else if (get_next_frame (prev) != NULL) return DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev)); diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index 5e94de4265..4ae8099d87 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -488,17 +488,6 @@ d10v_extract_struct_value_address (struct regcache *regcache) return (addr | DMEM_START); } -/* Immediately after a function call, return the saved pc. We can't - use frame->return_pc beause that is determined by reading R13 off - the stack and that may not be written yet. */ - -static CORE_ADDR -d10v_saved_pc_after_call (struct frame_info *frame) -{ - return ((read_register (LR_REGNUM) << 2) - | IMEM_START); -} - static int check_prologue (unsigned short op) { @@ -1700,7 +1689,6 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_frame_args_skip (gdbarch, 0); set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue); - set_gdbarch_saved_pc_after_call (gdbarch, d10v_saved_pc_after_call); set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); set_gdbarch_stack_align (gdbarch, d10v_stack_align); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index d08f14652b..257f2b91cb 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -728,9 +728,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of unwind_pc, has predicate */ /* Skip verify of frame_args_address, invalid_p == 0 */ /* Skip verify of frame_locals_address, invalid_p == 0 */ - if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) - && (gdbarch->saved_pc_after_call == 0)) - fprintf_unfiltered (log, "\n\tsaved_pc_after_call"); + /* Skip verify of saved_pc_after_call, has predicate */ if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && (gdbarch->frame_num_args == 0)) fprintf_unfiltered (log, "\n\tframe_num_args"); @@ -2152,6 +2150,15 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) (long) current_gdbarch->return_value_on_stack /*RETURN_VALUE_ON_STACK ()*/); #endif +#ifdef SAVED_PC_AFTER_CALL_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "SAVED_PC_AFTER_CALL_P()", + XSTRING (SAVED_PC_AFTER_CALL_P ())); + fprintf_unfiltered (file, + "gdbarch_dump: SAVED_PC_AFTER_CALL_P() = %d\n", + SAVED_PC_AFTER_CALL_P ()); +#endif #ifdef SAVED_PC_AFTER_CALL fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", @@ -4902,6 +4909,13 @@ set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, gdbarch->frame_locals_address = frame_locals_address; } +int +gdbarch_saved_pc_after_call_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->saved_pc_after_call != 0; +} + CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index b2644f766a..c1f02c81e5 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -2385,6 +2385,31 @@ extern void set_gdbarch_frame_locals_address (struct gdbarch *gdbarch, gdbarch_f #endif #endif +#if defined (SAVED_PC_AFTER_CALL) +/* Legacy for systems yet to multi-arch SAVED_PC_AFTER_CALL */ +#if !defined (SAVED_PC_AFTER_CALL_P) +#define SAVED_PC_AFTER_CALL_P() (1) +#endif +#endif + +/* Default predicate for non- multi-arch targets. */ +#if (!GDB_MULTI_ARCH) && !defined (SAVED_PC_AFTER_CALL_P) +#define SAVED_PC_AFTER_CALL_P() (0) +#endif + +extern int gdbarch_saved_pc_after_call_p (struct gdbarch *gdbarch); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (SAVED_PC_AFTER_CALL_P) +#error "Non multi-arch definition of SAVED_PC_AFTER_CALL" +#endif +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (SAVED_PC_AFTER_CALL_P) +#define SAVED_PC_AFTER_CALL_P() (gdbarch_saved_pc_after_call_p (current_gdbarch)) +#endif + +/* Default (function) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (SAVED_PC_AFTER_CALL) +#define SAVED_PC_AFTER_CALL(frame) (internal_error (__FILE__, __LINE__, "SAVED_PC_AFTER_CALL"), 0) +#endif + typedef CORE_ADDR (gdbarch_saved_pc_after_call_ftype) (struct frame_info *frame); extern CORE_ADDR gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, struct frame_info *frame); extern void set_gdbarch_saved_pc_after_call (struct gdbarch *gdbarch, gdbarch_saved_pc_after_call_ftype *saved_pc_after_call); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index e5cb51ddf3..5807eb21c8 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -599,7 +599,7 @@ F:2:DEPRECATED_FRAME_SAVED_PC:CORE_ADDR:deprecated_frame_saved_pc:struct frame_i M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame: f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:get_frame_base::0 f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:get_frame_base::0 -f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0 +F::SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame f:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame::0:0 # F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp::0:0 diff --git a/gdb/infrun.c b/gdb/infrun.c index be6e0926e6..3fda9649f0 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2675,7 +2675,44 @@ step_over_function (struct execution_control_state *ecs) struct symtab_and_line sr_sal; init_sal (&sr_sal); /* initialize to zeros */ - sr_sal.pc = ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ())); + + /* NOTE: cagney/2003-04-06: + + At this point the equality get_frame_pc() == get_frame_func() + should hold. This may make it possible for this code to tell the + frame where it's function is, instead of the reverse. This would + avoid the need to search for the frame's function, which can get + very messy when there is no debug info available (look at the + heuristic find pc start code found in targets like the MIPS). */ + + /* NOTE: cagney/2003-04-06: Deprecate SAVED_PC_AFTER_CALL? + + The intent of SAVED_PC_AFTER_CALL was to: + + - provide a very light weight equivalent to frame_unwind_pc() + (nee FRAME_SAVED_PC) that avoids the prologue analyzer + + - avoid handling the case where the PC hasn't been saved in the + prologue analyzer + + Unfortunatly, not five lines further down, is a call to + get_frame_id() and that is guarenteed to trigger the prologue + analyzer. + + The `correct fix' is for the prologe analyzer to handle the case + where the prologue is incomplete (PC in prologue) and, + consequently, the return pc has not yet been saved. It should be + noted that the prologue analyzer needs to handle this case + anyway: frameless leaf functions that don't save the return PC; + single stepping through a prologue. + + The d10v handles all this by bailing out of the prologue analsis + when it reaches the current instruction. */ + + if (SAVED_PC_AFTER_CALL_P ()) + sr_sal.pc = ADDR_BITS_REMOVE (SAVED_PC_AFTER_CALL (get_current_frame ())); + else + sr_sal.pc = ADDR_BITS_REMOVE (frame_pc_unwind (get_current_frame ())); sr_sal.section = find_pc_overlay (sr_sal.pc); check_for_old_step_resume_breakpoint (); -- 2.34.1