* [patch] "single step" atomic instruction sequences as a whole.
@ 2006-06-22 20:56 PAUL GILLIAM
2006-06-22 21:53 ` PAUL GILLIAM
2006-11-10 21:18 ` Daniel Jacobowitz
0 siblings, 2 replies; 43+ messages in thread
From: PAUL GILLIAM @ 2006-06-22 20:56 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3286 bytes --]
This fixes a problem noticed on ppc64-linux: automatically stepping out
of the 'puts' library function (because it had no line number
information) would cause an endless loop. This happened because of the
following sequence of instructions:
L1: lwarx r11,0,r3
cmpw r11,r9
bne- L2
stwcx. r0,0,r3
bne- L1
L2: isync
GDB can not single step this sequence instruction by instruction because
the 'reserve' made by the lwarx instruction will always be lost by the
the time the stwcx instruction has executed.
Other architectures may have similar instruction sequences which must
not be single stepped, one at a time.
To fix this, we must 'single step' these sequences as a whole, using the
same mechanism used by software single step.
Toward that end, I changed the existing software_single_step so that it
would return 1 if it handled the step and 0 if it did not. All the
existing versions where changed to always return 1.
Then I added a software_single_step routine for ppc-linux. This
platform did not previous use this function because it has a hardware
single step. Now, this routine ('ppc_atomic_single_step') checks to see
if the instruction about to be stepped is an stwcx instruction. If not,
it returns 0 to indicate that the single step has not been handled and
the regular hardware single step should be used. If the instruction
about to be single stepped was an stwcx instruction, then the code is
scanned looking for the corresponding stwcx instruction, after which a
breakpoint is placed. If a branch is detected while scanning, a
breakpoint is also placed at the target of that branch. Then flags are
set as they where for the old software single step and 1 is returned to
indicate that the step has been handled.
I have attached two patches. 'change-software-single-step.diff' makes
the generic changes to all the existing software single step routines:
changing their type from void to int and always returning a 1.
'ppc-atomic-single-step.diff' adds the new ppc_atomic_single_step
routine to ppc-linux-tdep.c and updates the ppc_linux_init_abi routine
to use set_gdbarch_software_single_step() to plug the new routine into
the architecture vector.
You may ask "but what if an architecture needs the old
software_single_step functionality *and* has sequences of instructions
that need to be atomic?" The answer is easy: do the test for the start
of an atomic sequence: if yes, then scan for its end as above and set
one or two breakpoints; if no, then examine the instruction to see if
it's a branch, setting a breakpoint at the target of the branch if it
is, and setting a breakpoint after the instruction if it is not or if
it's conditional. In either event the step was handled, so return 1.
You may ask "isn't this going to take a long time, examining every
instruction before it is stepped?" Well, a little. But no more then an
architecture without a hardware supported single step which has to
examine every instruction to see if it's a branch. I did some timing
analysis and the difference was minor.
This was first discussed on the gdb mailing list here:
http://sourceware.org/ml/gdb/2006-06/msg00048.html
OK to commit?
-=# Paul #=-
[-- Attachment #2: change-software-single-step.diff --]
[-- Type: text/x-patch, Size: 17363 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* gdbarch.sh: Change the return type of software_single_step from
void to int and reformatted some comments to <= 80 columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Change the return type
from void to int and always return 1.
* alpha-tdep.h: Change the return type of alpha_software_single_step
from void to int.
* arm-tdep.c (arm_software_single_step): Change the return type from
void to int and always return 1.
* cris-tdep.c (cris_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.c (mips_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.h: Change the return type of mips_software_single_step
from void to int.
* rs6000-tdep.c (rs6000_software_single_step): Change the return type
from void to int and always return 1.
*rs6000-tdep.h: Change the return type of rs6000_software_single_step
from void to int.
* sparc-tdep.c (sparc_software_single_step): Change the return type
from void to int and always return 1.
* sparc-tdep.h: Change the return type of sparc_software_single_step
from void to int.
* wince.c (wince_software_single_step {three times}): Change the
return type from void to int and always return 1.
infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly. True means that the software_single_step
breakpoints where inserted; false means they where not.
Index: alpha-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
retrieving revision 1.154
diff -a -u -r1.154 alpha-tdep.c
--- alpha-tdep.c 18 Apr 2006 19:20:05 -0000 1.154
+++ alpha-tdep.c 22 Jun 2006 17:49:27 -0000
@@ -1489,7 +1489,7 @@
return (pc + 4);
}
-void
+int
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
static CORE_ADDR next_pc;
@@ -1507,6 +1507,7 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
\f
Index: alpha-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.h,v
retrieving revision 1.23
diff -a -u -r1.23 alpha-tdep.h
--- alpha-tdep.h 17 Dec 2005 22:33:59 -0000 1.23
+++ alpha-tdep.h 22 Jun 2006 17:49:27 -0000
@@ -100,7 +100,7 @@
};
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 *);
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.209
diff -a -u -r1.209 arm-tdep.c
--- arm-tdep.c 17 May 2006 14:40:39 -0000 1.209
+++ arm-tdep.c 22 Jun 2006 17:49:27 -0000
@@ -1846,7 +1846,7 @@
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
@@ -1861,6 +1861,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1
}
#include "bfd-in2.h"
Index: cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.136
diff -a -u -r1.136 cris-tdep.c
--- cris-tdep.c 18 Apr 2006 19:20:06 -0000 1.136
+++ cris-tdep.c 22 Jun 2006 17:49:28 -0000
@@ -2117,7 +2117,7 @@
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;
@@ -2150,6 +2150,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.329
diff -a -u -r1.329 gdbarch.c
--- gdbarch.c 18 Apr 2006 19:20:06 -0000 1.329
+++ gdbarch.c 22 Jun 2006 17:49:28 -0000
@@ -3318,14 +3318,14 @@
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
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.285
diff -a -u -r1.285 gdbarch.h
--- gdbarch.h 18 Apr 2006 19:20:06 -0000 1.285
+++ gdbarch.h 22 Jun 2006 17:49:28 -0000
@@ -1165,14 +1165,16 @@
#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. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1189,8 +1191,8 @@
#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"
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.364
diff -a -u -r1.364 gdbarch.sh
--- gdbarch.sh 18 Apr 2006 19:20:06 -0000 1.364
+++ gdbarch.sh 22 Jun 2006 17:49:28 -0000
@@ -602,15 +602,19 @@
# 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.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# 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:=: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
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.211
diff -a -u -r1.211 infrun.c
--- infrun.c 16 Jun 2006 01:12:58 -0000 1.211
+++ infrun.c 22 Jun 2006 17:49:28 -0000
@@ -556,13 +556,15 @@
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;
+ 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;
+ }
}
/* If there were any forks/vforks/execs that were caught and are
@@ -1375,7 +1377,7 @@
(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;
@@ -1395,7 +1397,7 @@
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;
@@ -1557,7 +1559,7 @@
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;
@@ -1621,7 +1623,7 @@
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;
}
@@ -1694,7 +1696,7 @@
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;
}
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.396
diff -a -u -r1.396 mips-tdep.c
--- mips-tdep.c 19 Jun 2006 18:50:09 -0000 1.396
+++ mips-tdep.c 22 Jun 2006 17:49:29 -0000
@@ -2185,7 +2185,7 @@
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;
@@ -2199,6 +2199,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: mips-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.h,v
retrieving revision 1.18
diff -a -u -r1.18 mips-tdep.h
--- mips-tdep.h 17 Dec 2005 22:34:01 -0000 1.18
+++ mips-tdep.h 22 Jun 2006 17:49:29 -0000
@@ -103,7 +103,7 @@
};
/* 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. */
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.258
diff -a -u -r1.258 rs6000-tdep.c
--- rs6000-tdep.c 23 Apr 2006 14:15:01 -0000 1.258
+++ rs6000-tdep.c 22 Jun 2006 17:49:29 -0000
@@ -704,7 +704,7 @@
/* AIX does not support PT_STEP. Simulate it. */
-void
+int
rs6000_software_single_step (enum target_signal signal,
int insert_breakpoints_p)
{
@@ -743,6 +743,8 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+
+ return 1;
}
Index: rs6000-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.h,v
retrieving revision 1.1
diff -a -u -r1.1 rs6000-tdep.h
--- rs6000-tdep.h 10 Feb 2006 20:56:14 -0000 1.1
+++ rs6000-tdep.h 22 Jun 2006 17:49:29 -0000
@@ -21,6 +21,6 @@
#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);
Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.172
diff -a -u -r1.172 sparc-tdep.c
--- sparc-tdep.c 18 Apr 2006 19:20:06 -0000 1.172
+++ sparc-tdep.c 22 Jun 2006 17:49:29 -0000
@@ -1131,7 +1131,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1161,6 +1161,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.h,v
retrieving revision 1.11
diff -a -u -r1.11 sparc-tdep.h
--- sparc-tdep.h 22 Jan 2006 20:07:38 -0000 1.11
+++ sparc-tdep.h 22 Jun 2006 17:49:29 -0000
@@ -167,8 +167,8 @@
\f
-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);
Index: wince.c
===================================================================
RCS file: /cvs/src/src/gdb/wince.c,v
retrieving revision 1.45
diff -a -u -r1.45 wince.c
--- wince.c 18 Apr 2006 19:20:06 -0000 1.45
+++ wince.c 22 Jun 2006 17:49:29 -0000
@@ -838,7 +838,7 @@
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -850,14 +850,15 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = mips_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif SHx
/* Renesas SH architecture instruction encoding masks */
@@ -979,7 +980,7 @@
instruction and setting a breakpoint on the "next" instruction
which would be executed. This code hails from sh-stub.c.
*/
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -989,13 +990,14 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
th->step_pc = sh_get_next_pc (&th->context);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif defined (ARM)
#undef check_for_step
@@ -1026,7 +1028,7 @@
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -1038,14 +1040,15 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = arm_get_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#endif
[-- Attachment #3: ppc-atomic-single-step.diff --]
[-- Type: text/x-patch, Size: 3487 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* ppc-linux-tdep.c (ppc_atomic_single_step): New function.
(ppc_linux_init_abi): Set software_single_step member of the gdbarch
vector to the new ppc_atomic_single_step function.
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.78
diff -a -u -r1.78 ppc-linux-tdep.c
--- ppc-linux-tdep.c 18 Apr 2006 19:20:06 -0000 1.78
+++ ppc-linux-tdep.c 22 Jun 2006 18:26:16 -0000
@@ -927,6 +927,84 @@
trad_frame_set_id (this_cache, frame_id_build (base, func));
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+ppc_atomic_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ if (insert_breakpoints_p)
+ {
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_insn (loc);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_insn (loc);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_insn (loc);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+ }
+ else
+ remove_single_step_breakpoints ();
+
+ return 1;
+}
+
static void
ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
struct frame_info *next_frame,
@@ -1080,6 +1158,10 @@
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
+
+ /* Enable software_single_step in case someone tries to sngle step a
+ sequence of instructions that should be atomic. */
+ set_gdbarch_software_single_step (gdbarch, ppc_atomic_single_step);
}
void
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2006-06-22 20:56 [patch] "single step" atomic instruction sequences as a whole PAUL GILLIAM
@ 2006-06-22 21:53 ` PAUL GILLIAM
2006-06-22 22:20 ` PAUL GILLIAM
2006-11-10 21:18 ` Daniel Jacobowitz
1 sibling, 1 reply; 43+ messages in thread
From: PAUL GILLIAM @ 2006-06-22 21:53 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 552 bytes --]
On Thu, 2006-06-22 at 12:51 -0700, PAUL GILLIAM wrote:
> You may ask "but what if an architecture needs the old
> software_single_step functionality *and* has sequences of instructions
> that need to be atomic?"
It turns out, there *is* such an architecture and it can have the *same*
sequences instruction that need to be atomic as PPC: the RS6000!
So here is a patch that adds dealing with atomic sequences for the
RS6000.
The attach patch assumes that the 'change-software-single-step.diff'
patch has been applied.
OK to commit?
-=# Paul #=-
[-- Attachment #2: rs6000-atomic-single-step.diff --]
[-- Type: text/x-patch, Size: 2854 bytes --]
--- old_rs6000-tdep.c 2006-06-22 13:16:03.000000000 -0700
+++ rs6000-tdep.c 2006-06-22 13:41:10.000000000 -0700
@@ -701,8 +701,81 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+deal_with_atomic_sequence (enum target_signal sig)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, 4);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
-/* AIX does not support PT_STEP. Simulate it. */
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it, dealing with any sequence of
+ instructions that must be atomic. */
int
rs6000_software_single_step (enum target_signal signal,
@@ -722,6 +795,9 @@
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (signal))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2006-06-22 21:53 ` PAUL GILLIAM
@ 2006-06-22 22:20 ` PAUL GILLIAM
0 siblings, 0 replies; 43+ messages in thread
From: PAUL GILLIAM @ 2006-06-22 22:20 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 758 bytes --]
On Thu, 2006-06-22 at 13:48 -0700, PAUL GILLIAM wrote:
> On Thu, 2006-06-22 at 12:51 -0700, PAUL GILLIAM wrote:
>
> > You may ask "but what if an architecture needs the old
> > software_single_step functionality *and* has sequences of instructions
> > that need to be atomic?"
>
> It turns out, there *is* such an architecture and it can have the *same*
> sequences instruction that need to be atomic as PPC: the RS6000!
>
> So here is a patch that adds dealing with atomic sequences for the
> RS6000.
>
> The attach patch assumes that the 'change-software-single-step.diff'
> patch has been applied.
>
> OK to commit?
>
> -=# Paul #=-
Damn! I forget the change log entry... here is the patch for
rs6000-tdep.c again.
OK to commit?
-=# Paul #=-
[-- Attachment #2: rs6000-atomic-single-step.diff --]
[-- Type: text/x-patch, Size: 3096 bytes --]
2006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* rs6000-tdep (deal_with_atomic_sequence): new
(rs6000_software_single_step): Call the new routine to check for atomic
sequences of instructions that need to be single stepped 'as a whole'.
--- old_rs6000-tdep.c 2006-06-22 13:16:03.000000000 -0700
+++ rs6000-tdep.c 2006-06-22 13:41:10.000000000 -0700
@@ -701,8 +701,81 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+deal_with_atomic_sequence (enum target_signal sig)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, 4);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
-/* AIX does not support PT_STEP. Simulate it. */
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it, dealing with any sequence of
+ instructions that must be atomic. */
int
rs6000_software_single_step (enum target_signal signal,
@@ -722,6 +795,9 @@
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (signal))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2006-06-22 20:56 [patch] "single step" atomic instruction sequences as a whole PAUL GILLIAM
2006-06-22 21:53 ` PAUL GILLIAM
@ 2006-11-10 21:18 ` Daniel Jacobowitz
1 sibling, 0 replies; 43+ messages in thread
From: Daniel Jacobowitz @ 2006-11-10 21:18 UTC (permalink / raw)
To: PAUL GILLIAM; +Cc: gdb-patches
On Thu, Jun 22, 2006 at 12:51:34PM -0700, PAUL GILLIAM wrote:
> This fixes a problem noticed on ppc64-linux: automatically stepping out
> of the 'puts' library function (because it had no line number
> information) would cause an endless loop. This happened because of the
> following sequence of instructions:
>
> L1: lwarx r11,0,r3
> cmpw r11,r9
> bne- L2
> stwcx. r0,0,r3
> bne- L1
> L2: isync
Since no one else did I guess I get to look at these :-)
Paul, do you know if these patches still work? There's a report that
they cause internal errors. One great way to test would be adding a
testcase to gdb.arch, and also running the GDB testsuite. I imagine
this is caused by single stepping over anything _but_ an atomic op,
since insert_single_step_breakpoint was called conditionally and
remove_single_step_breakpoints unconditionally. I imagine we got there
because you always return 1, even if you didn't do anything.
I'm still not thrilled with the approach but no one came up with an
alternative so we'll do it your way - implemented is better than not.
> I have attached two patches. 'change-software-single-step.diff' makes
> the generic changes to all the existing software single step routines:
> changing their type from void to int and always returning a 1.
Two things. First of all, the patch won't compile; I saw at least one
"return 1" without a semicolon. Secondly, here's some suggestions for
the ChangeLog:
> * gdbarch.sh: Change the return type of software_single_step from
> void to int and reformatted some comments to <= 80 columns.
> * gdbarch.c, gdbarch.h: Regenerated.
> * alpha-tdep.c (alpha_software_single_step): Change the return type
> from void to int and always return 1.
> * alpha-tdep.h: Change the return type of alpha_software_single_step
> from void to int.
* gdbarch.sh (software_single_step): Return int. Doc fixes.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Return 1.
* alpha-tdep.h (alpha_software_single_step): Update.
Or, for big mechanical changes like this one, I think it's reasonable
to summarize:
* alpha-tdep.c, alpha-tdep.h, arm-tdep.c, [list all the
files]: Update software_single_step methods.
> 'ppc-atomic-single-step.diff' adds the new ppc_atomic_single_step
> routine to ppc-linux-tdep.c and updates the ppc_linux_init_abi routine
> to use set_gdbarch_software_single_step() to plug the new routine into
> the architecture vector.
> + /* Enable software_single_step in case someone tries to sngle step a
> + sequence of instructions that should be atomic. */
Two spaces after a period.
> + for (i= 1; i < 5; ++i)
Spaces around an operator.
> + error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
Line too long. Either wrap the string or add newlines to the error
message, for instance:
error (_("Tried to step over an atomic sequence of instructions but "
"could not find the end of the sequence."));
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re:[patch] "single step" atomic instruction sequences as a whole.
@ 2006-09-18 11:59 emin ak
2006-11-09 13:07 ` [patch] " emin ak
0 siblings, 1 reply; 43+ messages in thread
From: emin ak @ 2006-09-18 11:59 UTC (permalink / raw)
To: gdb-patches
Hi All;
Is there aynone can succesfully apply or care about this patch. I have
the same problem with my powerpc.
I have checked the latest cvs gdb and I have found this patch did'nt
merge into mainline. Will it commit later?
Thanks. Best Regards.
Emin Ak
>Sorry forgot the logs.
>--------------------test function.
>#include <stdio.h>
>#define __KERNEL__
>#include <asm/atomic.h>
>
>atomic_t i;
>int main(void)
>{
>printf("atomic_step_test\n");
>atomic_set(&i,5);
>printf("i=%d\n",atomic_read(&i));
>atomic_dec(&i);
>printf("i=%d\n",atomic_read(&i));
>
>
>}
>----------- gdb logs-----------
>Breakpoint 2, main () at test.c:8
>8 printf("atomic_step_test\n");
>(gdb) next
>9 atomic_set(&i,5);
>(gdb) next
>10 printf("i=%d\n",atomic_read(&i));
>(gdb) next
>151 :"=m" (v->counter), "=qm" (c)
>(gdb) next
>Stepping over an atomic sequence of instructions beginning at 0x10000484
>breakpoint.c:7730: internal-error: remove_single_step_breakpoints:
>Assertion `single_step_breakpoints[0] != NULL' failed.
>A problem internal to GDB has been detected,
>further debugging may prove unreliable.
>Quit this debugging session? (y or n)
>--------------------------
>Regards.
>Emre
> Hello Mr Gilliam;
> Firstly thank you very much for your patch about single stepping problem
> on atomic instructions. In my opinion, this bug is very critical for
> powerpc arch (especially while kernel debugging). We have experienced this
> problem with both with h/w probe (BDI2000) and KGDB while debugging
> kernel. I have applied your patch to latest gdb (20060911 taken from cvs)
> and after correctting some fail warnings and test it on a PPC8540. It can
> successfullt detects 'lwarx' instruction but can't step over the loop and
> a little moment later, it gives an error message like 'breakpoint.c:7730:
> internal-error: remove_single_step_breakpoints: Assertion
> `single_step_breakpoints[0] != NULL' failed.'
> I have corrected some patch error, I dont know, maybe this is the reason
> of the problem. Here is the output of gdb and my test program that include
> atomic_dec function.
> Where can be the problem? And thank alot again, because atomic functions
> are everywhere on kernel waiting to cause infinite loops..
> Regards.
> Emre KARA
>
>
>
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2006-09-18 11:59 emin ak
@ 2006-11-09 13:07 ` emin ak
0 siblings, 0 replies; 43+ messages in thread
From: emin ak @ 2006-11-09 13:07 UTC (permalink / raw)
To: pgilliam; +Cc: gdb-patches
Mr Gilliam,
I'am very interested in one of your gdb patches about ""single step"
atomic instruction sequences as a whole". we have experienced serious
problems on atomic functions while debugging linux kernel and we have
found only your approach can solve the problem. I have applied it
againts latest cvs source but it is not working truly, it can detects
atomic inc. successfully but cant step over them and gives this error:
'breakpoint.c:7730: internal-error: remove_single_step_breakpoints: Assertion
`single_step_breakpoints[0] != NULL' failed.'
Mr Gilliam, if you can kindly guide me (or give a clue) to overcome
this problem, I can reorganize this patch and resend it to community
Thank you very much for your time.
Best Regards.
Emin Ak
2006/9/18, emin ak <eminak71@gmail.com>:
> Hi All;
> Is there aynone can succesfully apply or care about this patch. I have
> the same problem with my powerpc.
> I have checked the latest cvs gdb and I have found this patch did'nt
> merge into mainline. Will it commit later?
> Thanks. Best Regards.
> Emin Ak
> >Sorry forgot the logs.
> >--------------------test function.
> >#include <stdio.h>
> >#define __KERNEL__
> >#include <asm/atomic.h>
> >
> >atomic_t i;
> >int main(void)
> >{
> >printf("atomic_step_test\n");
> >atomic_set(&i,5);
> >printf("i=%d\n",atomic_read(&i));
> >atomic_dec(&i);
> >printf("i=%d\n",atomic_read(&i));
> >
> >
> >}
> >----------- gdb logs-----------
> >Breakpoint 2, main () at test.c:8
> >8 printf("atomic_step_test\n");
> >(gdb) next
> >9 atomic_set(&i,5);
> >(gdb) next
> >10 printf("i=%d\n",atomic_read(&i));
> >(gdb) next
> >151 :"=m" (v->counter), "=qm" (c)
> >(gdb) next
> >Stepping over an atomic sequence of instructions beginning at 0x10000484
> >breakpoint.c:7730: internal-error: remove_single_step_breakpoints:
> >Assertion `single_step_breakpoints[0] != NULL' failed.
> >A problem internal to GDB has been detected,
> >further debugging may prove unreliable.
> >Quit this debugging session? (y or n)
> >--------------------------
> >Regards.
> >Emre
> > Hello Mr Gilliam;
> > Firstly thank you very much for your patch about single stepping problem
> > on atomic instructions. In my opinion, this bug is very critical for
> > powerpc arch (especially while kernel debugging). We have experienced this
> > problem with both with h/w probe (BDI2000) and KGDB while debugging
> > kernel. I have applied your patch to latest gdb (20060911 taken from cvs)
> > and after correctting some fail warnings and test it on a PPC8540. It can
> > successfullt detects 'lwarx' instruction but can't step over the loop and
> > a little moment later, it gives an error message like 'breakpoint.c:7730:
> > internal-error: remove_single_step_breakpoints: Assertion
> > `single_step_breakpoints[0] != NULL' failed.'
> > I have corrected some patch error, I dont know, maybe this is the reason
> > of the problem. Here is the output of gdb and my test program that include
> > atomic_dec function.
> > Where can be the problem? And thank alot again, because atomic functions
> > are everywhere on kernel waiting to cause infinite loops..
> > Regards.
> > Emre KARA
> >
> >
> >
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [patch] "single step" atomic instruction sequences as a whole.
@ 2007-02-06 11:02 Luis Machado
2007-02-06 12:11 ` Emi SUZUKI
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-02-06 11:02 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1201 bytes --]
Hi,
Some months ago Paul Gilliam submitted a set of three patches to fix a single
stepping problem through atomic instruction sequences on a POWER
architecture. The problem caused GDB to hang when one tried to single step
through these instructions. Suppose that you have the following block of
instructions:
L1: lwarx r11,0,r3
cmpw r11,r9
bne- L2
stwcx. r0,0,r3
bne- L1
L2: isync
It's not possible to do a single step through each one of these instructions
since the 'reserve' made by the lwarx instruction will always be lost by the
the time the stwcx instruction has executed.
The patch treats the whole L1/L2 interval as a single instruction, avoiding a
single step through each one of the instructions contained in the L1/L2
interval, which would lead GDB to a hang
More details regarding this patch can be found at the original messages.
* Patches 1 and 2: http://sourceware.org/ml/gdb-patches/2006-06/msg00339.html
* Patch 3: http://sourceware.org/ml/gdb-patches/2006-06/msg00341.html
I'm re-submitting this patch in order for it to be reviewed. Could this patch
be applied?
Regards,
Luis
[-- Attachment #2: ppc-atomic.single-step.diff --]
[-- Type: text/x-diff, Size: 3488 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* ppc-linux-tdep.c (ppc_atomic_single_step): New function.
(ppc_linux_init_abi): Set software_single_step member of the gdbarch
vector to the new ppc_atomic_single_step function.
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.78
diff -a -u -r1.78 ppc-linux-tdep.c
--- ppc-linux-tdep.c 18 Apr 2006 19:20:06 -0000 1.78
+++ ppc-linux-tdep.c 22 Jun 2006 18:26:16 -0000
@@ -927,6 +927,84 @@
trad_frame_set_id (this_cache, frame_id_build (base, func));
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+ppc_atomic_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ if (insert_breakpoints_p)
+ {
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_insn (loc);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_insn (loc);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_insn (loc);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+ }
+ else
+ remove_single_step_breakpoints ();
+
+ return 1;
+}
+
static void
ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
struct frame_info *next_frame,
@@ -1080,6 +1158,10 @@
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
+
+ /* Enable software_single_step in case someone tries to sngle step a
+ sequence of instructions that should be atomic. */
+ set_gdbarch_software_single_step (gdbarch, ppc_atomic_single_step);
}
void
[-- Attachment #3: rs6000-atomic-single-step.diff --]
[-- Type: text/x-diff, Size: 2855 bytes --]
--- old_rs6000-tdep.c 2006-06-22 13:16:03.000000000 -0700
+++ rs6000-tdep.c 2006-06-22 13:41:10.000000000 -0700
@@ -701,8 +701,81 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+deal_with_atomic_sequence (enum target_signal sig)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, 4);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
-/* AIX does not support PT_STEP. Simulate it. */
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it, dealing with any sequence of
+ instructions that must be atomic. */
int
rs6000_software_single_step (enum target_signal signal,
@@ -722,6 +795,9 @@
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (signal))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
[-- Attachment #4: change-software-single-step.diff --]
[-- Type: text/x-diff, Size: 17363 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* gdbarch.sh: Change the return type of software_single_step from
void to int and reformatted some comments to <= 80 columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Change the return type
from void to int and always return 1.
* alpha-tdep.h: Change the return type of alpha_software_single_step
from void to int.
* arm-tdep.c (arm_software_single_step): Change the return type from
void to int and always return 1.
* cris-tdep.c (cris_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.c (mips_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.h: Change the return type of mips_software_single_step
from void to int.
* rs6000-tdep.c (rs6000_software_single_step): Change the return type
from void to int and always return 1.
*rs6000-tdep.h: Change the return type of rs6000_software_single_step
from void to int.
* sparc-tdep.c (sparc_software_single_step): Change the return type
from void to int and always return 1.
* sparc-tdep.h: Change the return type of sparc_software_single_step
from void to int.
* wince.c (wince_software_single_step {three times}): Change the
return type from void to int and always return 1.
infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly. True means that the software_single_step
breakpoints where inserted; false means they where not.
Index: alpha-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
retrieving revision 1.154
diff -a -u -r1.154 alpha-tdep.c
--- alpha-tdep.c 18 Apr 2006 19:20:05 -0000 1.154
+++ alpha-tdep.c 22 Jun 2006 17:49:27 -0000
@@ -1489,7 +1489,7 @@
return (pc + 4);
}
-void
+int
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
static CORE_ADDR next_pc;
@@ -1507,6 +1507,7 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
\f
Index: alpha-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.h,v
retrieving revision 1.23
diff -a -u -r1.23 alpha-tdep.h
--- alpha-tdep.h 17 Dec 2005 22:33:59 -0000 1.23
+++ alpha-tdep.h 22 Jun 2006 17:49:27 -0000
@@ -100,7 +100,7 @@
};
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 *);
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.209
diff -a -u -r1.209 arm-tdep.c
--- arm-tdep.c 17 May 2006 14:40:39 -0000 1.209
+++ arm-tdep.c 22 Jun 2006 17:49:27 -0000
@@ -1846,7 +1846,7 @@
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
@@ -1861,6 +1861,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1
}
#include "bfd-in2.h"
Index: cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.136
diff -a -u -r1.136 cris-tdep.c
--- cris-tdep.c 18 Apr 2006 19:20:06 -0000 1.136
+++ cris-tdep.c 22 Jun 2006 17:49:28 -0000
@@ -2117,7 +2117,7 @@
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;
@@ -2150,6 +2150,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.329
diff -a -u -r1.329 gdbarch.c
--- gdbarch.c 18 Apr 2006 19:20:06 -0000 1.329
+++ gdbarch.c 22 Jun 2006 17:49:28 -0000
@@ -3318,14 +3318,14 @@
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
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.285
diff -a -u -r1.285 gdbarch.h
--- gdbarch.h 18 Apr 2006 19:20:06 -0000 1.285
+++ gdbarch.h 22 Jun 2006 17:49:28 -0000
@@ -1165,14 +1165,16 @@
#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. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1189,8 +1191,8 @@
#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"
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.364
diff -a -u -r1.364 gdbarch.sh
--- gdbarch.sh 18 Apr 2006 19:20:06 -0000 1.364
+++ gdbarch.sh 22 Jun 2006 17:49:28 -0000
@@ -602,15 +602,19 @@
# 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.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# 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:=: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
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.211
diff -a -u -r1.211 infrun.c
--- infrun.c 16 Jun 2006 01:12:58 -0000 1.211
+++ infrun.c 22 Jun 2006 17:49:28 -0000
@@ -556,13 +556,15 @@
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;
+ 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;
+ }
}
/* If there were any forks/vforks/execs that were caught and are
@@ -1375,7 +1377,7 @@
(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;
@@ -1395,7 +1397,7 @@
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;
@@ -1557,7 +1559,7 @@
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;
@@ -1621,7 +1623,7 @@
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;
}
@@ -1694,7 +1696,7 @@
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;
}
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.396
diff -a -u -r1.396 mips-tdep.c
--- mips-tdep.c 19 Jun 2006 18:50:09 -0000 1.396
+++ mips-tdep.c 22 Jun 2006 17:49:29 -0000
@@ -2185,7 +2185,7 @@
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;
@@ -2199,6 +2199,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: mips-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.h,v
retrieving revision 1.18
diff -a -u -r1.18 mips-tdep.h
--- mips-tdep.h 17 Dec 2005 22:34:01 -0000 1.18
+++ mips-tdep.h 22 Jun 2006 17:49:29 -0000
@@ -103,7 +103,7 @@
};
/* 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. */
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.258
diff -a -u -r1.258 rs6000-tdep.c
--- rs6000-tdep.c 23 Apr 2006 14:15:01 -0000 1.258
+++ rs6000-tdep.c 22 Jun 2006 17:49:29 -0000
@@ -704,7 +704,7 @@
/* AIX does not support PT_STEP. Simulate it. */
-void
+int
rs6000_software_single_step (enum target_signal signal,
int insert_breakpoints_p)
{
@@ -743,6 +743,8 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+
+ return 1;
}
Index: rs6000-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.h,v
retrieving revision 1.1
diff -a -u -r1.1 rs6000-tdep.h
--- rs6000-tdep.h 10 Feb 2006 20:56:14 -0000 1.1
+++ rs6000-tdep.h 22 Jun 2006 17:49:29 -0000
@@ -21,6 +21,6 @@
#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);
Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.172
diff -a -u -r1.172 sparc-tdep.c
--- sparc-tdep.c 18 Apr 2006 19:20:06 -0000 1.172
+++ sparc-tdep.c 22 Jun 2006 17:49:29 -0000
@@ -1131,7 +1131,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1161,6 +1161,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.h,v
retrieving revision 1.11
diff -a -u -r1.11 sparc-tdep.h
--- sparc-tdep.h 22 Jan 2006 20:07:38 -0000 1.11
+++ sparc-tdep.h 22 Jun 2006 17:49:29 -0000
@@ -167,8 +167,8 @@
\f
-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);
Index: wince.c
===================================================================
RCS file: /cvs/src/src/gdb/wince.c,v
retrieving revision 1.45
diff -a -u -r1.45 wince.c
--- wince.c 18 Apr 2006 19:20:06 -0000 1.45
+++ wince.c 22 Jun 2006 17:49:29 -0000
@@ -838,7 +838,7 @@
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -850,14 +850,15 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = mips_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif SHx
/* Renesas SH architecture instruction encoding masks */
@@ -979,7 +980,7 @@
instruction and setting a breakpoint on the "next" instruction
which would be executed. This code hails from sh-stub.c.
*/
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -989,13 +990,14 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
th->step_pc = sh_get_next_pc (&th->context);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif defined (ARM)
#undef check_for_step
@@ -1026,7 +1028,7 @@
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -1038,14 +1040,15 @@
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = arm_get_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#endif
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-06 11:02 Luis Machado
@ 2007-02-06 12:11 ` Emi SUZUKI
2007-02-07 13:10 ` Luis Machado
0 siblings, 1 reply; 43+ messages in thread
From: Emi SUZUKI @ 2007-02-06 12:11 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 1709 bytes --]
Hello Luis and members,
I am working on Linux running on PlayStation 3, and on Fedora Core 5
for PowerPC running on our own hardware equipped with 'Cell' CPU.
I have also been annoyed by this problem for months, because the main
core of Cell is PowerPC.
As far as I know, the patch by Paul has a problem mentioned by the
messages below:
http://sourceware.org/ml/gdb-patches/2006-09/msg00060.html
http://sourceware.org/ml/gdb-patches/2006-09/msg00097.html
http://sourceware.org/ml/gdb-patches/2006-11/msg00049.html
http://sourceware.org/ml/gdb-patches/2006-11/msg00074.html
And the idea is a bit confusing for me...
I just thought that SOFTWARE_SINGLE_STEP_P should indicate if the
target will do software single-stepping at the next time it proceed.
And all the architectures which should skip atomic sequences of
instructions by themselves need to implement are
SOFTWARE_SINGLE_STEP_P to check if the skipping is needed, and
SOFTWARE_SINGLE_STEP to actually skip the sequence.
# I remember someone said that ARM and MIPS have a similar problem.
As a effect of the change above, the return value of SOFTWARE_SINGLE_STEP_P
cannot be used as the condition of thread hopping check or removing
a software single-stepping breakpoint on handle_inferior_event: it
may not be welcomed.
Anyway, I will attach a patch applied on our environment. It's for
CVS head.
Since it's my first time of posting here, any comments are very
appreciated.
P.S.
I have not completed the legal process of copyright assignment, and
unfortunately the boss said to me that it will take months...
Please point me if the patch can be applied and surely needs an
assignment, I will make them hurry.
--
Emi SUZUKI
[-- Attachment #2: rs6000-skip-atomic-sequnce.diff --]
[-- Type: Text/Plain, Size: 6894 bytes --]
diff -uBbEw -r -x CVS src/gdb/config/rs6000/tm-rs6000.h gdb/gdb/config/rs6000/tm-rs6000.h
--- src/gdb/config/rs6000/tm-rs6000.h 2007-01-10 02:59:05.000000000 +0900
+++ gdb/gdb/config/rs6000/tm-rs6000.h 2007-02-06 15:39:31.000000000 +0900
@@ -90,3 +90,8 @@
extern void (*rs6000_set_host_arch_hook) (int);
+extern int rs6000_software_single_step_p (void);
+#ifdef SOFTWARE_SINGLE_STEP_P
+#undef SOFTWARE_SINGLE_STEP_P
+#endif
+#define SOFTWARE_SINGLE_STEP_P() rs6000_software_single_step_p()
diff -uBbEw -r -x CVS src/gdb/infrun.c gdb/gdb/infrun.c
--- src/gdb/infrun.c 2007-01-11 05:10:23.000000000 +0900
+++ gdb/gdb/infrun.c 2007-02-06 15:41:00.000000000 +0900
@@ -556,7 +556,9 @@
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
SKIP_PERMANENT_BREAKPOINT ();
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (step)
+ {
+ if (SOFTWARE_SINGLE_STEP_P ())
{
/* Do it the hard way, w/temp breakpoints */
SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
@@ -565,6 +567,8 @@
/* 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 ();
}
@@ -1570,8 +1574,6 @@
if (stepping_past_singlestep_breakpoint)
{
- 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));
@@ -1584,9 +1586,13 @@
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
+
+ if (singlestep_breakpoints_inserted_p)
+ {
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
+ }
ecs->random_signal = 0;
@@ -1620,7 +1626,7 @@
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
@@ -1691,7 +1697,7 @@
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ /* if (singlestep_breakpoints_inserted_p) */
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
@@ -1740,7 +1746,7 @@
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
@@ -1762,7 +1768,7 @@
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
diff -uBbEw -r -x CVS src/gdb/rs6000-tdep.c gdb/gdb/rs6000-tdep.c
--- src/gdb/rs6000-tdep.c 2007-01-10 02:58:57.000000000 +0900
+++ gdb/gdb/rs6000-tdep.c 2007-02-06 15:40:03.000000000 +0900
@@ -701,6 +701,79 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+CORE_ADDR
+rs6000_deal_with_atomic_sequence (CORE_ADDR pc)
+{
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int last_break = 0;
+ int i;
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return -1;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ if (last_break == 0)
+ return -1;
+
+ return breaks[0];
+}
+
+/* SOFTWARE_SINGLE_STEP_P */
+int
+rs6000_software_single_step_p (void)
+{
+ return (rs6000_deal_with_atomic_sequence (read_pc ()) != -1);
+}
/* AIX does not support PT_STEP. Simulate it. */
@@ -720,8 +793,21 @@
{
loc = read_pc ();
- insn = read_memory_integer (loc, 4);
+ /* check if running on atomic sequence */
+ breaks[0] = rs6000_deal_with_atomic_sequence (loc);
+ if (breaks[0] != -1)
+ {
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions. \n\
+Beginning at %s, break at %s next time.\n"),
+ core_addr_to_string (loc),
+ core_addr_to_string (breaks[0]));
+ gdb_flush (gdb_stdout);
+ breaks[1] = -1;
+ }
+ else
+ {
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
@@ -729,6 +815,7 @@
/* Don't put two breakpoints on the same address. */
if (breaks[1] == breaks[0])
breaks[1] = -1;
+ }
for (ii = 0; ii < 2; ++ii)
{
@@ -3413,6 +3500,7 @@
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
for the descriptor and ".FN" for the entry-point -- a user
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-06 12:11 ` Emi SUZUKI
@ 2007-02-07 13:10 ` Luis Machado
2007-02-08 13:00 ` Emi SUZUKI
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-02-07 13:10 UTC (permalink / raw)
To: gdb-patches
Hi Emi,
It's great that we have someone working on this issue also.
What's exactly been modified on your patch for single stepping of atomic
instruction sequences? Does it handle the issues that you have mentioned
about thread hopping check?
Regards,
Luis
On Tuesday 06 February 2007 10:11, Emi SUZUKI wrote:
> Hello Luis and members,
>
> I am working on Linux running on PlayStation 3, and on Fedora Core 5
> for PowerPC running on our own hardware equipped with 'Cell' CPU.
> I have also been annoyed by this problem for months, because the main
> core of Cell is PowerPC.
>
> As far as I know, the patch by Paul has a problem mentioned by the
> messages below:
> http://sourceware.org/ml/gdb-patches/2006-09/msg00060.html
> http://sourceware.org/ml/gdb-patches/2006-09/msg00097.html
> http://sourceware.org/ml/gdb-patches/2006-11/msg00049.html
> http://sourceware.org/ml/gdb-patches/2006-11/msg00074.html
>
> And the idea is a bit confusing for me...
>
> I just thought that SOFTWARE_SINGLE_STEP_P should indicate if the
> target will do software single-stepping at the next time it proceed.
> And all the architectures which should skip atomic sequences of
> instructions by themselves need to implement are
> SOFTWARE_SINGLE_STEP_P to check if the skipping is needed, and
> SOFTWARE_SINGLE_STEP to actually skip the sequence.
> # I remember someone said that ARM and MIPS have a similar problem.
>
> As a effect of the change above, the return value of SOFTWARE_SINGLE_STEP_P
> cannot be used as the condition of thread hopping check or removing
> a software single-stepping breakpoint on handle_inferior_event: it
> may not be welcomed.
>
> Anyway, I will attach a patch applied on our environment. It's for
> CVS head.
> Since it's my first time of posting here, any comments are very
> appreciated.
>
> P.S.
> I have not completed the legal process of copyright assignment, and
> unfortunately the boss said to me that it will take months...
> Please point me if the patch can be applied and surely needs an
> assignment, I will make them hurry.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-07 13:10 ` Luis Machado
@ 2007-02-08 13:00 ` Emi SUZUKI
0 siblings, 0 replies; 43+ messages in thread
From: Emi SUZUKI @ 2007-02-08 13:00 UTC (permalink / raw)
To: gdb-patches
Hello Luis,
Thank you for your reply.
* On Wed, 07 Feb 2007 11:10:01 -0200, Luis Machado wrote:
> What's exactly been modified on your patch for single stepping of atomic
> instruction sequences?
OK, I will explain about them one by one.
First, I defined the entity of SOFTWARE_SINGLE_STEP_P macro on
rs6000-tdep.c. It returns true if the new function
'rs6000_deal_with_atomic_sequence' returns a non-zero value, say,
skipping an atomic sequence instruction is needed.
'rs6000_deal_with_atomic_sequence' is derived from Paul's patch to
search the subsequent instructions: it start reading instructions from
PC and returns the address which indicates the end of the atomic
sequence if any is found. It is also called by 'rs6000_software_single_step'
to get the address to which a software single-step breakpoint will be
set. 'rs6000_software_single_step' is set to gdbarch by
'set_gdbarch_software_single_step'.
Note that the gdbarch definition for RS6000 is also used when GDB was
configured for the POWER architectures, so the modification also
effects on ppc*-linux configuration without defining in ppc-linux-tdep.c.
# I didn't see any differences between the patchs for those two files
# which you have resent, but point me out if I have missed something.
By the changes above, GDB sometimes makes the target do software
single-stepping even if the target environment supports hardware
single-stepping: the basic behavior is the same as what Paul's
patchset does.
But the function handle_inferior_event, defined in infrun.c, has some
codes based on the assumption that the status of hardware
single-stepping support is not changed during the debugging session.
So I removed these codes.
And the thread hopping procedures should be done when the thread other
than the one doing software single-stepping runs on a stop-code for
software single-stepping. It can also occur while "temporary
software single-stepping" is being done, but handle_inferior_event
doesn't take those things into consideration.
So I added the code to save 'singlestep_ptid' in resume, even when
a hardware single-stepping will be done. It will be compared with
the ptid of the trapped thread for checking if the thread hopping
occured.
> Does it handle the issues that you have mentioned
> about thread hopping check?
It should do, logically. But I have checked only on our hardware.
I will appreciate if you check it on your environment.
Maybe I should write a test code for testsuite...
Best regards,
--
Emi SUZUKI
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
@ 2007-02-17 2:24 Luis Machado
2007-02-27 13:00 ` Emi SUZUKI
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-02-17 2:24 UTC (permalink / raw)
To: gdb-patches
Emi,
I tried your patch against the CVS head. GDB seems to handle this set of
instructions just fine:
0x40000119a00 <._IO_puts+80>: beq- cr7,0x40000119a3c <._IO_puts
+140>
0x40000119a04 <._IO_puts+84>: li r0,1
0x40000119a08 <._IO_puts+88>: lwarx r11,0,r3
0x40000119a0c <._IO_puts+92>: cmpw r11,r9
0x40000119a10 <._IO_puts+96>: bne- 0x40000119a1c <._IO_puts+108>
0x40000119a14 <._IO_puts+100>: stwcx. r0,0,r3
0x40000119a18 <._IO_puts+104>: bne+ 0x40000119a08 <._IO_puts+88>
0x40000119a1c <._IO_puts+108>: isync
0x40000119a20 <._IO_puts+112>: cmpwi cr7,r11,0
0x40000119a24 <._IO_puts+116>: bne- cr7,0x40000119b84 <._IO_puts
+468>
If i step through "lwarx", i end up with this:
Stepping over an atomic sequence of instructions.
Beginning at 0x0000040000119a08, break at 0x0000040000119a18 next time.
0x0000040000119a18 in ._IO_puts () from /lib64/power5/libc.so.6
So far so good. But if we continue executing the program we will
eventually reach a set of instructions like this one:
0x40000119ae8 <._IO_puts+312>: lwarx r9,0,r3
0x40000119aec <._IO_puts+316>: stwcx. r0,0,r3
0x40000119af0 <._IO_puts+320>: bne+ 0x40000119ae8 <._IO_puts+312>
At this point, GDB keeps stepping through the lwarx and stwcx
instructions endlessly. If i hit continue right after the first
breakpoint (0x40000119a08), the program ends normally
I tested the same instruction block with Paul's patch and this did not
happen, stating that it skipped the atomic instruction set as usual, and
ending the program.
I'm trying to figure out what is going on exactly.
Regards,
Luis
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-17 2:24 Luis Machado
@ 2007-02-27 13:00 ` Emi SUZUKI
2007-02-27 13:17 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Emi SUZUKI @ 2007-02-27 13:00 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 1443 bytes --]
Luis,
Thank you for testing and sorry for being late to be back on this.
From: Luis Machado <luisgpm at linux.vnet.ibm.com>
Subject: Re: [patch] "single step" atomic instruction sequences as a whole.
Date: Sat, 17 Feb 2007 00:23:19 -0200
> So far so good. But if we continue executing the program we will
> eventually reach a set of instructions like this one:
>
> 0x40000119ae8 <._IO_puts+312>: lwarx r9,0,r3
> 0x40000119aec <._IO_puts+316>: stwcx. r0,0,r3
> 0x40000119af0 <._IO_puts+320>: bne+ 0x40000119ae8 <._IO_puts+312>
>
> At this point, GDB keeps stepping through the lwarx and stwcx
> instructions endlessly. If i hit continue right after the first
> breakpoint (0x40000119a08), the program ends normally
>
> I tested the same instruction block with Paul's patch and this did not
> happen, stating that it skipped the atomic instruction set as usual, and
> ending the program.
I have investigeted it and found that the code in my patch cannot
detect the region to skip from the sequence of instructions mentioned
above.
But, in fact, I have diverted that part of codes from Paul's one :-(
I have been misguided by some useless codes in that patch... Yes, I
should have made myself understand more deeply about its behavior.
Anyway, I have looked anew at that part of codes and improved it.
Please try the attached version of patchset, if you don't mind.
It's for CVS head.
Best regards,
--
Emi SUZUKI
[-- Attachment #2: rs6000-atomic-sequence_070227.diff --]
[-- Type: Text/Plain, Size: 7612 bytes --]
diff -ruN -x CVS src/gdb/config/rs6000/tm-rs6000.h gdb/gdb/config/rs6000/tm-rs6000.h
--- src/gdb/config/rs6000/tm-rs6000.h 2007-01-10 02:59:05.000000000 +0900
+++ gdb/gdb/config/rs6000/tm-rs6000.h 2007-02-27 21:52:46.000000000 +0900
@@ -90,3 +90,9 @@
extern void (*rs6000_set_host_arch_hook) (int);
+extern int rs6000_software_single_step_p (void);
+#ifdef SOFTWARE_SINGLE_STEP_P
+#undef SOFTWARE_SINGLE_STEP_P
+#endif
+#define SOFTWARE_SINGLE_STEP_P() rs6000_software_single_step_p()
+
diff -ruN -x CVS src/gdb/infrun.c gdb/gdb/infrun.c
--- src/gdb/infrun.c 2007-02-27 21:34:23.000000000 +0900
+++ gdb/gdb/infrun.c 2007-02-27 21:28:54.000000000 +0900
@@ -556,15 +556,19 @@
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
SKIP_PERMANENT_BREAKPOINT ();
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (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;
+ if (SOFTWARE_SINGLE_STEP_P ())
+ {
+ /* 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 ();
}
@@ -1566,8 +1570,6 @@
if (stepping_past_singlestep_breakpoint)
{
- 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));
@@ -1580,9 +1582,13 @@
{
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);
- singlestep_breakpoints_inserted_p = 0;
+
+ if (singlestep_breakpoints_inserted_p)
+ {
+ /* Pull the single step breakpoints out of the target. */
+ SOFTWARE_SINGLE_STEP (0, 0);
+ singlestep_breakpoints_inserted_p = 0;
+ }
ecs->random_signal = 0;
@@ -1616,7 +1622,7 @@
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
@@ -1687,7 +1693,7 @@
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
@@ -1736,7 +1742,7 @@
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
@@ -1758,7 +1764,7 @@
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
diff -ruN -x CVS src/gdb/rs6000-tdep.c gdb/gdb/rs6000-tdep.c
--- src/gdb/rs6000-tdep.c 2007-02-21 12:01:58.000000000 +0900
+++ gdb/gdb/rs6000-tdep.c 2007-02-27 21:00:20.000000000 +0900
@@ -701,6 +701,64 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define LDARX_INSTRUCTION 0x7C000108
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+CORE_ADDR
+rs6000_deal_with_atomic_sequence (CORE_ADDR pc)
+{
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int i;
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return -1;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* At most one conditional branch instuction appears between
+ the lwarx/ldarx and stwcx/stdcx instructions. But its target
+ address should be where the second conditional branch goes
+ when the branch is not taken. */
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ return loc;
+}
+
+/* SOFTWARE_SINGLE_STEP_P */
+int
+rs6000_software_single_step_p (void)
+{
+ return (rs6000_deal_with_atomic_sequence (read_pc ()) != -1);
+}
/* AIX does not support PT_STEP. Simulate it. */
@@ -720,15 +778,29 @@
{
loc = read_pc ();
- insn = read_memory_integer (loc, 4);
+ /* check if running on an atomic sequence of instructions */
+ breaks[0] = rs6000_deal_with_atomic_sequence (loc);
- 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;
+ if (breaks[0] != -1)
+ {
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions. \n\
+Beginning at %s, break at %s next time.\n"),
+ core_addr_to_string (loc),
+ core_addr_to_string (breaks[0]));
+ gdb_flush (gdb_stdout);
+ breaks[1] = -1;
+ }
+ else
+ {
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ 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;
+ }
for (ii = 0; ii < 2; ++ii)
{
@@ -3446,6 +3518,7 @@
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
for the descriptor and ".FN" for the entry-point -- a user
@@ -3530,3 +3603,4 @@
gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep);
gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep);
}
+
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-27 13:00 ` Emi SUZUKI
@ 2007-02-27 13:17 ` Daniel Jacobowitz
2007-02-28 8:08 ` Emi SUZUKI
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-02-27 13:17 UTC (permalink / raw)
To: Emi SUZUKI; +Cc: gdb-patches
On Tue, Feb 27, 2007 at 10:00:28PM +0900, Emi SUZUKI wrote:
> Anyway, I have looked anew at that part of codes and improved it.
> Please try the attached version of patchset, if you don't mind.
> It's for CVS head.
Please forgive me if I've asked you this question before, but do you
have (or are you willing to get) a GDB copyright assignment? I don't
think we can accept a patch of this size without one.
If not, that's OK - I'm sure we can come up with something.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-27 13:17 ` Daniel Jacobowitz
@ 2007-02-28 8:08 ` Emi SUZUKI
2007-02-28 11:46 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Emi SUZUKI @ 2007-02-28 8:08 UTC (permalink / raw)
To: drow; +Cc: gdb-patches
Daniel,
I'm glad to hear from you about the size of patch for which the
assignment is needed.
From: Daniel Jacobowitz <drow at false.org>
Subject: Re: [patch] "single step" atomic instruction sequences as a whole.
Date: Tue, 27 Feb 2007 08:17:24 -0500
> Please forgive me if I've asked you this question before, but do you
> have (or are you willing to get) a GDB copyright assignment? I don't
> think we can accept a patch of this size without one.
I have received a form from FSF for it (and got a sticker of gnu), and
the legal process in the campany is going on. But unfortunately, my
boss told me that it will take long (he said that it means 3 months at
worst...)
Meanwhile they also demand me to make some contribution to the mainline.
So now I think I have a ground to ask for them to hurry.
My best regards,
--
Emi SUZUKI
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-28 8:08 ` Emi SUZUKI
@ 2007-02-28 11:46 ` Daniel Jacobowitz
2007-02-28 16:09 ` Luis Machado
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-02-28 11:46 UTC (permalink / raw)
To: Emi SUZUKI; +Cc: gdb-patches
On Wed, Feb 28, 2007 at 05:07:13PM +0900, Emi SUZUKI wrote:
> I have received a form from FSF for it (and got a sticker of gnu), and
> the legal process in the campany is going on. But unfortunately, my
> boss told me that it will take long (he said that it means 3 months at
> worst...)
Unfortunately this is common :-( Thank you - I'm glad to hear it is
in progress. We'll wait.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-28 11:46 ` Daniel Jacobowitz
@ 2007-02-28 16:09 ` Luis Machado
2007-03-02 12:47 ` Emi SUZUKI
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-02-28 16:09 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2874 bytes --]
Hi,
I refreshed Paul's patches to apply cleanly on HEAD. I did a test run
and it still works as expected.
->
(gdb) start
(gdb) x/g &puts
0x400001dc1d8 <puts>: 0x00000400000e99b0
(gdb) x/10i 0x00000400000e99b0 + 80
0x400000e9a00 <._IO_puts+80>: beq- cr7,0x400000e9a3c <._IO_puts+140>
0x400000e9a04 <._IO_puts+84>: li r0,1
0x400000e9a08 <._IO_puts+88>: lwarx r11,0,r3
0x400000e9a0c <._IO_puts+92>: cmpw r11,r9
0x400000e9a10 <._IO_puts+96>: bne- 0x400000e9a1c <._IO_puts+108>
0x400000e9a14 <._IO_puts+100>: stwcx. r0,0,r3
0x400000e9a18 <._IO_puts+104>: bne+ 0x400000e9a08 <._IO_puts+88>
0x400000e9a1c <._IO_puts+108>: isync
0x400000e9a20 <._IO_puts+112>: cmpwi cr7,r11,0
0x400000e9a24 <._IO_puts+116>: bne- cr7,0x400000e9b84 <._IO_puts+468>
(gdb) b *0x400000e9a04
Breakpoint 2 at 0x400000e9a04
(gdb) c
Continuing.
Breakpoint 2, 0x00000400000e9a04 in ._IO_puts () from /lib64/power5/libc.so.6
(gdb) si
0x00000400000e9a08 in ._IO_puts () from /lib64/power5/libc.so.6
(gdb)
Stepping over an atomic sequence of instructions beginning at 0x00000400000e9a08
0x00000400000e9a18 in ._IO_puts () from /lib64/power5/libc.so.6
(gdb) x/5i 0x00000400000e9a08
0x400000e9a08 <._IO_puts+88>: lwarx r11,0,r3
0x400000e9a0c <._IO_puts+92>: cmpw r11,r9
0x400000e9a10 <._IO_puts+96>: bne- 0x400000e9a1c <._IO_puts+108>
0x400000e9a14 <._IO_puts+100>: stwcx. r0,0,r3
0x400000e9a18 <._IO_puts+104>: bne+ 0x400000e9a08 <._IO_puts+88>
(gdb)
<-
Also, i haven't been able to reproduce the issue related at this post:
(http://sourceware.org/ml/gdb-patches/2006-09/msg00060.html)
This is the test run on my power machine. No Internal errors at this
time.
->
(gdb) start
Breakpoint 1 at 0x10000674: file atomic.c, line 9.
Starting program: /home/luis/binaries/atomic64
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
warning: Breakpoint address adjusted from 0x10010b58 to 0x100004f0.
main (argc=1, argv=0xfffff8351e8 "") at atomic.c:9
9 printf("atomic_step_test\n");
(gdb) n
atomic_step_test
10 atomic_set(&i,5);
(gdb)
11 printf("i=%d\n",atomic_read(&i));
(gdb)
i=5
12 atomic_dec(&i);
(gdb)
13 printf("i=%d\n",atomic_read(&i));
(gdb)
i=4
16 }
(gdb)
0x00000400000a0c8c in .generic_start_main ()
from /lib64/power5/libc.so.6
(gdb)
Single stepping until exit from function .generic_start_main,
which has no line number information.
0x00000400000150f0 in ._dl_fini () from /lib64/ld64.so.1
(gdb)
Single stepping until exit from function ._dl_fini,
which has no line number information.
Stepping over an atomic sequence of instructions beginning at
0x00000400000fa69c
Stepping over an atomic sequence of instructions beginning at
0x00000400000fa820
Program exited with code 04.
(gdb)
<-
Regards,
Luis
[-- Attachment #2: change-software-single-step.diff --]
[-- Type: text/x-patch, Size: 16370 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* gdbarch.sh: Change the return type of software_single_step from
void to int and reformatted some comments to <= 80 columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Change the return type
from void to int and always return 1.
* alpha-tdep.h: Change the return type of alpha_software_single_step
from void to int.
* arm-tdep.c (arm_software_single_step): Change the return type from
void to int and always return 1.
* cris-tdep.c (cris_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.c (mips_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.h: Change the return type of mips_software_single_step
from void to int.
* rs6000-tdep.c (rs6000_software_single_step): Change the return type
from void to int and always return 1.
*rs6000-tdep.h: Change the return type of rs6000_software_single_step
from void to int.
* sparc-tdep.c (sparc_software_single_step): Change the return type
from void to int and always return 1.
* sparc-tdep.h: Change the return type of sparc_software_single_step
from void to int.
* wince.c (wince_software_single_step {three times}): Change the
return type from void to int and always return 1.
infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly. True means that the software_single_step
breakpoints where inserted; false means they where not.
Index: alpha-tdep.c
===================================================================
--- alpha-tdep.c.orig
+++ alpha-tdep.c
@@ -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;
}
\f
Index: alpha-tdep.h
===================================================================
--- alpha-tdep.h.orig
+++ alpha-tdep.h
@@ -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 *);
Index: arm-tdep.c
===================================================================
--- arm-tdep.c.orig
+++ arm-tdep.c
@@ -1905,7 +1905,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
@@ -1920,6 +1920,8 @@ arm_software_single_step (enum target_si
}
else
remove_single_step_breakpoints ();
+
+ return 1
}
#include "bfd-in2.h"
Index: cris-tdep.c
===================================================================
--- cris-tdep.c.orig
+++ cris-tdep.c
@@ -2117,7 +2117,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;
@@ -2150,6 +2150,8 @@ cris_software_single_step (enum target_s
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdbarch.c
===================================================================
--- gdbarch.c.orig
+++ gdbarch.c
@@ -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
Index: gdbarch.h
===================================================================
--- gdbarch.h.orig
+++ gdbarch.h
@@ -1144,14 +1144,16 @@ 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. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1168,8 +1170,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"
Index: gdbarch.sh
===================================================================
--- gdbarch.sh.orig
+++ gdbarch.sh
@@ -614,15 +614,19 @@ 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.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# 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:=: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
Index: infrun.c
===================================================================
--- infrun.c.orig
+++ infrun.c
@@ -559,14 +559,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
@@ -1390,7 +1392,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;
@@ -1410,7 +1412,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;
@@ -1581,7 +1583,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;
@@ -1690,7 +1692,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;
}
@@ -1761,7 +1763,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;
}
Index: mips-tdep.c
===================================================================
--- mips-tdep.c.orig
+++ mips-tdep.c
@@ -2200,7 +2200,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;
@@ -2214,6 +2214,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
Index: mips-tdep.h
===================================================================
--- mips-tdep.h.orig
+++ mips-tdep.h
@@ -103,7 +103,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. */
Index: rs6000-tdep.c
===================================================================
--- rs6000-tdep.c.orig
+++ rs6000-tdep.c
@@ -704,7 +704,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)
{
@@ -743,6 +743,8 @@ rs6000_software_single_step (enum target
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+
+ return 1;
}
Index: rs6000-tdep.h
===================================================================
--- rs6000-tdep.h.orig
+++ rs6000-tdep.h
@@ -21,6 +21,6 @@
#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);
Index: sparc-tdep.c
===================================================================
--- sparc-tdep.c.orig
+++ sparc-tdep.c
@@ -1179,7 +1179,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;
@@ -1209,6 +1209,8 @@ sparc_software_single_step (enum target_
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
--- sparc-tdep.h.orig
+++ sparc-tdep.h
@@ -167,8 +167,8 @@ extern struct sparc_frame_cache *
\f
-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);
Index: wince.c
===================================================================
--- wince.c.orig
+++ wince.c
@@ -839,7 +839,7 @@ undoSStep (thread_info * th)
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -851,14 +851,15 @@ wince_software_single_step (enum target_
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = mips_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif SHx
/* Renesas SH architecture instruction encoding masks */
@@ -980,7 +981,7 @@ undoSStep (thread_info * th)
instruction and setting a breakpoint on the "next" instruction
which would be executed. This code hails from sh-stub.c.
*/
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -990,13 +991,14 @@ wince_software_single_step (enum target_
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
th->step_pc = sh_get_next_pc (&th->context);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif defined (ARM)
#undef check_for_step
@@ -1027,7 +1029,7 @@ undoSStep (thread_info * th)
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -1039,14 +1041,15 @@ wince_software_single_step (enum target_
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = arm_get_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#endif
[-- Attachment #3: ppc-atomic.single-step.diff --]
[-- Type: text/x-patch, Size: 3409 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* ppc-linux-tdep.c (ppc_atomic_single_step): New function.
(ppc_linux_init_abi): Set software_single_step member of the gdbarch
vector to the new ppc_atomic_single_step function.
Index: ppc-linux-tdep.c
===================================================================
--- ppc-linux-tdep.c.orig
+++ ppc-linux-tdep.c
@@ -931,6 +931,84 @@ ppc_linux_sigtramp_cache (struct frame_i
trad_frame_set_id (this_cache, frame_id_build (base, func));
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+ppc_atomic_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+ if (insert_breakpoints_p)
+ {
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_insn (loc);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_insn (loc);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_insn (loc);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+ }
+ else
+ remove_single_step_breakpoints ();
+
+ return 1;
+}
+
static void
ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
struct frame_info *next_frame,
@@ -1084,6 +1162,10 @@ ppc_linux_init_abi (struct gdbarch_info
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
+
+ /* Enable software_single_step in case someone tries to sngle step a
+ sequence of instructions that should be atomic. */
+ set_gdbarch_software_single_step (gdbarch, ppc_atomic_single_step);
}
void
[-- Attachment #4: rs6000-atomic-single-step.diff --]
[-- Type: text/x-patch, Size: 2855 bytes --]
--- old_rs6000-tdep.c 2006-06-22 13:16:03.000000000 -0700
+++ rs6000-tdep.c 2006-06-22 13:41:10.000000000 -0700
@@ -701,8 +701,81 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+deal_with_atomic_sequence (enum target_signal sig)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, 4);
+ int last_break = 0;
+ int i;
+
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION)
+ return 0;
-/* AIX does not support PT_STEP. Simulate it. */
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, 4);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't but
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i= 0; i < last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+ gdb_flush (gdb_stdout);
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it, dealing with any sequence of
+ instructions that must be atomic. */
int
rs6000_software_single_step (enum target_signal signal,
@@ -722,6 +795,9 @@
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (signal))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-02-28 16:09 ` Luis Machado
@ 2007-03-02 12:47 ` Emi SUZUKI
2007-03-06 11:00 ` Andreas Schwab
0 siblings, 1 reply; 43+ messages in thread
From: Emi SUZUKI @ 2007-03-02 12:47 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 2315 bytes --]
Hello Luis,
From: Luis Machado <luisgpm at linux dot vnet dot ibm dot com>
Subject: Re: [patch] "single step" atomic instruction sequences as a whole.
Date: Wed, 28 Feb 2007 13:09:00 -0300
> Also, i haven't been able to reproduce the issue related at this post:
> (http://sourceware.org/ml/gdb-patches/2006-09/msg00060.html)
I think one of the reasons why is that you didn't build the target as
Emre did; 'atomic_dec' seemed to be inline expanded in that target.
I could get it with -O3 option of gcc-4.1.0 on my machine running FC5.
And I could reproduce the issue with your patch by setting a
breakpoint at where 'printf' preceded by 'atomic_dec' is before
running the target.
But the fix is fairly easy:
===================================================================
diff -u rs6000-tdep.c.old rs6000-tdep.c
--- rs6000-tdep.c.old 2007-03-02 19:33:12.000000000 +0900
+++ rs6000-tdep.c 2007-03-02 19:34:07.000000000 +0900
@@ -764,7 +764,7 @@
if (last_break && breaks[1] == breaks[0])
last_break = 0;
- for (i= 0; i < last_break; ++i)
+ for (i= 0; i <= last_break; ++i)
insert_single_step_breakpoint (breaks[i]);
printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
diff -u ppc-linux-tdep.c.old ppc-linux-tdep.c
--- ppc-linux-tdep.c.old 2007-03-02 19:33:33.000000000 +0900
+++ ppc-linux-tdep.c 2007-03-02 19:33:54.000000000 +0900
@@ -996,7 +996,7 @@
if (last_break && breaks[1] == breaks[0])
last_break = 0;
- for (i= 0; i < last_break; ++i)
+ for (i= 0; i <= last_break; ++i)
insert_single_step_breakpoint (breaks[i]);
printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
===================================================================
Another thing I want to notice you about Paul's patch is that the
patch for ppc-linux-tdep.c is not needed at all: they do exactly the
same and RS6000 is the superset of PowerPC.
And I think that the load or store instructions which deal with
doublewords can be appeared as a part of the atomic sequence; Paul's
patch doesn't check it. But maybe not needed for now.
BTW, I had another mistake on my patch send last time...
Please replace the attached one.
My best regards,
--
Emi SUZUKI
[-- Attachment #2: rs6000-atomic-sequence_070302.diff --]
[-- Type: Text/Plain, Size: 7042 bytes --]
diff -uBbEw -ruN -x CVS src/gdb/config/rs6000/tm-rs6000.h gdb/gdb/config/rs6000/tm-rs6000.h
--- src/gdb/config/rs6000/tm-rs6000.h 2007-03-02 21:42:44.000000000 +0900
+++ gdb/gdb/config/rs6000/tm-rs6000.h 2007-03-02 21:17:31.000000000 +0900
@@ -30,3 +30,9 @@
#define PROCESS_LINENUMBER_HOOK() aix_process_linenos ()
extern void aix_process_linenos (void);
+extern int rs6000_software_single_step_p (void);
+
+#ifdef SOFTWARE_SINGLE_STEP_P
+#undef SOFTWARE_SINGLE_STEP_P
+#endif
+#define SOFTWARE_SINGLE_STEP_P() rs6000_software_single_step_p()
diff -uBbEw -ruN -x CVS src/gdb/infrun.c gdb/gdb/infrun.c
--- src/gdb/infrun.c 2007-03-02 21:42:43.000000000 +0900
+++ gdb/gdb/infrun.c 2007-03-02 21:28:25.000000000 +0900
@@ -556,7 +556,9 @@
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
SKIP_PERMANENT_BREAKPOINT ();
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (step)
+ {
+ if (SOFTWARE_SINGLE_STEP_P ())
{
/* Do it the hard way, w/temp breakpoints */
SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
@@ -565,6 +567,8 @@
/* 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 ();
}
@@ -1565,8 +1569,6 @@
if (stepping_past_singlestep_breakpoint)
{
- 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));
@@ -1579,9 +1581,13 @@
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
+
+ if (singlestep_breakpoints_inserted_p)
+ {
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
+ }
ecs->random_signal = 0;
@@ -1615,7 +1621,7 @@
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
@@ -1686,7 +1692,7 @@
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
@@ -1735,7 +1741,7 @@
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
@@ -1757,7 +1763,7 @@
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
diff -uBbEw -ruN -x CVS src/gdb/rs6000-tdep.c gdb/gdb/rs6000-tdep.c
--- src/gdb/rs6000-tdep.c 2007-03-02 21:42:45.000000000 +0900
+++ gdb/gdb/rs6000-tdep.c 2007-03-02 21:15:39.000000000 +0900
@@ -696,6 +696,79 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define LDARX_INSTRUCTION 0x7C000108
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+CORE_ADDR
+rs6000_deal_with_atomic_sequence (CORE_ADDR pc, CORE_ADDR *branch)
+{
+ CORE_ADDR loc = pc;
+ CORE_ADDR bc = -1;
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int i;
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return -1;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* At most one conditional branch instruction is between the lwarx
+ and stwcx. instructions. */
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ bc = IMMEDIATE_PART (insn);
+ if (!ABSOLUTE_P (insn))
+ bc += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ error (_("Tried to step over an atomic sequence of instructions but it did not end as expected."));
+
+ /* set the location of conditional branch instruction between the lwarx
+ and stwcx. instruction if any. */
+ if (bc != loc)
+ *branch = bc;
+ else
+ *branch = -1;
+
+ return loc;
+}
+
+/* SOFTWARE_SINGLE_STEP_P */
+int
+rs6000_software_single_step_p (void)
+{
+ CORE_ADDR branch;
+ return (rs6000_deal_with_atomic_sequence (read_pc (), &branch) != -1);
+}
/* AIX does not support PT_STEP. Simulate it. */
@@ -715,8 +788,20 @@
{
loc = read_pc ();
- insn = read_memory_integer (loc, 4);
+ /* check if running on an atomic sequence of instructions */
+ breaks[0] = rs6000_deal_with_atomic_sequence (loc, &breaks[1]);
+ if (breaks[0] != -1)
+ {
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions. \n\
+Beginning at %s, break at %s next time.\n"),
+ core_addr_to_string (loc),
+ core_addr_to_string (breaks[0]));
+ gdb_flush (gdb_stdout);
+ }
+ else
+ {
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
@@ -724,6 +809,7 @@
/* Don't put two breakpoints on the same address. */
if (breaks[1] == breaks[0])
breaks[1] = -1;
+ }
for (ii = 0; ii < 2; ++ii)
{
@@ -3442,6 +3529,7 @@
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
for the descriptor and ".FN" for the entry-point -- a user
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-03-02 12:47 ` Emi SUZUKI
@ 2007-03-06 11:00 ` Andreas Schwab
2007-03-06 12:24 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Andreas Schwab @ 2007-03-06 11:00 UTC (permalink / raw)
To: Emi SUZUKI; +Cc: gdb-patches
Emi SUZUKI <emi-suzuki@tjsys.co.jp> writes:
> + /* Assume that the atomic sequence ends with a stwcx instruction
> + followed by a conditional branch instruction. */
> + if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
> + error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
I don't think error should be called here. It would probably be better to
just continue with the normal single-step here.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, MaxfeldstraÃe 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-03-06 11:00 ` Andreas Schwab
@ 2007-03-06 12:24 ` Daniel Jacobowitz
2007-03-08 8:50 ` Emi SUZUKI
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-03-06 12:24 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Emi SUZUKI, gdb-patches
On Tue, Mar 06, 2007 at 12:00:21PM +0100, Andreas Schwab wrote:
> Emi SUZUKI <emi-suzuki@tjsys.co.jp> writes:
>
> > + /* Assume that the atomic sequence ends with a stwcx instruction
> > + followed by a conditional branch instruction. */
> > + if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
> > + error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
>
> I don't think error should be called here. It would probably be better to
> just continue with the normal single-step here.
Maybe a (once-only) warning? It would be nice to let the user know
we're confused.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-03-06 12:24 ` Daniel Jacobowitz
@ 2007-03-08 8:50 ` Emi SUZUKI
2007-03-08 16:15 ` Ulrich Weigand
0 siblings, 1 reply; 43+ messages in thread
From: Emi SUZUKI @ 2007-03-08 8:50 UTC (permalink / raw)
To: drow; +Cc: schwab, gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 1893 bytes --]
Andreas and Daniel,
Thank you for the comments.
From: Daniel Jacobowitz <drow at false.org>
Subject: Re: [patch] "single step" atomic instruction sequences as a whole.
Date: Tue, 06 Mar 2007 07:24:36 -0500
> On Tue, Mar 06, 2007 at 12:00:21PM +0100, Andreas Schwab wrote:
> > > + /* Assume that the atomic sequence ends with a stwcx instruction
> > > + followed by a conditional branch instruction. */
> > > + if ((insn & STWCX_MASK) != STWCX_INSTRUCTION)
> > > + error (_("Tried to step over an atomic sequence of instructions but could not find the end of the sequence."));
> >
> > I don't think error should be called here. It would probably be better to
> > just continue with the normal single-step here.
>
> Maybe a (once-only) warning? It would be nice to let the user know
> we're confused.
That's the last thing I have wondered what to do with respect to
Paul's patch.
Maybe any errors should not be called in that function, because the
function is just for checking if there is any sequence of instructions
that should be avoided running through. I have no idea about the
warning, though, it might be a help for debugging some of complecated
issues.
Anyway, I found that calling warning instead of error, and returning -1
(indecates that any atomic sequences are not found) after warning
fulfills both suggestions. I have done with the attached.
Meanwhile the things about RS6000-AIX came to me: it does not support
hardware single stepping, so SOFTWARE_SINGLE_STEP_P should always
return true. My patch has nothing to concern about it...
I have added a new file, tm-rs6000aix.h, to undef SOFTWARE_SINGLE_STEP_P
for only that target, but felt somewhat strange about the solution.
I feel like adding some trick for SOFTWARE_SINGLE_STEP_P to gdbarch.c
rather than undef'ing it, but no idea has come to mind for now.
My best regards,
--
Emi SUZUKI
[-- Attachment #2: rs6000-atomic-sequence_070308.diff --]
[-- Type: Text/Plain, Size: 10745 bytes --]
diff -ruN -x CVS -x '*~' src/gdb/config/powerpc/aix.mt gdb/gdb/config/powerpc/aix.mt
--- src/gdb/config/powerpc/aix.mt 2006-02-11 05:56:15.000000000 +0900
+++ gdb/gdb/config/powerpc/aix.mt 2007-03-08 16:18:37.000000000 +0900
@@ -1,4 +1,4 @@
# Target: PowerPC running AIX
TDEPFILES= rs6000-tdep.o rs6000-aix-tdep.o \
xcoffread.o ppc-sysv-tdep.o solib.o solib-svr4.o
-DEPRECATED_TM_FILE= config/rs6000/tm-rs6000.h
+DEPRECATED_TM_FILE= config/rs6000/tm-rs6000aix.h
diff -ruN -x CVS -x '*~' src/gdb/config/rs6000/tm-rs6000.h gdb/gdb/config/rs6000/tm-rs6000.h
--- src/gdb/config/rs6000/tm-rs6000.h 2007-03-02 21:42:44.000000000 +0900
+++ gdb/gdb/config/rs6000/tm-rs6000.h 2007-03-06 20:43:40.000000000 +0900
@@ -30,3 +30,9 @@
#define PROCESS_LINENUMBER_HOOK() aix_process_linenos ()
extern void aix_process_linenos (void);
+extern int rs6000_software_single_step_p (void);
+
+#ifdef SOFTWARE_SINGLE_STEP_P
+#undef SOFTWARE_SINGLE_STEP_P
+#endif
+#define SOFTWARE_SINGLE_STEP_P() rs6000_software_single_step_p()
diff -ruN -x CVS -x '*~' src/gdb/config/rs6000/tm-rs6000aix.h gdb/gdb/config/rs6000/tm-rs6000aix.h
--- src/gdb/config/rs6000/tm-rs6000aix.h 1970-01-01 09:00:00.000000000 +0900
+++ gdb/gdb/config/rs6000/tm-rs6000aix.h 2007-03-08 17:24:14.000000000 +0900
@@ -0,0 +1,33 @@
+/* Macro definitions for RS6000 running under AIX.
+ Copyright 2007 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef TM_RS6000AIX_H
+#define TM_RS6000AIX_H
+
+/* Use generic RS6000 definitions. */
+#include "rs6000/tm-rs6000.h"
+
+/* Almost all OS running on RS6000/PPC supports handling hardware single
+ step, but sometimes use software single step for skipping atomic
+ sequences of instructions. Only RS6000-AIX always use software single
+ step, so we use the default function for it. */
+#undef SOFTWARE_SINGLE_STEP_P
+
+#endif /* TM_RS6000AIX_H */
diff -ruN -x CVS -x '*~' src/gdb/infrun.c gdb/gdb/infrun.c
--- src/gdb/infrun.c 2007-03-02 21:42:43.000000000 +0900
+++ gdb/gdb/infrun.c 2007-03-02 21:28:25.000000000 +0900
@@ -556,15 +556,19 @@
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
SKIP_PERMANENT_BREAKPOINT ();
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (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;
+ if (SOFTWARE_SINGLE_STEP_P ())
+ {
+ /* 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 ();
}
@@ -1565,8 +1569,6 @@
if (stepping_past_singlestep_breakpoint)
{
- 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));
@@ -1579,9 +1581,13 @@
{
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);
- singlestep_breakpoints_inserted_p = 0;
+
+ if (singlestep_breakpoints_inserted_p)
+ {
+ /* Pull the single step breakpoints out of the target. */
+ SOFTWARE_SINGLE_STEP (0, 0);
+ singlestep_breakpoints_inserted_p = 0;
+ }
ecs->random_signal = 0;
@@ -1615,7 +1621,7 @@
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
@@ -1686,7 +1692,7 @@
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
@@ -1735,7 +1741,7 @@
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
@@ -1757,7 +1763,7 @@
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
diff -ruN -x CVS -x '*~' src/gdb/rs6000-aix-tdep.c gdb/gdb/rs6000-aix-tdep.c
--- src/gdb/rs6000-aix-tdep.c 2007-03-02 21:42:43.000000000 +0900
+++ gdb/gdb/rs6000-aix-tdep.c 2007-03-08 16:18:21.000000000 +0900
@@ -39,9 +39,6 @@
static void
rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- /* RS6000/AIX does not support PT_STEP. Has to be simulated. */
- set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
-
/* Minimum possible text address in AIX. */
gdbarch_tdep (gdbarch)->text_segment_base = 0x10000000;
}
diff -ruN -x CVS -x '*~' src/gdb/rs6000-tdep.c gdb/gdb/rs6000-tdep.c
--- src/gdb/rs6000-tdep.c 2007-03-02 21:42:45.000000000 +0900
+++ gdb/gdb/rs6000-tdep.c 2007-03-07 18:01:01.000000000 +0900
@@ -696,6 +696,86 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define LDARX_INSTRUCTION 0x7C000108
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+CORE_ADDR
+rs6000_deal_with_atomic_sequence (CORE_ADDR pc, CORE_ADDR *branch)
+{
+ CORE_ADDR loc = pc;
+ CORE_ADDR bc = -1;
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int i;
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return -1;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* At most one conditional branch instruction is between the lwarx
+ and stwcx. instructions. */
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ bc = IMMEDIATE_PART (insn);
+ if (!ABSOLUTE_P (insn))
+ bc += loc;
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ {
+ warning (_("Tried to step over an atomic sequence of instructions from %s but could not find the end of the sequence.", core_addr_to_string (pc)));
+ return -1;
+ }
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ {
+ warning (_("Tried to step over an atomic sequence of instructions from %s but it did not end as expected.", core_addr_to_string (pc)));
+ return -1;
+ }
+
+ /* set the location of conditional branch instruction between the lwarx
+ and stwcx. instruction if any. */
+ if (bc != loc)
+ *branch = bc;
+ else
+ *branch = -1;
+
+ return loc;
+}
+
+/* SOFTWARE_SINGLE_STEP_P */
+int
+rs6000_software_single_step_p (void)
+{
+ CORE_ADDR branch;
+ return (rs6000_deal_with_atomic_sequence (read_pc (), &branch) != -1);
+}
/* AIX does not support PT_STEP. Simulate it. */
@@ -715,21 +795,35 @@
{
loc = read_pc ();
- insn = read_memory_integer (loc, 4);
+ /* check if running on an atomic sequence of instructions */
+ breaks[0] = rs6000_deal_with_atomic_sequence (loc, &breaks[1]);
- 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;
+ if (breaks[0] != -1)
+ {
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions. \n\
+Beginning at %s, break at %s next time.\n"),
+ core_addr_to_string (loc),
+ core_addr_to_string (breaks[0]));
+ gdb_flush (gdb_stdout);
+ }
+ else
+ {
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ 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;
+ }
for (ii = 0; ii < 2; ++ii)
{
/* ignore invalid breakpoint. */
if (breaks[ii] == -1)
continue;
+
insert_single_step_breakpoint (breaks[ii]);
}
}
@@ -3442,6 +3536,7 @@
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
for the descriptor and ".FN" for the entry-point -- a user
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-03-08 8:50 ` Emi SUZUKI
@ 2007-03-08 16:15 ` Ulrich Weigand
2007-03-13 6:12 ` SUZUKI Emi
0 siblings, 1 reply; 43+ messages in thread
From: Ulrich Weigand @ 2007-03-08 16:15 UTC (permalink / raw)
To: Emi SUZUKI; +Cc: drow, schwab, gdb-patches
Emi Suzuki wrote:
> Meanwhile the things about RS6000-AIX came to me: it does not support
> hardware single stepping, so SOFTWARE_SINGLE_STEP_P should always
> return true. My patch has nothing to concern about it...
>
> I have added a new file, tm-rs6000aix.h, to undef SOFTWARE_SINGLE_STEP_P
> for only that target, but felt somewhat strange about the solution.
> I feel like adding some trick for SOFTWARE_SINGLE_STEP_P to gdbarch.c
> rather than undef'ing it, but no idea has come to mind for now.
We're trying to get rid of the tm.h files, and do everything strictly
via the gdbarch callbacks. (This is also necessary for multi-arch
debugging.) I'd much prefer a solution that does not add new tm.h
files (or contents).
Why don't we extend the gdbarch_software_single_step call with a return
value? Common code would call the gdbarch routine, but if it returns
a nonzero value, it will fall back to using hardware single step after
all.
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-03-08 16:15 ` Ulrich Weigand
@ 2007-03-13 6:12 ` SUZUKI Emi
0 siblings, 0 replies; 43+ messages in thread
From: SUZUKI Emi @ 2007-03-13 6:12 UTC (permalink / raw)
To: uweigand, gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 2466 bytes --]
Hello Ulrich,
Thank you for your suggestion.
From: Ulrich Weigand <uweigand at de.ibm.com>
Subject: Re: [patch] "single step" atomic instruction sequences as a whole.
Date: Thu, 08 Mar 2007 17:15:42 +0100 (CET)
> Emi Suzuki wrote:
> > I have added a new file, tm-rs6000aix.h, to undef SOFTWARE_SINGLE_STEP_P
> > for only that target, but felt somewhat strange about the solution.
> > I feel like adding some trick for SOFTWARE_SINGLE_STEP_P to gdbarch.c
> > rather than undef'ing it, but no idea has come to mind for now.
>
> We're trying to get rid of the tm.h files, and do everything strictly
> via the gdbarch callbacks. (This is also necessary for multi-arch
> debugging.) I'd much prefer a solution that does not add new tm.h
> files (or contents).
Yes, that's exactly what I really intend, do everything via the
gdbarch callbacks.
> Why don't we extend the gdbarch_software_single_step call with a return
> value? Common code would call the gdbarch routine, but if it returns
> a nonzero value, it will fall back to using hardware single step after
> all.
It's like what the original patchset does for this issue (provided
http://sourceware.org/ml/gdb-patches/2006-06/msg00339.html and
http://sourceware.org/ml/gdb-patches/2006-06/msg00341.html).
I have felt something uncomfortable to them, because it uses
SOFTWARE_SINGLE_STEP_P to check both if the target will do software
single stepping at the next time it proceed and if the target has done
software single stepping after it get stopped.
But now I have noticed that calling gdbarch_software_single_step
*instead of* SOFTWARE_SINGLE_STEP_P will clear my confusion and avoid
adding new tm.h files. I've changed the whole solution like below:
* make gdbarch_software_single_step return 1 (means non-zero) if it
inserted software single step breakpoint, or return 0.
* defined default_software_single_step in arch-utils.c, and make it
the default of gdbarch_software_single_step.
* call SOFTWARE_SINGLE_STEP instead of SOFTWARE_SINGLE_STEP_P, to
check if software single stepping will be done when proceeding.
* put an alternative way to check if software single stepping was
done when stopped (mainly, it would be checking of
singlestep_breakpoint_inserted_p).
One thing I am not sure about my change is adjust_pc_after_break in
infrun.c. And I am not familier with the use of gdbarch.sh, it is
much appreciated if anyone would review them.
--
Emi SUZUKI
[-- Attachment #2: gdbarch_software_singlestep.diff --]
[-- Type: Text/Plain, Size: 22284 bytes --]
Index: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.223
diff -u -r1.223 infrun.c
--- gdb/infrun.c 9 Mar 2007 16:20:42 -0000 1.223
+++ gdb/infrun.c 13 Mar 2007 05:37:27 -0000
@@ -552,15 +552,18 @@
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
SKIP_PERMANENT_BREAKPOINT ();
- if (SOFTWARE_SINGLE_STEP_P () && step)
+ if (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;
+ /* Try to do it the hard way, w/temp breakpoints */
+ if (SOFTWARE_SINGLE_STEP (sig, 1 /* insert-breakpoints */))
+ {
+ /* Succeeded, so 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 ();
}
@@ -1196,22 +1199,18 @@
breakpoint would be. */
breakpoint_pc = read_pc_pid (ecs->ptid) - DECR_PC_AFTER_BREAK;
- if (SOFTWARE_SINGLE_STEP_P ())
+ if (singlestep_breakpoints_inserted_p)
{
/* When using software single-step, a SIGTRAP can only indicate
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
- [prev_pc] (in program execution order) always is. Assume
- that following instruction was reached and hence a software
- breakpoint was hit. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
- else if (software_breakpoint_inserted_here_p (breakpoint_pc))
- /* The inferior was free running (i.e., no single-step
- breakpoints inserted) and it hit a software breakpoint. */
- write_pc_pid (breakpoint_pc, ecs->ptid);
+
+ /* When software single stepping, the instruction at [prev_pc]
+ is never a breakpoint, but the instruction following
+ [prev_pc] (in program execution order) always is. Assume
+ that following instruction was reached and hence a software
+ breakpoint was hit. */
+ write_pc_pid (breakpoint_pc, ecs->ptid);
}
else
{
@@ -1405,7 +1404,7 @@
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() */
stop_stepping (ecs);
return;
@@ -1561,8 +1560,6 @@
if (stepping_past_singlestep_breakpoint)
{
- 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));
@@ -1575,9 +1572,13 @@
{
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);
- singlestep_breakpoints_inserted_p = 0;
+
+ if (singlestep_breakpoints_inserted_p)
+ {
+ /* Pull the single step breakpoints out of the target. */
+ SOFTWARE_SINGLE_STEP (0, 0);
+ singlestep_breakpoints_inserted_p = 0;
+ }
ecs->random_signal = 0;
@@ -1611,7 +1612,7 @@
if (!breakpoint_thread_match (stop_pc, ecs->ptid))
thread_hop_needed = 1;
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
/* We have not context switched yet, so this should be true
no matter which thread hit the singlestep breakpoint. */
@@ -1682,7 +1683,7 @@
/* Saw a breakpoint, but it was hit by the wrong thread.
Just continue. */
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
@@ -1731,7 +1732,7 @@
return;
}
}
- else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ else if (singlestep_breakpoints_inserted_p)
{
sw_single_step_trap_p = 1;
ecs->random_signal = 0;
@@ -1753,7 +1754,7 @@
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
}
- if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
+ if (singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
SOFTWARE_SINGLE_STEP (0, 0);
Index: gdb/cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.138
diff -u -r1.138 cris-tdep.c
--- gdb/cris-tdep.c 27 Feb 2007 20:17:18 -0000 1.138
+++ gdb/cris-tdep.c 13 Mar 2007 05:36:05 -0000
@@ -2119,7 +2119,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdb/rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.265
diff -u -r1.265 rs6000-tdep.c
--- gdb/rs6000-tdep.c 27 Feb 2007 23:04:28 -0000 1.265
+++ gdb/rs6000-tdep.c 13 Mar 2007 05:38:22 -0000
@@ -696,10 +696,101 @@
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define LDARX_INSTRUCTION 0x7C000108
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+
+int
+rs6000_deal_with_atomic_sequence (enum target_signal signal,
+ int insert_breakpoints_p)
+{
+ CORE_ADDR loc, pc;
+ int i, insn;
+ CORE_ADDR breaks[2] = { -1, -1 };
+
+ if (insert_breakpoints_p)
+ {
+ pc = read_pc ();
+ loc = pc;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* Assume all atomic sequences start with an lwarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i= 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* At most one conditional branch instruction is between the lwarx
+ and stwcx. instructions. */
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ int opcode = BC_INSTRUCTION >> 26;
+ breaks[1] = branch_dest (opcode, insn, loc, -1);
+ continue;
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
+ {
+ warning (_("Tried to step over an atomic sequence of instructions from %s but could not find the end of the sequence."), core_addr_to_string (pc));
+ return 0;
+ }
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ {
+ warning (_("Tried to step over an atomic sequence of instructions from %s but it did not end as expected."), core_addr_to_string (pc));
+ return 0;
+ }
+
+ breaks[0] = loc;
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions. \n\
+Beginning at %s, break at %s next time.\n"),
+ core_addr_to_string (pc),
+ core_addr_to_string (breaks[0]));
+
+ /* It cannot be happened, but just check it */
+ if (breaks[1] == loc)
+ breaks[1] = -1;
+
+ for (i = 0; i < 2; ++i)
+ {
+ /* ignore invalid breakpoint. */
+ if (breaks[i] == -1)
+ continue;
+
+ insert_single_step_breakpoint (breaks[i]);
+ }
+ }
+ else
+ remove_single_step_breakpoints ();
+
+ /* software single step breakpoint is inserted or removed */
+ return 1;
+}
/* AIX does not support PT_STEP. Simulate it. */
-void
+int
rs6000_software_single_step (enum target_signal signal,
int insert_breakpoints_p)
{
@@ -711,6 +802,10 @@
CORE_ADDR breaks[2];
int opcode;
+ /* check if running through the atomic sequence of instructions first. */
+ if (rs6000_deal_with_atomic_sequence (signal, insert_breakpoints_p))
+ return 1;
+
if (insert_breakpoints_p)
{
loc = read_pc ();
@@ -738,6 +833,8 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+
+ return 1;
}
@@ -3442,6 +3539,7 @@
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ set_gdbarch_software_single_step (gdbarch, rs6000_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
Index: gdb/mips-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.h,v
retrieving revision 1.19
diff -u -r1.19 mips-tdep.h
--- gdb/mips-tdep.h 9 Jan 2007 17:58:52 -0000 1.19
+++ gdb/mips-tdep.h 13 Mar 2007 05:38:01 -0000
@@ -103,7 +103,7 @@
};
/* 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. */
Index: gdb/spu-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/spu-tdep.c,v
retrieving revision 1.10
diff -u -r1.10 spu-tdep.c
--- gdb/spu-tdep.c 9 Mar 2007 03:51:04 -0000 1.10
+++ gdb/spu-tdep.c 13 Mar 2007 05:38:39 -0000
@@ -1078,7 +1078,7 @@
/* Software single-stepping support. */
-void
+int
spu_software_single_step (enum target_signal signal, int insert_breakpoints_p)
{
if (insert_breakpoints_p)
@@ -1093,7 +1093,7 @@
pc = extract_unsigned_integer (buf, 4) & -4;
if (target_read_memory (pc, buf, 4))
- return;
+ return 0;
insn = extract_unsigned_integer (buf, 4);
/* Next sequential instruction is at PC + 4, except if the current
@@ -1125,6 +1125,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
Index: gdb/sparc64-sol2-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-sol2-tdep.c,v
retrieving revision 1.11
diff -u -r1.11 sparc64-sol2-tdep.c
--- gdb/sparc64-sol2-tdep.c 9 Jan 2007 17:58:58 -0000 1.11
+++ gdb/sparc64-sol2-tdep.c 13 Mar 2007 05:38:33 -0000
@@ -170,7 +170,7 @@
tdep->plt_entry_size = 16;
/* Solaris has kernel-assisted single-stepping support. */
- set_gdbarch_software_single_step (gdbarch, NULL);
+ set_gdbarch_software_single_step (gdbarch, default_software_single_step);
}
\f
Index: gdb/sparc-sol2-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-sol2-tdep.c,v
retrieving revision 1.12
diff -u -r1.12 sparc-sol2-tdep.c
--- gdb/sparc-sol2-tdep.c 9 Jan 2007 17:58:58 -0000 1.12
+++ gdb/sparc-sol2-tdep.c 13 Mar 2007 05:38:24 -0000
@@ -188,7 +188,7 @@
tdep->plt_entry_size = 12;
/* Solaris has kernel-assisted single-stepping support. */
- set_gdbarch_software_single_step (gdbarch, NULL);
+ set_gdbarch_software_single_step (gdbarch, default_software_single_step);
frame_unwind_append_sniffer (gdbarch, sparc32_sol2_sigtramp_frame_sniffer);
}
Index: gdb/arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.143
diff -u -r1.143 arch-utils.c
--- gdb/arch-utils.c 26 Feb 2007 20:13:18 -0000 1.143
+++ gdb/arch-utils.c 13 Mar 2007 05:35:28 -0000
@@ -270,6 +270,13 @@
return regno;
}
+int
+default_software_single_step (enum target_signal sig,
+ int insert_breakpoints_p)
+{
+ return 0;
+}
+
\f
/* Functions to manipulate the endianness of the target. */
Index: gdb/arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.86
diff -u -r1.86 arch-utils.h
--- gdb/arch-utils.h 26 Feb 2007 20:13:18 -0000 1.86
+++ gdb/arch-utils.h 13 Mar 2007 05:35:28 -0000
@@ -112,6 +112,9 @@
int default_remote_register_number (struct gdbarch *gdbarch,
int regno);
+extern int default_software_single_step (enum target_signal sig,
+ int insert_breakpoints_p);
+
/* For compatibility with older architectures, returns
(LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid
name. */
Index: gdb/gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.294
diff -u -r1.294 gdbarch.h
--- gdb/gdbarch.h 8 Feb 2007 21:00:29 -0000 1.294
+++ gdb/gdbarch.h 13 Mar 2007 05:36:46 -0000
@@ -1153,23 +1153,8 @@
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. */
-#if defined (SOFTWARE_SINGLE_STEP)
-/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
-#if !defined (SOFTWARE_SINGLE_STEP_P)
-#define SOFTWARE_SINGLE_STEP_P() (1)
-#endif
-#endif
-
-extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch);
-#if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP_P)
-#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
-#endif
-#if !defined (SOFTWARE_SINGLE_STEP_P)
-#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"
Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.224
diff -u -r1.224 arm-tdep.c
--- gdb/arm-tdep.c 27 Feb 2007 20:17:18 -0000 1.224
+++ gdb/arm-tdep.c 13 Mar 2007 05:35:44 -0000
@@ -1907,7 +1907,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
#include "bfd-in2.h"
Index: gdb/mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.405
diff -u -r1.405 mips-tdep.c
--- gdb/mips-tdep.c 7 Mar 2007 21:32:47 -0000 1.405
+++ gdb/mips-tdep.c 13 Mar 2007 05:38:00 -0000
@@ -2218,6 +2218,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: gdb/gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.376
diff -u -r1.376 gdbarch.sh
--- gdb/gdbarch.sh 28 Feb 2007 17:35:00 -0000 1.376
+++ gdb/gdbarch.sh 13 Mar 2007 05:37:00 -0000
@@ -622,7 +622,7 @@
#
# 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
+f:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p::default_software_single_step::0
# 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
Index: gdb/gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.338
diff -u -r1.338 gdbarch.c
--- gdb/gdbarch.c 28 Feb 2007 17:34:58 -0000 1.338
+++ gdb/gdbarch.c 13 Mar 2007 05:36:32 -0000
@@ -447,6 +447,7 @@
current_gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
current_gdbarch->addr_bits_remove = core_addr_identity;
current_gdbarch->smash_text_address = core_addr_identity;
+ current_gdbarch->software_single_step = default_software_single_step;
current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code;
current_gdbarch->skip_solib_resolver = generic_skip_solib_resolver;
current_gdbarch->in_solib_return_trampoline = generic_in_solib_return_trampoline;
@@ -600,7 +601,7 @@
/* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
/* Skip verify of addr_bits_remove, invalid_p == 0 */
/* Skip verify of smash_text_address, invalid_p == 0 */
- /* Skip verify of software_single_step, has predicate */
+ /* Skip verify of software_single_step, invalid_p == 0 */
/* Skip verify of single_step_through_delay, has predicate */
if (current_gdbarch->print_insn == 0)
fprintf_unfiltered (log, "\n\tprint_insn");
@@ -1510,15 +1511,6 @@
fprintf_unfiltered (file,
"gdbarch_dump: smash_text_address = <0x%lx>\n",
(long) current_gdbarch->smash_text_address);
-#ifdef SOFTWARE_SINGLE_STEP_P
- fprintf_unfiltered (file,
- "gdbarch_dump: %s # %s\n",
- "SOFTWARE_SINGLE_STEP_P()",
- XSTRING (SOFTWARE_SINGLE_STEP_P ()));
-#endif
- fprintf_unfiltered (file,
- "gdbarch_dump: gdbarch_software_single_step_p() = %d\n",
- gdbarch_software_single_step_p (current_gdbarch));
#ifdef SOFTWARE_SINGLE_STEP
fprintf_unfiltered (file,
"gdbarch_dump: %s # %s\n",
@@ -3283,20 +3275,13 @@
}
int
-gdbarch_software_single_step_p (struct gdbarch *gdbarch)
-{
- gdb_assert (gdbarch != NULL);
- return gdbarch->software_single_step != NULL;
-}
-
-void
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
Index: gdb/sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.178
diff -u -r1.178 sparc-tdep.c
--- gdb/sparc-tdep.c 27 Feb 2007 20:17:19 -0000 1.178
+++ gdb/sparc-tdep.c 13 Mar 2007 05:38:33 -0000
@@ -1176,7 +1176,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1206,6 +1206,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: gdb/alpha-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.h,v
retrieving revision 1.27
diff -u -r1.27 alpha-tdep.h
--- gdb/alpha-tdep.h 9 Jan 2007 17:58:49 -0000 1.27
+++ gdb/alpha-tdep.h 13 Mar 2007 05:35:23 -0000
@@ -107,7 +107,7 @@
};
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 *);
Index: gdb/rs6000-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.h,v
retrieving revision 1.3
diff -u -r1.3 rs6000-tdep.h
--- gdb/rs6000-tdep.h 27 Feb 2007 23:04:28 -0000 1.3
+++ gdb/rs6000-tdep.h 13 Mar 2007 05:38:22 -0000
@@ -21,7 +21,7 @@
#include "defs.h"
-extern void rs6000_software_single_step (enum target_signal signal,
+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
Index: gdb/alpha-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
retrieving revision 1.162
diff -u -r1.162 alpha-tdep.c
--- gdb/alpha-tdep.c 27 Feb 2007 20:17:18 -0000 1.162
+++ gdb/alpha-tdep.c 13 Mar 2007 05:35:22 -0000
@@ -1518,7 +1518,7 @@
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,8 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+
+ return 1;
}
\f
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
@ 2007-03-15 22:24 Luis Machado
2007-04-10 20:40 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-03-15 22:24 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1773 bytes --]
Hi,
This is a modified version of Paul's patch for the single stepping over
atomic instruction sequences.
The main modification is the removal of the portion of code that was
previously added to ppc-linux-tdep.* files. As some people on the
mailing list noticed, it was not really needed. The contents of that
file were transferred to the rs6000-tdep.c file.
rs6000-tdep.c now handles all the functionality for the single stepping
over locking instruction sets, and a suggested modification was included
in the code in order to fix possible internal errors due to inconsistent
handling of breakpoint creation/removal.
Follows the testsuite runs with and without the patch for HEAD.
Testsuite Summary with the patch applied
# of expected passes 11071
# of unexpected failures 356
# of expected failures 42
# of known failures 41
# of unresolved testcases 3
# of untested testcases 11
# of unsupported tests 18
Testsuite Summary without the patch
# of expected passes 11071
# of unexpected failures 357
# of expected failures 42
# of known failures 41
# of unresolved testcases 3
# of untested testcases 10
# of unsupported tests 18
It appears to have no regressions.
I am aware that Emi is currently working on a similar patch, based on
Paul's also. But since this is an issue that's been rolling for long and
that negatively impacts on more specific debugging activities, wouldn't
it be possible to include this patch as a fix while we wait for Emi's
copyright assignment to be ready? After his copyright assignment is
ready, it would be possible for him to incorporate additional changes
that he wrote on top of this one.
Regards,
Luis
[-- Attachment #2: single_stepping.diff --]
[-- Type: text/x-patch, Size: 21814 bytes --]
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* gdbarch.sh: Change the return type of software_single_step from
void to int and reformatted some comments to <= 80 columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Change the return type
from void to int and always return 1.
* alpha-tdep.h: Change the return type of alpha_software_single_step
from void to int.
* arm-tdep.c (arm_software_single_step): Change the return type from
void to int and always return 1.
* cris-tdep.c (cris_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.c (mips_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.h: Change the return type of mips_software_single_step
from void to int.
* rs6000-tdep.c (rs6000_software_single_step): Change the return type
from void to int and always return 1.
*rs6000-tdep.h: Change the return type of rs6000_software_single_step
from void to int.
* sparc-tdep.c (sparc_software_single_step): Change the return type
from void to int and always return 1.
* sparc-tdep.h: Change the return type of sparc_software_single_step
from void to int.
* wince.c (wince_software_single_step {three times}): Change the
return type from void to int and always return 1.
infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly. True means that the software_single_step
breakpoints where inserted; false means they where not.
20006-06-22 Paul Gilliam <pgilliam@us.ibm.com>
* gdbarch.sh: Change the return type of software_single_step from
void to int and reformatted some comments to <= 80 columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Change the return type
from void to int and always return 1.
* alpha-tdep.h: Change the return type of alpha_software_single_step
from void to int.
* arm-tdep.c (arm_software_single_step): Change the return type from
void to int and always return 1.
* cris-tdep.c (cris_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.c (mips_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.h: Change the return type of mips_software_single_step
from void to int.
* rs6000-tdep.c (rs6000_software_single_step): Change the return type
from void to int and always return 1.
*rs6000-tdep.h: Change the return type of rs6000_software_single_step
from void to int.
* sparc-tdep.c (sparc_software_single_step): Change the return type
from void to int and always return 1.
* sparc-tdep.h: Change the return type of sparc_software_single_step
from void to int.
* wince.c (wince_software_single_step {three times}): Change the
return type from void to int and always return 1.
infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly. True means that the software_single_step
breakpoints where inserted; false means they where not.
Index: alpha-tdep.c
===================================================================
--- alpha-tdep.c.orig
+++ alpha-tdep.c
@@ -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;
}
\f
Index: alpha-tdep.h
===================================================================
--- alpha-tdep.h.orig
+++ alpha-tdep.h
@@ -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 *);
Index: arm-tdep.c
===================================================================
--- arm-tdep.c.orig
+++ arm-tdep.c
@@ -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"
Index: cris-tdep.c
===================================================================
--- cris-tdep.c.orig
+++ cris-tdep.c
@@ -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. */
Index: gdbarch.c
===================================================================
--- gdbarch.c.orig
+++ gdbarch.c
@@ -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
Index: gdbarch.h
===================================================================
--- gdbarch.h.orig
+++ gdbarch.h
@@ -1144,14 +1144,16 @@ 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. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1168,8 +1170,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"
Index: gdbarch.sh
===================================================================
--- gdbarch.sh.orig
+++ gdbarch.sh
@@ -614,15 +614,19 @@ 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.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# 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:=: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
Index: infrun.c
===================================================================
--- infrun.c.orig
+++ infrun.c
@@ -555,14 +555,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
@@ -1385,7 +1387,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;
@@ -1405,7 +1407,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;
@@ -1576,7 +1578,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;
@@ -1685,7 +1687,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;
}
@@ -1756,7 +1758,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;
}
Index: mips-tdep.c
===================================================================
--- mips-tdep.c.orig
+++ mips-tdep.c
@@ -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
Index: mips-tdep.h
===================================================================
--- mips-tdep.h.orig
+++ mips-tdep.h
@@ -103,7 +103,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. */
Index: rs6000-tdep.c
===================================================================
--- rs6000-tdep.c.orig
+++ rs6000-tdep.c
@@ -718,10 +718,98 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
return little_breakpoint;
}
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7C000028
+#define LDARX_INSTRUCTION 0x7C000108
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+#define IMMEDIATE_PART(insn) (((insn & ~3) << 16) >> 16)
+#define ABSOLUTE_P(insn) ((int) ((insn >> 1) & 1))
+
+static int
+deal_with_atomic_sequence (enum target_signal sig, int insert_breakpoints_p)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int last_break = 0;
+ int i;
-/* AIX does not support PT_STEP. Simulate it. */
+ if (insert_breakpoints_p)
+ {
+
+ /* Assume all atomic sequences start with an lwarx or ldarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than 6 instructions. */
+ for (i = 1; i < 5; ++i)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* Assume at most one conditional branch instruction between
+ the lwarx and stwcx instructions.*/
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ last_break = 1;
+ breaks[1] = IMMEDIATE_PART (insn);
+ if ( ! ABSOLUTE_P(insn))
+ breaks[1] += loc;
+ continue;
+ }
-void
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx instruction
+ followed by a conditional branch instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
+ warning (_("Tried to step over an atomic sequence of instructions at %s\n \
+ but could not find the end of the sequence."),
+ core_addr_to_string(pc));
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ if ((insn & BC_MASK) != BC_INSTRUCTION)
+ warning (_("Tried to step over an atomic sequence of instructions at %s\n \
+ but the instruction sequence ended in an unexpected way."),
+ core_addr_to_string(pc));
+
+ breaks[0] = loc;
+
+ /* This should never happen, but make sure we don't put
+ two breakpoints on the same address. */
+ if (last_break && breaks[1] == breaks[0])
+ last_break = 0;
+
+ for (i = 0; i <= last_break; ++i)
+ insert_single_step_breakpoint (breaks[i]);
+
+ printf_unfiltered (_("Stepping over an atomic sequence of instructions beginning at %s\n"),
+ core_addr_to_string (pc));
+
+ gdb_flush (gdb_stdout);
+ }
+ else
+ remove_single_step_breakpoints();
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it, dealing with any sequence of
+ instructions that must be atomic. */
+
+int
rs6000_software_single_step (enum target_signal signal,
int insert_breakpoints_p)
{
@@ -739,6 +827,9 @@ rs6000_software_single_step (enum target
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (signal, insert_breakpoints_p))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
@@ -760,6 +851,8 @@ rs6000_software_single_step (enum target
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+
+ return 1;
}
@@ -3400,6 +3493,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);
+ /* Watch for locking instruction sequences during single stepping */
+ 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
Index: rs6000-tdep.h
===================================================================
--- rs6000-tdep.h.orig
+++ rs6000-tdep.h
@@ -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. */
Index: sparc-tdep.c
===================================================================
--- sparc-tdep.c.orig
+++ sparc-tdep.c
@@ -1176,7 +1176,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;
@@ -1206,6 +1206,8 @@ sparc_software_single_step (enum target_
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
--- sparc-tdep.h.orig
+++ sparc-tdep.h
@@ -167,8 +167,8 @@ extern struct sparc_frame_cache *
\f
-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);
Index: wince.c
===================================================================
--- wince.c.orig
+++ wince.c
@@ -839,7 +839,7 @@ undoSStep (thread_info * th)
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -851,14 +851,15 @@ wince_software_single_step (enum target_
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = mips_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif SHx
/* Renesas SH architecture instruction encoding masks */
@@ -980,7 +981,7 @@ undoSStep (thread_info * th)
instruction and setting a breakpoint on the "next" instruction
which would be executed. This code hails from sh-stub.c.
*/
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -990,13 +991,14 @@ wince_software_single_step (enum target_
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
th->step_pc = sh_get_next_pc (&th->context);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#elif defined (ARM)
#undef check_for_step
@@ -1027,7 +1029,7 @@ undoSStep (thread_info * th)
}
}
-void
+int
wince_software_single_step (enum target_signal ignore,
int insert_breakpoints_p)
{
@@ -1039,14 +1041,15 @@ wince_software_single_step (enum target_
if (!insert_breakpoints_p)
{
undoSStep (th);
- return;
+ return 1;
}
th->stepped = 1;
pc = read_register (PC_REGNUM);
th->step_pc = arm_get_next_pc (pc);
insert_single_step_breakpoint (th->step_pc);
- return;
+
+ return 1;
}
#endif
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-03-15 22:24 Luis Machado
@ 2007-04-10 20:40 ` Daniel Jacobowitz
2007-04-12 12:09 ` Luis Machado
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-10 20:40 UTC (permalink / raw)
To: Luis Machado; +Cc: gdb-patches
On Thu, Mar 15, 2007 at 07:24:14PM -0300, Luis Machado wrote:
> I am aware that Emi is currently working on a similar patch, based on
> Paul's also. But since this is an issue that's been rolling for long and
> that negatively impacts on more specific debugging activities, wouldn't
> it be possible to include this patch as a fix while we wait for Emi's
> copyright assignment to be ready? After his copyright assignment is
> ready, it would be possible for him to incorporate additional changes
> that he wrote on top of this one.
I agree. However, the patch can't be applied as-is. There are a
couple of cosmetic issues, and at least one syntax error ("return 1",
no semicolon). Let's do it in two pieces, please.
Could you post a patch which changes the type of the
software_single_step gdbarch method to return int, updates infrun.c,
and nothing else? Then we can look at the PowerPC bits (which are
more interesting) separately.
When you're editing a bunch of tdep files, please use the
gdb_mbuild.sh script to make sure they all still compile.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-10 20:40 ` Daniel Jacobowitz
@ 2007-04-12 12:09 ` Luis Machado
2007-04-12 12:15 ` Daniel Jacobowitz
2007-04-12 14:32 ` Ulrich Weigand
0 siblings, 2 replies; 43+ messages in thread
From: Luis Machado @ 2007-04-12 12:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1036 bytes --]
Daniel,
Thanks for your reply. The syntax problem was corrected.
I've ran the gdb_mbuild.sh script and had no problems that are directly
related to my patch. I had a compilation problem with the spu-elf, but
that seems to be in cvs-HEAD as well. I also changed the return type of
the software single step method for spu-elf and the local return values
from the method ("return" to "return 1"), since they were still void.
The wince.c file modification was droped due to its removal from the
tree.
> Could you post a patch which changes the type of the
> software_single_step gdbarch method to return int, updates infrun.c,
> and nothing else? Then we can look at the PowerPC bits (which are
> more interesting) separately.
Attached follows the patch that only changes the infrun bits and also
the return type of the software_single_step methods for various archs.
> When you're editing a bunch of tdep files, please use the
> gdb_mbuild.sh script to make sure they all still compile.
Thanks for the hint on this.
Regards,
Luis
[-- Attachment #2: single_stepping.diff --]
[-- Type: text/x-patch, Size: 15467 bytes --]
2007-04-12 Luis Machado <luisgpm@br.ibm.com>
* gdbarch.sh: Change the return type of software_single_step from
void to int and reformatted some comments to <= 80 columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Change the return type
from void to int and always return 1.
* alpha-tdep.h: Change the return type of alpha_software_single_step
from void to int.
* arm-tdep.c (arm_software_single_step): Change the return type from
void to int and always return 1.
* cris-tdep.c (cris_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.c (mips_software_single_step): Change the return type
from void to int and always return 1.
* mips-tdep.h: Change the return type of mips_software_single_step
from void to int.
* rs6000-tdep.c (rs6000_software_single_step): Change the return type
from void to int and always return 1.
*rs6000-tdep.h: Change the return type of rs6000_software_single_step
from void to int.
* sparc-tdep.c (sparc_software_single_step): Change the return type
from void to int and always return 1.
* sparc-tdep.h: Change the return type of sparc_software_single_step
from void to int.
* spu-tdep.c (spu_software_single_step): Change the return type
from void to int and always return 1.
infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly. True means that the software_single_step
breakpoints where inserted; false means they where not.
Index: alpha-tdep.c
===================================================================
--- alpha-tdep.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ alpha-tdep.c 2007-04-11 07:20:44.000000000 -0700
@@ -1518,7 +1518,7 @@
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 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
\f
Index: alpha-tdep.h
===================================================================
--- alpha-tdep.h.orig 2007-04-11 07:20:42.000000000 -0700
+++ alpha-tdep.h 2007-04-11 07:20:44.000000000 -0700
@@ -107,7 +107,7 @@
};
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 *);
Index: arm-tdep.c
===================================================================
--- arm-tdep.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ arm-tdep.c 2007-04-11 07:20:44.000000000 -0700
@@ -1907,7 +1907,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
#include "bfd-in2.h"
Index: cris-tdep.c
===================================================================
--- cris-tdep.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ cris-tdep.c 2007-04-11 07:20:44.000000000 -0700
@@ -2119,7 +2119,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdbarch.c
===================================================================
--- gdbarch.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ gdbarch.c 2007-04-11 07:20:44.000000000 -0700
@@ -3289,14 +3289,14 @@
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
Index: gdbarch.h
===================================================================
--- gdbarch.h.orig 2007-04-11 07:20:42.000000000 -0700
+++ gdbarch.h 2007-04-11 07:20:44.000000000 -0700
@@ -1144,14 +1144,16 @@
#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. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1168,8 +1170,8 @@
#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"
Index: gdbarch.sh
===================================================================
--- gdbarch.sh.orig 2007-04-11 07:20:42.000000000 -0700
+++ gdbarch.sh 2007-04-11 07:20:44.000000000 -0700
@@ -614,15 +614,19 @@
# 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.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# 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:=: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
Index: infrun.c
===================================================================
--- infrun.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ infrun.c 2007-04-11 07:20:44.000000000 -0700
@@ -548,14 +548,16 @@
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 @@
(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 @@
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 @@
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 @@
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 @@
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;
}
Index: mips-tdep.c
===================================================================
--- mips-tdep.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ mips-tdep.c 2007-04-11 07:20:44.000000000 -0700
@@ -2204,7 +2204,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: mips-tdep.h
===================================================================
--- mips-tdep.h.orig 2007-04-11 07:20:42.000000000 -0700
+++ mips-tdep.h 2007-04-11 07:20:44.000000000 -0700
@@ -100,7 +100,7 @@
};
/* 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. */
Index: rs6000-tdep.h
===================================================================
--- rs6000-tdep.h.orig 2007-04-11 07:20:42.000000000 -0700
+++ rs6000-tdep.h 2007-04-11 07:20:44.000000000 -0700
@@ -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. */
Index: sparc-tdep.c
===================================================================
--- sparc-tdep.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ sparc-tdep.c 2007-04-11 07:20:44.000000000 -0700
@@ -1176,7 +1176,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1206,6 +1206,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
--- sparc-tdep.h.orig 2007-04-11 07:20:42.000000000 -0700
+++ sparc-tdep.h 2007-04-11 07:20:44.000000000 -0700
@@ -167,8 +167,8 @@
\f
-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);
Index: rs6000-tdep.c
===================================================================
--- rs6000-tdep.c.orig 2007-04-11 07:20:42.000000000 -0700
+++ rs6000-tdep.c 2007-04-11 07:20:44.000000000 -0700
@@ -722,7 +722,7 @@
/* 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 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+ return 1;
}
Index: spu-tdep.c
===================================================================
--- spu-tdep.c.orig 2007-04-11 12:53:45.000000000 -0700
+++ spu-tdep.c 2007-04-11 13:07:55.000000000 -0700
@@ -1078,7 +1078,7 @@
/* Software single-stepping support. */
-void
+int
spu_software_single_step (enum target_signal signal, int insert_breakpoints_p)
{
if (insert_breakpoints_p)
@@ -1093,7 +1093,7 @@
pc = extract_unsigned_integer (buf, 4) & -4;
if (target_read_memory (pc, buf, 4))
- return;
+ return 1;
insn = extract_unsigned_integer (buf, 4);
/* Next sequential instruction is at PC + 4, except if the current
@@ -1125,6 +1125,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 12:09 ` Luis Machado
@ 2007-04-12 12:15 ` Daniel Jacobowitz
2007-04-12 12:54 ` Luis Machado
2007-04-12 14:32 ` Ulrich Weigand
1 sibling, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 12:15 UTC (permalink / raw)
To: Luis Machado; +Cc: gdb-patches
On Thu, Apr 12, 2007 at 09:09:24AM -0300, Luis Machado wrote:
> Daniel,
>
> Thanks for your reply. The syntax problem was corrected.
>
> I've ran the gdb_mbuild.sh script and had no problems that are directly
> related to my patch. I had a compilation problem with the spu-elf, but
> that seems to be in cvs-HEAD as well. I also changed the return type of
> the software single step method for spu-elf and the local return values
> from the method ("return" to "return 1"), since they were still void.
This version is basically OK.
> 2007-04-12 Luis Machado <luisgpm@br.ibm.com>
>
> * gdbarch.sh: Change the return type of software_single_step from
> void to int and reformatted some comments to <= 80 columns.
* gdbarch.sh (software_single_step): Change the return type
from void to int and reformatted some comments to <= 80
columns.
> * alpha-tdep.c (alpha_software_single_step): Change the return type
> from void to int and always return 1.
> * alpha-tdep.h: Change the return type of alpha_software_single_step
> from void to int.
> * arm-tdep.c (arm_software_single_step): Change the return type from
> void to int and always return 1.
* alpha-tdep.h (alpha_software_single_step): Likewise.
* arm-tdep.c (arm_software_single_step): Likewise.
... et cetera. No need to repeat.
> infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
> and act accordingly. True means that the software_single_step
> breakpoints where inserted; false means they where not.
* infrun.c (resume): Check the return value from
SOFTWARE_SINGLE_STEP and act accordingly.
Note, part of this explanatory comment vanished because we don't put
"why" in ChangeLogs. This is the sort of thing that one ought to know
when working with the code. Therefore it should be a comment in the
code. Please describe the return value in gdbarch.sh.
Thanks!
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 12:15 ` Daniel Jacobowitz
@ 2007-04-12 12:54 ` Luis Machado
2007-04-12 12:58 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-04-12 12:54 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 231 bytes --]
Daniel,
The changes were made according to the suggestions. Changelog updated
and the gdbarch now has a comment on the meaning of the new return value
for the software_single_step methods.
Patch attached.
Thanks!
Regards,
Luis
[-- Attachment #2: single_stepping.diff --]
[-- Type: text/x-patch, Size: 14987 bytes --]
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.
* spu-tdep.c (spu_software_single_step): Likewise.
* infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly.
Index: alpha-tdep.c
===================================================================
--- alpha-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ alpha-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -1518,7 +1518,7 @@
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 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
\f
Index: alpha-tdep.h
===================================================================
--- alpha-tdep.h.orig 2007-04-12 05:36:14.000000000 -0700
+++ alpha-tdep.h 2007-04-12 05:40:59.000000000 -0700
@@ -107,7 +107,7 @@
};
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 *);
Index: arm-tdep.c
===================================================================
--- arm-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ arm-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -1907,7 +1907,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
#include "bfd-in2.h"
Index: cris-tdep.c
===================================================================
--- cris-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ cris-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -2119,7 +2119,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdbarch.c
===================================================================
--- gdbarch.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ gdbarch.c 2007-04-12 05:40:59.000000000 -0700
@@ -3289,14 +3289,14 @@
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
Index: gdbarch.h
===================================================================
--- gdbarch.h.orig 2007-04-12 05:36:14.000000000 -0700
+++ gdbarch.h 2007-04-12 05:40:59.000000000 -0700
@@ -1144,14 +1144,16 @@
#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. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1168,8 +1170,8 @@
#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"
Index: gdbarch.sh
===================================================================
--- gdbarch.sh.orig 2007-04-12 05:36:14.000000000 -0700
+++ gdbarch.sh 2007-04-12 05:42:52.000000000 -0700
@@ -614,15 +614,21 @@
# 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.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# 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
+# where inserted; 0 means they where 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
Index: infrun.c
===================================================================
--- infrun.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ infrun.c 2007-04-12 05:40:59.000000000 -0700
@@ -548,14 +548,16 @@
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 @@
(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 @@
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 @@
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 @@
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 @@
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;
}
Index: mips-tdep.c
===================================================================
--- mips-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ mips-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -2204,7 +2204,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: mips-tdep.h
===================================================================
--- mips-tdep.h.orig 2007-04-12 05:36:14.000000000 -0700
+++ mips-tdep.h 2007-04-12 05:40:59.000000000 -0700
@@ -100,7 +100,7 @@
};
/* 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. */
Index: rs6000-tdep.h
===================================================================
--- rs6000-tdep.h.orig 2007-04-12 05:36:14.000000000 -0700
+++ rs6000-tdep.h 2007-04-12 05:40:59.000000000 -0700
@@ -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. */
Index: sparc-tdep.c
===================================================================
--- sparc-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ sparc-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -1176,7 +1176,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1206,6 +1206,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
--- sparc-tdep.h.orig 2007-04-12 05:36:14.000000000 -0700
+++ sparc-tdep.h 2007-04-12 05:40:59.000000000 -0700
@@ -167,8 +167,8 @@
\f
-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);
Index: rs6000-tdep.c
===================================================================
--- rs6000-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ rs6000-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -722,7 +722,7 @@
/* 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 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+ return 1;
}
Index: spu-tdep.c
===================================================================
--- spu-tdep.c.orig 2007-04-12 05:36:14.000000000 -0700
+++ spu-tdep.c 2007-04-12 05:40:59.000000000 -0700
@@ -1078,7 +1078,7 @@
/* Software single-stepping support. */
-void
+int
spu_software_single_step (enum target_signal signal, int insert_breakpoints_p)
{
if (insert_breakpoints_p)
@@ -1093,7 +1093,7 @@
pc = extract_unsigned_integer (buf, 4) & -4;
if (target_read_memory (pc, buf, 4))
- return;
+ return 1;
insn = extract_unsigned_integer (buf, 4);
/* Next sequential instruction is at PC + 4, except if the current
@@ -1125,6 +1125,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 12:54 ` Luis Machado
@ 2007-04-12 12:58 ` Daniel Jacobowitz
2007-04-12 13:30 ` Luis Machado
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 12:58 UTC (permalink / raw)
To: Luis Machado; +Cc: gdb-patches, Ulrich.Weigand
On Thu, Apr 12, 2007 at 09:53:59AM -0300, Luis Machado wrote:
> +# A return value of 1 means that the software_single_step breakpoints
> +# where inserted; 0 means they where not.
Sorry, two little things: "were" instead of "where", and you need to
rerun gdbarch.sh after changing it (this comment didn't get added to
gdbarch.c).
With those, the patch is OK to commit. Ulrich, I guess you should do
it since Luis is with IBM?
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 12:58 ` Daniel Jacobowitz
@ 2007-04-12 13:30 ` Luis Machado
2007-04-12 13:35 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-04-12 13:30 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 178 bytes --]
The typos were corrected and the gdbarch.[c|h] files were updated with
gdbarch.sh, though the comment was just added to gdbarch.h, not
gdbarch.c, is this correct?
Regards,
Luis
[-- Attachment #2: single_stepping.diff --]
[-- Type: text/x-patch, Size: 15109 bytes --]
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.
* spu-tdep.c (spu_software_single_step): Likewise.
* infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly.
Index: alpha-tdep.c
===================================================================
--- alpha-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ alpha-tdep.c 2007-04-12 06:05:21.000000000 -0700
@@ -1518,7 +1518,7 @@
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 @@
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
\f
Index: alpha-tdep.h
===================================================================
--- alpha-tdep.h.orig 2007-04-12 06:04:10.000000000 -0700
+++ alpha-tdep.h 2007-04-12 06:05:21.000000000 -0700
@@ -107,7 +107,7 @@
};
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 *);
Index: arm-tdep.c
===================================================================
--- arm-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ arm-tdep.c 2007-04-12 06:05:21.000000000 -0700
@@ -1907,7 +1907,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
#include "bfd-in2.h"
Index: cris-tdep.c
===================================================================
--- cris-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ cris-tdep.c 2007-04-12 06:05:21.000000000 -0700
@@ -2119,7 +2119,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
Index: gdbarch.c
===================================================================
--- gdbarch.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ gdbarch.c 2007-04-12 06:12:53.000000000 -0700
@@ -3289,14 +3289,14 @@
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
Index: gdbarch.h
===================================================================
--- gdbarch.h.orig 2007-04-12 06:04:10.000000000 -0700
+++ gdbarch.h 2007-04-12 06:15:05.000000000 -0700
@@ -1144,14 +1144,19 @@
#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 @@
#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"
Index: gdbarch.sh
===================================================================
--- gdbarch.sh.orig 2007-04-12 06:04:10.000000000 -0700
+++ gdbarch.sh 2007-04-12 06:12:32.000000000 -0700
@@ -614,15 +614,22 @@
# 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
Index: infrun.c
===================================================================
--- infrun.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ infrun.c 2007-04-12 06:05:21.000000000 -0700
@@ -548,14 +548,16 @@
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 @@
(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 @@
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 @@
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 @@
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 @@
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;
}
Index: mips-tdep.c
===================================================================
--- mips-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ mips-tdep.c 2007-04-12 06:05:21.000000000 -0700
@@ -2204,7 +2204,7 @@
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 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
Index: mips-tdep.h
===================================================================
--- mips-tdep.h.orig 2007-04-12 06:04:10.000000000 -0700
+++ mips-tdep.h 2007-04-12 06:05:21.000000000 -0700
@@ -100,7 +100,7 @@
};
/* 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. */
Index: rs6000-tdep.h
===================================================================
--- rs6000-tdep.h.orig 2007-04-12 06:04:10.000000000 -0700
+++ rs6000-tdep.h 2007-04-12 06:05:22.000000000 -0700
@@ -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. */
Index: sparc-tdep.c
===================================================================
--- sparc-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ sparc-tdep.c 2007-04-12 06:05:22.000000000 -0700
@@ -1176,7 +1176,7 @@
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1206,6 +1206,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
Index: sparc-tdep.h
===================================================================
--- sparc-tdep.h.orig 2007-04-12 06:04:10.000000000 -0700
+++ sparc-tdep.h 2007-04-12 06:05:22.000000000 -0700
@@ -167,8 +167,8 @@
\f
-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);
Index: rs6000-tdep.c
===================================================================
--- rs6000-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ rs6000-tdep.c 2007-04-12 06:05:22.000000000 -0700
@@ -722,7 +722,7 @@
/* 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 @@
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+ return 1;
}
Index: spu-tdep.c
===================================================================
--- spu-tdep.c.orig 2007-04-12 06:04:10.000000000 -0700
+++ spu-tdep.c 2007-04-12 06:05:22.000000000 -0700
@@ -1078,7 +1078,7 @@
/* Software single-stepping support. */
-void
+int
spu_software_single_step (enum target_signal signal, int insert_breakpoints_p)
{
if (insert_breakpoints_p)
@@ -1093,7 +1093,7 @@
pc = extract_unsigned_integer (buf, 4) & -4;
if (target_read_memory (pc, buf, 4))
- return;
+ return 1;
insn = extract_unsigned_integer (buf, 4);
/* Next sequential instruction is at PC + 4, except if the current
@@ -1125,6 +1125,8 @@
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 13:30 ` Luis Machado
@ 2007-04-12 13:35 ` Daniel Jacobowitz
2007-04-12 14:58 ` Ulrich Weigand
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 13:35 UTC (permalink / raw)
To: Luis Machado; +Cc: gdb-patches
On Thu, Apr 12, 2007 at 10:25:26AM -0300, Luis Machado wrote:
> The typos were corrected and the gdbarch.[c|h] files were updated with
> gdbarch.sh, though the comment was just added to gdbarch.h, not
> gdbarch.c, is this correct?
Yes, it is. This version is fine.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 13:35 ` Daniel Jacobowitz
@ 2007-04-12 14:58 ` Ulrich Weigand
2007-04-12 15:33 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-12 14:58 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Luis Machado, gdb-patches
Daniel Jacobowitz wrote:
> On Thu, Apr 12, 2007 at 10:25:26AM -0300, Luis Machado wrote:
> > The typos were corrected and the gdbarch.[c|h] files were updated with
> > gdbarch.sh, though the comment was just added to gdbarch.h, not
> > gdbarch.c, is this correct?
>
> Yes, it is. This version is fine.
I've checked this in now.
While we're on this topic, I'm wondering whether we could do some
further simplification on the single-step code. In particular,
now every single-step implementation makes use of the
insert_single_step_breakpoint helper to insert breakpoints,
and the !insert_breakpoint_p side of every single-step implementation
consist of a sole call to the remove_single_step_breakpoints helper.
It might be a good idea to actually enforce that behaviour. In fact,
we could just *remove* the insert_breakpoint_p flag of the gdbarch
callback, call that callback solely in insert the breakpoints (which
*must* use the insert_single_step_breakpoint helper), and just call
remove_single_step_breakpoints directly from common code instead of
the gdbarch callback to remove the breakpoints.
That would allow future changes to the details of single-step
breakpoint implementation in common code without having to go
through all implementations every time ...
What do you think?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 14:58 ` Ulrich Weigand
@ 2007-04-12 15:33 ` Daniel Jacobowitz
2007-04-12 17:16 ` Ulrich Weigand
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 15:33 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: Luis Machado, gdb-patches
On Thu, Apr 12, 2007 at 04:58:21PM +0200, Ulrich Weigand wrote:
> While we're on this topic, I'm wondering whether we could do some
> further simplification on the single-step code. In particular,
> now every single-step implementation makes use of the
> insert_single_step_breakpoint helper to insert breakpoints,
> and the !insert_breakpoint_p side of every single-step implementation
> consist of a sole call to the remove_single_step_breakpoints helper.
>
> It might be a good idea to actually enforce that behaviour. In fact,
> we could just *remove* the insert_breakpoint_p flag of the gdbarch
> callback, call that callback solely in insert the breakpoints (which
> *must* use the insert_single_step_breakpoint helper), and just call
> remove_single_step_breakpoints directly from common code instead of
> the gdbarch callback to remove the breakpoints.
>
> That would allow future changes to the details of single-step
> breakpoint implementation in common code without having to go
> through all implementations every time ...
>
> What do you think?
"Yes please". That's one of the reasons I wanted to get the common
helper in place.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 15:33 ` Daniel Jacobowitz
@ 2007-04-12 17:16 ` Ulrich Weigand
2007-04-12 18:25 ` Daniel Jacobowitz
0 siblings, 1 reply; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-12 17:16 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Luis Machado, gdb-patches
Daniel Jacobowitz wrote:
> "Yes please". That's one of the reasons I wanted to get the common
> helper in place.
OK, I'll come up with a patch.
However, there's one thing I overlooked in alpha-tdep.c:
static CORE_ADDR next_pc;
CORE_ADDR pc;
if (insert_breakpoints_p)
{
pc = read_pc ();
next_pc = alpha_next_pc (pc);
insert_single_step_breakpoint (next_pc);
}
else
{
remove_single_step_breakpoints ();
write_pc (next_pc);
}
I would think the "write_pc (next_pc)" statement in the
!insert_breakpoints_p case should be unnecessary. This should
already have been taken care of by infrun, shouldn't it?
Also, I've noticed that none of the existing implementations
makes any use of the "signal" argument. Should we remove this
as well?
Finally, all single-step implementations currently have to
fall back to global functions like read_pc (or current_regcache)
to find the target registers. I understand this is something
we should be moving away from, so if we're already changing
the signature, maybe we should pass in a regcache argument?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 17:16 ` Ulrich Weigand
@ 2007-04-12 18:25 ` Daniel Jacobowitz
2007-04-12 20:09 ` Ulrich Weigand
0 siblings, 1 reply; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 18:25 UTC (permalink / raw)
To: gdb-patches
On Thu, Apr 12, 2007 at 07:16:14PM +0200, Ulrich Weigand wrote:
> I would think the "write_pc (next_pc)" statement in the
> !insert_breakpoints_p case should be unnecessary. This should
> already have been taken care of by infrun, shouldn't it?
I'm afraid I don't know what this is for. You're probably correct,
though.
> Also, I've noticed that none of the existing implementations
> makes any use of the "signal" argument. Should we remove this
> as well?
Sure.
> Finally, all single-step implementations currently have to
> fall back to global functions like read_pc (or current_regcache)
> to find the target registers. I understand this is something
> we should be moving away from, so if we're already changing
> the signature, maybe we should pass in a regcache argument?
Hmm, or a frame?
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 18:25 ` Daniel Jacobowitz
@ 2007-04-12 20:09 ` Ulrich Weigand
2007-04-12 20:16 ` Mark Kettenis
2007-04-12 20:48 ` Daniel Jacobowitz
0 siblings, 2 replies; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-12 20:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
> On Thu, Apr 12, 2007 at 07:16:14PM +0200, Ulrich Weigand wrote:
> > I would think the "write_pc (next_pc)" statement in the
> > !insert_breakpoints_p case should be unnecessary. This should
> > already have been taken care of by infrun, shouldn't it?
>
> I'm afraid I don't know what this is for. You're probably correct,
> though.
I'd say we should remove it. The use of the contents of the
static variable next_pc from a previous invocation strikes me
as suspect anyway -- what if we're in another thread now?
I don't have a way to test on alpha-linux unfortunately. Do you?
> > Finally, all single-step implementations currently have to
> > fall back to global functions like read_pc (or current_regcache)
> > to find the target registers. I understand this is something
> > we should be moving away from, so if we're already changing
> > the signature, maybe we should pass in a regcache argument?
>
> Hmm, or a frame?
I thought "resume" (where this is called) too low-level for
a frame to make sense. You cannot single-step anywhere but
in the innermost frame, so a regcache seemed more appropriate.
(How would I actually get hold of a frame in resume?)
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 20:09 ` Ulrich Weigand
@ 2007-04-12 20:16 ` Mark Kettenis
2007-04-12 20:43 ` Ulrich Weigand
2007-04-12 20:49 ` Daniel Jacobowitz
2007-04-12 20:48 ` Daniel Jacobowitz
1 sibling, 2 replies; 43+ messages in thread
From: Mark Kettenis @ 2007-04-12 20:16 UTC (permalink / raw)
To: uweigand; +Cc: drow, gdb-patches
> Date: Thu, 12 Apr 2007 22:09:10 +0200 (CEST)
> From: "Ulrich Weigand" <uweigand@de.ibm.com>
>
> Daniel Jacobowitz wrote:
> > On Thu, Apr 12, 2007 at 07:16:14PM +0200, Ulrich Weigand wrote:
> > > I would think the "write_pc (next_pc)" statement in the
> > > !insert_breakpoints_p case should be unnecessary. This should
> > > already have been taken care of by infrun, shouldn't it?
> >
> > I'm afraid I don't know what this is for. You're probably correct,
> > though.
>
> I'd say we should remove it. The use of the contents of the
> static variable next_pc from a previous invocation strikes me
> as suspect anyway -- what if we're in another thread now?
I suspect the write_pc call is there to make stepping delay-slot
instructions work.
> I don't have a way to test on alpha-linux unfortunately. Do you?
I can test OpenBSD/alpha later this week if necessary.
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 20:16 ` Mark Kettenis
@ 2007-04-12 20:43 ` Ulrich Weigand
2007-04-14 15:20 ` Mark Kettenis
2007-04-12 20:49 ` Daniel Jacobowitz
1 sibling, 1 reply; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-12 20:43 UTC (permalink / raw)
To: Mark Kettenis; +Cc: drow, gdb-patches
Mark Kettenis wrote:
> I suspect the write_pc call is there to make stepping delay-slot
> instructions work.
Maybe I'm confused, but I thought alpha didn't have delay slots?
There is a special gdbarch routine single_step_through_delay for
targets that have those ...
> > I don't have a way to test on alpha-linux unfortunately. Do you?
>
> I can test OpenBSD/alpha later this week if necessary.
Thanks for the offer! (I just noticed that Linux/alpha doesn't use
software single-step anyway, but OpenBSD/alpha does.)
Would you mind testing this small patch that simply removes the
write_pc call? All remaining changes should then be mechanical.
Thanks,
Ulrich
* alpha-tdep.c (alpha_software_single_step): Do not call write_pc
when removing single-step breakpoints.
Index: gdb/alpha-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
retrieving revision 1.163
diff -u -p -r1.163 alpha-tdep.c
--- gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163
+++ gdb/alpha-tdep.c 12 Apr 2007 20:39:08 -0000
@@ -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;
}
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 20:43 ` Ulrich Weigand
@ 2007-04-14 15:20 ` Mark Kettenis
2007-04-14 18:13 ` Ulrich Weigand
0 siblings, 1 reply; 43+ messages in thread
From: Mark Kettenis @ 2007-04-14 15:20 UTC (permalink / raw)
To: uweigand; +Cc: drow, gdb-patches
> Date: Thu, 12 Apr 2007 22:43:49 +0200 (CEST)
> From: "Ulrich Weigand" <uweigand@de.ibm.com>
>
> Mark Kettenis wrote:
>
> > I suspect the write_pc call is there to make stepping delay-slot
> > instructions work.
>
> Maybe I'm confused, but I thought alpha didn't have delay slots?
> There is a special gdbarch routine single_step_through_delay for
> targets that have those ...
Duh, you're right. I must have been hacking tto much on sparc64 and
mips64 lately.
> > > I don't have a way to test on alpha-linux unfortunately. Do you?
> >
> > I can test OpenBSD/alpha later this week if necessary.
>
> Thanks for the offer! (I just noticed that Linux/alpha doesn't use
> software single-step anyway, but OpenBSD/alpha does.)
Indeed.
> Would you mind testing this small patch that simply removes the
> write_pc call?
It actually gets rid of a couple of FAILs. So please go ahead and
commit this.
> * alpha-tdep.c (alpha_software_single_step): Do not call write_pc
> when removing single-step breakpoints.
>
> Index: gdb/alpha-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
> retrieving revision 1.163
> diff -u -p -r1.163 alpha-tdep.c
> --- gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163
> +++ gdb/alpha-tdep.c 12 Apr 2007 20:39:08 -0000
> @@ -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;
> }
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-14 15:20 ` Mark Kettenis
@ 2007-04-14 18:13 ` Ulrich Weigand
0 siblings, 0 replies; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-14 18:13 UTC (permalink / raw)
To: Mark Kettenis; +Cc: drow, gdb-patches
Mark Kettenis wrote:
> It actually gets rid of a couple of FAILs. So please go ahead and
> commit this.
>
> > * alpha-tdep.c (alpha_software_single_step): Do not call write_pc
> > when removing single-step breakpoints.
I've checked this in now, thanks!
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 20:16 ` Mark Kettenis
2007-04-12 20:43 ` Ulrich Weigand
@ 2007-04-12 20:49 ` Daniel Jacobowitz
1 sibling, 0 replies; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 20:49 UTC (permalink / raw)
To: gdb-patches
On Thu, Apr 12, 2007 at 10:16:43PM +0200, Mark Kettenis wrote:
> > I don't have a way to test on alpha-linux unfortunately. Do you?
>
> I can test OpenBSD/alpha later this week if necessary.
I can also test alpha-linux if necessary - well, not this moment, but
once Debian gets an Alpha up again.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 20:09 ` Ulrich Weigand
2007-04-12 20:16 ` Mark Kettenis
@ 2007-04-12 20:48 ` Daniel Jacobowitz
1 sibling, 0 replies; 43+ messages in thread
From: Daniel Jacobowitz @ 2007-04-12 20:48 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches
On Thu, Apr 12, 2007 at 10:09:10PM +0200, Ulrich Weigand wrote:
> I thought "resume" (where this is called) too low-level for
> a frame to make sense. You cannot single-step anywhere but
> in the innermost frame, so a regcache seemed more appropriate.
> (How would I actually get hold of a frame in resume?)
I guess you'd just use the current one, but a regcache is fine too.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 12:09 ` Luis Machado
2007-04-12 12:15 ` Daniel Jacobowitz
@ 2007-04-12 14:32 ` Ulrich Weigand
2007-04-12 14:47 ` Luis Machado
1 sibling, 1 reply; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-12 14:32 UTC (permalink / raw)
To: luisgpm; +Cc: Daniel Jacobowitz, gdb-patches
Luis Machado wrote:
> I've ran the gdb_mbuild.sh script and had no problems that are directly
> related to my patch. I had a compilation problem with the spu-elf, but
> that seems to be in cvs-HEAD as well. I also changed the return type of
> the software single step method for spu-elf and the local return values
> from the method ("return" to "return 1"), since they were still void.
Could you elaborate on that spu-elf compilation problem you were seeing?
I just built spu-elf on CVS head without problems ...
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 14:32 ` Ulrich Weigand
@ 2007-04-12 14:47 ` Luis Machado
2007-04-12 15:00 ` Ulrich Weigand
0 siblings, 1 reply; 43+ messages in thread
From: Luis Machado @ 2007-04-12 14:47 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches
Ulrich,
I had the following errors on HEAD. It might be due to my specific build
environment though.
spu-linux-nat.c: In function 'fetch_ppc_register':
spu-linux-nat.c:64: error: 'PPC_PTRACE_PEEKUSR_3264' undeclared (first
use in this function)
spu-linux-nat.c:64: error: (Each undeclared identifier is reported only
once
spu-linux-nat.c:64: error: for each function it appears in.)
spu-linux-nat.c: In function 'fetch_ppc_memory_1':
spu-linux-nat.c:97: error: 'PPC_PTRACE_PEEKTEXT_3264' undeclared (first
use in this function)
spu-linux-nat.c: In function 'store_ppc_memory_1':
spu-linux-nat.c:116: error: 'PPC_PTRACE_POKEDATA_3264' undeclared (first
use in this function)
The only change i made to the SPU architecture ws the return type from
the spu_software_single_step function.
Regards,
Luis
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [patch] "single step" atomic instruction sequences as a whole.
2007-04-12 14:47 ` Luis Machado
@ 2007-04-12 15:00 ` Ulrich Weigand
0 siblings, 0 replies; 43+ messages in thread
From: Ulrich Weigand @ 2007-04-12 15:00 UTC (permalink / raw)
To: luisgpm; +Cc: gdb-patches
Luis Machado wrote:
> spu-linux-nat.c:64: error: 'PPC_PTRACE_PEEKUSR_3264' undeclared
> spu-linux-nat.c:97: error: 'PPC_PTRACE_PEEKTEXT_3264' undeclared
> spu-linux-nat.c:116: error: 'PPC_PTRACE_POKEDATA_3264' undeclared
That's the native side. Did you build on a powerpc64 host?
Those defines should be in the ppc64 system header files. What
distribution (version of glibc, kernel-header) are you using?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2007-04-14 16:19 UTC | newest]
Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-22 20:56 [patch] "single step" atomic instruction sequences as a whole PAUL GILLIAM
2006-06-22 21:53 ` PAUL GILLIAM
2006-06-22 22:20 ` PAUL GILLIAM
2006-11-10 21:18 ` Daniel Jacobowitz
2006-09-18 11:59 emin ak
2006-11-09 13:07 ` [patch] " emin ak
2007-02-06 11:02 Luis Machado
2007-02-06 12:11 ` Emi SUZUKI
2007-02-07 13:10 ` Luis Machado
2007-02-08 13:00 ` Emi SUZUKI
2007-02-17 2:24 Luis Machado
2007-02-27 13:00 ` Emi SUZUKI
2007-02-27 13:17 ` Daniel Jacobowitz
2007-02-28 8:08 ` Emi SUZUKI
2007-02-28 11:46 ` Daniel Jacobowitz
2007-02-28 16:09 ` Luis Machado
2007-03-02 12:47 ` Emi SUZUKI
2007-03-06 11:00 ` Andreas Schwab
2007-03-06 12:24 ` Daniel Jacobowitz
2007-03-08 8:50 ` Emi SUZUKI
2007-03-08 16:15 ` Ulrich Weigand
2007-03-13 6:12 ` SUZUKI Emi
2007-03-15 22:24 Luis Machado
2007-04-10 20:40 ` Daniel Jacobowitz
2007-04-12 12:09 ` Luis Machado
2007-04-12 12:15 ` Daniel Jacobowitz
2007-04-12 12:54 ` Luis Machado
2007-04-12 12:58 ` Daniel Jacobowitz
2007-04-12 13:30 ` Luis Machado
2007-04-12 13:35 ` Daniel Jacobowitz
2007-04-12 14:58 ` Ulrich Weigand
2007-04-12 15:33 ` Daniel Jacobowitz
2007-04-12 17:16 ` Ulrich Weigand
2007-04-12 18:25 ` Daniel Jacobowitz
2007-04-12 20:09 ` Ulrich Weigand
2007-04-12 20:16 ` Mark Kettenis
2007-04-12 20:43 ` Ulrich Weigand
2007-04-14 15:20 ` Mark Kettenis
2007-04-14 18:13 ` Ulrich Weigand
2007-04-12 20:49 ` Daniel Jacobowitz
2007-04-12 20:48 ` Daniel Jacobowitz
2007-04-12 14:32 ` Ulrich Weigand
2007-04-12 14:47 ` Luis Machado
2007-04-12 15:00 ` Ulrich Weigand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox