From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28394 invoked by alias); 10 May 2005 16:54:53 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 28341 invoked from network); 10 May 2005 16:54:48 -0000 Received: from unknown (HELO mtagate4.de.ibm.com) (195.212.29.153) by sourceware.org with SMTP; 10 May 2005 16:54:48 -0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate4.de.ibm.com (8.12.10/8.12.10) with ESMTP id j4AGsmqF152744 for ; Tue, 10 May 2005 16:54:48 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.12.10/NCO/VER6.6) with ESMTP id j4AGsmnC287088 for ; Tue, 10 May 2005 18:54:48 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11/8.13.3) with ESMTP id j4AGslEc019598 for ; Tue, 10 May 2005 18:54:47 +0200 Received: from 53v30g15.boeblingen.de.ibm.com (53v30g15.boeblingen.de.ibm.com [9.152.26.155]) by d12av02.megacenter.de.ibm.com (8.12.11/8.12.11) with ESMTP id j4AGslcp019595 for ; Tue, 10 May 2005 18:54:47 +0200 Received: from 53v30g15.boeblingen.de.ibm.com (localhost [127.0.0.1]) by 53v30g15.boeblingen.de.ibm.com (8.12.10/8.12.10) with ESMTP id j4AGsUql028710 for ; Tue, 10 May 2005 18:54:30 +0200 Received: (from uweigand@localhost) by 53v30g15.boeblingen.de.ibm.com (8.12.10/8.12.10/Submit) id j4AGsTCj028703 for gdb-patches@sources.redhat.com; Tue, 10 May 2005 18:54:29 +0200 From: Ulrich Weigand Message-Id: <200505101654.j4AGsTCj028703@53v30g15.boeblingen.de.ibm.com> Subject: [RFA] gdbserver fetch/store registers problem on s390x To: gdb-patches@sources.redhat.com Date: Tue, 10 May 2005 19:48:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2005-05/txt/msg00225.txt.bz2 Hello, this patch fixes another problem with gdbserver on s390x occurring on recent kernels. The problem is that some registers accessed by ptrace (notably the access registers and the floating-point status register) are still 32 bits wide, even though the PTRACE_PEEKUSER and PTRACE_POKEUSER commands always transfer 64 bits. This is a problem for two reasons: when fetching those registers, a 4-byte buffer is allocated via alloca, but then 8 bytes are written to that buffer (which just happens to work because alloca rounds the size up to the next multiple of 8 anyway). The same holds for storing the register; but in this case the second 4 bytes have just random contents, and recent kernels won't allow the POKEUSER command to succeed unless those extra bytes are zero. The following patch fixes this problem by always allocating a buffer that has multiple of sizeof (PTRACE_XFER_TYPE) as size, and by zeroing out the excess bytes of the buffer when storing the register. Tested on s390-ibm-linux and s390x-ibm-linux. OK? Bye, Ulrich ChangeLog: * linux-low.c (fetch_register): Ensure buffer size is a multiple of sizeof (PTRACE_XFER_TYPE). (usr_store_inferior_registers): Likewise. Zero out excess bytes. Index: gdb/gdbserver/linux-low.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v retrieving revision 1.34 diff -c -p -r1.34 linux-low.c *** gdb/gdbserver/linux-low.c 3 Mar 2005 16:56:53 -0000 1.34 --- gdb/gdbserver/linux-low.c 10 May 2005 11:53:40 -0000 *************** static void *** 1095,1101 **** fetch_register (int regno) { CORE_ADDR regaddr; ! register int i; char *buf; if (regno >= the_low_target.num_regs) --- 1095,1101 ---- fetch_register (int regno) { CORE_ADDR regaddr; ! int i, size; char *buf; if (regno >= the_low_target.num_regs) *************** fetch_register (int regno) *** 1106,1113 **** regaddr = register_addr (regno); if (regaddr == -1) return; ! buf = alloca (register_size (regno)); ! for (i = 0; i < register_size (regno); i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; *(PTRACE_XFER_TYPE *) (buf + i) = --- 1106,1115 ---- regaddr = register_addr (regno); if (regaddr == -1) return; ! size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1) ! & - sizeof (PTRACE_XFER_TYPE); ! buf = alloca (size); ! for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; *(PTRACE_XFER_TYPE *) (buf + i) = *************** static void *** 1147,1153 **** usr_store_inferior_registers (int regno) { CORE_ADDR regaddr; ! int i; char *buf; if (regno >= 0) --- 1149,1155 ---- usr_store_inferior_registers (int regno) { CORE_ADDR regaddr; ! int i, size; char *buf; if (regno >= 0) *************** usr_store_inferior_registers (int regno) *** 1162,1170 **** if (regaddr == -1) return; errno = 0; ! buf = alloca (register_size (regno)); collect_register (regno, buf); ! for (i = 0; i < register_size (regno); i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, --- 1164,1175 ---- if (regaddr == -1) return; errno = 0; ! size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1) ! & - sizeof (PTRACE_XFER_TYPE); ! buf = alloca (size); ! memset (buf, 0, size); collect_register (regno, buf); ! for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, -- Dr. Ulrich Weigand Linux on zSeries Development Ulrich.Weigand@de.ibm.com