2003-06-08 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Mon, 9 Jun 2003 01:02:07 +0000 (01:02 +0000)
committerAndrew Cagney <cagney@redhat.com>
Mon, 9 Jun 2003 01:02:07 +0000 (01:02 +0000)
* gdbarch.sh (UNWIND_SP): Add.
* 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.

2003-06-08  Andrew Cagney  <cagney@redhat.com>

* gdbint.texinfo (Target Architecture Definition): Document
"unwind_sp".  Cross reference "unwind_sp" and TARGET_READ_SP.

gdb/ChangeLog
gdb/d10v-tdep.c
gdb/doc/ChangeLog
gdb/doc/gdbint.texinfo
gdb/frame.c
gdb/frame.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/regcache.c

index a49e596cd4cb39d35723d39e15d721dfd0cddd4e..78ff45ecbc85a79fde6513687b9522135915974d 100644 (file)
@@ -1,3 +1,16 @@
+2003-06-08  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbarch.sh (UNWIND_SP): Add.
+       * 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.
+
 2003-06-08  Andrew Cagney  <cagney@redhat.com>
 
        Deprecate BIG_REMOTE_BREAKPOINT, LITTLE_REMOTE_BREAKPOINT and
index a83d6bae20f1a9e99b9913c51c19fb9db07a4b5d..84d0a85244d0029007d3b6a207ef488b5f61901f 100644 (file)
@@ -102,8 +102,6 @@ a0_regnum (struct gdbarch *gdbarch)
 
 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);
@@ -902,9 +900,11 @@ d10v_write_pc (CORE_ADDR val, ptid_t ptid)
 }
 
 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
@@ -1528,7 +1528,7 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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 b9c28f006b2c243292b77a986438e47656b85b6f..653c565e69a000cb35d0d1f96b4f6353869f6061 100644 (file)
@@ -1,3 +1,8 @@
+2003-06-08  Andrew Cagney  <cagney@redhat.com>
+
+       * gdbint.texinfo (Target Architecture Definition): Document
+       "unwind_sp".  Cross reference "unwind_sp" and TARGET_READ_SP.
+
 2003-06-07  Adam Fedor  <fedor@gnu.org>
 
        * gdb.texinfo: Add Objective-C documentation.
index dc5c6b809d8d0f5e246e62fe157f382bf7f2bc10..75444ee64cd0257d752cc9a0390aeebe8bf81c7d 100644 (file)
@@ -3291,6 +3291,23 @@ return d10v_make_iaddr (pc);
 @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 @dfn{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,15 +3907,17 @@ Number of bits in a short integer; defaults to @code{2 * TARGET_CHAR_BIT}.
 @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
 Returns a @code{(register, offset)} pair representing the virtual frame
index 4b103cdfa067289f4f66c4d2bca131862b9ffe75..b7a87857ce6b31dd4ad2c1b9c758bfd0eabcc83f 100644 (file)
@@ -2250,6 +2250,37 @@ get_frame_arch (struct frame_info *this_frame)
   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 bfd94694375431b617e488e239655fc5aa3e9311..04fa67dfd0ea2a004333116e4f279f3248061c17 100644 (file)
@@ -166,6 +166,13 @@ extern struct frame_info *frame_find_by_id (struct frame_id id);
    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 eeea6257dcab80b9d0ef674a47943a3e7be7a672..648b8f50e74346797ca4d078a1d15223f45790d8 100644 (file)
@@ -243,6 +243,7 @@ struct gdbarch
   gdbarch_deprecated_frame_chain_valid_ftype *deprecated_frame_chain_valid;
   gdbarch_deprecated_frame_saved_pc_ftype *deprecated_frame_saved_pc;
   gdbarch_unwind_pc_ftype *unwind_pc;
+  gdbarch_unwind_sp_ftype *unwind_sp;
   gdbarch_frame_args_address_ftype *frame_args_address;
   gdbarch_frame_locals_address_ftype *frame_locals_address;
   gdbarch_deprecated_saved_pc_after_call_ftype *deprecated_saved_pc_after_call;
@@ -410,6 +411,7 @@ struct gdbarch startup_gdbarch =
   0,  /* deprecated_frame_chain_valid */
   0,  /* deprecated_frame_saved_pc */
   0,  /* unwind_pc */
+  0,  /* unwind_sp */
   0,  /* frame_args_address */
   0,  /* frame_locals_address */
   0,  /* deprecated_saved_pc_after_call */
@@ -721,6 +723,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of deprecated_frame_chain_valid, has predicate */
   /* Skip verify of deprecated_frame_saved_pc, has predicate */
   /* Skip verify of unwind_pc, has predicate */
+  /* Skip verify of unwind_sp, has predicate */
   /* Skip verify of frame_args_address, invalid_p == 0 */
   /* Skip verify of frame_locals_address, invalid_p == 0 */
   /* Skip verify of deprecated_saved_pc_after_call, has predicate */
@@ -2636,6 +2639,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
     fprintf_unfiltered (file,
                         "gdbarch_dump: unwind_pc = 0x%08lx\n",
                         (long) current_gdbarch->unwind_pc);
+  if (GDB_MULTI_ARCH)
+    fprintf_unfiltered (file,
+                        "gdbarch_dump: gdbarch_unwind_sp_p() = %d\n",
+                        gdbarch_unwind_sp_p (current_gdbarch));
+  if (GDB_MULTI_ARCH)
+    fprintf_unfiltered (file,
+                        "gdbarch_dump: unwind_sp = 0x%08lx\n",
+                        (long) current_gdbarch->unwind_sp);
 #ifdef USE_STRUCT_CONVENTION
   fprintf_unfiltered (file,
                       "gdbarch_dump: %s # %s\n",
@@ -4970,6 +4981,32 @@ set_gdbarch_unwind_pc (struct gdbarch *gdbarch,
   gdbarch->unwind_pc = unwind_pc;
 }
 
+int
+gdbarch_unwind_sp_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->unwind_sp != 0;
+}
+
+CORE_ADDR
+gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch->unwind_sp == 0)
+    internal_error (__FILE__, __LINE__,
+                    "gdbarch: gdbarch_unwind_sp invalid");
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_sp called\n");
+  return gdbarch->unwind_sp (gdbarch, next_frame);
+}
+
+void
+set_gdbarch_unwind_sp (struct gdbarch *gdbarch,
+                       gdbarch_unwind_sp_ftype unwind_sp)
+{
+  gdbarch->unwind_sp = unwind_sp;
+}
+
 CORE_ADDR
 gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi)
 {
index 092f4877a0fadc407f8b28bcec32d6784dd2636b..e9895cfe042380bd0cad5e70a015a85820f7d661 100644 (file)
@@ -371,6 +371,8 @@ extern void set_gdbarch_deprecated_target_read_fp (struct gdbarch *gdbarch, gdba
 #define DEPRECATED_TARGET_READ_FP() (gdbarch_deprecated_target_read_fp (current_gdbarch))
 #endif
 
+/* UNWIND_SP is a direct replacement for TARGET_READ_SP. */
+
 #if defined (TARGET_READ_SP)
 /* Legacy for systems yet to multi-arch TARGET_READ_SP */
 #if !defined (TARGET_READ_SP_P)
@@ -504,7 +506,8 @@ extern void set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int num_pseudo
 
 /* 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). */
+   all (-1).
+   SP_REGNUM will hopefully be replaced by UNWIND_SP. */
 
 /* Default (value) for non- multi-arch platforms. */
 #if (!GDB_MULTI_ARCH) && !defined (SP_REGNUM)
@@ -2257,6 +2260,12 @@ typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct fra
 extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame);
 extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc);
 
+extern int gdbarch_unwind_sp_p (struct gdbarch *gdbarch);
+
+typedef CORE_ADDR (gdbarch_unwind_sp_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame);
+extern CORE_ADDR gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame);
+extern void set_gdbarch_unwind_sp (struct gdbarch *gdbarch, gdbarch_unwind_sp_ftype *unwind_sp);
+
 /* Default (function) for non- multi-arch platforms. */
 #if (!GDB_MULTI_ARCH) && !defined (FRAME_ARGS_ADDRESS)
 #define FRAME_ARGS_ADDRESS(fi) (get_frame_base (fi))
index 3f2bbeef4869f7e9b3b60d49c0f1b272358d6587..c1f83a91aff4f461a77029c299ca192d281ade6e 100755 (executable)
@@ -431,6 +431,7 @@ f:2:TARGET_WRITE_PC:void:write_pc:CORE_ADDR val, ptid_t ptid:val, ptid::0:generi
 # 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
+# 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
@@ -452,6 +453,7 @@ v:2:NUM_PSEUDO_REGS:int:num_pseudo_regs::::0:0::0:::
 # 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 @@ F:2:DEPRECATED_FRAME_CHAIN_VALID:int:deprecated_frame_chain_valid:CORE_ADDR chai
 # 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 95843366d6ec768c7cf5db023d268a6e09a81ae7..facaab38e1efe4df6b11278252f5cffe519785e5 100644 (file)
@@ -1351,8 +1351,11 @@ read_sp (void)
 {
   if (TARGET_READ_SP_P ())
     return TARGET_READ_SP ();
-  /* Else return SP from get_current_frame.  */
+  else if (gdbarch_unwind_sp_p (current_gdbarch))
+    return get_frame_sp (get_current_frame ());
   else if (SP_REGNUM >= 0)
+    /* Try SP_REGNUM last: this makes all sorts of [wrong] assumptions
+       about the architecture so put it at the end.  */
     return read_register (SP_REGNUM);
   internal_error (__FILE__, __LINE__, "read_sp: Unable to find SP");
 }