2003-06-06 Andrew Cagney * gdbarch.sh (UNWIND_SP): Add. (TARGET_READ_SP): Change to function with predicate. * gdbarch.h, gdbarch.c: Re-generate. * frame.c (frame_sp_unwind): New function. (get_frame_sp): New function. * frame.h (get_frame_sp, frame_sp_unwind): Declare. * regcache.c (read_sp): Rewrite, try each of TARGET_READ_SP, gdbarch_unwind_sp and SP_REGNUM when looking for the SP register value. * d10v-tdep.c (d10v_unwind_sp): Replace d10v_read_sp. (d10v_gdbarch_init): Set unwind_sp instead of read_sp. Index: doc/ChangeLog 2003-06-06 Andrew Cagney * gdbint.texinfo (Target Architecture Definition): Document "unwind_sp". Cross reference "unwind_sp" and TARGET_READ_SP. Index: d10v-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/d10v-tdep.c,v retrieving revision 1.118 diff -u -r1.118 d10v-tdep.c --- d10v-tdep.c 3 Jun 2003 18:53:37 -0000 1.118 +++ d10v-tdep.c 6 Jun 2003 19:18:57 -0000 @@ -101,8 +101,6 @@ extern void _initialize_d10v_tdep (void); -static CORE_ADDR d10v_read_sp (void); - static void d10v_eva_prepare_to_trace (void); static void d10v_eva_get_trace_data (void); @@ -918,9 +916,11 @@ } static CORE_ADDR -d10v_read_sp (void) +d10v_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return (d10v_make_daddr (read_register (D10V_SP_REGNUM))); + ULONGEST sp; + frame_unwind_unsigned_register (next_frame, D10V_SP_REGNUM, &sp); + return d10v_make_daddr (sp); } /* When arguments must be pushed onto the stack, they go on in reverse @@ -1604,7 +1604,7 @@ set_gdbarch_read_pc (gdbarch, d10v_read_pc); set_gdbarch_write_pc (gdbarch, d10v_write_pc); - set_gdbarch_read_sp (gdbarch, d10v_read_sp); + set_gdbarch_unwind_sp (gdbarch, d10v_unwind_sp); set_gdbarch_num_regs (gdbarch, d10v_num_regs); set_gdbarch_sp_regnum (gdbarch, D10V_SP_REGNUM); Index: frame.c =================================================================== RCS file: /cvs/src/src/gdb/frame.c,v retrieving revision 1.117 diff -u -r1.117 frame.c --- frame.c 3 Jun 2003 18:53:37 -0000 1.117 +++ frame.c 6 Jun 2003 19:18:57 -0000 @@ -2250,6 +2250,37 @@ return current_gdbarch; } +/* Stack pointer methods. */ + +CORE_ADDR +get_frame_sp (struct frame_info *this_frame) +{ + return frame_sp_unwind (this_frame->next); +} + +CORE_ADDR +frame_sp_unwind (struct frame_info *next_frame) +{ + /* Normality, an architecture that provides a way of obtaining any + frame inner-most address. */ + if (gdbarch_unwind_sp_p (current_gdbarch)) + return gdbarch_unwind_sp (current_gdbarch, next_frame); + /* Things are looking grim. If it's the inner-most frame and there + is a TARGET_READ_SP then that can be used. */ + if (next_frame->level < 0 && TARGET_READ_SP_P ()) + return TARGET_READ_SP (); + /* Now things are really are grim. Hope that the value returned by + the SP_REGNUM register is meaningful. */ + if (SP_REGNUM >= 0) + { + ULONGEST sp; + frame_unwind_unsigned_register (next_frame, SP_REGNUM, &sp); + return sp; + } + internal_error (__FILE__, __LINE__, "Missing unwind SP method"); +} + + int legacy_frame_p (struct gdbarch *current_gdbarch) { Index: frame.h =================================================================== RCS file: /cvs/src/src/gdb/frame.h,v retrieving revision 1.96 diff -u -r1.96 frame.h --- frame.h 3 Jun 2003 18:53:37 -0000 1.96 +++ frame.h 6 Jun 2003 19:19:00 -0000 @@ -166,6 +166,13 @@ This replaced: frame->pc; */ extern CORE_ADDR get_frame_pc (struct frame_info *); +/* The frame's inner-most bound. AKA the stack-pointer. Confusingly + known as top-of-stack. */ + +extern CORE_ADDR get_frame_sp (struct frame_info *); +extern CORE_ADDR frame_sp_unwind (struct frame_info *); + + /* Following on from the `resume' address. Return the entry point address of the function containing that resume address, or zero if that function isn't known. */ Index: gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.240 diff -u -r1.240 gdbarch.sh --- gdbarch.sh 2 Jun 2003 02:54:34 -0000 1.240 +++ gdbarch.sh 6 Jun 2003 19:19:07 -0000 @@ -431,7 +431,8 @@ # This is simply not needed. See value_of_builtin_frame_fp_reg and # call_function_by_hand. F::DEPRECATED_TARGET_READ_FP:CORE_ADDR:deprecated_target_read_fp:void -f:2:TARGET_READ_SP:CORE_ADDR:read_sp:void:::0:generic_target_read_sp::0 +# UNWIND_SP is a direct replacement for TARGET_READ_SP. +F:2:TARGET_READ_SP:CORE_ADDR:read_sp:void # The dummy call frame SP should be set by push_dummy_call. F:2:DEPRECATED_DUMMY_WRITE_SP:void:deprecated_dummy_write_sp:CORE_ADDR val:val # Function for getting target's idea of a frame pointer. FIXME: GDB's @@ -452,6 +453,7 @@ # GDB's standard (or well known) register numbers. These can map onto # a real register or a pseudo (computed) register or not be defined at # all (-1). +# SP_REGNUM will hopefully be replaced by UNWIND_SP. v:2:SP_REGNUM:int:sp_regnum::::-1:-1::0 # This is simply not needed. See value_of_builtin_frame_fp_reg and # call_function_by_hand. @@ -609,6 +611,7 @@ # interfaces they have very different underlying implementations. F:2:DEPRECATED_FRAME_SAVED_PC:CORE_ADDR:deprecated_frame_saved_pc:struct frame_info *fi:fi::0:0 M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame: +M::UNWIND_SP:CORE_ADDR:unwind_sp: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::DEPRECATED_SAVED_PC_AFTER_CALL:CORE_ADDR:deprecated_saved_pc_after_call:struct frame_info *frame:frame Index: regcache.c =================================================================== RCS file: /cvs/src/src/gdb/regcache.c,v retrieving revision 1.82 diff -u -r1.82 regcache.c --- regcache.c 17 May 2003 05:59:58 -0000 1.82 +++ regcache.c 6 Jun 2003 19:19:09 -0000 @@ -1375,7 +1375,26 @@ CORE_ADDR read_sp (void) { - return TARGET_READ_SP (); + /* Try TARGET_READ_SP first: that way code that provides + TARGET_READ_SP method preserves its current behavior. */ + if (TARGET_READ_SP_P ()) + return TARGET_READ_SP (); + /* Try UNWIND_SP second: ensures that architectures which need to + unwind/unpack SP in weird and wonderful ways always override + SP_REGNUM. The d10v, for instance needs to convert the SP + pointer register into a CORE_ADDR. The MIPS needs to sign extend + its SP register. */ + if (gdbarch_unwind_sp_p (current_gdbarch)) + return get_frame_sp (get_current_frame ()); + /* Try SP_REGNUM last: this makes all sorts of [wrong] assumptions + about the architecture so put it at the end. */ + if (SP_REGNUM >= 0) + { + ULONGEST sp; + regcache_cooked_read_unsigned (current_regcache, SP_REGNUM, &sp); + return sp; + } + internal_error (__FILE__, __LINE__, "read_sp"); } void Index: doc/gdbint.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v retrieving revision 1.148 diff -u -r1.148 gdbint.texinfo --- doc/gdbint.texinfo 1 Jun 2003 23:05:43 -0000 1.148 +++ doc/gdbint.texinfo 6 Jun 2003 19:19:14 -0000 @@ -3291,6 +3291,23 @@ @noindent @xref{DEPRECATED_FRAME_SAVED_PC}, which this method replaces. +@item CORE_ADDR unwind_sp (struct frame_info *@var{this_frame}) +@findex unwind_sp +@anchor{unwind_sp} Return the frame's inner most stack address. This is +commonly refered to as the frame's stack pointer. + +The implementation, which must be frame agnostic (work with any frame), +is typically no more than: + +@smallexample +ULONGEST sp; +frame_unwind_unsigned_register (this_frame, D10V_SP_REGNUM, &sp); +return d10v_make_daddr (sp); +@end smallexample + +@noindent +@xref{TARGET_READ_SP}, which this method replaces. + @item FUNCTION_EPILOGUE_SIZE @findex FUNCTION_EPILOGUE_SIZE For some COFF targets, the @code{x_sym.x_misc.x_fsize} field of the @@ -3890,14 +3907,16 @@ @findex write_pc @findex read_sp @findex read_fp -These change the behavior of @code{read_pc}, @code{write_pc}, -@code{read_sp} and @code{deprecated_read_fp}. For most targets, these -may be left undefined. @value{GDBN} will call the read and write -register functions with the relevant @code{_REGNUM} argument. +@anchor{TARGET_READ_SP} These change the behavior of @code{read_pc}, +@code{write_pc}, @code{read_sp} and @code{deprecated_read_fp}. For most +targets, these may be left undefined. @value{GDBN} will call the read +and write register functions with the relevant @code{_REGNUM} argument. These macros are useful when a target keeps one of these registers in a hard to get at place; for example, part in a segment register and part in an ordinary register. + +@xref{unwind_sp}, which replaces @code{TARGET_READ_SP}. @item TARGET_VIRTUAL_FRAME_POINTER(@var{pc}, @var{regp}, @var{offsetp}) @findex TARGET_VIRTUAL_FRAME_POINTER