2001-04-06 David Smith <dsmith@redhat.com>
authorDavid Smith <dsmith@redhat.com>
Fri, 6 Apr 2001 17:53:39 +0000 (17:53 +0000)
committerDavid Smith <dsmith@redhat.com>
Fri, 6 Apr 2001 17:53:39 +0000 (17:53 +0000)
* arch-utils.c (default_prepare_to_proceed)
(generic_prepare_to_proceed): Added new functions.
* arch-utils.h: New function declarations for
default_prepare_to_proceed() and generic_prepare_to_proceed().
* gdbarch.sh: Added PREPARE_TO_PROCEED.
* gdbarch.c: Regenerated.
* gdbarch.h: Regenerated.
* inferior.h: Added get_last_target_status() declaration.
* infrun.c (get_last_target_status): Added new function.
(handle_inferior_event): Saves last pid and waitstatus, which will
get returned by get_last_target_status().

* hppa-tdep.c (prepare_to_proceed):  Added comment stating that
prepare_to_proceed() is potentially redundant since
default_prepare_to_proceed() has been added.
* linux-thread.c (prepare_to_proceed): Ditto.
* lin-lwp.c (prepare_to_proceed): Ditto.
* m3-nat.c (prepare_to_proceed): Ditto.

12 files changed:
gdb/ChangeLog
gdb/arch-utils.c
gdb/arch-utils.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/hppa-tdep.c
gdb/inferior.h
gdb/infrun.c
gdb/lin-lwp.c
gdb/linux-thread.c
gdb/m3-nat.c

index 6ee409d79bd370e1b5f3ddb29f918825441f8e8d..f521bdc9dcb38360012b3a8045752493f18028fd 100644 (file)
@@ -1,3 +1,24 @@
+2001-04-06  David Smith  <dsmith@redhat.com>
+
+       * arch-utils.c (default_prepare_to_proceed)
+       (generic_prepare_to_proceed): Added new functions.
+       * arch-utils.h: New function declarations for
+       default_prepare_to_proceed() and generic_prepare_to_proceed().
+       * gdbarch.sh: Added PREPARE_TO_PROCEED.
+       * gdbarch.c: Regenerated.
+       * gdbarch.h: Regenerated.
+       * inferior.h: Added get_last_target_status() declaration.
+       * infrun.c (get_last_target_status): Added new function.
+       (handle_inferior_event): Saves last pid and waitstatus, which will
+       get returned by get_last_target_status(). 
+
+       * hppa-tdep.c (prepare_to_proceed):  Added comment stating that
+       prepare_to_proceed() is potentially redundant since
+       default_prepare_to_proceed() has been added.
+       * linux-thread.c (prepare_to_proceed): Ditto.
+       * lin-lwp.c (prepare_to_proceed): Ditto.
+       * m3-nat.c (prepare_to_proceed): Ditto.
+       
 2001-04-05  Andrew Cagney  <ac131313@redhat.com>
 
        Obsolete powerpcle-*-cygwin* and powerpcle-*-solaris* platforms
index 004d3aeb10d46b50f0c4cc31e1e634fd20cad43d..10f0fc503affc4a08c6b35a41354bd8c9083cc61 100644 (file)
@@ -239,6 +239,61 @@ default_frame_address (struct frame_info *fi)
   return fi->frame;
 }
 
+/* Default prepare_to_procced().  */
+int
+default_prepare_to_proceed (int select_it)
+{
+  return 0;
+}
+
+/* Generic prepare_to_proceed().  This one should be suitable for most
+   targets that support threads. */
+int
+generic_prepare_to_proceed (int select_it)
+{
+  int wait_pid;
+  struct target_waitstatus wait_status;
+
+  /* Get the last target status returned by target_wait().  */
+  get_last_target_status (&wait_pid, &wait_status);
+
+  /* Make sure we were stopped at a breakpoint.  */
+  if (wait_status.kind != TARGET_WAITKIND_STOPPED
+      || wait_status.value.sig != TARGET_SIGNAL_TRAP)
+    {
+      return 0;
+    }
+
+  if (wait_pid != -1 && inferior_pid != wait_pid)
+    {
+      /* Switched over from WAIT_PID.  */
+      CORE_ADDR wait_pc = read_pc_pid (wait_pid);
+
+      /* Avoid switching where it wouldn't do any good, i.e. if both
+         threads are at the same breakpoint.  */
+      if (wait_pc != read_pc () && breakpoint_here_p (wait_pc))
+       {
+         if (select_it)
+           {
+             /* User hasn't deleted the breakpoint.  Switch back to
+                WAIT_PID and return non-zero.  */
+             inferior_pid = wait_pid;
+
+             /* FIXME: This stuff came from switch_to_thread() in
+                thread.c (which should probably be a public function).  */
+             flush_cached_frames ();
+             registers_changed ();
+             stop_pc = wait_pc;
+             select_frame (get_current_frame (), 0);
+           }
+
+         return 1;
+       }
+    }
+  return 0;
+  
+}
+
 /* Functions to manipulate the endianness of the target.  */
 
 #ifdef TARGET_BYTE_ORDER_SELECTABLE
index bdd72fca0c65f9434290238b4e05372873db90c3..d468da6a58949607b2323f756d515b48c78519d6 100644 (file)
@@ -105,5 +105,10 @@ extern int no_op_reg_to_regnum (int reg);
 
 extern CORE_ADDR default_frame_address (struct frame_info *);
 
+/* Default prepare_to_procced. */
+
+extern int default_prepare_to_proceed (int select_it);
+
+extern int generic_prepare_to_proceed (int select_it);
 
 #endif
index 5735315c2fd7d900e9a143e5ed65881fdc98b928..d84e41deb571e304ab71ba07c34b7145ee06eaec 100644 (file)
@@ -226,6 +226,7 @@ struct gdbarch
   gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint;
   gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint;
   CORE_ADDR decr_pc_after_break;
+  gdbarch_prepare_to_proceed_ftype *prepare_to_proceed;
   CORE_ADDR function_start_offset;
   gdbarch_remote_translate_xfer_address_ftype *remote_translate_xfer_address;
   CORE_ADDR frame_args_skip;
@@ -380,6 +381,7 @@ struct gdbarch startup_gdbarch =
   0,
   0,
   0,
+  0,
   /* startup_gdbarch() */
 };
 
@@ -457,6 +459,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
   gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
   gdbarch->decr_pc_after_break = -1;
+  gdbarch->prepare_to_proceed = default_prepare_to_proceed;
   gdbarch->function_start_offset = -1;
   gdbarch->remote_translate_xfer_address = generic_remote_translate_xfer_address;
   gdbarch->frame_args_skip = -1;
@@ -710,6 +713,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
       && (gdbarch->decr_pc_after_break == -1))
     internal_error (__FILE__, __LINE__,
                     "gdbarch: verify_gdbarch: decr_pc_after_break invalid");
+  /* Skip verify of prepare_to_proceed, invalid_p == 0 */
   if ((GDB_MULTI_ARCH >= 2)
       && (gdbarch->function_start_offset == -1))
     internal_error (__FILE__, __LINE__,
@@ -1320,6 +1324,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: DECR_PC_AFTER_BREAK # %s\n",
                       XSTRING (DECR_PC_AFTER_BREAK));
 #endif
+#ifdef PREPARE_TO_PROCEED
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: %s # %s\n",
+                      "PREPARE_TO_PROCEED(select_it)",
+                      XSTRING (PREPARE_TO_PROCEED (select_it)));
+#endif
 #ifdef FUNCTION_START_OFFSET
   fprintf_unfiltered (file,
                       "gdbarch_dump: FUNCTION_START_OFFSET # %s\n",
@@ -2034,6 +2044,13 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: DECR_PC_AFTER_BREAK = %ld\n",
                       (long) DECR_PC_AFTER_BREAK);
 #endif
+#ifdef PREPARE_TO_PROCEED
+  if (GDB_MULTI_ARCH)
+    fprintf_unfiltered (file,
+                        "gdbarch_dump: PREPARE_TO_PROCEED = 0x%08lx\n",
+                        (long) current_gdbarch->prepare_to_proceed
+                        /*PREPARE_TO_PROCEED ()*/);
+#endif
 #ifdef FUNCTION_START_OFFSET
   fprintf_unfiltered (file,
                       "gdbarch_dump: FUNCTION_START_OFFSET = %ld\n",
@@ -3868,6 +3885,24 @@ set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch,
   gdbarch->decr_pc_after_break = decr_pc_after_break;
 }
 
+int
+gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, int select_it)
+{
+  if (gdbarch->prepare_to_proceed == 0)
+    internal_error (__FILE__, __LINE__,
+                    "gdbarch: gdbarch_prepare_to_proceed invalid");
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_prepare_to_proceed called\n");
+  return gdbarch->prepare_to_proceed (select_it);
+}
+
+void
+set_gdbarch_prepare_to_proceed (struct gdbarch *gdbarch,
+                                gdbarch_prepare_to_proceed_ftype prepare_to_proceed)
+{
+  gdbarch->prepare_to_proceed = prepare_to_proceed;
+}
+
 CORE_ADDR
 gdbarch_function_start_offset (struct gdbarch *gdbarch)
 {
index 34891a43b93a6a7ad547abec1a6b0794f4063828..548d5a0e1eefe67289d4ad03eaf6ee7c3fbce813 100644 (file)
@@ -1215,6 +1215,20 @@ extern void set_gdbarch_decr_pc_after_break (struct gdbarch *gdbarch, CORE_ADDR
 #endif
 #endif
 
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (PREPARE_TO_PROCEED)
+#define PREPARE_TO_PROCEED(select_it) (default_prepare_to_proceed (select_it))
+#endif
+
+typedef int (gdbarch_prepare_to_proceed_ftype) (int select_it);
+extern int gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, int select_it);
+extern void set_gdbarch_prepare_to_proceed (struct gdbarch *gdbarch, gdbarch_prepare_to_proceed_ftype *prepare_to_proceed);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (PREPARE_TO_PROCEED)
+#define PREPARE_TO_PROCEED(select_it) (gdbarch_prepare_to_proceed (current_gdbarch, select_it))
+#endif
+#endif
+
 extern CORE_ADDR gdbarch_function_start_offset (struct gdbarch *gdbarch);
 extern void set_gdbarch_function_start_offset (struct gdbarch *gdbarch, CORE_ADDR function_start_offset);
 #if GDB_MULTI_ARCH
index 991ea132415663e3ebf83d0a38e72faadb447c2d..7517e41c26cdfdef1441b4c2f615c1499511faca 100755 (executable)
@@ -489,6 +489,7 @@ f:2:BREAKPOINT_FROM_PC:unsigned char *:breakpoint_from_pc:CORE_ADDR *pcptr, int
 f:2:MEMORY_INSERT_BREAKPOINT:int:memory_insert_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_insert_breakpoint::0
 f:2:MEMORY_REMOVE_BREAKPOINT:int:memory_remove_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_remove_breakpoint::0
 v:2:DECR_PC_AFTER_BREAK:CORE_ADDR:decr_pc_after_break::::0:-1
+f::PREPARE_TO_PROCEED:int:prepare_to_proceed:int select_it:select_it::0:default_prepare_to_proceed::0
 v:2:FUNCTION_START_OFFSET:CORE_ADDR:function_start_offset::::0:-1
 #
 f:2:REMOTE_TRANSLATE_XFER_ADDRESS:void:remote_translate_xfer_address:CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len:gdb_addr, gdb_len, rem_addr, rem_len:::generic_remote_translate_xfer_address::0
index 3a879088cdeee826c0a5404a9b90d6c5d3463552..855fcb344c19d697c1f76f282db6dbdadd2fcf5f 100644 (file)
@@ -4591,7 +4591,10 @@ unwind_command (char *exp, int from_tty)
    For these reasons, we have to violate information hiding and
    call "breakpoint_here_p".  If core gdb thinks there is a bpt
    here, that's what counts, as core gdb is the one which is
-   putting the BPT instruction in and taking it out. */
+   putting the BPT instruction in and taking it out.
+
+   Note that this implementation is potentially redundant now that
+   default_prepare_to_proceed() has been added.  */
 int
 hppa_prepare_to_proceed (void)
 {
index d944deb21882a7b1fc6054367044ab1e1b4d25ee..b41e941a4d716d593494b903ecbae443f3148320 100644 (file)
@@ -261,6 +261,8 @@ extern int signal_print_update (int, int);
 
 extern int signal_pass_update (int, int);
 
+extern void get_last_target_status(int *pid, struct target_waitstatus *status);
+
 /* From infcmd.c */
 
 extern void tty_command (char *, int);
index 7c9a38c5ec59d5f0b3d2e3260360093a67a7d11e..028fe0994a01b25f45c45e4bca0c6bcf98898b59 100644 (file)
@@ -406,6 +406,12 @@ static struct breakpoint *through_sigtramp_breakpoint = NULL;
    currently be running in a syscall. */
 static int number_of_threads_in_syscalls;
 
+/* This is a cached copy of the pid/waitstatus of the last event
+   returned by target_wait()/target_wait_hook().  This information is
+   returned by get_last_target_status(). */
+static int target_last_wait_pid = -1;
+static struct target_waitstatus target_last_waitstatus;
+
 /* This is used to remember when a fork, vfork or exec event
    was caught by a catchpoint, and thus the event is to be
    followed at the next resume of the inferior, and not
@@ -1407,6 +1413,18 @@ check_for_old_step_resume_breakpoint (void)
     warning ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint");
 }
 
+/* Return the cached copy of the last pid/waitstatus returned by
+   target_wait()/target_wait_hook().  The data is actually cached by
+   handle_inferior_event(), which gets called immediately after
+   target_wait()/target_wait_hook().  */
+
+void
+get_last_target_status(int *pid, struct target_waitstatus *status)
+{
+  *pid = target_last_wait_pid;
+  *status = target_last_waitstatus;
+}
+
 /* Given an execution control state that has been freshly filled in
    by an event from the inferior, figure out what it means and take
    appropriate action.  */
@@ -1417,6 +1435,10 @@ handle_inferior_event (struct execution_control_state *ecs)
   CORE_ADDR tmp;
   int stepped_after_stopped_by_watchpoint;
 
+  /* Cache the last pid/waitstatus. */
+  target_last_wait_pid = ecs->pid;
+  target_last_waitstatus = *ecs->wp;
+
   /* Keep this extra brace for now, minimizes diffs.  */
   {
     switch (ecs->infwait_state)
index 42e98de701d970aaf140c1c4e15afcb510e272c1..ee1b844c48e9c53c9ca61f1f0fa22b3b76baf0fa 100644 (file)
@@ -283,7 +283,11 @@ save_inferior_pid (void)
 }
 \f
 
-/* Implementation of the PREPARE_TO_PROCEED hook for the Linux LWP layer.  */
+/* Implementation of the PREPARE_TO_PROCEED hook for the Linux LWP
+   layer.
+
+   Note that this implementation is potentially redundant now that
+   default_prepare_to_proceed() has been added.  */
 
 int
 lin_lwp_prepare_to_proceed (void)
index d06e3f6444ef9422ffdd2060b27412c18595ec2c..8e73eb2fd8425d9def599e966c82577ad85d5832 100644 (file)
@@ -1051,7 +1051,10 @@ quit:
 }
 
 /* If we have switched threads from a one that stopped at breakpoint,
-   return 1 otherwise 0.  */
+   return 1 otherwise 0.
+
+   Note that this implementation is potentially redundant now that
+   default_prepare_to_proceed() has been added.  */
 
 int
 linuxthreads_prepare_to_proceed (int step)
index 4fcf951d8e60ebe872ab74d49e8ef2fb381bfc85..3ff9835d0d8c39fa23a51c2215a2ddf7749e9333 100644 (file)
@@ -1573,6 +1573,8 @@ mach_thread_output_id (int mid)
  *  if SELECT_IT is nonzero, reselect the thread that was active when
  *  we stopped at a breakpoint.
  *
+ * Note that this implementation is potentially redundant now that
+ * default_prepare_to_proceed() has been added.  
  */
 
 mach3_prepare_to_proceed (int select_it)