2003-04-08 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Tue, 8 Apr 2003 21:56:10 +0000 (21:56 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 8 Apr 2003 21:56:10 +0000 (21:56 +0000)
* 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
gdb/arch-utils.c
gdb/d10v-tdep.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/infrun.c

index c1ba5bb0195a5fedf9fd613adeab0fad7126aa9e..a86fe644a7a4956e6ebaafdc7142b0695c040505 100644 (file)
@@ -1,3 +1,15 @@
+2003-04-08  Andrew Cagney  <cagney@redhat.com>
+
+       * 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  <ezannoni@redhat.com>
 
         * infrun.c (stop_soon): Rename from stop_soon_quietly.
index 712b03ebcc96c406f863a129a471a46e86f86b9a..cba0175709de27ec20151ad9c7aee6a4a2363d9e 100644 (file)
@@ -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));
index 5e94de4265012f14e04a517b76a7f289212fe5b5..4ae8099d87cb3a3c33faf138f12f1a9edafa8842 100644 (file)
@@ -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);
 
index d08f14652b9d1dc643f390558f93f719570b6e10..257f2b91cbe6da65521d090182eaba33c839d1d0 100644 (file)
@@ -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)
 {
index b2644f766aad0d92cc0c5c25c0546fcce8d97bb6..c1f02c81e52175bfb4518057c84118469becc05a 100644 (file)
@@ -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);
index e5cb51ddf33ed67af6471e7d0c138569dd81f96a..5807eb21c8cbeb890e3d0a0e831ea65ce050a6bb 100755 (executable)
@@ -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
index be6e0926e627ec7750692aef5bd54c0fd879dbff..3fda9649f075771ab3189b967d7fed1e147f30d7 100644 (file)
@@ -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 ();