#include <signal.h>
-/* unistd.h is needed to #define X_OK */
-#ifdef USG
-#include <unistd.h>
-#else
-#include <sys/file.h>
-#endif
-
/* Prototypes for local functions */
static void signals_info PARAMS ((char *, int));
static int hook_stop_stub PARAMS ((char *));
+static void delete_breakpoint_current_contents PARAMS ((PTR));
+
/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
program. It needs to examine the jmp_buf argument and extract the PC
from it. The return value is non-zero on success, zero otherwise. */
#define IN_SOLIB_RETURN_TRAMPOLINE(pc,name) 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
static int trap_expected;
+#ifdef SOLIB_ADD
/* Nonzero if we want to give control to the user when we're notified
of shared library events by the dynamic linker. */
static int stop_on_solib_events;
+#endif
#ifdef HP_OS_BUG
/* Nonzero if the next time we try to continue the inferior, it will
static int stop_print_frame;
-#ifdef NO_SINGLE_STEP
-extern int one_stepped; /* From machine dependent code */
-extern void single_step (); /* Same. */
-#endif /* NO_SINGLE_STEP */
-
-extern void write_pc_pid PARAMS ((CORE_ADDR, int));
-
\f
/* Things to clean up if we QUIT out of resume (). */
/* ARGSUSED */
step one instruction before inserting breakpoints
so that we do not stop right away. */
- if (breakpoint_here_p (read_pc ()))
+ if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
oneproc = 1;
#ifdef STEP_SKIPS_DELAY
struct cleanup *old_cleanups;
struct target_waitstatus w;
int another_trap;
- int random_signal;
+ int random_signal = 0;
CORE_ADDR stop_func_start;
CORE_ADDR stop_func_end;
char *stop_func_name;
#endif
stop_func_start = 0;
+ stop_func_end = 0;
stop_func_name = 0;
/* Don't care about return value; stop_func_start and stop_func_name
will both be 0 if it doesn't work. */
/* See if there is a breakpoint at the current PC. */
stop_bpstat = bpstat_stop_status
(&stop_pc,
-#if DECR_PC_AFTER_BREAK
+ (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.
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 */
+ && CURRENTLY_STEPPING ()) :
+ 0)
);
/* Following in case break condition called a
function. */
another_trap = 1;
break;
-#ifdef SOLIB_ADD
case BPSTAT_WHAT_CHECK_SHLIBS:
+#ifdef SOLIB_ADD
{
extern int auto_solib_add;
breakpoint_re_set. */
target_terminal_ours_for_output ();
SOLIB_ADD (NULL, 0, NULL);
- re_enable_breakpoints_in_shlibs ();
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
}
}
#endif
+ break;
case BPSTAT_WHAT_LAST:
/* Not a real code, but listed here to shut up gcc -Wall. */
/* Did we just take a signal? */
if (IN_SIGTRAMP (stop_pc, stop_func_name)
- && !IN_SIGTRAMP (prev_pc, prev_func_name))
+ && !IN_SIGTRAMP (prev_pc, prev_func_name)
+ && read_sp () INNER_THAN step_sp)
{
/* We've just taken a signal; go until we are back to
the point where we took it and one more. */
{
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = prev_pc;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
/* We could probably be setting the frame to
step_frame_address; I don't think anyone thought to try it. */
step_resume_breakpoint =
SKIP_PROLOGUE (prologue_pc);
}
- if ((/* Might be a non-recursive call. If the symbols are missing
- enough that stop_func_start == prev_func_start even though
- they are really two functions, we will treat some calls as
- jumps. */
- stop_func_start != prev_func_start
-
- /* Might be a recursive call if either we have a prologue
- or the call instruction itself saves the PC on the stack. */
- || prologue_pc != stop_func_start
- || read_sp () != step_sp)
+ if (!(step_sp INNER_THAN read_sp ()) /* don't mistake (sig)return as a call */
+ && (/* Might be a non-recursive call. If the symbols are missing
+ enough that stop_func_start == prev_func_start even though
+ they are really two functions, we will treat some calls as
+ jumps. */
+ stop_func_start != prev_func_start
+
+ /* Might be a recursive call if either we have a prologue
+ or the call instruction itself saves the PC on the stack. */
+ || prologue_pc != stop_func_start
+ || read_sp () != step_sp)
&& (/* PC is completely out of bounds of any known objfiles. Treat
like a subroutine call. */
! stop_func_start
break;
}
- if (step_over_calls > 0)
+ if (step_over_calls > 0 || IGNORE_HELPER_CALL (stop_pc))
/* We're doing a "next". */
goto step_over_function;
if (tmp)
{
struct symtab_and_line xxx;
-
+ /* Why isn't this s_a_l called "sr_sal", like all of the
+ other s_a_l's where this code is duplicated? */
+ INIT_SAL (&xxx); /* initialize to zeroes */
xxx.pc = tmp;
- xxx.symtab = NULL;
- xxx.line = 0;
step_resume_breakpoint =
set_momentary_breakpoint (xxx, NULL, bp_step_resume);
insert_breakpoints ();
{
/* Set a special breakpoint after the return */
struct symtab_and_line sr_sal;
+
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc =
ADDR_BITS_REMOVE
(SAVED_PC_AFTER_CALL (get_current_frame ()));
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
step_resume_breakpoint =
set_momentary_breakpoint (sr_sal, get_current_frame (),
bp_step_resume);
{
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = stop_func_start;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
/* 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. */
/* And put the step-breakpoint there and go until there. */
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = tmp;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
/* 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. */
}
step_range_start = sal.pc;
step_range_end = sal.end;
+ step_frame_address = FRAME_FP (get_current_frame ());
+ current_line = sal.line;
+ current_symtab = sal.symtab;
goto keep_going;
check_sigtramp2:
if (trap_expected
&& IN_SIGTRAMP (stop_pc, stop_func_name)
- && !IN_SIGTRAMP (prev_pc, prev_func_name))
+ && !IN_SIGTRAMP (prev_pc, prev_func_name)
+ && read_sp () INNER_THAN step_sp)
{
/* What has happened here is that we have just stepped the inferior
with a signal (because it is a signal which shouldn't make
it says "exceedingly difficult"). */
struct symtab_and_line sr_sal;
+ INIT_SAL (&sr_sal); /* initialize to zeroes */
sr_sal.pc = prev_pc;
- sr_sal.symtab = NULL;
- sr_sal.line = 0;
/* We perhaps could set the frame if we kept track of what
the frame corresponding to prev_pc was. But we don't,
so don't. */