diff options
author | Andrew Cagney <cagney@redhat.com> | 2004-10-31 17:38:16 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2004-10-31 17:38:16 +0000 |
commit | 3352ef37c28505dc3b970e81705977955830eb83 (patch) | |
tree | 324c0600169169c5dbe6e7057b73f38a8720e50a /gdb/infrun.c | |
parent | 2440b685a76ca2758eb810a305e6a903805fe199 (diff) | |
download | gdb-3352ef37c28505dc3b970e81705977955830eb83.zip gdb-3352ef37c28505dc3b970e81705977955830eb83.tar.gz gdb-3352ef37c28505dc3b970e81705977955830eb83.tar.bz2 |
2004-10-31 Orjan Friberg <organ.friberg@axis.com>
Andrew Cagney <cagney@gnu.org>
* gdbarch.sh (single_step_through_delay): Add.
* gdbarch.h, gdbarch.c: Re-generate.
* config/mips/tm-mips.h (STEP_SKIPS_DELAY_P, STEP_SKIPS_DELAY)
(mips_step_skips_delay): Delete.
* mips-tdep.c (mips_single_step_through_delay): Replace
mips_step_skips_delay.
(mips_gdbarch_init): Set single_step_through_delay.
(mips_dump_tdep): Do not print STEP_SKIPS_DELAY.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index d35ecde..396a616 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -714,24 +714,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 @@ -1781,6 +1774,39 @@ 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 (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, |