From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17074 invoked by alias); 11 May 2008 22:11:23 -0000 Received: (qmail 17063 invoked by uid 22791); 11 May 2008 22:11:23 -0000 X-Spam-Check-By: sourceware.org Received: from 74-93-104-97-Washington.hfc.comcastbusiness.net (HELO sunset.davemloft.net) (74.93.104.97) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 11 May 2008 22:11:05 +0000 Received: from localhost (localhost [127.0.0.1]) by sunset.davemloft.net (Postfix) with ESMTP id 0993EC8C2D6; Sun, 11 May 2008 15:10:59 -0700 (PDT) Date: Sun, 11 May 2008 22:44:00 -0000 Message-Id: <20080511.151058.76271725.davem@davemloft.net> To: mark.kettenis@xs4all.nl Cc: gdb-patches@sourceware.org, roland@redhat.com Subject: Re: [PATCH]: Fix syscall restart handling on sparc*-linux From: David Miller In-Reply-To: <200805112033.m4BKXYXQ010781@brahms.sibelius.xs4all.nl> References: <20080511.131850.175173142.davem@davemloft.net> <200805112033.m4BKXYXQ010781@brahms.sibelius.xs4all.nl> X-Mailer: Mew version 5.2 on Emacs 22.1 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-05/txt/msg00371.txt.bz2 From: Mark Kettenis Date: Sun, 11 May 2008 22:33:34 +0200 (CEST) > > Date: Sun, 11 May 2008 13:18:50 -0700 (PDT) > > From: David Miller > > > > 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 * 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); +} + 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); +} + 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); }