5a72cdabf8
- `set scheduler-locking step' is no longer enforced but it is now default.
1161 lines
42 KiB
Diff
1161 lines
42 KiB
Diff
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=235186
|
||
|
||
2007-01-10 Daniel Jacobowitz <dan@codesourcery.com>
|
||
|
||
* infrun.c (singlestep_pc): New variable.
|
||
(resume): Set singlestep_pc.
|
||
(context_switch): Add a debugging message. Flush the frame cache.
|
||
(handle_inferior_event): Add debugging messages. Handle thread
|
||
hops when a software single step has completed. Let context_switch
|
||
handle flushing the frame cache.
|
||
|
||
--- ./gdb/infrun.c 9 Jan 2007 17:58:51 -0000 1.218
|
||
+++ ./gdb/infrun.c 10 Jan 2007 20:10:23 -0000 1.219
|
||
@@ -469,6 +469,9 @@ static int singlestep_breakpoints_insert
|
||
/* The thread we inserted single-step breakpoints for. */
|
||
static ptid_t singlestep_ptid;
|
||
|
||
+/* PC when we started this single-step. */
|
||
+static CORE_ADDR singlestep_pc;
|
||
+
|
||
/* If another thread hit the singlestep breakpoint, we save the original
|
||
thread here so that we can resume single-stepping it later. */
|
||
static ptid_t saved_singlestep_ptid;
|
||
@@ -563,6 +566,7 @@ resume (int step, enum target_signal sig
|
||
`wait_for_inferior' */
|
||
singlestep_breakpoints_inserted_p = 1;
|
||
singlestep_ptid = inferior_ptid;
|
||
+ singlestep_pc = read_pc ();
|
||
}
|
||
|
||
/* If there were any forks/vforks/execs that were caught and are
|
||
@@ -1126,6 +1130,14 @@ context_switch (struct execution_control
|
||
be lost. This may happen as a result of the target module
|
||
mishandling thread creation. */
|
||
|
||
+ if (debug_infrun)
|
||
+ {
|
||
+ fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
|
||
+ target_pid_to_str (inferior_ptid));
|
||
+ fprintf_unfiltered (gdb_stdlog, "to %s\n",
|
||
+ target_pid_to_str (ecs->ptid));
|
||
+ }
|
||
+
|
||
if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
|
||
{ /* Perform infrun state context switch: */
|
||
/* Save infrun state for the old thread. */
|
||
@@ -1149,6 +1161,7 @@ context_switch (struct execution_control
|
||
&ecs->current_line, &ecs->current_symtab);
|
||
}
|
||
inferior_ptid = ecs->ptid;
|
||
+ flush_cached_frames ();
|
||
}
|
||
|
||
static void
|
||
@@ -1609,6 +1622,14 @@ handle_inferior_event (struct execution_
|
||
}
|
||
else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
|
||
{
|
||
+ /* We have not context switched yet, so this should be true
|
||
+ no matter which thread hit the singlestep breakpoint. */
|
||
+ gdb_assert (ptid_equal (inferior_ptid, singlestep_ptid));
|
||
+ if (debug_infrun)
|
||
+ fprintf_unfiltered (gdb_stdlog, "infrun: software single step "
|
||
+ "trap for %s\n",
|
||
+ target_pid_to_str (ecs->ptid));
|
||
+
|
||
ecs->random_signal = 0;
|
||
/* The call to in_thread_list is necessary because PTIDs sometimes
|
||
change when we go from single-threaded to multi-threaded. If
|
||
@@ -1617,9 +1638,46 @@ handle_inferior_event (struct execution_
|
||
if (!ptid_equal (singlestep_ptid, ecs->ptid)
|
||
&& in_thread_list (singlestep_ptid))
|
||
{
|
||
- thread_hop_needed = 1;
|
||
- stepping_past_singlestep_breakpoint = 1;
|
||
- saved_singlestep_ptid = singlestep_ptid;
|
||
+ /* If the PC of the thread we were trying to single-step
|
||
+ has changed, discard this event (which we were going
|
||
+ to ignore anyway), and pretend we saw that thread
|
||
+ trap. This prevents us continuously moving the
|
||
+ single-step breakpoint forward, one instruction at a
|
||
+ time. If the PC has changed, then the thread we were
|
||
+ trying to single-step has trapped or been signalled,
|
||
+ but the event has not been reported to GDB yet.
|
||
+
|
||
+ There might be some cases where this loses signal
|
||
+ information, if a signal has arrived at exactly the
|
||
+ same time that the PC changed, but this is the best
|
||
+ we can do with the information available. Perhaps we
|
||
+ should arrange to report all events for all threads
|
||
+ when they stop, or to re-poll the remote looking for
|
||
+ this particular thread (i.e. temporarily enable
|
||
+ schedlock). */
|
||
+ if (read_pc_pid (singlestep_ptid) != singlestep_pc)
|
||
+ {
|
||
+ if (debug_infrun)
|
||
+ fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
|
||
+ " but expected thread advanced also\n");
|
||
+
|
||
+ /* The current context still belongs to
|
||
+ singlestep_ptid. Don't swap here, since that's
|
||
+ the context we want to use. Just fudge our
|
||
+ state and continue. */
|
||
+ ecs->ptid = singlestep_ptid;
|
||
+ stop_pc = read_pc_pid (ecs->ptid);
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ if (debug_infrun)
|
||
+ fprintf_unfiltered (gdb_stdlog,
|
||
+ "infrun: unexpected thread\n");
|
||
+
|
||
+ thread_hop_needed = 1;
|
||
+ stepping_past_singlestep_breakpoint = 1;
|
||
+ saved_singlestep_ptid = singlestep_ptid;
|
||
+ }
|
||
}
|
||
}
|
||
|
||
@@ -1702,8 +1760,6 @@ handle_inferior_event (struct execution_
|
||
|
||
if (deprecated_context_hook)
|
||
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
|
||
-
|
||
- flush_cached_frames ();
|
||
}
|
||
|
||
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
|
||
|
||
|
||
|
||
2007-04-12 Luis Machado <luisgpm@br.ibm.com>
|
||
|
||
* gdbarch.sh (software_single_step): Change the return type
|
||
from void to int and reformatted some comments to <= 80
|
||
columns.
|
||
* gdbarch.c, gdbarch.h: Regenerated.
|
||
* alpha-tdep.c (alpha_software_single_step): Likewise.
|
||
* alpha-tdep.h (alpha_software_single_step): Likewise.
|
||
* arm-tdep.c (arm_software_single_step): Likewise.
|
||
* cris-tdep.c (cris_software_single_step): Likewise.
|
||
* mips-tdep.c (mips_software_single_step): Likewise.
|
||
* mips-tdep.h (mips_software_single_step): Likewise.
|
||
* rs6000-tdep.c (rs6000_software_single_step): Likewise.
|
||
* rs6000-tdep.h (rs6000_software_single_step): Likewise.
|
||
* sparc-tdep.c (sparc_software_single_step): Likewise.
|
||
* sparc-tdep.h (sparc_software_single_step): Likewise.
|
||
[REMOVED] * spu-tdep.c (spu_software_single_step): Likewise.
|
||
* infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
|
||
and act accordingly.
|
||
|
||
--- ./gdb/alpha-tdep.c 27 Feb 2007 20:17:18 -0000 1.162
|
||
+++ ./gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163
|
||
@@ -1518,7 +1518,7 @@ alpha_next_pc (CORE_ADDR pc)
|
||
return (pc + ALPHA_INSN_SIZE);
|
||
}
|
||
|
||
-void
|
||
+int
|
||
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
{
|
||
static CORE_ADDR next_pc;
|
||
@@ -1536,6 +1536,7 @@ alpha_software_single_step (enum target_
|
||
remove_single_step_breakpoints ();
|
||
write_pc (next_pc);
|
||
}
|
||
+ return 1;
|
||
}
|
||
|
||
|
||
--- ./gdb/alpha-tdep.h 9 Jan 2007 17:58:49 -0000 1.27
|
||
+++ ./gdb/alpha-tdep.h 12 Apr 2007 14:52:19 -0000 1.28
|
||
@@ -107,7 +107,7 @@ struct gdbarch_tdep
|
||
};
|
||
|
||
extern unsigned int alpha_read_insn (CORE_ADDR pc);
|
||
-extern void alpha_software_single_step (enum target_signal, int);
|
||
+extern int alpha_software_single_step (enum target_signal, int);
|
||
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
|
||
|
||
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);
|
||
--- ./gdb/arm-tdep.c 30 Mar 2007 22:50:33 -0000 1.225
|
||
+++ ./gdb/arm-tdep.c 12 Apr 2007 14:52:19 -0000 1.226
|
||
@@ -1907,7 +1907,7 @@ arm_get_next_pc (CORE_ADDR pc)
|
||
single_step() is also called just after the inferior stops. If we
|
||
had set up a simulated single-step, we undo our damage. */
|
||
|
||
-static void
|
||
+static int
|
||
arm_software_single_step (enum target_signal sig, int insert_bpt)
|
||
{
|
||
/* NOTE: This may insert the wrong breakpoint instruction when
|
||
@@ -1922,6 +1922,8 @@ arm_software_single_step (enum target_si
|
||
}
|
||
else
|
||
remove_single_step_breakpoints ();
|
||
+
|
||
+ return 1;
|
||
}
|
||
|
||
#include "bfd-in2.h"
|
||
--- ./gdb/cris-tdep.c 27 Feb 2007 20:17:18 -0000 1.138
|
||
+++ ./gdb/cris-tdep.c 12 Apr 2007 14:52:19 -0000 1.139
|
||
@@ -2119,7 +2119,7 @@ find_step_target (inst_env_type *inst_en
|
||
digs through the opcodes in order to find all possible targets.
|
||
Either one ordinary target or two targets for branches may be found. */
|
||
|
||
-static void
|
||
+static int
|
||
cris_software_single_step (enum target_signal ignore, int insert_breakpoints)
|
||
{
|
||
inst_env_type inst_env;
|
||
@@ -2152,6 +2152,8 @@ cris_software_single_step (enum target_s
|
||
}
|
||
else
|
||
remove_single_step_breakpoints ();
|
||
+
|
||
+ return 1;
|
||
}
|
||
|
||
/* Calculates the prefix value for quick offset addressing mode. */
|
||
--- ./gdb/gdbarch.c 28 Feb 2007 17:34:58 -0000 1.338
|
||
+++ ./gdb/gdbarch.c 12 Apr 2007 14:52:19 -0000 1.339
|
||
@@ -3289,14 +3289,14 @@ gdbarch_software_single_step_p (struct g
|
||
return gdbarch->software_single_step != NULL;
|
||
}
|
||
|
||
-void
|
||
+int
|
||
gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p)
|
||
{
|
||
gdb_assert (gdbarch != NULL);
|
||
gdb_assert (gdbarch->software_single_step != NULL);
|
||
if (gdbarch_debug >= 2)
|
||
fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n");
|
||
- gdbarch->software_single_step (sig, insert_breakpoints_p);
|
||
+ return gdbarch->software_single_step (sig, insert_breakpoints_p);
|
||
}
|
||
|
||
void
|
||
--- ./gdb/gdbarch.h 8 Feb 2007 21:00:29 -0000 1.294
|
||
+++ ./gdb/gdbarch.h 12 Apr 2007 14:52:19 -0000 1.295
|
||
@@ -1144,14 +1144,19 @@ extern void set_gdbarch_smash_text_addre
|
||
#define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr))
|
||
#endif
|
||
|
||
-/* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
|
||
- the target needs software single step. An ISA method to implement it.
|
||
+/* FIXME/cagney/2001-01-18: This should be split in two. A target method that
|
||
+ indicates if the target needs software single step. An ISA method to
|
||
+ implement it.
|
||
|
||
- FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
|
||
- using the breakpoint system instead of blatting memory directly (as with rs6000).
|
||
+ FIXME/cagney/2001-01-18: This should be replaced with something that inserts
|
||
+ breakpoints using the breakpoint system instead of blatting memory directly
|
||
+ (as with rs6000).
|
||
|
||
- FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
|
||
- single step. If not, then implement single step using breakpoints. */
|
||
+ FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
|
||
+ target can single step. If not, then implement single step using breakpoints.
|
||
+
|
||
+ A return value of 1 means that the software_single_step breakpoints
|
||
+ were inserted; 0 means they were not. */
|
||
|
||
#if defined (SOFTWARE_SINGLE_STEP)
|
||
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
|
||
@@ -1168,8 +1173,8 @@ extern int gdbarch_software_single_step_
|
||
#define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch))
|
||
#endif
|
||
|
||
-typedef void (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
|
||
-extern void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
|
||
+typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
|
||
+extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
|
||
extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
|
||
#if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP)
|
||
#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
|
||
--- ./gdb/gdbarch.sh 28 Feb 2007 17:35:00 -0000 1.376
|
||
+++ ./gdb/gdbarch.sh 12 Apr 2007 14:52:19 -0000 1.377
|
||
@@ -614,15 +614,22 @@ f:=:CORE_ADDR:addr_bits_remove:CORE_ADDR
|
||
# It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
|
||
# ADDR_BITS_REMOVE.
|
||
f:=:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr::core_addr_identity::0
|
||
-# FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
|
||
-# the target needs software single step. An ISA method to implement it.
|
||
+
|
||
+# FIXME/cagney/2001-01-18: This should be split in two. A target method that
|
||
+# indicates if the target needs software single step. An ISA method to
|
||
+# implement it.
|
||
+#
|
||
+# FIXME/cagney/2001-01-18: This should be replaced with something that inserts
|
||
+# breakpoints using the breakpoint system instead of blatting memory directly
|
||
+# (as with rs6000).
|
||
#
|
||
-# FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
|
||
-# using the breakpoint system instead of blatting memory directly (as with rs6000).
|
||
+# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
|
||
+# target can single step. If not, then implement single step using breakpoints.
|
||
#
|
||
-# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
|
||
-# single step. If not, then implement single step using breakpoints.
|
||
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
|
||
+# A return value of 1 means that the software_single_step breakpoints
|
||
+# were inserted; 0 means they were not.
|
||
+F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
|
||
+
|
||
# Return non-zero if the processor is executing a delay slot and a
|
||
# further single-step is needed before the instruction finishes.
|
||
M::int:single_step_through_delay:struct frame_info *frame:frame
|
||
--- ./gdb/infrun.c 29 Mar 2007 07:35:39 -0000 1.225
|
||
+++ ./gdb/infrun.c 12 Apr 2007 14:52:19 -0000 1.226
|
||
@@ -548,14 +548,16 @@ resume (int step, enum target_signal sig
|
||
if (SOFTWARE_SINGLE_STEP_P () && step)
|
||
{
|
||
/* Do it the hard way, w/temp breakpoints */
|
||
- SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
|
||
- /* ...and don't ask hardware to do it. */
|
||
- step = 0;
|
||
- /* and do not pull these breakpoints until after a `wait' in
|
||
- `wait_for_inferior' */
|
||
- singlestep_breakpoints_inserted_p = 1;
|
||
- singlestep_ptid = inferior_ptid;
|
||
- singlestep_pc = read_pc ();
|
||
+ if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ))
|
||
+ {
|
||
+ /* ...and don't ask hardware to do it. */
|
||
+ step = 0;
|
||
+ /* and do not pull these breakpoints until after a `wait' in
|
||
+ `wait_for_inferior' */
|
||
+ singlestep_breakpoints_inserted_p = 1;
|
||
+ singlestep_ptid = inferior_ptid;
|
||
+ singlestep_pc = read_pc ();
|
||
+ }
|
||
}
|
||
|
||
/* If there were any forks/vforks/execs that were caught and are
|
||
@@ -1378,7 +1380,7 @@ handle_inferior_event (struct execution_
|
||
(LONGEST) ecs->ws.value.integer));
|
||
gdb_flush (gdb_stdout);
|
||
target_mourn_inferior ();
|
||
- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
|
||
+ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
|
||
stop_print_frame = 0;
|
||
stop_stepping (ecs);
|
||
return;
|
||
@@ -1398,7 +1400,7 @@ handle_inferior_event (struct execution_
|
||
target_mourn_inferior ();
|
||
|
||
print_stop_reason (SIGNAL_EXITED, stop_signal);
|
||
- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
|
||
+ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
|
||
stop_stepping (ecs);
|
||
return;
|
||
|
||
@@ -1569,7 +1571,7 @@ handle_inferior_event (struct execution_
|
||
if (debug_infrun)
|
||
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
|
||
/* Pull the single step breakpoints out of the target. */
|
||
- SOFTWARE_SINGLE_STEP (0, 0);
|
||
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
|
||
singlestep_breakpoints_inserted_p = 0;
|
||
|
||
ecs->random_signal = 0;
|
||
@@ -1678,7 +1680,7 @@ handle_inferior_event (struct execution_
|
||
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
|
||
{
|
||
/* Pull the single step breakpoints out of the target. */
|
||
- SOFTWARE_SINGLE_STEP (0, 0);
|
||
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
|
||
singlestep_breakpoints_inserted_p = 0;
|
||
}
|
||
|
||
@@ -1749,7 +1751,7 @@ handle_inferior_event (struct execution_
|
||
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
|
||
{
|
||
/* Pull the single step breakpoints out of the target. */
|
||
- SOFTWARE_SINGLE_STEP (0, 0);
|
||
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
|
||
singlestep_breakpoints_inserted_p = 0;
|
||
}
|
||
|
||
--- ./gdb/mips-tdep.c 30 Mar 2007 22:50:33 -0000 1.407
|
||
+++ ./gdb/mips-tdep.c 12 Apr 2007 14:52:19 -0000 1.408
|
||
@@ -2204,7 +2204,7 @@ mips_addr_bits_remove (CORE_ADDR addr)
|
||
single_step is also called just after the inferior stops. If we had
|
||
set up a simulated single-step, we undo our damage. */
|
||
|
||
-void
|
||
+int
|
||
mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
{
|
||
CORE_ADDR pc, next_pc;
|
||
@@ -2218,6 +2218,8 @@ mips_software_single_step (enum target_s
|
||
}
|
||
else
|
||
remove_single_step_breakpoints ();
|
||
+
|
||
+ return 1;
|
||
}
|
||
|
||
/* Test whether the PC points to the return instruction at the
|
||
--- ./gdb/mips-tdep.h 30 Mar 2007 22:50:33 -0000 1.20
|
||
+++ ./gdb/mips-tdep.h 12 Apr 2007 14:52:20 -0000 1.21
|
||
@@ -100,7 +100,7 @@ enum
|
||
};
|
||
|
||
/* Single step based on where the current instruction will take us. */
|
||
-extern void mips_software_single_step (enum target_signal, int);
|
||
+extern int mips_software_single_step (enum target_signal, int);
|
||
|
||
/* Tell if the program counter value in MEMADDR is in a MIPS16
|
||
function. */
|
||
--- ./gdb/rs6000-tdep.c 10 Apr 2007 16:02:41 -0000 1.270
|
||
+++ ./gdb/rs6000-tdep.c 12 Apr 2007 14:52:20 -0000 1.271
|
||
@@ -722,7 +722,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
|
||
|
||
/* AIX does not support PT_STEP. Simulate it. */
|
||
|
||
-void
|
||
+int
|
||
rs6000_software_single_step (enum target_signal signal,
|
||
int insert_breakpoints_p)
|
||
{
|
||
@@ -761,6 +761,7 @@ rs6000_software_single_step (enum target
|
||
|
||
errno = 0; /* FIXME, don't ignore errors! */
|
||
/* What errors? {read,write}_memory call error(). */
|
||
+ return 1;
|
||
}
|
||
|
||
|
||
--- ./gdb/rs6000-tdep.h 27 Feb 2007 23:04:28 -0000 1.3
|
||
+++ ./gdb/rs6000-tdep.h 12 Apr 2007 14:52:20 -0000 1.4
|
||
@@ -21,8 +21,8 @@
|
||
|
||
#include "defs.h"
|
||
|
||
-extern void rs6000_software_single_step (enum target_signal signal,
|
||
- int insert_breakpoints_p);
|
||
+extern int rs6000_software_single_step (enum target_signal signal,
|
||
+ int insert_breakpoints_p);
|
||
|
||
/* Hook in rs6000-tdep.c for determining the TOC address when
|
||
calling functions in the inferior. */
|
||
--- ./gdb/sparc-tdep.c 11 Apr 2007 07:10:08 -0000 1.179
|
||
+++ ./gdb/sparc-tdep.c 12 Apr 2007 14:52:20 -0000 1.180
|
||
@@ -1329,7 +1329,7 @@ sparc_step_trap (unsigned long insn)
|
||
return 0;
|
||
}
|
||
|
||
-void
|
||
+int
|
||
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
{
|
||
struct gdbarch *arch = current_gdbarch;
|
||
@@ -1359,6 +1359,8 @@ sparc_software_single_step (enum target_
|
||
}
|
||
else
|
||
remove_single_step_breakpoints ();
|
||
+
|
||
+ return 1;
|
||
}
|
||
|
||
static void
|
||
--- ./gdb/sparc-tdep.h 9 Jan 2007 17:58:58 -0000 1.12
|
||
+++ ./gdb/sparc-tdep.h 12 Apr 2007 14:52:20 -0000 1.13
|
||
@@ -167,8 +167,8 @@ extern struct sparc_frame_cache *
|
||
|
||
|
||
|
||
-extern void sparc_software_single_step (enum target_signal sig,
|
||
- int insert_breakpoints_p);
|
||
+extern int sparc_software_single_step (enum target_signal sig,
|
||
+ int insert_breakpoints_p);
|
||
|
||
extern void sparc_supply_rwindow (struct regcache *regcache,
|
||
CORE_ADDR sp, int regnum);
|
||
|
||
|
||
|
||
2007-04-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||
|
||
* alpha-tdep.c (alpha_software_single_step): Do not call write_pc
|
||
when removing single-step breakpoints.
|
||
|
||
--- ./gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163
|
||
+++ ./gdb/alpha-tdep.c 14 Apr 2007 16:17:39 -0000 1.164
|
||
@@ -1521,7 +1521,7 @@ alpha_next_pc (CORE_ADDR pc)
|
||
int
|
||
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
{
|
||
- static CORE_ADDR next_pc;
|
||
+ CORE_ADDR next_pc;
|
||
CORE_ADDR pc;
|
||
|
||
if (insert_breakpoints_p)
|
||
@@ -1534,7 +1534,6 @@ alpha_software_single_step (enum target_
|
||
else
|
||
{
|
||
remove_single_step_breakpoints ();
|
||
- write_pc (next_pc);
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
|
||
|
||
2007-04-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||
|
||
* gdbarch.sh (software_single_step): Remove "insert_breakpoints_p" and
|
||
"sig" arguments, add "regcache" argument.
|
||
* gdbarch.c, gdbarch.h: Regenerate.
|
||
|
||
* infrun.c (resume): Update SOFTWARE_SINGLE_STEP call arguments.
|
||
(handle_inferior_event): Call remove_single_step_breakpoints directly
|
||
instead of calling SOFTWARE_SINGLE_STEP to remove breakpoints.
|
||
|
||
* alpha-tdep.c (alpha_software_single_step): Update argument list.
|
||
Remove handling of !insert_breakpoints_p case.
|
||
* arm-tdep.c (arm_software_single_step): Likewise.
|
||
* cris-tdep.c (cris_software_single_step): Likewise.
|
||
* mips-tdep.c (mips_software_single_step): Likewise.
|
||
* rs6000-tdep.c (rs6000_software_single_step): Likewise.
|
||
* sparc-tdep.c (sparc_software_single_step): Likewise.
|
||
[REMOVED] * spu-tdep.c (spu_software_single_step): Likewise.
|
||
|
||
* alpha-tdep.h (alpha_software_single_step): Update prototype.
|
||
* mips-tdep.h (mips_software_single_step): Likewise.
|
||
* rs6000-tdep.h (rs6000_software_single_step): Likewise.
|
||
* sparc-tdep.h (sparc_software_single_step): Likewise.
|
||
|
||
--- ./gdb/alpha-tdep.c 14 Apr 2007 16:17:39 -0000 1.164
|
||
+++ ./gdb/alpha-tdep.c 14 Apr 2007 18:10:54 -0000 1.165
|
||
@@ -1391,10 +1391,7 @@ fp_register_sign_bit (LONGEST reg)
|
||
/* alpha_software_single_step() is called just before we want to resume
|
||
the inferior, if we want to single-step it but there is no hardware
|
||
or kernel single-step support (NetBSD on Alpha, for example). We find
|
||
- the target of the coming instruction and breakpoint it.
|
||
-
|
||
- single_step is also called just after the inferior stops. If we had
|
||
- set up a simulated single-step, we undo our damage. */
|
||
+ the target of the coming instruction and breakpoint it. */
|
||
|
||
static CORE_ADDR
|
||
alpha_next_pc (CORE_ADDR pc)
|
||
@@ -1519,22 +1516,14 @@ alpha_next_pc (CORE_ADDR pc)
|
||
}
|
||
|
||
int
|
||
-alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
+alpha_software_single_step (struct regcache *regcache)
|
||
{
|
||
- CORE_ADDR next_pc;
|
||
- CORE_ADDR pc;
|
||
+ CORE_ADDR pc, next_pc;
|
||
|
||
- if (insert_breakpoints_p)
|
||
- {
|
||
- pc = read_pc ();
|
||
- next_pc = alpha_next_pc (pc);
|
||
+ pc = read_pc ();
|
||
+ next_pc = alpha_next_pc (pc);
|
||
|
||
- insert_single_step_breakpoint (next_pc);
|
||
- }
|
||
- else
|
||
- {
|
||
- remove_single_step_breakpoints ();
|
||
- }
|
||
+ insert_single_step_breakpoint (next_pc);
|
||
return 1;
|
||
}
|
||
|
||
--- ./gdb/alpha-tdep.h 12 Apr 2007 14:52:19 -0000 1.28
|
||
+++ ./gdb/alpha-tdep.h 14 Apr 2007 18:10:54 -0000 1.29
|
||
@@ -107,7 +107,7 @@ struct gdbarch_tdep
|
||
};
|
||
|
||
extern unsigned int alpha_read_insn (CORE_ADDR pc);
|
||
-extern int alpha_software_single_step (enum target_signal, int);
|
||
+extern int alpha_software_single_step (struct regcache *regcache);
|
||
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
|
||
|
||
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);
|
||
--- ./gdb/arm-tdep.c 12 Apr 2007 14:52:19 -0000 1.226
|
||
+++ ./gdb/arm-tdep.c 14 Apr 2007 18:10:54 -0000 1.227
|
||
@@ -1902,26 +1902,17 @@ arm_get_next_pc (CORE_ADDR pc)
|
||
/* single_step() is called just before we want to resume the inferior,
|
||
if we want to single-step it but there is no hardware or kernel
|
||
single-step support. We find the target of the coming instruction
|
||
- and breakpoint it.
|
||
-
|
||
- single_step() is also called just after the inferior stops. If we
|
||
- had set up a simulated single-step, we undo our damage. */
|
||
+ and breakpoint it. */
|
||
|
||
static int
|
||
-arm_software_single_step (enum target_signal sig, int insert_bpt)
|
||
+arm_software_single_step (struct regcache *regcache)
|
||
{
|
||
/* NOTE: This may insert the wrong breakpoint instruction when
|
||
single-stepping over a mode-changing instruction, if the
|
||
CPSR heuristics are used. */
|
||
|
||
- if (insert_bpt)
|
||
- {
|
||
- CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
|
||
-
|
||
- insert_single_step_breakpoint (next_pc);
|
||
- }
|
||
- else
|
||
- remove_single_step_breakpoints ();
|
||
+ CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
|
||
+ insert_single_step_breakpoint (next_pc);
|
||
|
||
return 1;
|
||
}
|
||
--- ./gdb/cris-tdep.c 12 Apr 2007 14:52:19 -0000 1.139
|
||
+++ ./gdb/cris-tdep.c 14 Apr 2007 18:10:54 -0000 1.140
|
||
@@ -2120,38 +2120,33 @@ find_step_target (inst_env_type *inst_en
|
||
Either one ordinary target or two targets for branches may be found. */
|
||
|
||
static int
|
||
-cris_software_single_step (enum target_signal ignore, int insert_breakpoints)
|
||
+cris_software_single_step (struct regcache *regcache)
|
||
{
|
||
inst_env_type inst_env;
|
||
|
||
- if (insert_breakpoints)
|
||
- {
|
||
- /* Analyse the present instruction environment and insert
|
||
- breakpoints. */
|
||
- int status = find_step_target (&inst_env);
|
||
- if (status == -1)
|
||
- {
|
||
- /* Could not find a target. Things are likely to go downhill
|
||
- from here. */
|
||
- warning (_("CRIS software single step could not find a step target."));
|
||
- }
|
||
- else
|
||
- {
|
||
- /* Insert at most two breakpoints. One for the next PC content
|
||
- and possibly another one for a branch, jump, etc. */
|
||
- CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM];
|
||
- insert_single_step_breakpoint (next_pc);
|
||
- if (inst_env.branch_found
|
||
- && (CORE_ADDR) inst_env.branch_break_address != next_pc)
|
||
- {
|
||
- CORE_ADDR branch_target_address
|
||
- = (CORE_ADDR) inst_env.branch_break_address;
|
||
- insert_single_step_breakpoint (branch_target_address);
|
||
- }
|
||
- }
|
||
+ /* Analyse the present instruction environment and insert
|
||
+ breakpoints. */
|
||
+ int status = find_step_target (&inst_env);
|
||
+ if (status == -1)
|
||
+ {
|
||
+ /* Could not find a target. Things are likely to go downhill
|
||
+ from here. */
|
||
+ warning (_("CRIS software single step could not find a step target."));
|
||
}
|
||
else
|
||
- remove_single_step_breakpoints ();
|
||
+ {
|
||
+ /* Insert at most two breakpoints. One for the next PC content
|
||
+ and possibly another one for a branch, jump, etc. */
|
||
+ CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM];
|
||
+ insert_single_step_breakpoint (next_pc);
|
||
+ if (inst_env.branch_found
|
||
+ && (CORE_ADDR) inst_env.branch_break_address != next_pc)
|
||
+ {
|
||
+ CORE_ADDR branch_target_address
|
||
+ = (CORE_ADDR) inst_env.branch_break_address;
|
||
+ insert_single_step_breakpoint (branch_target_address);
|
||
+ }
|
||
+ }
|
||
|
||
return 1;
|
||
}
|
||
--- ./gdb/gdbarch.c 12 Apr 2007 14:52:19 -0000 1.339
|
||
+++ ./gdb/gdbarch.c 14 Apr 2007 18:10:54 -0000 1.340
|
||
@@ -1522,8 +1522,8 @@ gdbarch_dump (struct gdbarch *current_gd
|
||
#ifdef SOFTWARE_SINGLE_STEP
|
||
fprintf_unfiltered (file,
|
||
"gdbarch_dump: %s # %s\n",
|
||
- "SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p)",
|
||
- XSTRING (SOFTWARE_SINGLE_STEP (sig, insert_breakpoints_p)));
|
||
+ "SOFTWARE_SINGLE_STEP(regcache)",
|
||
+ XSTRING (SOFTWARE_SINGLE_STEP (regcache)));
|
||
#endif
|
||
fprintf_unfiltered (file,
|
||
"gdbarch_dump: software_single_step = <0x%lx>\n",
|
||
@@ -3290,13 +3290,13 @@ gdbarch_software_single_step_p (struct g
|
||
}
|
||
|
||
int
|
||
-gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p)
|
||
+gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache)
|
||
{
|
||
gdb_assert (gdbarch != NULL);
|
||
gdb_assert (gdbarch->software_single_step != NULL);
|
||
if (gdbarch_debug >= 2)
|
||
fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n");
|
||
- return gdbarch->software_single_step (sig, insert_breakpoints_p);
|
||
+ return gdbarch->software_single_step (regcache);
|
||
}
|
||
|
||
void
|
||
--- ./gdb/gdbarch.h 12 Apr 2007 14:52:19 -0000 1.295
|
||
+++ ./gdb/gdbarch.h 14 Apr 2007 18:10:54 -0000 1.296
|
||
@@ -1173,14 +1173,14 @@ extern int gdbarch_software_single_step_
|
||
#define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch))
|
||
#endif
|
||
|
||
-typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
|
||
-extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
|
||
+typedef int (gdbarch_software_single_step_ftype) (struct regcache *regcache);
|
||
+extern int gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache);
|
||
extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
|
||
#if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP)
|
||
#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
|
||
#endif
|
||
#if !defined (SOFTWARE_SINGLE_STEP)
|
||
-#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p))
|
||
+#define SOFTWARE_SINGLE_STEP(regcache) (gdbarch_software_single_step (current_gdbarch, regcache))
|
||
#endif
|
||
|
||
/* Return non-zero if the processor is executing a delay slot and a
|
||
--- ./gdb/gdbarch.sh 12 Apr 2007 14:52:19 -0000 1.377
|
||
+++ ./gdb/gdbarch.sh 14 Apr 2007 18:10:54 -0000 1.378
|
||
@@ -628,7 +628,7 @@ f:=:CORE_ADDR:smash_text_address:CORE_AD
|
||
#
|
||
# A return value of 1 means that the software_single_step breakpoints
|
||
# were inserted; 0 means they were not.
|
||
-F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
|
||
+F:=:int:software_single_step:struct regcache *regcache:regcache
|
||
|
||
# Return non-zero if the processor is executing a delay slot and a
|
||
# further single-step is needed before the instruction finishes.
|
||
--- ./gdb/infrun.c 13 Apr 2007 13:29:42 -0000 1.227
|
||
+++ ./gdb/infrun.c 14 Apr 2007 18:10:54 -0000 1.228
|
||
@@ -548,7 +548,7 @@ resume (int step, enum target_signal sig
|
||
if (SOFTWARE_SINGLE_STEP_P () && step)
|
||
{
|
||
/* Do it the hard way, w/temp breakpoints */
|
||
- if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ))
|
||
+ if (SOFTWARE_SINGLE_STEP (current_regcache))
|
||
{
|
||
/* ...and don't ask hardware to do it. */
|
||
step = 0;
|
||
@@ -1571,7 +1571,7 @@ handle_inferior_event (struct execution_
|
||
if (debug_infrun)
|
||
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
|
||
/* Pull the single step breakpoints out of the target. */
|
||
- (void) SOFTWARE_SINGLE_STEP (0, 0);
|
||
+ remove_single_step_breakpoints ();
|
||
singlestep_breakpoints_inserted_p = 0;
|
||
|
||
ecs->random_signal = 0;
|
||
@@ -1680,7 +1680,7 @@ handle_inferior_event (struct execution_
|
||
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
|
||
{
|
||
/* Pull the single step breakpoints out of the target. */
|
||
- (void) SOFTWARE_SINGLE_STEP (0, 0);
|
||
+ remove_single_step_breakpoints ();
|
||
singlestep_breakpoints_inserted_p = 0;
|
||
}
|
||
|
||
@@ -1751,7 +1751,7 @@ handle_inferior_event (struct execution_
|
||
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
|
||
{
|
||
/* Pull the single step breakpoints out of the target. */
|
||
- (void) SOFTWARE_SINGLE_STEP (0, 0);
|
||
+ remove_single_step_breakpoints ();
|
||
singlestep_breakpoints_inserted_p = 0;
|
||
}
|
||
|
||
--- ./gdb/mips-tdep.c 12 Apr 2007 14:52:19 -0000 1.408
|
||
+++ ./gdb/mips-tdep.c 14 Apr 2007 18:10:54 -0000 1.409
|
||
@@ -2199,26 +2199,17 @@ mips_addr_bits_remove (CORE_ADDR addr)
|
||
/* mips_software_single_step() is called just before we want to resume
|
||
the inferior, if we want to single-step it but there is no hardware
|
||
or kernel single-step support (MIPS on GNU/Linux for example). We find
|
||
- the target of the coming instruction and breakpoint it.
|
||
-
|
||
- single_step is also called just after the inferior stops. If we had
|
||
- set up a simulated single-step, we undo our damage. */
|
||
+ the target of the coming instruction and breakpoint it. */
|
||
|
||
int
|
||
-mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
+mips_software_single_step (struct regcache *regcache)
|
||
{
|
||
CORE_ADDR pc, next_pc;
|
||
|
||
- if (insert_breakpoints_p)
|
||
- {
|
||
- pc = read_register (mips_regnum (current_gdbarch)->pc);
|
||
- next_pc = mips_next_pc (pc);
|
||
-
|
||
- insert_single_step_breakpoint (next_pc);
|
||
- }
|
||
- else
|
||
- remove_single_step_breakpoints ();
|
||
+ pc = read_register (mips_regnum (current_gdbarch)->pc);
|
||
+ next_pc = mips_next_pc (pc);
|
||
|
||
+ insert_single_step_breakpoint (next_pc);
|
||
return 1;
|
||
}
|
||
|
||
--- ./gdb/mips-tdep.h 12 Apr 2007 14:52:20 -0000 1.21
|
||
+++ ./gdb/mips-tdep.h 14 Apr 2007 18:10:54 -0000 1.22
|
||
@@ -100,7 +100,7 @@ enum
|
||
};
|
||
|
||
/* Single step based on where the current instruction will take us. */
|
||
-extern int mips_software_single_step (enum target_signal, int);
|
||
+extern int mips_software_single_step (struct regcache *regcache);
|
||
|
||
/* Tell if the program counter value in MEMADDR is in a MIPS16
|
||
function. */
|
||
--- ./gdb/rs6000-tdep.c 12 Apr 2007 14:52:20 -0000 1.271
|
||
+++ ./gdb/rs6000-tdep.c 14 Apr 2007 18:10:54 -0000 1.272
|
||
@@ -723,8 +723,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
|
||
/* AIX does not support PT_STEP. Simulate it. */
|
||
|
||
int
|
||
-rs6000_software_single_step (enum target_signal signal,
|
||
- int insert_breakpoints_p)
|
||
+rs6000_software_single_step (struct regcache *regcache)
|
||
{
|
||
CORE_ADDR dummy;
|
||
int breakp_sz;
|
||
@@ -734,30 +733,25 @@ rs6000_software_single_step (enum target
|
||
CORE_ADDR breaks[2];
|
||
int opcode;
|
||
|
||
- if (insert_breakpoints_p)
|
||
- {
|
||
- loc = read_pc ();
|
||
+ loc = read_pc ();
|
||
|
||
- insn = read_memory_integer (loc, 4);
|
||
+ insn = read_memory_integer (loc, 4);
|
||
|
||
- breaks[0] = loc + breakp_sz;
|
||
- opcode = insn >> 26;
|
||
- breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
|
||
+ breaks[0] = loc + breakp_sz;
|
||
+ opcode = insn >> 26;
|
||
+ breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
|
||
|
||
- /* Don't put two breakpoints on the same address. */
|
||
- if (breaks[1] == breaks[0])
|
||
- breaks[1] = -1;
|
||
+ /* Don't put two breakpoints on the same address. */
|
||
+ if (breaks[1] == breaks[0])
|
||
+ breaks[1] = -1;
|
||
|
||
- for (ii = 0; ii < 2; ++ii)
|
||
- {
|
||
- /* ignore invalid breakpoint. */
|
||
- if (breaks[ii] == -1)
|
||
- continue;
|
||
- insert_single_step_breakpoint (breaks[ii]);
|
||
- }
|
||
+ for (ii = 0; ii < 2; ++ii)
|
||
+ {
|
||
+ /* ignore invalid breakpoint. */
|
||
+ if (breaks[ii] == -1)
|
||
+ continue;
|
||
+ insert_single_step_breakpoint (breaks[ii]);
|
||
}
|
||
- else
|
||
- remove_single_step_breakpoints ();
|
||
|
||
errno = 0; /* FIXME, don't ignore errors! */
|
||
/* What errors? {read,write}_memory call error(). */
|
||
--- ./gdb/rs6000-tdep.h 12 Apr 2007 14:52:20 -0000 1.4
|
||
+++ ./gdb/rs6000-tdep.h 14 Apr 2007 18:10:54 -0000 1.5
|
||
@@ -21,8 +21,7 @@
|
||
|
||
#include "defs.h"
|
||
|
||
-extern int rs6000_software_single_step (enum target_signal signal,
|
||
- int insert_breakpoints_p);
|
||
+extern int rs6000_software_single_step (struct regcache *regcache);
|
||
|
||
/* Hook in rs6000-tdep.c for determining the TOC address when
|
||
calling functions in the inferior. */
|
||
--- ./gdb/sparc-tdep.c 12 Apr 2007 14:52:20 -0000 1.180
|
||
+++ ./gdb/sparc-tdep.c 14 Apr 2007 18:10:54 -0000 1.181
|
||
@@ -1330,35 +1330,30 @@ sparc_step_trap (unsigned long insn)
|
||
}
|
||
|
||
int
|
||
-sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
|
||
+sparc_software_single_step (struct regcache *regcache)
|
||
{
|
||
struct gdbarch *arch = current_gdbarch;
|
||
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
|
||
CORE_ADDR npc, nnpc;
|
||
|
||
- if (insert_breakpoints_p)
|
||
- {
|
||
- CORE_ADDR pc, orig_npc;
|
||
+ CORE_ADDR pc, orig_npc;
|
||
|
||
- pc = sparc_address_from_register (tdep->pc_regnum);
|
||
- orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
|
||
+ pc = sparc_address_from_register (tdep->pc_regnum);
|
||
+ orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
|
||
|
||
- /* Analyze the instruction at PC. */
|
||
- nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
|
||
- if (npc != 0)
|
||
- insert_single_step_breakpoint (npc);
|
||
-
|
||
- if (nnpc != 0)
|
||
- insert_single_step_breakpoint (nnpc);
|
||
-
|
||
- /* Assert that we have set at least one breakpoint, and that
|
||
- they're not set at the same spot - unless we're going
|
||
- from here straight to NULL, i.e. a call or jump to 0. */
|
||
- gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
|
||
- gdb_assert (nnpc != npc || orig_npc == 0);
|
||
- }
|
||
- else
|
||
- remove_single_step_breakpoints ();
|
||
+ /* Analyze the instruction at PC. */
|
||
+ nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
|
||
+ if (npc != 0)
|
||
+ insert_single_step_breakpoint (npc);
|
||
+
|
||
+ if (nnpc != 0)
|
||
+ insert_single_step_breakpoint (nnpc);
|
||
+
|
||
+ /* Assert that we have set at least one breakpoint, and that
|
||
+ they're not set at the same spot - unless we're going
|
||
+ from here straight to NULL, i.e. a call or jump to 0. */
|
||
+ gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
|
||
+ gdb_assert (nnpc != npc || orig_npc == 0);
|
||
|
||
return 1;
|
||
}
|
||
--- ./gdb/sparc-tdep.h 12 Apr 2007 14:52:20 -0000 1.13
|
||
+++ ./gdb/sparc-tdep.h 14 Apr 2007 18:10:54 -0000 1.14
|
||
@@ -167,8 +167,7 @@ extern struct sparc_frame_cache *
|
||
|
||
|
||
|
||
-extern int sparc_software_single_step (enum target_signal sig,
|
||
- int insert_breakpoints_p);
|
||
+extern int sparc_software_single_step (struct regcache *regcache);
|
||
|
||
extern void sparc_supply_rwindow (struct regcache *regcache,
|
||
CORE_ADDR sp, int regnum);
|
||
|
||
|
||
|
||
2007-05-11 Ulrich Weigand <uweigand@de.ibm.com>
|
||
|
||
* breakpoint.c (single_step_breakpoint_inserted_here_p): New function.
|
||
(breakpoint_inserted_here_p): Call it.
|
||
(software_breakpoint_inserted_here_p): Likewise.
|
||
|
||
--- ./gdb/breakpoint.c 3 May 2007 17:42:25 -0000 1.247
|
||
+++ ./gdb/breakpoint.c 11 May 2007 12:44:34 -0000 1.248
|
||
@@ -202,6 +202,8 @@ static void tcatch_command (char *arg, i
|
||
|
||
static void ep_skip_leading_whitespace (char **s);
|
||
|
||
+static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
|
||
+
|
||
/* Prototypes for exported functions. */
|
||
|
||
/* If FALSE, gdb will not use hardware support for watchpoints, even
|
||
@@ -1841,6 +1843,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc
|
||
}
|
||
}
|
||
|
||
+ /* Also check for software single-step breakpoints. */
|
||
+ if (single_step_breakpoint_inserted_here_p (pc))
|
||
+ return 1;
|
||
+
|
||
return 0;
|
||
}
|
||
|
||
@@ -1872,6 +1878,10 @@ software_breakpoint_inserted_here_p (COR
|
||
}
|
||
}
|
||
|
||
+ /* Also check for software single-step breakpoints. */
|
||
+ if (single_step_breakpoint_inserted_here_p (pc))
|
||
+ return 1;
|
||
+
|
||
return 0;
|
||
}
|
||
|
||
@@ -7951,6 +7961,23 @@ remove_single_step_breakpoints (void)
|
||
}
|
||
}
|
||
|
||
+/* Check whether a software single-step breakpoint is inserted at PC. */
|
||
+
|
||
+static int
|
||
+single_step_breakpoint_inserted_here_p (CORE_ADDR pc)
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < 2; i++)
|
||
+ {
|
||
+ struct bp_target_info *bp_tgt = single_step_breakpoints[i];
|
||
+ if (bp_tgt && bp_tgt->placed_address == pc)
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
|
||
/* This help string is used for the break, hbreak, tbreak and thbreak commands.
|
||
It is defined as a macro to prevent duplication.
|
||
|
||
|
||
|
||
2007-05-08 Paul Gilliam <pgilliam@us.ibm.com>
|
||
Luis Machado <luisgpm@br.ibm.com>
|
||
|
||
* rs6000-tdep.c: (LWARX_MASK, LWARX_INSTRUCTION, LDARX_INSTRUCTION,
|
||
STWCX_MASK, STWCX_INSTRUCTION, STDCX_INSTRUCTION, BC_MASK,
|
||
BC_INSTRUCTION): Define.
|
||
(deal_with_atomic_sequence): New function.
|
||
(rs6000_software_single_step): Call deal_with_atomic_sequence.
|
||
(rs6000_gdbarch_init): Install deal_with_atomic_sequence as
|
||
gdbarch_software_single_step routine.
|
||
|
||
--- ./gdb/rs6000-tdep.c 7 May 2007 01:25:07 -0000 1.274
|
||
+++ ./gdb/rs6000-tdep.c 8 May 2007 12:49:12 -0000 1.275
|
||
@@ -707,7 +707,95 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
|
||
}
|
||
|
||
|
||
-/* AIX does not support PT_STEP. Simulate it. */
|
||
+/* Instruction masks used during single-stepping of atomic sequences. */
|
||
+#define LWARX_MASK 0xfc0007fe
|
||
+#define LWARX_INSTRUCTION 0x7c000028
|
||
+#define LDARX_INSTRUCTION 0x7c0000A8
|
||
+#define STWCX_MASK 0xfc0007ff
|
||
+#define STWCX_INSTRUCTION 0x7c00012d
|
||
+#define STDCX_INSTRUCTION 0x7c0001ad
|
||
+#define BC_MASK 0xfc000000
|
||
+#define BC_INSTRUCTION 0x40000000
|
||
+
|
||
+/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
|
||
+ instruction and ending with a STWCX/STDCX instruction. If such a sequence
|
||
+ is found, attempt to step through it. A breakpoint is placed at the end of
|
||
+ the sequence. */
|
||
+
|
||
+static int
|
||
+deal_with_atomic_sequence (struct regcache *regcache)
|
||
+{
|
||
+ CORE_ADDR pc = read_pc ();
|
||
+ CORE_ADDR breaks[2] = {-1, -1};
|
||
+ CORE_ADDR loc = pc;
|
||
+ CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination. */
|
||
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
|
||
+ int insn_count;
|
||
+ int index;
|
||
+ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
|
||
+ const int atomic_sequence_length = 16; /* Instruction sequence length. */
|
||
+ const int opcode = BC_INSTRUCTION; /* Branch instruction's OPcode. */
|
||
+ int bc_insn_count = 0; /* Conditional branch instruction count. */
|
||
+
|
||
+ /* Assume all atomic sequences start with a lwarx/ldarx instruction. */
|
||
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
|
||
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
|
||
+ return 0;
|
||
+
|
||
+ /* Assume that no atomic sequence is longer than "atomic_sequence_length"
|
||
+ instructions. */
|
||
+ for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
|
||
+ {
|
||
+ loc += PPC_INSN_SIZE;
|
||
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
|
||
+
|
||
+ /* Assume that there is at most one conditional branch in the atomic
|
||
+ sequence. If a conditional branch is found, put a breakpoint in
|
||
+ its destination address. */
|
||
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
|
||
+ {
|
||
+ if (bc_insn_count >= 1)
|
||
+ return 0; /* More than one conditional branch found, fallback
|
||
+ to the standard single-step code. */
|
||
+
|
||
+ branch_bp = branch_dest (opcode, insn, pc, breaks[0]);
|
||
+
|
||
+ if (branch_bp != -1)
|
||
+ {
|
||
+ breaks[1] = branch_bp;
|
||
+ bc_insn_count++;
|
||
+ last_breakpoint++;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
|
||
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */
|
||
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
|
||
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
|
||
+ return 0;
|
||
+
|
||
+ loc += PPC_INSN_SIZE;
|
||
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
|
||
+
|
||
+ /* Insert a breakpoint right after the end of the atomic sequence. */
|
||
+ breaks[0] = loc;
|
||
+
|
||
+ /* Check for duplicated breakpoints. */
|
||
+ if (last_breakpoint && (breaks[1] == breaks[0]))
|
||
+ last_breakpoint = 0;
|
||
+
|
||
+ /* Effectively inserts the breakpoints. */
|
||
+ for (index = 0; index <= last_breakpoint; index++)
|
||
+ insert_single_step_breakpoint (breaks[index]);
|
||
+
|
||
+ return 1;
|
||
+}
|
||
+
|
||
+/* AIX does not support PT_STEP. Simulate it. */
|
||
|
||
int
|
||
rs6000_software_single_step (struct regcache *regcache)
|
||
@@ -724,6 +812,9 @@ rs6000_software_single_step (struct regc
|
||
|
||
insn = read_memory_integer (loc, 4);
|
||
|
||
+ if (deal_with_atomic_sequence (regcache))
|
||
+ return 1;
|
||
+
|
||
breaks[0] = loc + breakp_sz;
|
||
opcode = insn >> 26;
|
||
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
|
||
@@ -3448,6 +3539,9 @@ rs6000_gdbarch_init (struct gdbarch_info
|
||
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
||
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
|
||
|
||
+ /* Handles single stepping of atomic sequences. */
|
||
+ set_gdbarch_software_single_step (gdbarch, deal_with_atomic_sequence);
|
||
+
|
||
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
|
||
for the descriptor and ".FN" for the entry-point -- a user
|
||
specifying "break FN" will unexpectedly end up with a breakpoint
|