From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20252 invoked by alias); 29 Jan 2008 23:35:49 -0000 Received: (qmail 20239 invoked by uid 22791); 29 Jan 2008 23:35:49 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate2.de.ibm.com (HELO mtagate2.de.ibm.com) (195.212.29.151) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 29 Jan 2008 23:35:20 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate2.de.ibm.com (8.13.8/8.13.8) with ESMTP id m0TNZHq4157326 for ; Tue, 29 Jan 2008 23:35:17 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m0TNZHBe2302076 for ; Wed, 30 Jan 2008 00:35:17 +0100 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m0TNZH0V021518 for ; Wed, 30 Jan 2008 00:35:17 +0100 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id m0TNZHFg021515; Wed, 30 Jan 2008 00:35:17 +0100 Message-Id: <200801292335.m0TNZHFg021515@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Wed, 30 Jan 2008 00:35:17 +0100 Subject: Re: [rfc][3/3] gdbserver bi-arch support: fix s390x partial register access To: drow@false.org (Daniel Jacobowitz) Date: Tue, 29 Jan 2008 23:50:00 -0000 From: "Ulrich Weigand" Cc: gdb-patches@sourceware.org In-Reply-To: <20080129202746.GB15063@caradoc.them.org> from "Daniel Jacobowitz" at Jan 29, 2008 03:27:46 PM X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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-01/txt/msg00744.txt.bz2 Daniel Jacobowitz wrote: > What do you think about passing data to the low target in this case? > For MIPS the right bits will be value-dependent - registers must be > sign extended. Hmm, what about the version below? This should allow the low target whatever flexibility it requires ... Bye, Ulrich ChangeLog: * linux-low.h (struct linux_target_ops): Replace left_pad_xfer field by collect_ptrace_register and supply_ptrace_register hooks. * linux-low.c (fetch_register): Use supply_ptrace_register callback instead of checking for the_low_target.left_pad_xfer. (usr_store_inferior_registers): Use collect_ptrace_register callback instead of checking for the_low_target.left_pad_xfer. * linux-s390-low.c (s390_collect_ptrace_register): New function. (s390_supply_ptrace_register): Likewise. (s390_fill_gregset): Call s390_collect_ptrace_register. (the_low_target): Update. * linux-ppc64-low.c (ppc_collect_ptrace_register): New function. (ppc_supply_ptrace_register): Likewise. (the_low_target): Update. * linux-i386-low.c (the_low_target): Update. * linux-x86-64-low.c (the_low_target): Update. diff -urNp gdb-orig/gdb/gdbserver/linux-i386-low.c gdb-head/gdb/gdbserver/linux-i386-low.c --- gdb-orig/gdb/gdbserver/linux-i386-low.c 2008-01-29 23:21:45.000000000 +0100 +++ gdb-head/gdb/gdbserver/linux-i386-low.c 2008-01-30 00:18:49.000000000 +0100 @@ -205,6 +205,7 @@ struct linux_target_ops the_low_target = NULL, NULL, NULL, - 0, + NULL, + NULL, "i386" }; diff -urNp gdb-orig/gdb/gdbserver/linux-low.c gdb-head/gdb/gdbserver/linux-low.c --- gdb-orig/gdb/gdbserver/linux-low.c 2008-01-29 23:34:20.000000000 +0100 +++ gdb-head/gdb/gdbserver/linux-low.c 2008-01-30 00:12:02.000000000 +0100 @@ -1391,10 +1391,9 @@ fetch_register (int regno) goto error_exit; } } - if (the_low_target.left_pad_xfer - && register_size (regno) < sizeof (PTRACE_XFER_TYPE)) - supply_register (regno, (buf + sizeof (PTRACE_XFER_TYPE) - - register_size (regno))); + + if (the_low_target.supply_ptrace_register) + the_low_target.supply_ptrace_register (regno, buf); else supply_register (regno, buf); @@ -1438,12 +1437,12 @@ usr_store_inferior_registers (int regno) & - sizeof (PTRACE_XFER_TYPE); buf = alloca (size); memset (buf, 0, size); - if (the_low_target.left_pad_xfer - && register_size (regno) < sizeof (PTRACE_XFER_TYPE)) - collect_register (regno, (buf + sizeof (PTRACE_XFER_TYPE) - - register_size (regno))); + + if (the_low_target.collect_ptrace_register) + the_low_target.collect_ptrace_register (regno, buf); else collect_register (regno, buf); + for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; diff -urNp gdb-orig/gdb/gdbserver/linux-low.h gdb-head/gdb/gdbserver/linux-low.h --- gdb-orig/gdb/gdbserver/linux-low.h 2008-01-29 23:21:45.000000000 +0100 +++ gdb-head/gdb/gdbserver/linux-low.h 2008-01-29 23:55:41.000000000 +0100 @@ -69,9 +69,10 @@ struct linux_target_ops int (*stopped_by_watchpoint) (void); CORE_ADDR (*stopped_data_address) (void); - /* Whether to left-pad registers for PEEKUSR/POKEUSR if they are smaller - than an xfer unit. */ - int left_pad_xfer; + /* Hooks to reformat register data for PEEKUSR/POKEUSR (in particular + for registers smaller than an xfer unit). */ + void (*collect_ptrace_register) (int regno, char *buf); + void (*supply_ptrace_register) (int regno, const char *buf); /* What string to report to GDB when it asks for the architecture, or NULL not to answer. */ diff -urNp gdb-orig/gdb/gdbserver/linux-ppc64-low.c gdb-head/gdb/gdbserver/linux-ppc64-low.c --- gdb-orig/gdb/gdbserver/linux-ppc64-low.c 2008-01-29 23:21:45.000000000 +0100 +++ gdb-head/gdb/gdbserver/linux-ppc64-low.c 2008-01-30 00:11:13.000000000 +0100 @@ -64,6 +64,26 @@ ppc_cannot_fetch_register (int regno) return 0; } +static void +ppc_collect_ptrace_register (int regno, char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + collect_register (regno, buf + sizeof (long) - size); + else + collect_register (regno, buf); +} + +static void +ppc_supply_ptrace_register (int regno, const char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + supply_register (regno, buf + sizeof (long) - size); + else + supply_register (regno, buf); +} + static CORE_ADDR ppc_get_pc (void) { @@ -187,5 +207,6 @@ struct linux_target_ops the_low_target = NULL, NULL, NULL, - 1 + ppc_collect_ptrace_register, + ppc_supply_ptrace_register, }; diff -urNp gdb-orig/gdb/gdbserver/linux-s390-low.c gdb-head/gdb/gdbserver/linux-s390-low.c --- gdb-orig/gdb/gdbserver/linux-s390-low.c 2008-01-29 23:34:20.000000000 +0100 +++ gdb-head/gdb/gdbserver/linux-s390-low.c 2008-01-30 00:13:19.000000000 +0100 @@ -79,6 +79,45 @@ s390_cannot_store_register (int regno) return 0; } +static void +s390_collect_ptrace_register (int regno, char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + { + memset (buf, 0, sizeof (long)); + + if (regno == find_regno ("pswa") + || (regno >= find_regno ("r0") && regno <= find_regno ("r15"))) + collect_register (regno, buf + sizeof (long) - size); + else + collect_register (regno, buf); + + /* When debugging a 32-bit inferior on a 64-bit host, make sure + the 31-bit addressing mode bit is set in the PSW mask. */ + if (regno == find_regno ("pswm")) + buf[size] |= 0x80; + } + else + collect_register (regno, buf); +} + +static void +s390_supply_ptrace_register (int regno, const char *buf) +{ + int size = register_size (regno); + if (size < sizeof (long)) + { + if (regno == find_regno ("pswa") + || (regno >= find_regno ("r0") && regno <= find_regno ("r15"))) + supply_register (regno, buf + sizeof (long) - size); + else + supply_register (regno, buf); + } + else + supply_register (regno, buf); +} + /* Provide only a fill function for the general register set. ps_lgetregs will use this for NPTL support. */ @@ -87,7 +126,7 @@ static void s390_fill_gregset (void *buf int i; for (i = 0; i < 34; i++) - collect_register (i, (char *) buf + s390_regmap[i]); + s390_collect_ptrace_register (i, (char *) buf + s390_regmap[i]); } struct regset_info target_regsets[] = { @@ -179,5 +218,11 @@ struct linux_target_ops the_low_target = NULL, s390_breakpoint_len, s390_breakpoint_at, + NULL, + NULL, + NULL, + NULL, + s390_collect_ptrace_register, + s390_supply_ptrace_register, }; diff -urNp gdb-orig/gdb/gdbserver/linux-x86-64-low.c gdb-head/gdb/gdbserver/linux-x86-64-low.c --- gdb-orig/gdb/gdbserver/linux-x86-64-low.c 2008-01-29 23:21:45.000000000 +0100 +++ gdb-head/gdb/gdbserver/linux-x86-64-low.c 2008-01-30 00:19:33.000000000 +0100 @@ -179,6 +179,7 @@ struct linux_target_ops the_low_target = NULL, NULL, NULL, - 0, + NULL, + NULL, "i386:x86-64", }; -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com