2007-11-12 Markus Deuling <deuling@de.ibm.com>
[deliverable/binutils-gdb.git] / gdb / infrun.c
index ae530b77e212115361e7b6e0991b91dd063176f8..cf7aa02abe1d7e4ce852acd7bfa6f2339cfd8ed2 100644 (file)
@@ -9,7 +9,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,9 +18,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "gdb_string.h"
@@ -80,11 +78,10 @@ static int currently_stepping (struct execution_control_state *ecs);
 
 static void xdb_handle_command (char *args, int from_tty);
 
-static int prepare_to_proceed (void);
+static int prepare_to_proceed (int);
 
 void _initialize_infrun (void);
 
-int inferior_ignoring_startup_exec_events = 0;
 int inferior_ignoring_leading_exec_events = 0;
 
 /* When set, stop the 'step' command if we enter a function which has
@@ -448,6 +445,11 @@ static CORE_ADDR singlestep_pc;
    thread here so that we can resume single-stepping it later.  */
 static ptid_t saved_singlestep_ptid;
 static int stepping_past_singlestep_breakpoint;
+
+/* Similarly, if we are stepping another thread past a breakpoint,
+   save the original thread here so that we can resume stepping it later.  */
+static ptid_t stepping_past_breakpoint_ptid;
+static int stepping_past_breakpoint;
 \f
 
 /* Things to clean up if we QUIT out of resume ().  */
@@ -528,7 +530,8 @@ resume (int step, enum target_signal sig)
   if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
     {
       if (gdbarch_skip_permanent_breakpoint_p (current_gdbarch))
-       gdbarch_skip_permanent_breakpoint (current_gdbarch, current_regcache);
+       gdbarch_skip_permanent_breakpoint (current_gdbarch,
+                                          get_current_regcache ());
       else
        error (_("\
 The program is stopped at a permanent breakpoint, but GDB does not know\n\
@@ -536,10 +539,10 @@ how to step past a permanent breakpoint on this architecture.  Try using\n\
 a command like `return' or `jump' to continue execution."));
     }
 
-  if (SOFTWARE_SINGLE_STEP_P () && step)
+  if (step && gdbarch_software_single_step_p (current_gdbarch))
     {
       /* Do it the hard way, w/temp breakpoints */
-      if (SOFTWARE_SINGLE_STEP (get_current_frame ()))
+      if (gdbarch_software_single_step (current_gdbarch, get_current_frame ()))
         {
           /* ...and don't ask hardware to do it.  */
           step = 0;
@@ -631,6 +634,12 @@ clear_proceed_status (void)
   proceed_to_finish = 0;
   breakpoint_proceeded = 1;    /* We're about to proceed... */
 
+  if (stop_registers)
+    {
+      regcache_xfree (stop_registers);
+      stop_registers = NULL;
+    }
+
   /* Discard any remaining commands or status from previous stop.  */
   bpstat_clear (&stop_bpstat);
 }
@@ -638,7 +647,7 @@ clear_proceed_status (void)
 /* This should be suitable for any targets that support threads. */
 
 static int
-prepare_to_proceed (void)
+prepare_to_proceed (int step)
 {
   ptid_t wait_ptid;
   struct target_waitstatus wait_status;
@@ -646,42 +655,35 @@ prepare_to_proceed (void)
   /* Get the last target status returned by target_wait().  */
   get_last_target_status (&wait_ptid, &wait_status);
 
-  /* Make sure we were stopped either at a breakpoint, or because
-     of a Ctrl-C.  */
+  /* Make sure we were stopped at a breakpoint.  */
   if (wait_status.kind != TARGET_WAITKIND_STOPPED
-      || (wait_status.value.sig != TARGET_SIGNAL_TRAP
-         && wait_status.value.sig != TARGET_SIGNAL_INT))
+      || wait_status.value.sig != TARGET_SIGNAL_TRAP)
     {
       return 0;
     }
 
+  /* Switched over from WAIT_PID.  */
   if (!ptid_equal (wait_ptid, minus_one_ptid)
-      && !ptid_equal (inferior_ptid, wait_ptid))
+      && !ptid_equal (inferior_ptid, wait_ptid)
+      && breakpoint_here_p (read_pc_pid (wait_ptid)))
     {
-      /* Switched over from WAIT_PID.  */
-      CORE_ADDR wait_pc = read_pc_pid (wait_ptid);
-
-      if (wait_pc != read_pc ())
+      /* If stepping, remember current thread to switch back to.  */
+      if (step)
        {
-         /* Switch back to WAIT_PID thread.  */
-         inferior_ptid = wait_ptid;
-
-         /* FIXME: This stuff came from switch_to_thread() in
-            thread.c (which should probably be a public function).  */
-         reinit_frame_cache ();
-         registers_changed ();
-         stop_pc = wait_pc;
+         stepping_past_breakpoint = 1;
+         stepping_past_breakpoint_ptid = inferior_ptid;
        }
 
+      /* Switch back to WAIT_PID thread.  */
+      switch_to_thread (wait_ptid);
+
       /* We return 1 to indicate that there is a breakpoint here,
-         so we need to step over it before continuing to avoid
-         hitting it straight away. */
-      if (breakpoint_here_p (wait_pc))
-       return 1;
+        so we need to step over it before continuing to avoid
+        hitting it straight away. */
+      return 1;
     }
 
   return 0;
-
 }
 
 /* Record the pc of the program the last time it stopped.  This is
@@ -747,7 +749,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
      prepare_to_proceed checks the current thread against the thread
      that reported the most recent event.  If a step-over is required
      it returns TRUE and sets the current thread to the old thread. */
-  if (prepare_to_proceed () && breakpoint_here_p (read_pc ()))
+  if (prepare_to_proceed (step))
     oneproc = 1;
 
   if (oneproc)
@@ -821,7 +823,7 @@ start_remote (int from_tty)
 {
   init_thread_list ();
   init_wait_for_inferior ();
-  stop_soon = STOP_QUIETLY;
+  stop_soon = STOP_QUIETLY_REMOTE;
   trap_expected = 0;
 
   /* Always go on waiting for the target, regardless of the mode. */
@@ -868,6 +870,7 @@ init_wait_for_inferior (void)
   clear_proceed_status ();
 
   stepping_past_singlestep_breakpoint = 0;
+  stepping_past_breakpoint = 0;
 }
 \f
 /* This enum encodes possible reasons for doing a target_wait, so that
@@ -878,6 +881,7 @@ enum infwait_states
 {
   infwait_normal_state,
   infwait_thread_hop_state,
+  infwait_step_watch_state,
   infwait_nonstep_watch_state
 };
 
@@ -1137,8 +1141,8 @@ context_switch (struct execution_control_state *ecs)
                         &ecs->stepping_through_solib_catchpoints,
                         &ecs->current_line, &ecs->current_symtab);
     }
-  inferior_ptid = ecs->ptid;
-  reinit_frame_cache ();
+
+  switch_to_thread (ecs->ptid);
 }
 
 static void
@@ -1183,52 +1187,33 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   breakpoint_pc = read_pc_pid (ecs->ptid) - gdbarch_decr_pc_after_break
                                            (current_gdbarch);
 
-  if (SOFTWARE_SINGLE_STEP_P ())
-    {
-      /* When using software single-step, a SIGTRAP can only indicate
-         an inserted breakpoint.  This actually makes things
-         easier.  */
-      if (singlestep_breakpoints_inserted_p)
-       /* When software single stepping, the instruction at [prev_pc]
-          is never a breakpoint, but the instruction following
-          [prev_pc] (in program execution order) always is.  Assume
-          that following instruction was reached and hence a software
-          breakpoint was hit.  */
-       write_pc_pid (breakpoint_pc, ecs->ptid);
-      else if (software_breakpoint_inserted_here_p (breakpoint_pc))
-       /* The inferior was free running (i.e., no single-step
-          breakpoints inserted) and it hit a software breakpoint.  */
-       write_pc_pid (breakpoint_pc, ecs->ptid);
-    }
-  else
+  /* Check whether there actually is a software breakpoint inserted
+     at that location.  */
+  if (software_breakpoint_inserted_here_p (breakpoint_pc))
     {
-      /* When using hardware single-step, a SIGTRAP is reported for
-         both a completed single-step and a software breakpoint.  Need
-         to differentiate between the two as the latter needs
-         adjusting but the former does not.
-
-         When the thread to be examined does not match the current thread
-         context we can't use currently_stepping, so assume no
-         single-stepping in this case.  */
-      if (ptid_equal (ecs->ptid, inferior_ptid) && currently_stepping (ecs))
-       {
-         if (prev_pc == breakpoint_pc
-             && software_breakpoint_inserted_here_p (breakpoint_pc))
-           /* Hardware single-stepped a software breakpoint (as
-              occures when the inferior is resumed with PC pointing
-              at not-yet-hit software breakpoint).  Since the
-              breakpoint really is executed, the inferior needs to be
-              backed up to the breakpoint address.  */
-           write_pc_pid (breakpoint_pc, ecs->ptid);
-       }
-      else
-       {
-         if (software_breakpoint_inserted_here_p (breakpoint_pc))
-           /* The inferior was free running (i.e., no hardware
-              single-step and no possibility of a false SIGTRAP) and
-              hit a software breakpoint.  */
-           write_pc_pid (breakpoint_pc, ecs->ptid);
-       }
+      /* When using hardware single-step, a SIGTRAP is reported for both
+        a completed single-step and a software breakpoint.  Need to
+        differentiate between the two, as the latter needs adjusting
+        but the former does not.
+
+        The SIGTRAP can be due to a completed hardware single-step only if 
+         - we didn't insert software single-step breakpoints
+         - the thread to be examined is still the current thread
+         - this thread is currently being stepped
+
+        If any of these events did not occur, we must have stopped due
+        to hitting a software breakpoint, and have to back up to the
+        breakpoint address.
+
+        As a special case, we could have hardware single-stepped a
+        software breakpoint.  In this case (prev_pc == breakpoint_pc),
+        we also need to back up to the breakpoint address.  */
+
+      if (singlestep_breakpoints_inserted_p
+         || !ptid_equal (ecs->ptid, inferior_ptid)
+         || !currently_stepping (ecs)
+         || prev_pc == breakpoint_pc)
+       write_pc_pid (breakpoint_pc, ecs->ptid);
     }
 }
 
@@ -1236,17 +1221,12 @@ adjust_pc_after_break (struct execution_control_state *ecs)
    by an event from the inferior, figure out what it means and take
    appropriate action.  */
 
-int stepped_after_stopped_by_watchpoint;
-
 void
 handle_inferior_event (struct execution_control_state *ecs)
 {
-  /* NOTE: bje/2005-05-02: If you're looking at this code and thinking
-     that the variable stepped_after_stopped_by_watchpoint isn't used,
-     then you're wrong!  See remote.c:remote_stopped_data_address.  */
-
   int sw_single_step_trap_p = 0;
-  int stopped_by_watchpoint = -1;      /* Mark as unknown.  */
+  int stopped_by_watchpoint;
+  int stepped_after_stopped_by_watchpoint = 0;
 
   /* Cache the last pid/waitstatus. */
   target_last_wait_ptid = ecs->ptid;
@@ -1266,7 +1246,14 @@ handle_inferior_event (struct execution_control_state *ecs)
     case infwait_normal_state:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: infwait_normal_state\n");
-      stepped_after_stopped_by_watchpoint = 0;
+      break;
+
+    case infwait_step_watch_state:
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog,
+                           "infrun: infwait_step_watch_state\n");
+
+      stepped_after_stopped_by_watchpoint = 1;
       break;
 
     case infwait_nonstep_watch_state:
@@ -1309,16 +1296,22 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_LOADED:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n");
-      /* Ignore gracefully during startup of the inferior, as it
-         might be the shell which has just loaded some objects,
-         otherwise add the symbols for the newly loaded objects.  */
-#ifdef SOLIB_ADD
+      /* Ignore gracefully during startup of the inferior, as it might
+         be the shell which has just loaded some objects, otherwise
+         add the symbols for the newly loaded objects.  Also ignore at
+         the beginning of an attach or remote session; we will query
+         the full list of libraries once the connection is
+         established.  */
       if (stop_soon == NO_STOP_QUIETLY)
        {
+         int breakpoints_were_inserted;
+
          /* Remove breakpoints, SOLIB_ADD might adjust
             breakpoint addresses via breakpoint_re_set.  */
+         breakpoints_were_inserted = breakpoints_inserted;
          if (breakpoints_inserted)
            remove_breakpoints ();
+         breakpoints_inserted = 0;
 
          /* Check for any newly added shared libraries if we're
             supposed to be adding them automatically.  Switch
@@ -1340,17 +1333,46 @@ handle_inferior_event (struct execution_control_state *ecs)
             exec/process stratum, instead relying on the target stack
             to propagate relevant changes (stop, section table
             changed, ...) up to other layers.  */
+#ifdef SOLIB_ADD
          SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
+#else
+         solib_add (NULL, 0, &current_target, auto_solib_add);
+#endif
          target_terminal_inferior ();
 
+         /* If requested, stop when the dynamic linker notifies
+            gdb of events.  This allows the user to get control
+            and place breakpoints in initializer routines for
+            dynamically loaded objects (among other things).  */
+         if (stop_on_solib_events)
+           {
+             stop_stepping (ecs);
+             return;
+           }
+
+         /* NOTE drow/2007-05-11: This might be a good place to check
+            for "catch load".  */
+
          /* Reinsert breakpoints and continue.  */
-         if (breakpoints_inserted)
-           insert_breakpoints ();
+         if (breakpoints_were_inserted)
+           {
+             insert_breakpoints ();
+             breakpoints_inserted = 1;
+           }
+       }
+
+      /* If we are skipping through a shell, or through shared library
+        loading that we aren't interested in, resume the program.  If
+        we're running the program normally, also resume.  But stop if
+        we're attaching or setting up a remote connection.  */
+      if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY)
+       {
+         resume (0, TARGET_SIGNAL_0);
+         prepare_to_wait (ecs);
+         return;
        }
-#endif
-      resume (0, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
+
+      break;
 
     case TARGET_WAITKIND_SPURIOUS:
       if (debug_infrun)
@@ -1372,7 +1394,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                                           (LONGEST) ecs->ws.value.integer));
       gdb_flush (gdb_stdout);
       target_mourn_inferior ();
-      singlestep_breakpoints_inserted_p = 0;   /* SOFTWARE_SINGLE_STEP_P() */
+      singlestep_breakpoints_inserted_p = 0;
       stop_print_frame = 0;
       stop_stepping (ecs);
       return;
@@ -1392,7 +1414,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       target_mourn_inferior ();
 
       print_stop_reason (SIGNAL_EXITED, stop_signal);
-      singlestep_breakpoints_inserted_p = 0;   /* SOFTWARE_SINGLE_STEP_P() */
+      singlestep_breakpoints_inserted_p = 0;
       stop_stepping (ecs);
       return;
 
@@ -1416,7 +1438,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       stop_pc = read_pc ();
 
-      stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid, 0);
+      stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
 
       ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
 
@@ -1464,7 +1486,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       ecs->saved_inferior_ptid = inferior_ptid;
       inferior_ptid = ecs->ptid;
 
-      stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid, 0);
+      stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
 
       ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
       inferior_ptid = ecs->saved_inferior_ptid;
@@ -1548,8 +1570,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   if (stepping_past_singlestep_breakpoint)
     {
-      gdb_assert (SOFTWARE_SINGLE_STEP_P ()
-                 && singlestep_breakpoints_inserted_p);
+      gdb_assert (singlestep_breakpoints_inserted_p);
       gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
       gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));
 
@@ -1581,6 +1602,37 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   stepping_past_singlestep_breakpoint = 0;
 
+  if (stepping_past_breakpoint)
+    {
+      stepping_past_breakpoint = 0;
+
+      /* If we stopped for some other reason than single-stepping, ignore
+        the fact that we were supposed to switch back.  */
+      if (stop_signal == TARGET_SIGNAL_TRAP)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: stepping_past_breakpoint\n");
+
+         /* Pull the single step breakpoints out of the target.  */
+         if (singlestep_breakpoints_inserted_p)
+           {
+             remove_single_step_breakpoints ();
+             singlestep_breakpoints_inserted_p = 0;
+           }
+
+         /* Note: We do not call context_switch at this point, as the
+            context is already set up for stepping the original thread.  */
+         switch_to_thread (stepping_past_breakpoint_ptid);
+         /* Suppress spurious "Switching to ..." message.  */
+         previous_inferior_ptid = inferior_ptid;
+
+         resume (1, TARGET_SIGNAL_0);
+         prepare_to_wait (ecs);
+         return;
+       }
+    }
+
   /* See if a thread hit a thread-specific breakpoint that was meant for
      another thread.  If so, then step that thread past the breakpoint,
      and continue it.  */
@@ -1598,7 +1650,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          if (!breakpoint_thread_match (stop_pc, ecs->ptid))
            thread_hop_needed = 1;
        }
-      else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+      else if (singlestep_breakpoints_inserted_p)
        {
          /* We have not context switched yet, so this should be true
             no matter which thread hit the singlestep breakpoint.  */
@@ -1669,7 +1721,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          /* Saw a breakpoint, but it was hit by the wrong thread.
             Just continue. */
 
-         if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+         if (singlestep_breakpoints_inserted_p)
            {
              /* Pull the single step breakpoints out of the target. */
              remove_single_step_breakpoints ();
@@ -1718,7 +1770,7 @@ handle_inferior_event (struct execution_control_state *ecs)
              return;
            }
        }
-      else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+      else if (singlestep_breakpoints_inserted_p)
        {
          sw_single_step_trap_p = 1;
          ecs->random_signal = 0;
@@ -1740,31 +1792,27 @@ handle_inferior_event (struct execution_control_state *ecs)
        deprecated_context_hook (pid_to_thread_id (ecs->ptid));
     }
 
-  if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+  if (singlestep_breakpoints_inserted_p)
     {
       /* Pull the single step breakpoints out of the target. */
       remove_single_step_breakpoints ();
       singlestep_breakpoints_inserted_p = 0;
     }
 
-  /* It may not be necessary to disable the watchpoint to stop over
-     it.  For example, the PA can (with some kernel cooperation)
-     single step over a watchpoint without disabling the watchpoint.  */
-  if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws))
+  if (stepped_after_stopped_by_watchpoint)
+    stopped_by_watchpoint = 0;
+  else
+    stopped_by_watchpoint = watchpoints_triggered (&ecs->ws);
+
+  /* If necessary, step over this watchpoint.  We'll be back to display
+     it in a moment.  */
+  if (stopped_by_watchpoint
+      && (HAVE_STEPPABLE_WATCHPOINT
+         || gdbarch_have_nonsteppable_watchpoint (current_gdbarch)))
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: STOPPED_BY_WATCHPOINT\n");
-      resume (1, 0);
-      prepare_to_wait (ecs);
-      return;
-    }
 
-  /* It is far more common to need to disable a watchpoint to step
-     the inferior over it.  FIXME.  What else might a debug
-     register or page protection watchpoint scheme need here?  */
-  if (gdbarch_have_nonsteppable_watchpoint (current_gdbarch)
-      && STOPPED_BY_WATCHPOINT (ecs->ws))
-    {
       /* At this point, we are stopped at an instruction which has
          attempted to write to a piece of memory under control of
          a watchpoint.  The instruction hasn't actually executed
@@ -1774,31 +1822,31 @@ handle_inferior_event (struct execution_control_state *ecs)
 
          In order to make watchpoints work `right', we really need
          to complete the memory write, and then evaluate the
-         watchpoint expression.  The following code does that by
-         removing the watchpoint (actually, all watchpoints and
-         breakpoints), single-stepping the target, re-inserting
-         watchpoints, and then falling through to let normal
-         single-step processing handle proceed.  Since this
-         includes evaluating watchpoints, things will come to a
-         stop in the correct manner.  */
-
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: STOPPED_BY_WATCHPOINT\n");
-      remove_breakpoints ();
+         watchpoint expression.  We do this by single-stepping the
+        target.
+
+        It may not be necessary to disable the watchpoint to stop over
+        it.  For example, the PA can (with some kernel cooperation)
+        single step over a watchpoint without disabling the watchpoint.
+
+        It is far more common to need to disable a watchpoint to step
+        the inferior over it.  If we have non-steppable watchpoints,
+        we must disable the current watchpoint; it's simplest to
+        disable all watchpoints and breakpoints.  */
+        
+      if (!HAVE_STEPPABLE_WATCHPOINT)
+       remove_breakpoints ();
       registers_changed ();
       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);   /* Single step */
-
       ecs->waiton_ptid = ecs->ptid;
-      ecs->wp = &(ecs->ws);
-      ecs->infwait_state = infwait_nonstep_watch_state;
+      if (HAVE_STEPPABLE_WATCHPOINT)
+       ecs->infwait_state = infwait_step_watch_state;
+      else
+       ecs->infwait_state = infwait_nonstep_watch_state;
       prepare_to_wait (ecs);
       return;
     }
 
-  /* It may be possible to simply continue after a watchpoint.  */
-  if (HAVE_CONTINUABLE_WATCHPOINT)
-    stopped_by_watchpoint = STOPPED_BY_WATCHPOINT (ecs->ws);
-
   ecs->stop_func_start = 0;
   ecs->stop_func_end = 0;
   ecs->stop_func_name = 0;
@@ -1806,7 +1854,8 @@ handle_inferior_event (struct execution_control_state *ecs)
      will both be 0 if it doesn't work.  */
   find_pc_partial_function (stop_pc, &ecs->stop_func_name,
                            &ecs->stop_func_start, &ecs->stop_func_end);
-  ecs->stop_func_start += DEPRECATED_FUNCTION_START_OFFSET;
+  ecs->stop_func_start
+    += gdbarch_deprecated_function_start_offset (current_gdbarch);
   ecs->another_trap = 0;
   bpstat_clear (&stop_bpstat);
   stop_step = 0;
@@ -1874,7 +1923,8 @@ handle_inferior_event (struct execution_control_state *ecs)
          && (stop_signal == TARGET_SIGNAL_ILL
              || stop_signal == TARGET_SIGNAL_SEGV
              || stop_signal == TARGET_SIGNAL_EMT))
-      || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP)
+      || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
+      || stop_soon == STOP_QUIETLY_REMOTE)
     {
       if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
        {
@@ -1887,7 +1937,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       /* This is originated from start_remote(), start_inferior() and
          shared libraries hook functions.  */
-      if (stop_soon == STOP_QUIETLY)
+      if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
        {
           if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
@@ -1918,8 +1968,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       else
        {
          /* See if there is a breakpoint at the current PC.  */
-         stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid,
-                                           stopped_by_watchpoint);
+         stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
 
          /* Following in case break condition called a
             function.  */
@@ -2077,7 +2126,8 @@ process_event_stop_test:
        remove_breakpoints ();
        breakpoints_inserted = 0;
        if (!gdbarch_get_longjmp_target_p (current_gdbarch)
-           || !gdbarch_get_longjmp_target (current_gdbarch, &jmp_buf_pc))
+           || !gdbarch_get_longjmp_target (current_gdbarch,
+                                           get_current_frame (), &jmp_buf_pc))
          {
            keep_going (ecs);
            return;
@@ -2220,10 +2270,6 @@ process_event_stop_test:
 #endif
          target_terminal_inferior ();
 
-         /* Try to reenable shared library breakpoints, additional
-            code segments in shared libraries might be mapped in now. */
-         re_enable_breakpoints_in_shlibs ();
-
          /* If requested, stop when the dynamic linker notifies
             gdb of events.  This allows the user to get control
             and place breakpoints in initializer routines for
@@ -2456,9 +2502,10 @@ process_event_stop_test:
          function.  That's what tells us (a) whether we want to step
          into it at all, and (b) what prologue we want to run to the
          end of, if we do step into it.  */
-      real_stop_pc = skip_language_trampoline (stop_pc);
+      real_stop_pc = skip_language_trampoline (get_current_frame (), stop_pc);
       if (real_stop_pc == 0)
-       real_stop_pc = gdbarch_skip_trampoline_code (current_gdbarch, stop_pc);
+       real_stop_pc = gdbarch_skip_trampoline_code
+                        (current_gdbarch, get_current_frame (), stop_pc);
       if (real_stop_pc != 0)
        ecs->stop_func_start = real_stop_pc;
 
@@ -2520,8 +2567,9 @@ process_event_stop_test:
                                          stop_pc, ecs->stop_func_name))
     {
       /* Determine where this trampoline returns.  */
-      CORE_ADDR real_stop_pc = gdbarch_skip_trampoline_code
-                                (current_gdbarch, stop_pc);
+      CORE_ADDR real_stop_pc;
+      real_stop_pc = gdbarch_skip_trampoline_code
+                      (current_gdbarch, get_current_frame (), stop_pc);
 
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: stepped into solib return tramp\n");
@@ -2678,8 +2726,10 @@ process_event_stop_test:
      function.  Fortunately, those days are nearly upon us.  */
 #endif
   {
-    struct frame_id current_frame = get_frame_id (get_current_frame ());
-    if (!(frame_id_inner (current_frame, step_frame_id)))
+    struct frame_info *frame = get_current_frame ();
+    struct frame_id current_frame = get_frame_id (frame);
+    if (!(frame_id_inner (get_frame_arch (frame), current_frame,
+                         step_frame_id)))
       step_frame_id = current_frame;
   }
 
@@ -2810,6 +2860,7 @@ insert_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
 {
   struct symtab_and_line sr_sal;
 
+  gdb_assert (return_frame != NULL);
   init_sal (&sr_sal);          /* initialize to zeros */
 
   sr_sal.pc = gdbarch_addr_bits_remove
@@ -3169,6 +3220,18 @@ Further execution is probably impossible.\n"));
          switch (bpstat_ret)
            {
            case PRINT_UNKNOWN:
+             /* If we had hit a shared library event breakpoint,
+                bpstat_print would print out this message.  If we hit
+                an OS-level shared library event, do the same
+                thing.  */
+             if (last.kind == TARGET_WAITKIND_LOADED)
+               {
+                 printf_filtered (_("Stopped due to shared library event\n"));
+                 source_flag = SRC_LINE;       /* something bogus */
+                 do_frame_printing = 0;
+                 break;
+               }
+
              /* FIXME: cagney/2002-12-01: Given that a frame ID does
                 (or should) carry around the function and does (or
                 should) use that when doing a frame comparison.  */
@@ -3213,9 +3276,15 @@ Further execution is probably impossible.\n"));
   /* Save the function value return registers, if we care.
      We might be about to restore their previous contents.  */
   if (proceed_to_finish)
-    /* NB: The copy goes through to the target picking up the value of
-       all the registers.  */
-    regcache_cpy (stop_registers, current_regcache);
+    {
+      /* This should not be necessary.  */
+      if (stop_registers)
+       regcache_xfree (stop_registers);
+
+      /* NB: The copy goes through to the target picking up the value of
+        all the registers.  */
+      stop_registers = regcache_dup (get_current_regcache ());
+    }
 
   if (stop_stack_dummy)
     {
@@ -3614,7 +3683,6 @@ struct inferior_status
   CORE_ADDR step_resume_break_address;
   int stop_after_trap;
   int stop_soon;
-  struct regcache *stop_registers;
 
   /* These are here because if call_function_by_hand has written some
      registers and then decides to call error(), we better not have changed
@@ -3670,9 +3738,7 @@ save_inferior_status (int restore_stack_info)
   inf_status->restore_stack_info = restore_stack_info;
   inf_status->proceed_to_finish = proceed_to_finish;
 
-  inf_status->stop_registers = regcache_dup_no_passthrough (stop_registers);
-
-  inf_status->registers = regcache_dup (current_regcache);
+  inf_status->registers = regcache_dup (get_current_regcache ());
 
   inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
   return inf_status;
@@ -3719,15 +3785,11 @@ restore_inferior_status (struct inferior_status *inf_status)
   breakpoint_proceeded = inf_status->breakpoint_proceeded;
   proceed_to_finish = inf_status->proceed_to_finish;
 
-  /* FIXME: Is the restore of stop_registers always needed. */
-  regcache_xfree (stop_registers);
-  stop_registers = inf_status->stop_registers;
-
   /* The inferior can be gone if the user types "print exit(0)"
      (and perhaps other times).  */
   if (target_has_execution)
     /* NB: The register write goes through to the target.  */
-    regcache_cpy (current_regcache, inf_status->registers);
+    regcache_cpy (get_current_regcache (), inf_status->registers);
   regcache_xfree (inf_status->registers);
 
   /* FIXME: If we are being called after stopping in a function which
@@ -3773,7 +3835,6 @@ discard_inferior_status (struct inferior_status *inf_status)
   /* See save_inferior_status for info on stop_bpstat. */
   bpstat_clear (&inf_status->stop_bpstat);
   regcache_xfree (inf_status->registers);
-  regcache_xfree (inf_status->stop_registers);
   xfree (inf_status);
 }
 
@@ -3916,12 +3977,6 @@ save_inferior_ptid (void)
 }
 \f
 
-static void
-build_infrun (void)
-{
-  stop_registers = regcache_xmalloc (current_gdbarch);
-}
-
 void
 _initialize_infrun (void)
 {
@@ -3929,9 +3984,6 @@ _initialize_infrun (void)
   int numsigs;
   struct cmd_list_element *c;
 
-  DEPRECATED_REGISTER_GDBARCH_SWAP (stop_registers);
-  deprecated_register_gdbarch_swap (NULL, 0, build_infrun);
-
   add_info ("signals", signals_info, _("\
 What debugger does when program gets various signals.\n\
 Specify a signal as argument to print info on that signal only."));
This page took 0.034795 seconds and 4 git commands to generate.