2005-01-12 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / infrun.c
index bec87465bdfd0c5e8916b5209b24b76be7ba22f9..d68ab16dfc50a150f73267e73a53c3095ad6fca4 100644 (file)
@@ -28,6 +28,7 @@
 #include "symtab.h"
 #include "frame.h"
 #include "inferior.h"
+#include "exceptions.h"
 #include "breakpoint.h"
 #include "gdb_wait.h"
 #include "gdbcore.h"
@@ -106,6 +107,8 @@ static ptid_t previous_inferior_ptid;
 
 static int may_follow_exec = MAY_FOLLOW_EXEC;
 
+static int debug_infrun = 0;
+
 /* If the program uses ELF-style shared libraries, then calls to
    functions in shared libraries go through stubs, which live in a
    table called the PLT (Procedure Linkage Table).  The first time the
@@ -161,24 +164,6 @@ static int may_follow_exec = MAY_FOLLOW_EXEC;
 #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
 #endif
 
-/* On MIPS16, a function that returns a floating point value may call
-   a library helper function to copy the return value to a floating point
-   register.  The IGNORE_HELPER_CALL macro returns non-zero if we
-   should ignore (i.e. step over) this function call.  */
-#ifndef IGNORE_HELPER_CALL
-#define IGNORE_HELPER_CALL(pc) 0
-#endif
-
-/* On some systems, the PC may be left pointing at an instruction that  won't
-   actually be executed.  This is usually indicated by a bit in the PSW.  If
-   we find ourselves in such a state, then we step the target beyond the
-   nullified instruction before returning control to the user so as to avoid
-   confusion. */
-
-#ifndef INSTRUCTION_NULLIFIED
-#define INSTRUCTION_NULLIFIED 0
-#endif
-
 /* We can't step off a permanent breakpoint in the ordinary way, because we
    can't remove it.  Instead, we have to advance the PC to the next
    instruction.  This macro should expand to a pointer to a function that
@@ -262,14 +247,6 @@ static int trap_expected;
 static int stop_on_solib_events;
 #endif
 
-#ifdef HP_OS_BUG
-/* Nonzero if the next time we try to continue the inferior, it will
-   step one instruction and generate a spurious trace trap.
-   This is used to compensate for a bug in HP-UX.  */
-
-static int trap_expected_after_continue;
-#endif
-
 /* Nonzero means expecting a trace trap
    and should stop the inferior and return silently when it happens.  */
 
@@ -304,14 +281,6 @@ static int stop_print_frame;
 
 static struct breakpoint *step_resume_breakpoint = NULL;
 
-/* On some platforms (e.g., HP-UX), hardware watchpoints have bad
-   interactions with an inferior that is running a kernel function
-   (aka, a system call or "syscall").  wait_for_inferior therefore
-   may have a need to know when the inferior is in a syscall.  This
-   is a count of the number of inferior threads which are known to
-   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()/deprecated_target_wait_hook().  This
    information is returned by get_last_target_status().  */
@@ -500,14 +469,15 @@ static const char *scheduler_enums[] = {
 static void
 set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
 {
-  /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
-     the set command passed as a parameter.  The clone operation will
-     include (BUG?) any ``set'' command callback, if present.
-     Commands like ``info set'' call all the ``show'' command
-     callbacks.  Unfortunately, for ``show'' commands cloned from
-     ``set'', this includes callbacks belonging to ``set'' commands.
-     Making this worse, this only occures if add_show_from_set() is
-     called after add_cmd_sfunc() (BUG?).  */
+  /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
+     function clones the set command passed as a parameter.  The clone
+     operation will include (BUG?) any ``set'' command callback, if
+     present.  Commands like ``info set'' call all the ``show''
+     command callbacks.  Unfortunately, for ``show'' commands cloned
+     from ``set'', this includes callbacks belonging to ``set''
+     commands.  Making this worse, this only occures if
+     deprecated_add_show_from_set() is called after add_cmd_sfunc()
+     (BUG?).  */
   if (cmd_type (c) == set_cmd)
     if (!target_can_lock_scheduler)
       {
@@ -532,6 +502,9 @@ resume (int step, enum target_signal sig)
   struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
   QUIT;
 
+  if (debug_infrun)
+    printf_unfiltered ("infrun: resume (step=%d, signal=%d)\n", step, sig);
+
   /* FIXME: calling breakpoint_here_p (read_pc ()) three times! */
 
 
@@ -595,9 +568,9 @@ resume (int step, enum target_signal sig)
 
       resume_ptid = RESUME_ALL;        /* Default */
 
-      if ((step || singlestep_breakpoints_inserted_p) &&
-         (stepping_past_singlestep_breakpoint
-          || (!breakpoints_inserted && breakpoint_here_p (read_pc ()))))
+      if ((step || singlestep_breakpoints_inserted_p)
+         && (stepping_past_singlestep_breakpoint
+             || (!breakpoints_inserted && breakpoint_here_p (read_pc ()))))
        {
          /* Stepping past a breakpoint without inserting breakpoints.
             Make sure only the current thread gets to step, so that
@@ -607,9 +580,9 @@ resume (int step, enum target_signal sig)
          resume_ptid = inferior_ptid;
        }
 
-      if ((scheduler_mode == schedlock_on) ||
-         (scheduler_mode == schedlock_step &&
-          (step || singlestep_breakpoints_inserted_p)))
+      if ((scheduler_mode == schedlock_on)
+         || (scheduler_mode == schedlock_step
+             && (step || singlestep_breakpoints_inserted_p)))
        {
          /* User-settable 'scheduler' mode requires solo thread resume. */
          resume_ptid = inferior_ptid;
@@ -664,8 +637,8 @@ prepare_to_proceed (void)
   /* Make sure we were stopped either at a breakpoint, or because
      of a Ctrl-C.  */
   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
+         && wait_status.value.sig != TARGET_SIGNAL_INT))
     {
       return 0;
     }
@@ -689,15 +662,15 @@ prepare_to_proceed (void)
          select_frame (get_current_frame ());
        }
 
-       /* 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;
+      /* 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;
     }
 
   return 0;
-  
+
 }
 
 /* Record the pc of the program the last time it stopped.  This is
@@ -729,24 +702,17 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
 
   if (addr == (CORE_ADDR) -1)
     {
-      /* If there is a breakpoint at the address we will resume at,
-         step one instruction before inserting breakpoints
-         so that we do not stop right away (and report a second
-         hit at this breakpoint).  */
-
       if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
+       /* There is a breakpoint at the address we will resume at,
+          step one instruction before inserting breakpoints so that
+          we do not stop right away (and report a second hit at this
+          breakpoint).  */
        oneproc = 1;
-
-#ifndef STEP_SKIPS_DELAY
-#define STEP_SKIPS_DELAY(pc) (0)
-#define STEP_SKIPS_DELAY_P (0)
-#endif
-      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
-         (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
-         is slow (it needs to read memory from the target).  */
-      if (STEP_SKIPS_DELAY_P
-         && breakpoint_here_p (read_pc () + 4)
-         && STEP_SKIPS_DELAY (read_pc ()))
+      else if (gdbarch_single_step_through_delay_p (current_gdbarch)
+              && gdbarch_single_step_through_delay (current_gdbarch,
+                                                    get_current_frame ()))
+       /* We stepped onto an instruction that needs to be stepped
+          again before re-inserting the breakpoint, do so.  */
        oneproc = 1;
     }
   else
@@ -754,6 +720,10 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
       write_pc (addr);
     }
 
+  if (debug_infrun)
+    printf_unfiltered ("infrun: proceed (addr=0x%s, signal=%d, step=%d)\n",
+                      paddr_nz (addr), siggnal, step);
+
   /* In a multi-threaded task we may select another thread
      and then continue or step.
 
@@ -768,18 +738,6 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   if (prepare_to_proceed () && breakpoint_here_p (read_pc ()))
     oneproc = 1;
 
-#ifdef HP_OS_BUG
-  if (trap_expected_after_continue)
-    {
-      /* If (step == 0), a trap will be automatically generated after
-         the first instruction is executed.  Force step one
-         instruction to clear this condition.  This should not occur
-         if step is nonzero, but it is harmless in that case.  */
-      oneproc = 1;
-      trap_expected_after_continue = 0;
-    }
-#endif /* HP_OS_BUG */
-
   if (oneproc)
     /* We will get a trace trap after one instruction.
        Continue it automatically and insert breakpoints then.  */
@@ -788,7 +746,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
     {
       insert_breakpoints ();
       /* If we get here there was no call to error() in 
-        insert breakpoints -- so they were inserted.  */
+         insert breakpoints -- so they were inserted.  */
       breakpoints_inserted = 1;
     }
 
@@ -826,7 +784,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
      cannot be read unless the inferior is stopped.  At that point, we
      are not guaranteed the inferior is stopped and so the read_pc ()
      call can fail.  Setting the prev_pc value here ensures the value is 
-     updated correctly when the inferior is stopped.  */  
+     updated correctly when the inferior is stopped.  */
   prev_pc = read_pc ();
 
   /* Resume inferior.  */
@@ -836,7 +794,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
      and in any case decode why it stopped, and act accordingly.  */
   /* Do this only if we are not using the event loop, or if the target
      does not support asynchronous execution. */
-  if (!event_loop_p || !target_can_async_p ())
+  if (!target_can_async_p ())
     {
       wait_for_inferior ();
       normal_stop ();
@@ -880,9 +838,6 @@ init_wait_for_inferior (void)
   /* These are meaningless until the first time through wait_for_inferior.  */
   prev_pc = 0;
 
-#ifdef HP_OS_BUG
-  trap_expected_after_continue = 0;
-#endif
   breakpoints_inserted = 0;
   breakpoint_init_inferior (inf_starting);
 
@@ -892,9 +847,6 @@ init_wait_for_inferior (void)
   /* The first resume is not following a fork/vfork/exec. */
   pending_follow.kind = TARGET_WAITKIND_SPURIOUS;      /* I.e., none. */
 
-  /* See wait_for_inferior's handling of SYSCALL_ENTRY/RETURN events. */
-  number_of_threads_in_syscalls = 0;
-
   clear_proceed_status ();
 
   stepping_past_singlestep_breakpoint = 0;
@@ -908,7 +860,6 @@ enum infwait_states
 {
   infwait_normal_state,
   infwait_thread_hop_state,
-  infwait_nullified_state,
   infwait_nonstep_watch_state
 };
 
@@ -944,16 +895,14 @@ struct execution_control_state
   CORE_ADDR stop_func_end;
   char *stop_func_name;
   struct symtab_and_line sal;
-  int remove_breakpoints_on_following_step;
   int current_line;
   struct symtab *current_symtab;
   int handling_longjmp;                /* FIXME */
   ptid_t ptid;
   ptid_t saved_inferior_ptid;
+  int step_after_step_resume_breakpoint;
   int stepping_through_solib_after_catch;
   bpstat stepping_through_solib_catchpoints;
-  int enable_hw_watchpoints_after_wait;
-  int stepping_through_sigtramp;
   int new_thread_event;
   struct target_waitstatus tmpstatus;
   enum infwait_states infwait_state;
@@ -963,12 +912,12 @@ struct execution_control_state
 
 void init_execution_control_state (struct execution_control_state *ecs);
 
-static void handle_step_into_function (struct execution_control_state *ecs);
 void handle_inferior_event (struct execution_control_state *ecs);
 
 static void step_into_function (struct execution_control_state *ecs);
-static void insert_step_resume_breakpoint (struct frame_info *step_frame,
-                                          struct execution_control_state *ecs);
+static void insert_step_resume_breakpoint_at_frame (struct frame_info *step_frame);
+static void insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
+                                                 struct frame_id sr_id);
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
 static void keep_going (struct execution_control_state *ecs);
@@ -988,6 +937,9 @@ wait_for_inferior (void)
   struct execution_control_state ecss;
   struct execution_control_state *ecs;
 
+  if (debug_infrun)
+    printf_unfiltered ("infrun: wait_for_inferior\n");
+
   old_cleanups = make_cleanup (delete_step_resume_breakpoint,
                               &step_resume_breakpoint);
 
@@ -1099,12 +1051,10 @@ init_execution_control_state (struct execution_control_state *ecs)
 {
   /* ecs->another_trap? */
   ecs->random_signal = 0;
-  ecs->remove_breakpoints_on_following_step = 0;
+  ecs->step_after_step_resume_breakpoint = 0;
   ecs->handling_longjmp = 0;   /* FIXME */
   ecs->stepping_through_solib_after_catch = 0;
   ecs->stepping_through_solib_catchpoints = NULL;
-  ecs->enable_hw_watchpoints_after_wait = 0;
-  ecs->stepping_through_sigtramp = 0;
   ecs->sal = find_pc_line (prev_pc, 0);
   ecs->current_line = ecs->sal.line;
   ecs->current_symtab = ecs->sal.symtab;
@@ -1113,18 +1063,6 @@ init_execution_control_state (struct execution_control_state *ecs)
   ecs->wp = &(ecs->ws);
 }
 
-/* Call this function before setting step_resume_breakpoint, as a
-   sanity check.  There should never be more than one step-resume
-   breakpoint per thread, so we should never be setting a new
-   step_resume_breakpoint when one is already active.  */
-static void
-check_for_old_step_resume_breakpoint (void)
-{
-  if (step_resume_breakpoint)
-    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()/deprecated_target_wait_hook().  The data is actually
    cached by handle_inferior_event(), which gets called immediately
@@ -1158,7 +1096,6 @@ context_switch (struct execution_control_state *ecs)
                         ecs->handling_longjmp, ecs->another_trap,
                         ecs->stepping_through_solib_after_catch,
                         ecs->stepping_through_solib_catchpoints,
-                        ecs->stepping_through_sigtramp,
                         ecs->current_line, ecs->current_symtab);
 
       /* Load infrun state for the new thread.  */
@@ -1169,92 +1106,11 @@ context_switch (struct execution_control_state *ecs)
                         &ecs->handling_longjmp, &ecs->another_trap,
                         &ecs->stepping_through_solib_after_catch,
                         &ecs->stepping_through_solib_catchpoints,
-                        &ecs->stepping_through_sigtramp,
                         &ecs->current_line, &ecs->current_symtab);
     }
   inferior_ptid = ecs->ptid;
 }
 
-/* Handle the inferior event in the cases when we just stepped
-   into a function.  */
-
-static void
-handle_step_into_function (struct execution_control_state *ecs)
-{
-  CORE_ADDR real_stop_pc;
-
-  if ((step_over_calls == STEP_OVER_NONE)
-      || ((step_range_end == 1)
-          && in_prologue (prev_pc, ecs->stop_func_start)))
-    {
-      /* I presume that step_over_calls is only 0 when we're
-         supposed to be stepping at the assembly language level
-         ("stepi").  Just stop.  */
-      /* Also, maybe we just did a "nexti" inside a prolog,
-         so we thought it was a subroutine call but it was not.
-         Stop as well.  FENN */
-      stop_step = 1;
-      print_stop_reason (END_STEPPING_RANGE, 0);
-      stop_stepping (ecs);
-      return;
-    }
-
-  if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
-    {
-      /* We're doing a "next", set a breakpoint at callee's return
-        address (the address at which the caller will resume).  */
-      insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()),
-                                    ecs);
-      keep_going (ecs);
-      return;
-    }
-
-  /* If we are in a function call trampoline (a stub between
-     the calling routine and the real function), locate the real
-     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);
-  if (real_stop_pc == 0)
-    real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
-  if (real_stop_pc != 0)
-    ecs->stop_func_start = real_stop_pc;
-
-  /* If we have line number information for the function we
-     are thinking of stepping into, step into it.
-
-     If there are several symtabs at that PC (e.g. with include
-     files), just want to know whether *any* of them have line
-     numbers.  find_pc_line handles this.  */
-  {
-    struct symtab_and_line tmp_sal;
-
-    tmp_sal = find_pc_line (ecs->stop_func_start, 0);
-    if (tmp_sal.line != 0)
-      {
-        step_into_function (ecs);
-        return;
-      }
-  }
-
-  /* If we have no line number and the step-stop-if-no-debug
-     is set, we stop the step so that the user has a chance to
-     switch in assembly mode.  */
-  if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
-    {
-      stop_step = 1;
-      print_stop_reason (END_STEPPING_RANGE, 0);
-      stop_stepping (ecs);
-      return;
-    }
-
-  /* Set a breakpoint at callee's return address (the address at which
-     the caller will resume).  */
-  insert_step_resume_breakpoint (get_prev_frame (get_current_frame ()), ecs);
-  keep_going (ecs);
-  return;
-}
-
 static void
 adjust_pc_after_break (struct execution_control_state *ecs)
 {
@@ -1272,14 +1128,14 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      affected by DECR_PC_AFTER_BREAK.  Other waitkinds which are implemented
      by software breakpoints should be handled through the normal breakpoint
      layer.
-     
+
      NOTE drow/2004-01-31: On some targets, breakpoints may generate
      different signals (SIGILL or SIGEMT for instance), but it is less
      clear where the PC is pointing afterwards.  It may not match
      DECR_PC_AFTER_BREAK.  I don't know any specific target that generates
      these signals at breakpoints (the code has been in GDB since at least
      1992) so I can not guess how to handle them here.
-     
+
      In earlier versions of GDB, a target with HAVE_NONSTEPPABLE_WATCHPOINTS
      would have the PC after hitting a watchpoint affected by
      DECR_PC_AFTER_BREAK.  I haven't found any target with both of these set
@@ -1299,8 +1155,8 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   if (SOFTWARE_SINGLE_STEP_P ())
     {
       /* When using software single-step, a SIGTRAP can only indicate
-        an inserted breakpoint.  This actually makes things
-        easier.  */
+         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
@@ -1316,9 +1172,9 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   else
     {
       /* 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.  */
+         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.  */
       if (currently_stepping (ecs))
        {
          if (prev_pc == breakpoint_pc
@@ -1356,7 +1212,7 @@ handle_inferior_event (struct execution_control_state *ecs)
      defined in the file "config/pa/nm-hppah.h", accesses the variable
      indirectly.  Mutter something rude about the HP merge.  */
   int sw_single_step_trap_p = 0;
-  int stopped_by_watchpoint = 0;
+  int stopped_by_watchpoint = -1;      /* Mark as unknown.  */
 
   /* Cache the last pid/waitstatus. */
   target_last_wait_ptid = ecs->ptid;
@@ -1367,34 +1223,21 @@ handle_inferior_event (struct execution_control_state *ecs)
   switch (ecs->infwait_state)
     {
     case infwait_thread_hop_state:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: infwait_thread_hop_state\n");
       /* Cancel the waiton_ptid. */
       ecs->waiton_ptid = pid_to_ptid (-1);
-      /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event
-         is serviced in this loop, below. */
-      if (ecs->enable_hw_watchpoints_after_wait)
-       {
-         TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
-         ecs->enable_hw_watchpoints_after_wait = 0;
-       }
-      stepped_after_stopped_by_watchpoint = 0;
       break;
 
     case infwait_normal_state:
-      /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event
-         is serviced in this loop, below. */
-      if (ecs->enable_hw_watchpoints_after_wait)
-       {
-         TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
-         ecs->enable_hw_watchpoints_after_wait = 0;
-       }
-      stepped_after_stopped_by_watchpoint = 0;
-      break;
-
-    case infwait_nullified_state:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: infwait_normal_state\n");
       stepped_after_stopped_by_watchpoint = 0;
       break;
 
     case infwait_nonstep_watch_state:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: infwait_nonstep_watch_state\n");
       insert_breakpoints ();
 
       /* FIXME-maybe: is this cleaner than setting a flag?  Does it
@@ -1413,6 +1256,7 @@ handle_inferior_event (struct execution_control_state *ecs)
   /* If it's a new process, add it to the thread database */
 
   ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid)
+                          && !ptid_equal (ecs->ptid, minus_one_ptid)
                           && !in_thread_list (ecs->ptid));
 
   if (ecs->ws.kind != TARGET_WAITKIND_EXITED
@@ -1423,36 +1267,13 @@ handle_inferior_event (struct execution_control_state *ecs)
       ui_out_text (uiout, "[New ");
       ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid));
       ui_out_text (uiout, "]\n");
-
-#if 0
-      /* NOTE: This block is ONLY meant to be invoked in case of a
-         "thread creation event"!  If it is invoked for any other
-         sort of event (such as a new thread landing on a breakpoint),
-         the event will be discarded, which is almost certainly
-         a bad thing!
-
-         To avoid this, the low-level module (eg. target_wait)
-         should call in_thread_list and add_thread, so that the
-         new thread is known by the time we get here.  */
-
-      /* We may want to consider not doing a resume here in order
-         to give the user a chance to play with the new thread.
-         It might be good to make that a user-settable option.  */
-
-      /* At this point, all threads are stopped (happens
-         automatically in either the OS or the native code).
-         Therefore we need to continue all threads in order to
-         make progress.  */
-
-      target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
-#endif
     }
 
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
+      if (debug_infrun)
+        printf_unfiltered ("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.  */
@@ -1470,20 +1291,20 @@ handle_inferior_event (struct execution_control_state *ecs)
             breakpoint_re_set.  */
          target_terminal_ours_for_output ();
          /* NOTE: cagney/2003-11-25: Make certain that the target
-             stack's section table is kept up-to-date.  Architectures,
-             (e.g., PPC64), use the section table to perform
-             operations such as address => section name and hence
-             require the table to contain all sections (including
-             those found in shared libraries).  */
+            stack's section table is kept up-to-date.  Architectures,
+            (e.g., PPC64), use the section table to perform
+            operations such as address => section name and hence
+            require the table to contain all sections (including
+            those found in shared libraries).  */
          /* NOTE: cagney/2003-11-25: Pass current_target and not
-             exec_ops to SOLIB_ADD.  This is because current GDB is
-             only tooled to propagate section_table changes out from
-             the "current_target" (see target_resize_to_sections), and
-             not up from the exec stratum.  This, of course, isn't
-             right.  "infrun.c" should only interact with the
-             exec/process stratum, instead relying on the target stack
-             to propagate relevant changes (stop, section table
-             changed, ...) up to other layers.  */
+            exec_ops to SOLIB_ADD.  This is because current GDB is
+            only tooled to propagate section_table changes out from
+            the "current_target" (see target_resize_to_sections), and
+            not up from the exec stratum.  This, of course, isn't
+            right.  "infrun.c" should only interact with the
+            exec/process stratum, instead relying on the target stack
+            to propagate relevant changes (stop, section table
+            changed, ...) up to other layers.  */
          SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
          target_terminal_inferior ();
 
@@ -1497,11 +1318,15 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
 
     case TARGET_WAITKIND_SPURIOUS:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_SPURIOUS\n");
       resume (0, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
 
     case TARGET_WAITKIND_EXITED:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_EXITED\n");
       target_terminal_ours (); /* Must do this before mourn anyway */
       print_stop_reason (EXITED, ecs->ws.value.integer);
 
@@ -1518,6 +1343,8 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
 
     case TARGET_WAITKIND_SIGNALLED:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_SIGNALLED\n");
       stop_print_frame = 0;
       stop_signal = ecs->ws.value.sig;
       target_terminal_ours (); /* Must do this before mourn anyway */
@@ -1538,6 +1365,8 @@ handle_inferior_event (struct execution_control_state *ecs)
          the above cases end in a continue or goto. */
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_FORKED\n");
       stop_signal = TARGET_SIGNAL_TRAP;
       pending_follow.kind = ecs->ws.kind;
 
@@ -1560,11 +1389,13 @@ handle_inferior_event (struct execution_control_state *ecs)
       goto process_event_stop_test;
 
     case TARGET_WAITKIND_EXECD:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_EXECED\n");
       stop_signal = TARGET_SIGNAL_TRAP;
 
       /* NOTE drow/2002-12-05: This code should be pushed down into the
-        target_wait function.  Until then following vfork on HP/UX 10.20
-        is probably broken by this.  Of course, it's broken anyway.  */
+         target_wait function.  Until then following vfork on HP/UX 10.20
+         is probably broken by this.  Of course, it's broken anyway.  */
       /* Is this a target which reports multiple exec events per actual
          call to exec()?  (HP-UX using ptrace does, for example.)  If so,
          ignore all but the last one.  Just resume the exec'r, and wait
@@ -1609,29 +1440,11 @@ handle_inferior_event (struct execution_control_state *ecs)
        }
       goto process_event_stop_test;
 
-      /* These syscall events are returned on HP-UX, as part of its
-         implementation of page-protection-based "hardware" watchpoints.
-         HP-UX has unfortunate interactions between page-protections and
-         some system calls.  Our solution is to disable hardware watches
-         when a system call is entered, and reenable them when the syscall
-         completes.  The downside of this is that we may miss the precise
-         point at which a watched piece of memory is modified.  "Oh well."
-
-         Note that we may have multiple threads running, which may each
-         enter syscalls at roughly the same time.  Since we don't have a
-         good notion currently of whether a watched piece of memory is
-         thread-private, we'd best not have any page-protections active
-         when any thread is in a syscall.  Thus, we only want to reenable
-         hardware watches when no threads are in a syscall.
-
-         Also, be careful not to try to gather much state about a thread
-         that's in a syscall.  It's frequently a losing proposition. */
+      /* Be careful not to try to gather much state about a thread
+         that's in a syscall.  It's frequently a losing proposition.  */
     case TARGET_WAITKIND_SYSCALL_ENTRY:
-      number_of_threads_in_syscalls++;
-      if (number_of_threads_in_syscalls == 1)
-       {
-         TARGET_DISABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
-       }
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
       resume (0, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
@@ -1640,42 +1453,32 @@ handle_inferior_event (struct execution_control_state *ecs)
          get it entirely out of the syscall.  (We get notice of the
          event when the thread is just on the verge of exiting a
          syscall.  Stepping one instruction seems to get it back
-         into user code.)
-
-         Note that although the logical place to reenable h/w watches
-         is here, we cannot.  We cannot reenable them before stepping
-         the thread (this causes the next wait on the thread to hang).
-
-         Nor can we enable them after stepping until we've done a wait.
-         Thus, we simply set the flag ecs->enable_hw_watchpoints_after_wait
-         here, which will be serviced immediately after the target
-         is waited on. */
+         into user code.)  */
     case TARGET_WAITKIND_SYSCALL_RETURN:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
-
-      if (number_of_threads_in_syscalls > 0)
-       {
-         number_of_threads_in_syscalls--;
-         ecs->enable_hw_watchpoints_after_wait =
-           (number_of_threads_in_syscalls == 0);
-       }
       prepare_to_wait (ecs);
       return;
 
     case TARGET_WAITKIND_STOPPED:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_STOPPED\n");
       stop_signal = ecs->ws.value.sig;
       break;
 
       /* We had an event in the inferior, but we are not interested
          in handling it at this level. The lower layers have already
          done what needs to be done, if anything.
-        
-        One of the possible circumstances for this is when the
-        inferior produces output for the console. The inferior has
-        not stopped, and we are ignoring the event.  Another possible
-        circumstance is any event which the lower level knows will be
-        reported multiple times without an intervening resume.  */
+
+         One of the possible circumstances for this is when the
+         inferior produces output for the console. The inferior has
+         not stopped, and we are ignoring the event.  Another possible
+         circumstance is any event which the lower level knows will be
+         reported multiple times without an intervening resume.  */
     case TARGET_WAITKIND_IGNORE:
+      if (debug_infrun)
+        printf_unfiltered ("infrun: TARGET_WAITKIND_IGNORE\n");
       prepare_to_wait (ecs);
       return;
     }
@@ -1696,19 +1499,25 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   stop_pc = read_pc_pid (ecs->ptid);
 
+  if (debug_infrun)
+    printf_unfiltered ("infrun: stop_pc = 0x%s\n", paddr_nz (stop_pc));
+
   if (stepping_past_singlestep_breakpoint)
     {
-      gdb_assert (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p);
+      gdb_assert (SOFTWARE_SINGLE_STEP_P ()
+                 && singlestep_breakpoints_inserted_p);
       gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
       gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));
 
       stepping_past_singlestep_breakpoint = 0;
 
       /* We've either finished single-stepping past the single-step
-        breakpoint, or stopped for some other reason.  It would be nice if
-        we could tell, but we can't reliably.  */
+         breakpoint, or stopped for some other reason.  It would be nice if
+         we could tell, but we can't reliably.  */
       if (stop_signal == TARGET_SIGNAL_TRAP)
-        {
+       {
+         if (debug_infrun)
+           printf_unfiltered ("infrun: stepping_past_singlestep_breakpoint\n");
          /* Pull the single step breakpoints out of the target.  */
          SOFTWARE_SINGLE_STEP (0, 0);
          singlestep_breakpoints_inserted_p = 0;
@@ -1762,66 +1571,69 @@ handle_inferior_event (struct execution_control_state *ecs)
        }
 
       if (thread_hop_needed)
-           {
-             int remove_status;
+       {
+         int remove_status;
 
-             /* Saw a breakpoint, but it was hit by the wrong thread.
-                Just continue. */
+         if (debug_infrun)
+           printf_unfiltered ("infrun: thread_hop_needed\n");
 
-             if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
-               {
-                 /* Pull the single step breakpoints out of the target. */
-                 SOFTWARE_SINGLE_STEP (0, 0);
-                 singlestep_breakpoints_inserted_p = 0;
-               }
+         /* Saw a breakpoint, but it was hit by the wrong thread.
+            Just continue. */
 
-             remove_status = remove_breakpoints ();
-             /* Did we fail to remove breakpoints?  If so, try
-                to set the PC past the bp.  (There's at least
-                one situation in which we can fail to remove
-                the bp's: On HP-UX's that use ttrace, we can't
-                change the address space of a vforking child
-                process until the child exits (well, okay, not
-                then either :-) or execs. */
-             if (remove_status != 0)
-               {
-                 /* FIXME!  This is obviously non-portable! */
-                 write_pc_pid (stop_pc + 4, ecs->ptid);
-                 /* We need to restart all the threads now,
-                  * unles we're running in scheduler-locked mode. 
-                  * Use currently_stepping to determine whether to 
-                  * step or continue.
-                  */
-                 /* FIXME MVS: is there any reason not to call resume()? */
-                 if (scheduler_mode == schedlock_on)
-                   target_resume (ecs->ptid,
-                                  currently_stepping (ecs), TARGET_SIGNAL_0);
-                 else
-                   target_resume (RESUME_ALL,
-                                  currently_stepping (ecs), TARGET_SIGNAL_0);
-                 prepare_to_wait (ecs);
-                 return;
-               }
+         if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+           {
+             /* Pull the single step breakpoints out of the target. */
+             SOFTWARE_SINGLE_STEP (0, 0);
+             singlestep_breakpoints_inserted_p = 0;
+           }
+
+         remove_status = remove_breakpoints ();
+         /* Did we fail to remove breakpoints?  If so, try
+            to set the PC past the bp.  (There's at least
+            one situation in which we can fail to remove
+            the bp's: On HP-UX's that use ttrace, we can't
+            change the address space of a vforking child
+            process until the child exits (well, okay, not
+            then either :-) or execs. */
+         if (remove_status != 0)
+           {
+             /* FIXME!  This is obviously non-portable! */
+             write_pc_pid (stop_pc + 4, ecs->ptid);
+             /* We need to restart all the threads now,
+              * unles we're running in scheduler-locked mode. 
+              * Use currently_stepping to determine whether to 
+              * step or continue.
+              */
+             /* FIXME MVS: is there any reason not to call resume()? */
+             if (scheduler_mode == schedlock_on)
+               target_resume (ecs->ptid,
+                              currently_stepping (ecs), TARGET_SIGNAL_0);
              else
-               {               /* Single step */
-                 breakpoints_inserted = 0;
-                 if (!ptid_equal (inferior_ptid, ecs->ptid))
-                   context_switch (ecs);
-                 ecs->waiton_ptid = ecs->ptid;
-                 ecs->wp = &(ecs->ws);
-                 ecs->another_trap = 1;
-
-                 ecs->infwait_state = infwait_thread_hop_state;
-                 keep_going (ecs);
-                 registers_changed ();
-                 return;
-               }
+               target_resume (RESUME_ALL,
+                              currently_stepping (ecs), TARGET_SIGNAL_0);
+             prepare_to_wait (ecs);
+             return;
+           }
+         else
+           {                   /* Single step */
+             breakpoints_inserted = 0;
+             if (!ptid_equal (inferior_ptid, ecs->ptid))
+               context_switch (ecs);
+             ecs->waiton_ptid = ecs->ptid;
+             ecs->wp = &(ecs->ws);
+             ecs->another_trap = 1;
+
+             ecs->infwait_state = infwait_thread_hop_state;
+             keep_going (ecs);
+             registers_changed ();
+             return;
+           }
        }
       else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
-        {
-          sw_single_step_trap_p = 1;
-          ecs->random_signal = 0;
-        }
+       {
+         sw_single_step_trap_p = 1;
+         ecs->random_signal = 0;
+       }
     }
   else
     ecs->random_signal = 1;
@@ -1830,6 +1642,9 @@ handle_inferior_event (struct execution_control_state *ecs)
      so, then switch to that thread.  */
   if (!ptid_equal (ecs->ptid, inferior_ptid))
     {
+      if (debug_infrun)
+       printf_unfiltered ("infrun: context switch\n");
+
       context_switch (ecs);
 
       if (deprecated_context_hook)
@@ -1845,32 +1660,13 @@ handle_inferior_event (struct execution_control_state *ecs)
       singlestep_breakpoints_inserted_p = 0;
     }
 
-  /* If PC is pointing at a nullified instruction, then step beyond
-     it so that the user won't be confused when GDB appears to be ready
-     to execute it. */
-
-  /*      if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */
-  if (INSTRUCTION_NULLIFIED)
-    {
-      registers_changed ();
-      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
-
-      /* We may have received a signal that we want to pass to
-         the inferior; therefore, we must not clobber the waitstatus
-         in WS. */
-
-      ecs->infwait_state = infwait_nullified_state;
-      ecs->waiton_ptid = ecs->ptid;
-      ecs->wp = &(ecs->tmpstatus);
-      prepare_to_wait (ecs);
-      return;
-    }
-
   /* 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 (debug_infrun)
+       printf_unfiltered ("infrun: STOPPED_BY_WATCHPOINT\n");
       resume (1, 0);
       prepare_to_wait (ecs);
       return;
@@ -1898,6 +1694,8 @@ handle_inferior_event (struct execution_control_state *ecs)
          includes evaluating watchpoints, things will come to a
          stop in the correct manner.  */
 
+      if (debug_infrun)
+       printf_unfiltered ("infrun: STOPPED_BY_WATCHPOINT\n");
       remove_breakpoints ();
       registers_changed ();
       target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);   /* Single step */
@@ -1920,7 +1718,7 @@ 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 += FUNCTION_START_OFFSET;
+  ecs->stop_func_start += DEPRECATED_FUNCTION_START_OFFSET;
   ecs->another_trap = 0;
   bpstat_clear (&stop_bpstat);
   stop_step = 0;
@@ -1930,6 +1728,41 @@ handle_inferior_event (struct execution_control_state *ecs)
   stopped_by_random_signal = 0;
   breakpoints_failed = 0;
 
+  if (stop_signal == TARGET_SIGNAL_TRAP
+      && trap_expected
+      && gdbarch_single_step_through_delay_p (current_gdbarch)
+      && currently_stepping (ecs))
+    {
+      /* We're trying to step of a breakpoint.  Turns out that we're
+        also on an instruction that needs to be stepped multiple
+        times before it's been fully executing. E.g., architectures
+        with a delay slot.  It needs to be stepped twice, once for
+        the instruction and once for the delay slot.  */
+      int step_through_delay
+       = gdbarch_single_step_through_delay (current_gdbarch,
+                                            get_current_frame ());
+      if (debug_infrun && step_through_delay)
+       printf_unfiltered ("infrun: step through delay\n");
+      if (step_range_end == 0 && step_through_delay)
+       {
+         /* The user issued a continue when stopped at a breakpoint.
+            Set up for another trap and get out of here.  */
+         ecs->another_trap = 1;
+         keep_going (ecs);
+         return;
+       }
+      else if (step_through_delay)
+       {
+         /* The user issued a step when stopped at a breakpoint.
+            Maybe we should stop, maybe we should not - the delay
+            slot *might* correspond to a line of source.  In any
+            case, don't decide that here, just set ecs->another_trap,
+            making sure we single-step again before breakpoints are
+            re-inserted.  */
+         ecs->another_trap = 1;
+       }
+    }
+
   /* Look at the cause of the stop, and decide what to do.
      The alternatives are:
      1) break; to really stop and return to the debugger,
@@ -1950,15 +1783,16 @@ handle_inferior_event (struct execution_control_state *ecs)
      stack.  */
 
   if (stop_signal == TARGET_SIGNAL_TRAP
-      || (breakpoints_inserted &&
-         (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)
+      || (breakpoints_inserted
+         && (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)
     {
       if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
        {
+          if (debug_infrun)
+           printf_unfiltered ("infrun: stopped\n");
          stop_print_frame = 0;
          stop_stepping (ecs);
          return;
@@ -1968,6 +1802,8 @@ handle_inferior_event (struct execution_control_state *ecs)
          shared libraries hook functions.  */
       if (stop_soon == STOP_QUIETLY)
        {
+          if (debug_infrun)
+           printf_unfiltered ("infrun: quietly stopped\n");
          stop_stepping (ecs);
          return;
        }
@@ -1987,11 +1823,15 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* Don't even think about breakpoints if just proceeded over a
          breakpoint.  */
       if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected)
-       bpstat_clear (&stop_bpstat);
+       {
+          if (debug_infrun)
+           printf_unfiltered ("infrun: trap expected\n");
+         bpstat_clear (&stop_bpstat);
+       }
       else
        {
          /* See if there is a breakpoint at the current PC.  */
-         stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid, 
+         stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid,
                                            stopped_by_watchpoint);
 
          /* Following in case break condition called a
@@ -2000,13 +1840,13 @@ handle_inferior_event (struct execution_control_state *ecs)
        }
 
       /* NOTE: cagney/2003-03-29: These two checks for a random signal
-        at one stage in the past included checks for an inferior
-        function call's call dummy's return breakpoint.  The original
-        comment, that went with the test, read:
+         at one stage in the past included checks for an inferior
+         function call's call dummy's return breakpoint.  The original
+         comment, that went with the test, read:
 
-        ``End of a stack dummy.  Some systems (e.g. Sony news) give
-        another signal besides SIGTRAP, so check here as well as
-        above.''
+         ``End of a stack dummy.  Some systems (e.g. Sony news) give
+         another signal besides SIGTRAP, so check here as well as
+         above.''
 
          If someone ever tries to get get call dummys on a
          non-executable stack to work (where the target would stop
@@ -2015,9 +1855,9 @@ handle_inferior_event (struct execution_control_state *ecs)
          enabled when momentary breakpoints were not being used, I
          suspect that it won't be the case.
 
-        NOTE: kettenis/2004-02-05: Indeed such checks don't seem to
-        be necessary for call dummies on a non-executable stack on
-        SPARC.  */
+         NOTE: kettenis/2004-02-05: Indeed such checks don't seem to
+         be necessary for call dummies on a non-executable stack on
+         SPARC.  */
 
       if (stop_signal == TARGET_SIGNAL_TRAP)
        ecs->random_signal
@@ -2048,6 +1888,9 @@ process_event_stop_test:
       /* Signal not for debugging purposes.  */
       int printed = 0;
 
+      if (debug_infrun)
+        printf_unfiltered ("infrun: random signal %d\n", stop_signal);
+
       stopped_by_random_signal = 1;
 
       if (signal_print[stop_signal])
@@ -2070,10 +1913,29 @@ process_event_stop_test:
       if (signal_program[stop_signal] == 0)
        stop_signal = TARGET_SIGNAL_0;
 
-      if (step_range_end != 0
-         && stop_signal != TARGET_SIGNAL_0
-         && stop_pc >= step_range_start && stop_pc < step_range_end
-         && frame_id_eq (get_frame_id (get_current_frame ()), step_frame_id))
+      if (prev_pc == read_pc ()
+         && !breakpoints_inserted
+         && breakpoint_here_p (read_pc ())
+         && step_resume_breakpoint == NULL)
+       {
+         /* We were just starting a new sequence, attempting to
+            single-step off of a breakpoint and expecting a SIGTRAP.
+            Intead this signal arrives.  This signal will take us out
+            of the stepping range so GDB needs to remember to, when
+            the signal handler returns, resume stepping off that
+            breakpoint.  */
+         /* To simplify things, "continue" is forced to use the same
+            code paths as single-step - set a breakpoint at the
+            signal return address and then, once hit, step off that
+            breakpoint.  */
+         insert_step_resume_breakpoint_at_frame (get_current_frame ());
+         ecs->step_after_step_resume_breakpoint = 1;
+       }
+      else if (step_range_end != 0
+              && stop_signal != TARGET_SIGNAL_0
+              && stop_pc >= step_range_start && stop_pc < step_range_end
+              && frame_id_eq (get_frame_id (get_current_frame ()),
+                              step_frame_id))
        {
          /* The inferior is about to take a signal that will take it
             out of the single step range.  Set a breakpoint at the
@@ -2084,7 +1946,7 @@ process_event_stop_test:
             Note that this is only needed for a signal delivered
             while in the single-step range.  Nested signals aren't a
             problem as they eventually all return.  */
-         insert_step_resume_breakpoint (get_current_frame (), ecs);
+         insert_step_resume_breakpoint_at_frame (get_current_frame ());
        }
       keep_going (ecs);
       return;
@@ -2100,9 +1962,6 @@ process_event_stop_test:
     if (what.call_dummy)
       {
        stop_stack_dummy = 1;
-#ifdef HP_OS_BUG
-       trap_expected_after_continue = 1;
-#endif
       }
 
     switch (what.main_action)
@@ -2111,6 +1970,8 @@ process_event_stop_test:
        /* If we hit the breakpoint at longjmp, disable it for the
           duration of this command.  Then, install a temporary
           breakpoint at the target of the jmp_buf. */
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_SET_LONGJMP_RESUME\n");
        disable_longjmp_breakpoint ();
        remove_breakpoints ();
        breakpoints_inserted = 0;
@@ -2127,32 +1988,17 @@ process_event_stop_test:
            delete_step_resume_breakpoint (&step_resume_breakpoint);
          }
 
-#if 0
-       /* FIXME - Need to implement nested temporary breakpoints */
-       if (step_over_calls > 0)
-         set_longjmp_resume_breakpoint (jmp_buf_pc, get_current_frame ());
-       else
-#endif /* 0 */
-         set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id);
+       set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id);
        ecs->handling_longjmp = 1;      /* FIXME */
        keep_going (ecs);
        return;
 
       case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
       case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE:
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_CLEAR_LONGJMP_RESUME\n");
        remove_breakpoints ();
        breakpoints_inserted = 0;
-#if 0
-       /* FIXME - Need to implement nested temporary breakpoints */
-       if (step_over_calls
-           && (frame_id_inner (get_frame_id (get_current_frame ()),
-                               step_frame_id)))
-         {
-           ecs->another_trap = 1;
-           keep_going (ecs);
-           return;
-         }
-#endif /* 0 */
        disable_longjmp_breakpoint ();
        ecs->handling_longjmp = 0;      /* FIXME */
        if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME)
@@ -2160,6 +2006,8 @@ process_event_stop_test:
        /* else fallthrough */
 
       case BPSTAT_WHAT_SINGLE:
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_SINGLE\n");
        if (breakpoints_inserted)
          {
            remove_breakpoints ();
@@ -2171,6 +2019,8 @@ process_event_stop_test:
        break;
 
       case BPSTAT_WHAT_STOP_NOISY:
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_STOP_NOISY\n");
        stop_print_frame = 1;
 
        /* We are about to nuke the step_resume_breakpointt via the
@@ -2180,6 +2030,8 @@ process_event_stop_test:
        return;
 
       case BPSTAT_WHAT_STOP_SILENT:
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_STOP_SILENT\n");
        stop_print_frame = 0;
 
        /* We are about to nuke the step_resume_breakpoin via the
@@ -2206,15 +2058,32 @@ process_event_stop_test:
           step-resume bp, but it makes no effort to ensure that
           the one deleted is the one currently stopped at.  MVS  */
 
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_STEP_RESUME\n");
+
        if (step_resume_breakpoint == NULL)
          {
            step_resume_breakpoint =
              bpstat_find_step_resume_breakpoint (stop_bpstat);
          }
        delete_step_resume_breakpoint (&step_resume_breakpoint);
+       if (ecs->step_after_step_resume_breakpoint)
+         {
+           /* Back when the step-resume breakpoint was inserted, we
+              were trying to single-step off a breakpoint.  Go back
+              to doing that.  */
+           ecs->step_after_step_resume_breakpoint = 0;
+           remove_breakpoints ();
+           breakpoints_inserted = 0;
+           ecs->another_trap = 1;
+           keep_going (ecs);
+           return;
+         }
        break;
 
       case BPSTAT_WHAT_THROUGH_SIGTRAMP:
+        if (debug_infrun)
+         printf_unfiltered ("infrun: BPSTATE_WHAT_THROUGH_SIGTRAMP\n");
        /* If were waiting for a trap, hitting the step_resume_break
           doesn't count as getting it.  */
        if (trap_expected)
@@ -2225,6 +2094,8 @@ process_event_stop_test:
       case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK:
 #ifdef SOLIB_ADD
        {
+          if (debug_infrun)
+           printf_unfiltered ("infrun: BPSTATE_WHAT_CHECK_SHLIBS\n");
          /* Remove breakpoints, we eventually want to step over the
             shlib event breakpoint, and SOLIB_ADD might adjust
             breakpoint addresses via breakpoint_re_set.  */
@@ -2238,20 +2109,20 @@ process_event_stop_test:
             breakpoint_re_set.  */
          target_terminal_ours_for_output ();
          /* NOTE: cagney/2003-11-25: Make certain that the target
-             stack's section table is kept up-to-date.  Architectures,
-             (e.g., PPC64), use the section table to perform
-             operations such as address => section name and hence
-             require the table to contain all sections (including
-             those found in shared libraries).  */
+            stack's section table is kept up-to-date.  Architectures,
+            (e.g., PPC64), use the section table to perform
+            operations such as address => section name and hence
+            require the table to contain all sections (including
+            those found in shared libraries).  */
          /* NOTE: cagney/2003-11-25: Pass current_target and not
-             exec_ops to SOLIB_ADD.  This is because current GDB is
-             only tooled to propagate section_table changes out from
-             the "current_target" (see target_resize_to_sections), and
-             not up from the exec stratum.  This, of course, isn't
-             right.  "infrun.c" should only interact with the
-             exec/process stratum, instead relying on the target stack
-             to propagate relevant changes (stop, section table
-             changed, ...) up to other layers.  */
+            exec_ops to SOLIB_ADD.  This is because current GDB is
+            only tooled to propagate section_table changes out from
+            the "current_target" (see target_resize_to_sections), and
+            not up from the exec stratum.  This, of course, isn't
+            right.  "infrun.c" should only interact with the
+            exec/process stratum, instead relying on the target stack
+            to propagate relevant changes (stop, section table
+            changed, ...) up to other layers.  */
          SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
          target_terminal_inferior ();
 
@@ -2279,8 +2150,8 @@ process_event_stop_test:
             the call that caused this catchpoint to trigger.  That
             gives the user a more useful vantage from which to
             examine their program's state. */
-         else if (what.main_action ==
-                  BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK)
+         else if (what.main_action
+                  == BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK)
            {
              /* ??rehrauer: If I could figure out how to get the
                 right return PC from here, we could just set a temp
@@ -2337,11 +2208,15 @@ process_event_stop_test:
       /* Have we reached our destination?  If not, keep going. */
       if (SOLIB_IN_DYNAMIC_LINKER (PIDGET (ecs->ptid), stop_pc))
        {
+          if (debug_infrun)
+           printf_unfiltered ("infrun: stepping in dynamic linker\n");
          ecs->another_trap = 1;
          keep_going (ecs);
          return;
        }
 #endif
+      if (debug_infrun)
+        printf_unfiltered ("infrun: step past dynamic linker\n");
       /* Else, stop and report the catchpoint(s) whose triggering
          caused us to begin stepping. */
       ecs->stepping_through_solib_after_catch = 0;
@@ -2355,6 +2230,9 @@ process_event_stop_test:
 
   if (step_resume_breakpoint)
     {
+      if (debug_infrun)
+        printf_unfiltered ("infrun: step-resume breakpoint\n");
+
       /* Having a step-resume breakpoint overrides anything
          else having to do with stepping commands until
          that breakpoint is reached.  */
@@ -2364,6 +2242,8 @@ process_event_stop_test:
 
   if (step_range_end == 0)
     {
+      if (debug_infrun)
+        printf_unfiltered ("infrun: no stepping, continue\n");
       /* Likewise if we aren't even stepping.  */
       keep_going (ecs);
       return;
@@ -2376,6 +2256,10 @@ process_event_stop_test:
      within it! */
   if (stop_pc >= step_range_start && stop_pc < step_range_end)
     {
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepping inside range [0x%s-0x%s]\n",
+                           paddr_nz (step_range_start),
+                           paddr_nz (step_range_end));
       keep_going (ecs);
       return;
     }
@@ -2392,6 +2276,9 @@ process_event_stop_test:
       CORE_ADDR pc_after_resolver =
        gdbarch_skip_solib_resolver (current_gdbarch, stop_pc);
 
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped into dynsym resolve code\n");
+
       if (pc_after_resolver)
        {
          /* Set up a step-resume breakpoint at the address
@@ -2400,62 +2287,117 @@ process_event_stop_test:
          init_sal (&sr_sal);
          sr_sal.pc = pc_after_resolver;
 
-         check_for_old_step_resume_breakpoint ();
-         step_resume_breakpoint =
-           set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
-         if (breakpoints_inserted)
-           insert_breakpoints ();
+         insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
        }
 
       keep_going (ecs);
       return;
     }
 
-  if (step_over_calls == STEP_OVER_UNDEBUGGABLE
-      && ecs->stop_func_name == NULL)
-    {
-      /* There is no symbol, not even a minimal symbol, corresponding
-         to the address where we just stopped.  So we just stepped
-         inside undebuggable code.  Since we want to step over this
-         kind of code, we keep going until the inferior returns from
-         the current function.  */
-      handle_step_into_function (ecs);
-      return;
-    }
-
   if (step_range_end != 1
       && (step_over_calls == STEP_OVER_UNDEBUGGABLE
          || step_over_calls == STEP_OVER_ALL)
       && get_frame_type (get_current_frame ()) == SIGTRAMP_FRAME)
     {
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped into signal trampoline\n");
       /* The inferior, while doing a "step" or "next", has ended up in
-        a signal trampoline (either by a signal being delivered or by
-        the signal handler returning).  Just single-step until the
-        inferior leaves the trampoline (either by calling the handler
-        or returning).  */
+         a signal trampoline (either by a signal being delivered or by
+         the signal handler returning).  Just single-step until the
+         inferior leaves the trampoline (either by calling the handler
+         or returning).  */
       keep_going (ecs);
       return;
     }
 
-  if (frame_id_eq (get_frame_id (get_prev_frame (get_current_frame ())),
-                   step_frame_id))
+  if (frame_id_eq (frame_unwind_id (get_current_frame ()), step_frame_id))
     {
       /* It's a subroutine call.  */
-      handle_step_into_function (ecs);
-      return;
-    }
+      CORE_ADDR real_stop_pc;
 
-  /* We've wandered out of the step range.  */
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped into subroutine\n");
 
-  ecs->sal = find_pc_line (stop_pc, 0);
+      if ((step_over_calls == STEP_OVER_NONE)
+         || ((step_range_end == 1)
+             && in_prologue (prev_pc, ecs->stop_func_start)))
+       {
+         /* I presume that step_over_calls is only 0 when we're
+            supposed to be stepping at the assembly language level
+            ("stepi").  Just stop.  */
+         /* Also, maybe we just did a "nexti" inside a prolog, so we
+            thought it was a subroutine call but it was not.  Stop as
+            well.  FENN */
+         stop_step = 1;
+         print_stop_reason (END_STEPPING_RANGE, 0);
+         stop_stepping (ecs);
+         return;
+       }
 
-  if (step_range_end == 1)
-    {
-      /* It is stepi or nexti.  We always want to stop stepping after
-         one instruction.  */
-      stop_step = 1;
-      print_stop_reason (END_STEPPING_RANGE, 0);
-      stop_stepping (ecs);
+      if (step_over_calls == STEP_OVER_ALL)
+       {
+         /* We're doing a "next", set a breakpoint at callee's return
+            address (the address at which the caller will
+            resume).  */
+         insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+         keep_going (ecs);
+         return;
+       }
+
+      /* If we are in a function call trampoline (a stub between the
+         calling routine and the real function), locate the real
+         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);
+      if (real_stop_pc == 0)
+       real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
+      if (real_stop_pc != 0)
+       ecs->stop_func_start = real_stop_pc;
+
+      if (IN_SOLIB_DYNSYM_RESOLVE_CODE (ecs->stop_func_start))
+       {
+         struct symtab_and_line sr_sal;
+         init_sal (&sr_sal);
+         sr_sal.pc = ecs->stop_func_start;
+
+         insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+         keep_going (ecs);
+         return;
+       }
+
+      /* If we have line number information for the function we are
+         thinking of stepping into, step into it.
+
+         If there are several symtabs at that PC (e.g. with include
+         files), just want to know whether *any* of them have line
+         numbers.  find_pc_line handles this.  */
+      {
+       struct symtab_and_line tmp_sal;
+
+       tmp_sal = find_pc_line (ecs->stop_func_start, 0);
+       if (tmp_sal.line != 0)
+         {
+           step_into_function (ecs);
+           return;
+         }
+      }
+
+      /* If we have no line number and the step-stop-if-no-debug is
+         set, we stop the step so that the user has a chance to switch
+         in assembly mode.  */
+      if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
+       {
+         stop_step = 1;
+         print_stop_reason (END_STEPPING_RANGE, 0);
+         stop_stepping (ecs);
+         return;
+       }
+
+      /* Set a breakpoint at callee's return address (the address at
+         which the caller will resume).  */
+      insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+      keep_going (ecs);
       return;
     }
 
@@ -2466,6 +2408,9 @@ process_event_stop_test:
       /* Determine where this trampoline returns.  */
       CORE_ADDR real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
 
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped into solib return tramp\n");
+
       /* Only proceed through if we know where it's going.  */
       if (real_stop_pc)
        {
@@ -2475,14 +2420,11 @@ process_event_stop_test:
          init_sal (&sr_sal);   /* initialize to zeroes */
          sr_sal.pc = real_stop_pc;
          sr_sal.section = find_pc_overlay (sr_sal.pc);
-         /* Do not specify what the fp should be when we stop
-            since on some machines the prologue
-            is where the new fp value is established.  */
-         check_for_old_step_resume_breakpoint ();
-         step_resume_breakpoint =
-           set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
-         if (breakpoints_inserted)
-           insert_breakpoints ();
+
+         /* Do not specify what the fp should be when we stop since
+            on some machines the prologue is where the new fp value
+            is established.  */
+         insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
 
          /* Restart without fiddling with the step ranges or
             other state.  */
@@ -2491,12 +2433,63 @@ process_event_stop_test:
        }
     }
 
+  /* NOTE: tausq/2004-05-24: This if block used to be done before all
+     the trampoline processing logic, however, there are some trampolines 
+     that have no names, so we should do trampoline handling first.  */
+  if (step_over_calls == STEP_OVER_UNDEBUGGABLE
+      && ecs->stop_func_name == NULL)
+    {
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped into undebuggable function\n");
+
+      /* The inferior just stepped into, or returned to, an
+         undebuggable function (where there is no symbol, not even a
+         minimal symbol, corresponding to the address where the
+         inferior stopped).  Since we want to skip this kind of code,
+         we keep going until the inferior returns from this
+         function.  */
+      if (step_stop_if_no_debug)
+       {
+         /* If we have no line number and the step-stop-if-no-debug
+            is set, we stop the step so that the user has a chance to
+            switch in assembly mode.  */
+         stop_step = 1;
+         print_stop_reason (END_STEPPING_RANGE, 0);
+         stop_stepping (ecs);
+         return;
+       }
+      else
+       {
+         /* Set a breakpoint at callee's return address (the address
+            at which the caller will resume).  */
+         insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+         keep_going (ecs);
+         return;
+       }
+    }
+
+  if (step_range_end == 1)
+    {
+      /* It is stepi or nexti.  We always want to stop stepping after
+         one instruction.  */
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepi/nexti\n");
+      stop_step = 1;
+      print_stop_reason (END_STEPPING_RANGE, 0);
+      stop_stepping (ecs);
+      return;
+    }
+
+  ecs->sal = find_pc_line (stop_pc, 0);
+
   if (ecs->sal.line == 0)
     {
       /* We have no line number information.  That means to stop
          stepping (does this always happen right after one instruction,
          when we do "s" in a function with no line numbers,
          or can this happen as a result of a return or longjmp?).  */
+      if (debug_infrun)
+        printf_unfiltered ("infrun: no line number info\n");
       stop_step = 1;
       print_stop_reason (END_STEPPING_RANGE, 0);
       stop_stepping (ecs);
@@ -2511,6 +2504,8 @@ process_event_stop_test:
          we don't stop if we step into the middle of a different line.
          That is said to make things like for (;;) statements work
          better.  */
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped to a different line\n");
       stop_step = 1;
       print_stop_reason (END_STEPPING_RANGE, 0);
       stop_stepping (ecs);
@@ -2531,6 +2526,8 @@ process_event_stop_test:
          This is particularly necessary for a one-line function,
          in which after skipping the prologue we better stop even though
          we will be in mid-line.  */
+      if (debug_infrun)
+        printf_unfiltered ("infrun: stepped to a different function\n");
       stop_step = 1;
       print_stop_reason (END_STEPPING_RANGE, 0);
       stop_stepping (ecs);
@@ -2551,15 +2548,15 @@ process_event_stop_test:
      stackless leaf function.  I think the logic should instead look
      at the unwound frame ID has that should give a more robust
      indication of what happened.  */
-     if (step-ID == current-ID)
-       still stepping in same function;
-     else if (step-ID == unwind (current-ID))
-       stepped into a function;
-     else
-       stepped out of a function;
-     /* Of course this assumes that the frame ID unwind code is robust
-        and we're willing to introduce frame unwind logic into this
-        function.  Fortunately, those days are nearly upon us.  */
+  if (step - ID == current - ID)
+    still stepping in same function;
+  else if (step - ID == unwind (current - ID))
+    stepped into a function;
+  else
+    stepped out of a function;
+  /* Of course this assumes that the frame ID unwind code is robust
+     and we're willing to introduce frame unwind logic into this
+     function.  Fortunately, those days are nearly upon us.  */
 #endif
   {
     struct frame_id current_frame = get_frame_id (get_current_frame ());
@@ -2567,6 +2564,8 @@ process_event_stop_test:
       step_frame_id = current_frame;
   }
 
+  if (debug_infrun)
+     printf_unfiltered ("infrun: keep going\n");
   keep_going (ecs);
 }
 
@@ -2612,7 +2611,7 @@ step_into_function (struct execution_control_state *ecs)
      ``ecs->stop_func_start == stop_pc'' will never succeed.  Adjust
      ecs->stop_func_start to an address at which a breakpoint may be
      legitimately placed.
-     
+
      Note:  kevinb/2004-01-19:  On FR-V, if this adjustment is not
      made, GDB will enter an infinite loop when stepping through
      optimized code consisting of VLIW instructions which contain
@@ -2622,12 +2621,12 @@ step_into_function (struct execution_control_state *ecs)
      set, GDB will adjust the breakpoint address to the beginning of
      the VLIW instruction.  Thus, we need to make the corresponding
      adjustment here when computing the stop address.  */
-     
+
   if (gdbarch_adjust_breakpoint_address_p (current_gdbarch))
     {
       ecs->stop_func_start
        = gdbarch_adjust_breakpoint_address (current_gdbarch,
-                                            ecs->stop_func_start);
+                                            ecs->stop_func_start);
     }
 
   if (ecs->stop_func_start == stop_pc)
@@ -2644,14 +2643,11 @@ step_into_function (struct execution_control_state *ecs)
       init_sal (&sr_sal);      /* initialize to zeroes */
       sr_sal.pc = ecs->stop_func_start;
       sr_sal.section = find_pc_overlay (ecs->stop_func_start);
+
       /* Do not specify what the fp should be when we stop since on
          some machines the prologue is where the new fp value is
          established.  */
-      check_for_old_step_resume_breakpoint ();
-      step_resume_breakpoint =
-       set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
-      if (breakpoints_inserted)
-       insert_breakpoints ();
+      insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
 
       /* And make sure stepping stops right away then.  */
       step_range_end = step_range_start;
@@ -2659,45 +2655,56 @@ step_into_function (struct execution_control_state *ecs)
   keep_going (ecs);
 }
 
-/* The inferior, as a result of a function call (has left) or signal
-   (about to leave) the single-step range.  Set a momentary breakpoint
-   within the step range where the inferior is expected to later
-   return.  */
+/* Insert a "step resume breakpoint" at SR_SAL with frame ID SR_ID.
+   This is used to both functions and to skip over code.  */
+
+static void
+insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
+                                     struct frame_id sr_id)
+{
+  /* There should never be more than one step-resume breakpoint per
+     thread, so we should never be setting a new
+     step_resume_breakpoint when one is already active.  */
+  gdb_assert (step_resume_breakpoint == NULL);
+  step_resume_breakpoint = set_momentary_breakpoint (sr_sal, sr_id,
+                                                    bp_step_resume);
+  if (breakpoints_inserted)
+    insert_breakpoints ();
+}
+                                     
+/* Insert a "step resume breakpoint" at RETURN_FRAME.pc.  This is used
+   to skip a function (next, skip-no-debug) or signal.  It's assumed
+   that the function/signal handler being skipped eventually returns
+   to the breakpoint inserted at RETURN_FRAME.pc.
+
+   For the skip-function case, the function may have been reached by
+   either single stepping a call / return / signal-return instruction,
+   or by hitting a breakpoint.  In all cases, the RETURN_FRAME belongs
+   to the skip-function's caller.
+
+   For the signals case, this is called with the interrupted
+   function's frame.  The signal handler, when it returns, will resume
+   the interrupted function at RETURN_FRAME.pc.  */
 
 static void
-insert_step_resume_breakpoint (struct frame_info *step_frame,
-                              struct execution_control_state *ecs)
+insert_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
 {
   struct symtab_and_line sr_sal;
 
-  /* This is only used within the step-resume range/frame.  */
-  gdb_assert (frame_id_eq (step_frame_id, get_frame_id (step_frame)));
-  gdb_assert (step_range_end != 0);
-  /* Remember, if the call instruction is the last in the step range,
-     the breakpoint will land just beyond that.  Hence ``<=
-     step_range_end''.  Also, ignore check when "nexti".  */
-  gdb_assert (step_range_start == step_range_end
-             || (get_frame_pc (step_frame) >= step_range_start
-                 && get_frame_pc (step_frame) <= step_range_end));
-
   init_sal (&sr_sal);          /* initialize to zeros */
 
-  sr_sal.pc = ADDR_BITS_REMOVE (get_frame_pc (step_frame));
+  sr_sal.pc = ADDR_BITS_REMOVE (get_frame_pc (return_frame));
   sr_sal.section = find_pc_overlay (sr_sal.pc);
 
-  check_for_old_step_resume_breakpoint ();
-
-  step_resume_breakpoint
-    = set_momentary_breakpoint (sr_sal, get_frame_id (step_frame),
-                               bp_step_resume);
-
-  if (breakpoints_inserted)
-    insert_breakpoints ();
+  insert_step_resume_breakpoint_at_sal (sr_sal, get_frame_id (return_frame));
 }
 
 static void
 stop_stepping (struct execution_control_state *ecs)
 {
+  if (debug_infrun)
+    printf_unfiltered ("infrun: stop_stepping\n");
+
   /* Let callers know we don't want to wait for the inferior anymore.  */
   ecs->wait_some_more = 0;
 }
@@ -2731,20 +2738,9 @@ keep_going (struct execution_control_state *ecs)
          The signal was SIGTRAP, e.g. it was our signal, but we
          decided we should resume from it.
 
-         We're going to run this baby now!
+         We're going to run this baby now!  */
 
-         Insert breakpoints now, unless we are trying to one-proceed
-         past a breakpoint.  */
-      /* If we've just finished a special step resume and we don't
-         want to hit a breakpoint, pull em out.  */
-      if (step_resume_breakpoint == NULL
-         && ecs->remove_breakpoints_on_following_step)
-       {
-         ecs->remove_breakpoints_on_following_step = 0;
-         remove_breakpoints ();
-         breakpoints_inserted = 0;
-       }
-      else if (!breakpoints_inserted && !ecs->another_trap)
+      if (!breakpoints_inserted && !ecs->another_trap)
        {
          breakpoints_failed = insert_breakpoints ();
          if (breakpoints_failed)
@@ -2786,6 +2782,8 @@ keep_going (struct execution_control_state *ecs)
 static void
 prepare_to_wait (struct execution_control_state *ecs)
 {
+  if (debug_infrun)
+    printf_unfiltered ("infrun: prepare_to_wait\n");
   if (ecs->infwait_state == infwait_normal_state)
     {
       overlay_cache_invalid = 1;
@@ -3010,8 +3008,8 @@ normal_stop (void)
            {
            case PRINT_UNKNOWN:
              /* 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.  */
+                (or should) carry around the function and does (or
+                should) use that when doing a frame comparison.  */
              if (stop_step
                  && frame_id_eq (step_frame_id,
                                  get_frame_id (get_current_frame ()))
@@ -3047,7 +3045,7 @@ normal_stop (void)
             LOCATION: Print only location
             SRC_AND_LOC: Print location and source line */
          if (do_frame_printing)
-           print_stack_frame (get_selected_frame (), 0, source_flag);
+           print_stack_frame (get_selected_frame (NULL), 0, source_flag);
 
          /* Display the auto-display expressions.  */
          do_displays ();
@@ -3477,7 +3475,7 @@ void
 write_inferior_status_register (struct inferior_status *inf_status, int regno,
                                LONGEST val)
 {
-  int size = DEPRECATED_REGISTER_RAW_SIZE (regno);
+  int size = register_size (current_gdbarch, regno);
   void *buf = alloca (size);
   store_signed_integer (buf, size, val);
   regcache_raw_write (inf_status->registers, regno, buf);
@@ -3823,6 +3821,10 @@ Pass and Stop may be combined.", NULL));
 This allows you to set a list of commands to be run each time execution\n\
 of the program stops.", &cmdlist);
 
+  add_set_cmd ("infrun", class_maintenance, var_zinteger,
+                 &debug_infrun, "Set inferior debugging.\n\
+When non-zero, inferior specific debugging is enabled.", &setdebuglist);
+
   numsigs = (int) TARGET_SIGNAL_LAST;
   signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs);
   signal_print = (unsigned char *)
@@ -3871,7 +3873,7 @@ of the program stops.", &cmdlist);
   signal_print[TARGET_SIGNAL_CANCEL] = 0;
 
 #ifdef SOLIB_ADD
-  add_show_from_set
+  deprecated_add_show_from_set
     (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
                  (char *) &stop_on_solib_events,
                  "Set stopping for shared library events.\n\
@@ -3890,7 +3892,7 @@ A fork or vfork creates a new process.  follow-fork-mode can be:\n\
   child   - the new process is debugged after a fork\n\
 The unfollowed process will continue to run.\n\
 By default, the debugger will follow the parent process.", &setlist);
-  add_show_from_set (c, &showlist);
+  deprecated_add_show_from_set (c, &showlist);
 
   c = add_set_enum_cmd ("scheduler-locking", class_run, scheduler_enums,       /* array of string names */
                        &scheduler_mode,        /* current mode  */
@@ -3902,7 +3904,7 @@ step == scheduler locked during every single-step operation.\n\
        Other threads may run while stepping over a function call ('next').", &setlist);
 
   set_cmd_sfunc (c, set_schedlock_func);       /* traps on target vector */
-  add_show_from_set (c, &showlist);
+  deprecated_add_show_from_set (c, &showlist);
 
   c = add_set_cmd ("step-mode", class_run,
                   var_boolean, (char *) &step_stop_if_no_debug,
@@ -3910,7 +3912,7 @@ step == scheduler locked during every single-step operation.\n\
 function without debug line information will stop at the first\n\
 instruction of that function. Otherwise, the function is skipped and\n\
 the step command stops at a different source line.", &setlist);
-  add_show_from_set (c, &showlist);
+  deprecated_add_show_from_set (c, &showlist);
 
   /* ptid initializations */
   null_ptid = ptid_build (0, 0, 0);
This page took 0.050856 seconds and 4 git commands to generate.