* breakpoint.c, breakpoint.h (breakpoint_init_inferior): New function
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 020ef5b47d0167f2a30fd11f34e8803a1891f6ba..37447334eb0d5c34857e02a02019c107191de5fc 100644 (file)
@@ -283,6 +283,14 @@ resume (step, sig)
   struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
   QUIT;
 
+#ifdef CANNOT_STEP_BREAKPOINT
+  /* Most targets can step a breakpoint instruction, thus executing it
+     normally.  But if this one cannot, just continue and we will hit
+     it anyway.  */
+  if (step && breakpoints_inserted && breakpoint_here_p (read_pc ()))
+    step = 0;
+#endif
+
 #ifdef NO_SINGLE_STEP
   if (step) {
     single_step(sig);  /* Do it the hard way, w/temp breakpoints */
@@ -439,7 +447,7 @@ init_wait_for_inferior ()
 
   trap_expected_after_continue = 0;
   breakpoints_inserted = 0;
-  mark_breakpoints_out ();
+  breakpoint_init_inferior ();
   stop_signal = 0;             /* Don't confuse first call to proceed(). */
 }
 
@@ -481,6 +489,13 @@ wait_for_inferior ()
   sal = find_pc_line(prev_pc, 0);
   current_line = sal.line;
 
+  /* Are we stepping?  */
+#define CURRENTLY_STEPPING() ((step_resume_breakpoint == NULL \
+                              && !handling_longjmp \
+                              && (step_range_end \
+                                  || trap_expected)) \
+                             || bpstat_should_step ())
+
   while (1)
     {
       /* Clean up saved state that will become invalid.  */
@@ -696,32 +711,33 @@ wait_for_inferior ()
          else
            {
              /* See if there is a breakpoint at the current PC.  */
+             stop_bpstat = bpstat_stop_status
+               (&stop_pc, stop_frame_address,
 #if DECR_PC_AFTER_BREAK
-             /* Notice the case of stepping through a jump
-                that lands just after a breakpoint.
-                Don't confuse that with hitting the breakpoint.
-                What we check for is that 1) stepping is going on
-                and 2) the pc before the last insn does not match
-                the address of the breakpoint before the current pc.  */
-             if (prev_pc == stop_pc - DECR_PC_AFTER_BREAK
-                 || !step_range_end
-                 || step_resume_breakpoint != NULL
-                 || handling_longjmp /* FIXME */)
-#endif /* DECR_PC_AFTER_BREAK not zero */
-               {
-                 stop_bpstat =
-                   bpstat_stop_status (&stop_pc, stop_frame_address);
-                 /* Following in case break condition called a
-                    function.  */
-                 stop_print_frame = 1;
-               }
+                /* Notice the case of stepping through a jump
+                   that lands just after a breakpoint.
+                   Don't confuse that with hitting the breakpoint.
+                   What we check for is that 1) stepping is going on
+                   and 2) the pc before the last insn does not match
+                   the address of the breakpoint before the current pc.  */
+                (prev_pc != stop_pc - DECR_PC_AFTER_BREAK
+                 && CURRENTLY_STEPPING ())
+#else /* DECR_PC_AFTER_BREAK zero */
+                0
+#endif /* DECR_PC_AFTER_BREAK zero */
+                );
+             /* Following in case break condition called a
+                function.  */
+             stop_print_frame = 1;
            }
 
          if (stop_signal == SIGTRAP)
            random_signal
              = !(bpstat_explains_signal (stop_bpstat)
                  || trap_expected
+#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
                  || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
+#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET.  */
                  || (step_range_end && step_resume_breakpoint == NULL));
          else
            {
@@ -730,7 +746,9 @@ wait_for_inferior ()
                    /* End of a stack dummy.  Some systems (e.g. Sony
                       news) give another signal besides SIGTRAP,
                       so check here as well as above.  */
+#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
                    || PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
+#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET.  */
                    );
              if (!random_signal)
                stop_signal = SIGTRAP;
@@ -793,6 +811,14 @@ wait_for_inferior ()
 
        what = bpstat_what (stop_bpstat);
 
+       if (what.call_dummy)
+         {
+           stop_stack_dummy = 1;
+#ifdef HP_OS_BUG
+           trap_expected_after_continue = 1;
+#endif
+         }
+
        switch (what.main_action)
          {
          case BPSTAT_WHAT_SET_LONGJMP_RESUME:
@@ -887,18 +913,28 @@ wait_for_inferior ()
         test for stepping.  But, if not stepping,
         do not stop.  */
 
+#ifndef CALL_DUMMY_BREAKPOINT_OFFSET
+      /* This is the old way of detecting the end of the stack dummy.
+        An architecture which defines CALL_DUMMY_BREAKPOINT_OFFSET gets
+        handled above.  As soon as we can test it on all of them, all
+        architectures should define it.  */
+
       /* If this is the breakpoint at the end of a stack dummy,
-        just stop silently.  */
-      if (PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address))
-         {
-           stop_print_frame = 0;
-           stop_stack_dummy = 1;
+        just stop silently, unless the user was doing an si/ni, in which
+        case she'd better know what she's doing.  */
+
+      if (PC_IN_CALL_DUMMY (stop_pc, stop_sp, stop_frame_address)
+         && !step_range_end)
+       {
+         stop_print_frame = 0;
+         stop_stack_dummy = 1;
 #ifdef HP_OS_BUG
-           trap_expected_after_continue = 1;
+         trap_expected_after_continue = 1;
 #endif
-           break;
-         }
-      
+         break;
+       }
+#endif /* No CALL_DUMMY_BREAKPOINT_OFFSET.  */
+
       if (step_resume_breakpoint)
        /* Having a step-resume breakpoint overrides anything
           else having to do with stepping commands until
@@ -1078,8 +1114,7 @@ step_into_function:
                 since on some machines the prologue
                 is where the new fp value is established.  */
              step_resume_breakpoint =
-               set_momentary_breakpoint (sr_sal, (CORE_ADDR)0,
-                                         bp_step_resume);
+               set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
              if (breakpoints_inserted)
                insert_breakpoints ();
 
@@ -1186,10 +1221,7 @@ step_into_function:
          /* We took a signal (which we are supposed to pass through to
             the inferior, else we'd have done a break above) and we
             haven't yet gotten our trap.  Simply continue.  */
-         resume ((step_range_end && step_resume_breakpoint == NULL)
-                 || (trap_expected && step_resume_breakpoint == NULL)
-                 || bpstat_should_step (),
-                 stop_signal);
+         resume (CURRENTLY_STEPPING (), stop_signal);
        }
       else
        {
@@ -1231,27 +1263,16 @@ step_into_function:
          /* I'm not sure when this following segment applies.  I do know, now,
             that we shouldn't rewrite the regs when we were stopped by a
             random signal from the inferior process.  */
+         /* FIXME: Shouldn't this be based on the valid bit of the SXIP?
+            (this is only used on the 88k).  */
 
           if (!bpstat_explains_signal (stop_bpstat)
              && (stop_signal != SIGCLD) 
               && !stopped_by_random_signal)
-            {
-            CORE_ADDR pc_contents = read_register (PC_REGNUM);
-            CORE_ADDR npc_contents = read_register (NPC_REGNUM);
-            if (pc_contents != npc_contents)
-              {
-              write_register (NNPC_REGNUM, npc_contents);
-              write_register (NPC_REGNUM, pc_contents);
-             }
-            }
+            SHIFT_INST_REGS();
 #endif /* SHIFT_INST_REGS */
 
-         resume ((step_resume_breakpoint == NULL
-                  && !handling_longjmp
-                  && (step_range_end
-                      || trap_expected))
-                 || bpstat_should_step (),
-                 stop_signal);
+         resume (CURRENTLY_STEPPING (), stop_signal);
        }
     }
 
This page took 0.025901 seconds and 4 git commands to generate.