Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH]: Fix syscall restart handling on sparc*-linux
@ 2008-05-11 22:03 David Miller
  2008-05-11 22:11 ` Mark Kettenis
  0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2008-05-11 22:03 UTC (permalink / raw)
  To: gdb-patches; +Cc: roland


I've just added a change to the Linux kernel so that gdb can cancel
system call restarting just like powerpc and x86 do under Linux.

I've done this by adding a piece of software state, a single bit, into
the processor state register provided to the debugger, that was
otherwise totally unused before.

The write_pc target method simply clears the bit, which does nothing
on previous kernels, but cancels syscall restart on newer kernels.

This fixes 40 or so testsuite failures.

Ok to commit?

2008-05-11  David S. Miller  <davem@davemloft.net>

	* sparc-linux-tdep.c (sparc_linux_write_pc): New.
	(sparc32_linux_init_abi): Register it.
	* sparc64-linux-tdep.c (sparc64_linux_write_pc): New.
	(sparc64_linux_init_abi): Register it.

Index: gdb/sparc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-linux-tdep.c,v
retrieving revision 1.26
diff -u -r1.26 sparc-linux-tdep.c
--- gdb/sparc-linux-tdep.c	11 May 2008 20:03:25 -0000	1.26
+++ gdb/sparc-linux-tdep.c	11 May 2008 20:12:11 -0000
@@ -211,6 +211,30 @@
   sparc32_collect_fpregset (regcache, regnum, fpregs);
 }
 
+/* Set the program counter for process PTID to PC.  */
+
+static void
+sparc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  ULONGEST psr;
+
+  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
+  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
+
+  /* Clear the "in syscall" bit to prevent the kernel from
+     messing with the PCs we just installed, if we happen to be
+     within an interrupted system call that the kernel wants to
+     restart.
+
+     Note that after we return from the dummy call, the PSR et al.
+     registers will be automatically restored, and the kernel
+     continues to restart the system call at this point.  */
+  regcache_cooked_read_unsigned (regcache, SPARC32_PSR_REGNUM, &psr);
+  psr &= ~0x000004000;
+  regcache_cooked_write_unsigned (regcache, SPARC32_PSR_REGNUM, psr);
+}
+
 \f
 
 static void
@@ -251,6 +275,8 @@
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+
+  set_gdbarch_write_pc (gdbarch, sparc_linux_write_pc);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
Index: gdb/sparc64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-linux-tdep.c,v
retrieving revision 1.20
diff -u -r1.20 sparc64-linux-tdep.c
--- gdb/sparc64-linux-tdep.c	11 May 2008 20:03:26 -0000	1.20
+++ gdb/sparc64-linux-tdep.c	11 May 2008 20:12:11 -0000
@@ -174,6 +174,30 @@
   sparc64_collect_fpregset (regcache, regnum, fpregs);
 }
 
+/* Set the program counter for process PTID to PC.  */
+
+static void
+sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  ULONGEST state;
+
+  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
+  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
+
+  /* Clear the "in syscall" bit to prevent the kernel from
+     messing with the PCs we just installed, if we happen to be
+     within an interrupted system call that the kernel wants to
+     restart.
+
+     Note that after we return from the dummy call, the TSTATE et al.
+     registers will be automatically restored, and the kernel
+     continues to restart the system call at this point.  */
+  regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
+  state &= ~((ULONGEST)0x20);
+  regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
+}
+
 \f
 
 static void
@@ -211,6 +235,8 @@
 
   /* Make sure we can single-step over signal return system calls.  */
   tdep->step_trap = sparc64_linux_step_trap;
+
+  set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);
 }
 \f
 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH]: Fix syscall restart handling on sparc*-linux
  2008-05-11 22:03 [PATCH]: Fix syscall restart handling on sparc*-linux David Miller
@ 2008-05-11 22:11 ` Mark Kettenis
  2008-05-11 22:44   ` David Miller
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Kettenis @ 2008-05-11 22:11 UTC (permalink / raw)
  To: davem; +Cc: gdb-patches, roland

> Date: Sun, 11 May 2008 13:18:50 -0700 (PDT)
> From: David Miller <davem@davemloft.net>
> 
> I've just added a change to the Linux kernel so that gdb can cancel
> system call restarting just like powerpc and x86 do under Linux.
> 
> I've done this by adding a piece of software state, a single bit, into
> the processor state register provided to the debugger, that was
> otherwise totally unused before.

Clever!

> The write_pc target method simply clears the bit, which does nothing
> on previous kernels, but cancels syscall restart on newer kernels.
> 
> This fixes 40 or so testsuite failures.
> 
> Ok to commit?

I wouldn't mind a #define for these bits.  Otherwise, it looks fine to me.

> 2008-05-11  David S. Miller  <davem@davemloft.net>
> 
> 	* sparc-linux-tdep.c (sparc_linux_write_pc): New.
> 	(sparc32_linux_init_abi): Register it.
> 	* sparc64-linux-tdep.c (sparc64_linux_write_pc): New.
> 	(sparc64_linux_init_abi): Register it.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH]: Fix syscall restart handling on sparc*-linux
  2008-05-11 22:11 ` Mark Kettenis
@ 2008-05-11 22:44   ` David Miller
  0 siblings, 0 replies; 3+ messages in thread
From: David Miller @ 2008-05-11 22:44 UTC (permalink / raw)
  To: mark.kettenis; +Cc: gdb-patches, roland

From: Mark Kettenis <mark.kettenis@xs4all.nl>
Date: Sun, 11 May 2008 22:33:34 +0200 (CEST)

> > Date: Sun, 11 May 2008 13:18:50 -0700 (PDT)
> > From: David Miller <davem@davemloft.net>
> > 
> > The write_pc target method simply clears the bit, which does nothing
> > on previous kernels, but cancels syscall restart on newer kernels.
> > 
> > This fixes 40 or so testsuite failures.
> > 
> > Ok to commit?
> 
> I wouldn't mind a #define for these bits.  Otherwise, it looks fine to me.

Done, and installed as follows:

2008-05-11  David S. Miller  <davem@davemloft.net>

	* sparc-linux-tdep.c (PSR_SYSCALL): Define.
	(sparc_linux_write_pc): New function.
	(sparc32_linux_init_abi): Register it.
	* sparc64-linux-tdep.c (TSTATE_SYSCALL): Define.
	(sparc64_linux_write_pc): New function.
	(sparc64_linux_init_abi): Register it.

Index: gdb/sparc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-linux-tdep.c,v
retrieving revision 1.26
diff -u -r1.26 sparc-linux-tdep.c
--- gdb/sparc-linux-tdep.c	11 May 2008 20:03:25 -0000	1.26
+++ gdb/sparc-linux-tdep.c	11 May 2008 22:09:09 -0000
@@ -211,6 +211,32 @@
   sparc32_collect_fpregset (regcache, regnum, fpregs);
 }
 
+/* Set the program counter for process PTID to PC.  */
+
+#define PSR_SYSCALL	0x00004000
+
+static void
+sparc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  ULONGEST psr;
+
+  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
+  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
+
+  /* Clear the "in syscall" bit to prevent the kernel from
+     messing with the PCs we just installed, if we happen to be
+     within an interrupted system call that the kernel wants to
+     restart.
+
+     Note that after we return from the dummy call, the PSR et al.
+     registers will be automatically restored, and the kernel
+     continues to restart the system call at this point.  */
+  regcache_cooked_read_unsigned (regcache, SPARC32_PSR_REGNUM, &psr);
+  psr &= ~PSR_SYSCALL;
+  regcache_cooked_write_unsigned (regcache, SPARC32_PSR_REGNUM, psr);
+}
+
 \f
 
 static void
@@ -251,6 +277,8 @@
 
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
+
+  set_gdbarch_write_pc (gdbarch, sparc_linux_write_pc);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
Index: gdb/sparc64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-linux-tdep.c,v
retrieving revision 1.20
diff -u -r1.20 sparc64-linux-tdep.c
--- gdb/sparc64-linux-tdep.c	11 May 2008 20:03:26 -0000	1.20
+++ gdb/sparc64-linux-tdep.c	11 May 2008 22:09:09 -0000
@@ -174,6 +174,32 @@
   sparc64_collect_fpregset (regcache, regnum, fpregs);
 }
 
+/* Set the program counter for process PTID to PC.  */
+
+#define TSTATE_SYSCALL	0x0000000000000020ULL
+
+static void
+sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  ULONGEST state;
+
+  regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
+  regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
+
+  /* Clear the "in syscall" bit to prevent the kernel from
+     messing with the PCs we just installed, if we happen to be
+     within an interrupted system call that the kernel wants to
+     restart.
+
+     Note that after we return from the dummy call, the TSTATE et al.
+     registers will be automatically restored, and the kernel
+     continues to restart the system call at this point.  */
+  regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
+  state &= ~TSTATE_SYSCALL;
+  regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
+}
+
 \f
 
 static void
@@ -211,6 +237,8 @@
 
   /* Make sure we can single-step over signal return system calls.  */
   tdep->step_trap = sparc64_linux_step_trap;
+
+  set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);
 }
 \f
 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-05-11 22:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-11 22:03 [PATCH]: Fix syscall restart handling on sparc*-linux David Miller
2008-05-11 22:11 ` Mark Kettenis
2008-05-11 22:44   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox