From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21168 invoked by alias); 25 Apr 2008 14:26:02 -0000 Received: (qmail 21036 invoked by uid 22791); 25 Apr 2008 14:25:54 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate8.de.ibm.com (HELO mtagate8.de.ibm.com) (195.212.29.157) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 25 Apr 2008 14:25:27 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate8.de.ibm.com (8.13.8/8.13.8) with ESMTP id m3PEPNaa079934 for ; Fri, 25 Apr 2008 14:25:23 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 m3PEPNPC3010604 for ; Fri, 25 Apr 2008 16:25:23 +0200 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 m3PEPGhp011594 for ; Fri, 25 Apr 2008 16:25:17 +0200 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 m3PEPGp6011396; Fri, 25 Apr 2008 16:25:16 +0200 Message-Id: <200804251425.m3PEPGp6011396@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Fri, 25 Apr 2008 16:25:10 +0200 Subject: [rfa, v2] Fix inferior calls during interrupted system calls on PowerPC To: gdb-patches@sourceware.org, drow@false.org Date: Fri, 25 Apr 2008 16:16:00 -0000 From: "Ulrich Weigand" In-Reply-To: <200803271933.m2RJXpRS017283@d12av02.megacenter.de.ibm.com> from "Ulrich Weigand" at Mar 27, 2008 08:33:51 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-04/txt/msg00573.txt.bz2 Hello, this is an updated version of the patch to fix inferior system calls during interrupted system calls on PowerPC Linux: http://sourceware.org/ml/gdb-patches/2008-03/msg00452.html Retested on powerpc-linux and powerpc64-linux, both natively and using a local gdbserver. Fixes all interrupt.exp failures. Dan, are the remote/gdbserver parts of this patch OK? Bye, Ulrich ChangeLog: * ppc-tdep.h (struct ppc_reg_offsets): New members orig_r3_offset and trap_offset. (struct gdbarch_tdep): New members ppc_orig_r3_regnum and ppc_trap_regnum. (PPC_ORIG_R3_REGNUM, PPC_TRAP_REGNUM): New enum members. (tdesc_powerpc_linux32, tdesc_powerpc_linux64): Declare. * rs6000-tdep.c: Include features/rs6000/powerpc-linux32.c and features/rs6000/powerpc-linux64.c. (ppc_greg_offset): Handle orig_r3 and trap. (ppc_supply_gregset, ppu_collect_gregset): Likewise. (rs6000_gdbarch_init): Handle org.gnu.gdb.power.linux feature. Set up ppc_orig_r3_regnum and ppc_trap_regnum tdep entries. (_initialize_rs6000_tdep): Call initialize_tdesc_powerpc_linux32 and initialize_tdesc_powerpc_linux64 * ppc-linux-tdep.c (ppc32_linux_reg_offsets): Initialize orig_r3_offset and trap_offset fields. (ppc64_linux_reg_offsets): Likewise. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install them. * ppcnbsd-tdep.c (_initialize_ppcnbsd_tdep): Initialize ppcnbsd_reg_offsets.orig_r3_offset and ppcnbsd_reg_offsets.trap_offset. * ppcobsd-tdep.c (_initialize_ppcobsd_tdep): Initialize ppcobsd_reg_offsets.orig_r3_offset and ppcobsd_reg_offsets.trap_offset. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Initialize orig_r3_offset and trap_offset fields. (rs6000_aix64_reg_offsets): Likewise. * ppc-linux-nat.c (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap. (fetch_ppc_registers, store_ppc_registers, store_register): Likewise. (ppc_linux_read_description): Return tdesc_powerpc_linux32 or tdesc_powerpc_linux64 as appropriate. * features/Makefile (WHICH): Use rs6000/powerpc-linux32 instead of rs6000/powerpc-32 and rs6000/powerpc-linux64 instead of rs6000/powerpc-64. Update -expedite variables accordingly. * features/rs6000/powerpc-linux32.xml: New file. * features/rs6000/powerpc-linux64.xml: New file. * features/rs6000/powerpc-linux32.c: New (generated) file. * features/rs6000/powerpc-linux64.c: New (generated) file. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-linux32.dat: New (generated) file. * regformats/rs6000/powerpc-linux64.dat: New (generated) file. gdbserver/ChangeLog: * Makefile.in: Replace powerpc-32 by powerpc-linux32 and powerpc-64 by powerpc-linux64 throughout. * configure.srv: Likewise. * linux-ppc-low.c (init_registers_powerpc_32): Replace by ... (init_registers_powerpc_linux32): ... this new declaration. (init_registers_powerpc_64): Replace by ... (init_registers_powerpc_linux64): ... this new declaration. (ppc_linux_num_regs): New define. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. Re-set the_low_target.num_regs to the appropriate value for the register set that is installed. (ppc_fill_gregset): Handle orig_r3 and trap. diff -urNp gdb-orig/gdb/features/Makefile gdb-head/gdb/features/Makefile --- gdb-orig/gdb/features/Makefile 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/features/Makefile 2008-04-22 23:17:19.188304086 +0200 @@ -32,15 +32,15 @@ # make GDB=/path/to/gdb XMLTOC="xml files" cfiles WHICH = arm-with-iwmmxt mips-linux mips64-linux \ - rs6000/powerpc-32 rs6000/powerpc-e500 rs6000/powerpc-64 + rs6000/powerpc-linux32 rs6000/powerpc-e500 rs6000/powerpc-linux64 # Record which registers should be sent to GDB by default after stop. arm-with-iwmmxt-expedite = r11,sp,pc mips-linux-expedite = r29,pc mips64-linux-expedite = r29,pc -rs6000/powerpc-32-expedite = r1,pc +rs6000/powerpc-linux32-expedite = r1,pc rs6000/powerpc-e500-expedite = r1,pc -rs6000/powerpc-64-expedite = r1,pc +rs6000/powerpc-linux64-expedite = r1,pc XSLTPROC = xsltproc outdir = ../regformats diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux32.c gdb-head/gdb/features/rs6000/powerpc-linux32.c --- gdb-orig/gdb/features/rs6000/powerpc-linux32.c 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux32.c 2008-04-22 23:17:19.194303224 +0200 @@ -0,0 +1,168 @@ +/* THIS FILE IS GENERATED. Original: powerpc-linux32.xml */ + +#include "defs.h" +#include "gdbtypes.h" +#include "target-descriptions.h" + +struct target_desc *tdesc_powerpc_linux32; +static void +initialize_tdesc_powerpc_linux32 (void) +{ + struct target_desc *result = allocate_target_description (); + struct tdesc_feature *feature; + struct type *field_type, *type; + + set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); + tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); + tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); + tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + field_type = tdesc_named_type (feature, "ieee_single"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4f"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int32"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4i32"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int16"); + type = init_vector_type (field_type, 8); + TYPE_NAME (type) = xstrdup ("v8i16"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int8"); + type = init_vector_type (field_type, 16); + TYPE_NAME (type) = xstrdup ("v16i8"); + tdesc_record_type (feature, type); + + type = init_composite_type (NULL, TYPE_CODE_UNION); + TYPE_NAME (type) = xstrdup ("vec128"); + field_type = tdesc_named_type (feature, "uint128"); + append_composite_type_field (type, xstrdup ("uint128"), field_type); + field_type = tdesc_named_type (feature, "v4f"); + append_composite_type_field (type, xstrdup ("v4_float"), field_type); + field_type = tdesc_named_type (feature, "v4i32"); + append_composite_type_field (type, xstrdup ("v4_int32"), field_type); + field_type = tdesc_named_type (feature, "v8i16"); + append_composite_type_field (type, xstrdup ("v8_int16"), field_type); + field_type = tdesc_named_type (feature, "v16i8"); + append_composite_type_field (type, xstrdup ("v16_int8"), field_type); + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + tdesc_record_type (feature, type); + + tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); + tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); + + tdesc_powerpc_linux32 = result; +} diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux32.xml gdb-head/gdb/features/rs6000/powerpc-linux32.xml --- gdb-orig/gdb/features/rs6000/powerpc-linux32.xml 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux32.xml 2008-04-22 23:17:19.198302650 +0200 @@ -0,0 +1,21 @@ + + + + + + + + powerpc:common + + + + + + + + diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux64.c gdb-head/gdb/features/rs6000/powerpc-linux64.c --- gdb-orig/gdb/features/rs6000/powerpc-linux64.c 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux64.c 2008-04-22 23:17:19.202302076 +0200 @@ -0,0 +1,168 @@ +/* THIS FILE IS GENERATED. Original: powerpc-linux64.xml */ + +#include "defs.h" +#include "gdbtypes.h" +#include "target-descriptions.h" + +struct target_desc *tdesc_powerpc_linux64; +static void +initialize_tdesc_powerpc_linux64 (void) +{ + struct target_desc *result = allocate_target_description (); + struct tdesc_feature *feature; + struct type *field_type, *type; + + set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); + tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); + tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); + tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + field_type = tdesc_named_type (feature, "ieee_single"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4f"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int32"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4i32"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int16"); + type = init_vector_type (field_type, 8); + TYPE_NAME (type) = xstrdup ("v8i16"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int8"); + type = init_vector_type (field_type, 16); + TYPE_NAME (type) = xstrdup ("v16i8"); + tdesc_record_type (feature, type); + + type = init_composite_type (NULL, TYPE_CODE_UNION); + TYPE_NAME (type) = xstrdup ("vec128"); + field_type = tdesc_named_type (feature, "uint128"); + append_composite_type_field (type, xstrdup ("uint128"), field_type); + field_type = tdesc_named_type (feature, "v4f"); + append_composite_type_field (type, xstrdup ("v4_float"), field_type); + field_type = tdesc_named_type (feature, "v4i32"); + append_composite_type_field (type, xstrdup ("v4_int32"), field_type); + field_type = tdesc_named_type (feature, "v8i16"); + append_composite_type_field (type, xstrdup ("v8_int16"), field_type); + field_type = tdesc_named_type (feature, "v16i8"); + append_composite_type_field (type, xstrdup ("v16_int8"), field_type); + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + tdesc_record_type (feature, type); + + tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); + tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); + + tdesc_powerpc_linux64 = result; +} diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux64.xml gdb-head/gdb/features/rs6000/powerpc-linux64.xml --- gdb-orig/gdb/features/rs6000/powerpc-linux64.xml 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux64.xml 2008-04-22 23:17:19.206301501 +0200 @@ -0,0 +1,21 @@ + + + + + + + + powerpc:common64 + + + + + + + + diff -urNp gdb-orig/gdb/gdbserver/configure.srv gdb-head/gdb/gdbserver/configure.srv --- gdb-orig/gdb/gdbserver/configure.srv 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/gdbserver/configure.srv 2008-04-22 23:18:35.143960979 +0200 @@ -106,16 +106,16 @@ case "${target}" in srv_linux_usrregs=yes srv_linux_thread_db=yes ;; - powerpc*-*-linux*) srv_regobj="reg-ppc.o powerpc-32.o powerpc-e500.o" - srv_regobj="${srv_regobj} reg-ppc64.o powerpc-64.o" + powerpc*-*-linux*) srv_regobj="reg-ppc.o powerpc-linux32.o powerpc-e500.o" + srv_regobj="${srv_regobj} reg-ppc64.o powerpc-linux64.o" srv_tgtobj="linux-low.o linux-ppc-low.o" - srv_xmlfiles="rs6000/powerpc-32.xml" + srv_xmlfiles="rs6000/powerpc-linux32.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" - srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-linux64.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml" srv_linux_usrregs=yes srv_linux_regsets=yes diff -urNp gdb-orig/gdb/gdbserver/linux-ppc-low.c gdb-head/gdb/gdbserver/linux-ppc-low.c --- gdb-orig/gdb/gdbserver/linux-ppc-low.c 2008-04-21 22:30:21.000000000 +0200 +++ gdb-head/gdb/gdbserver/linux-ppc-low.c 2008-04-22 23:20:45.930988056 +0200 @@ -33,16 +33,25 @@ static unsigned long ppc_hwcap; /* Defined in auto-generated file reg-ppc.c. */ void init_registers_ppc (void); -/* Defined in auto-generated file powerpc-32.c. */ -void init_registers_powerpc_32 (void); +/* Defined in auto-generated file powerpc-linux32.c. */ +void init_registers_powerpc_linux32 (void); /* Defined in auto-generated file powerpc-e500.c. */ void init_registers_powerpc_e500 (void); /* Defined in auto-generated file reg-ppc64.c. */ void init_registers_ppc64 (void); -/* Defined in auto-generated file powerpc-64.c. */ -void init_registers_powerpc_64 (void); +/* Defined in auto-generated file powerpc-linux64.c. */ +void init_registers_powerpc_linux64 (void); #define ppc_num_regs 71 +#define ppc_linux_num_regs 73 + +/* This sometimes isn't defined. */ +#ifndef PT_ORIG_R3 +#define PT_ORIG_R3 34 +#endif +#ifndef PT_TRAP +#define PT_TRAP 40 +#endif #ifdef __powerpc64__ /* We use a constant for FPSCR instead of PT_FPSCR, because @@ -65,7 +74,9 @@ static int ppc_regmap[] = PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216, PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248, PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8, - PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256 }; + PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256, + PT_ORIG_R3 * 8, PT_TRAP * 8 + }; #else /* Currently, don't check/send MQ. */ static int ppc_regmap[] = @@ -86,7 +97,8 @@ static int ppc_regmap[] = PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216, PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248, PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, - PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4 + PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, + PT_ORIG_R3 * 4, PT_TRAP * 4 }; static int ppc_regmap_e500[] = @@ -107,7 +119,8 @@ static int ppc_regmap_e500[] = -1, -1, -1, -1, -1, -1, -1, -1, PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, - PT_CTR * 4, PT_XER * 4, -1 + PT_CTR * 4, PT_XER * 4, -1, + PT_ORIG_R3 * 4, PT_TRAP * 4 }; #endif @@ -120,6 +133,11 @@ ppc_cannot_store_register (int regno) return 2; #endif + /* Some kernels do not allow us to store orig_r3 or trap. */ + if (regno == find_regno ("orig_r3") + || regno == find_regno ("trap")) + return 2; + return 0; } @@ -227,6 +245,7 @@ ppc_arch_setup (void) AltiVec registers. Reset ppc_hwcap to ensure that the collect_register call below does not fail. */ init_registers_ppc64 (); + the_low_target.num_regs = ppc_num_regs; ppc_hwcap = 0; /* Only if the high bit of the MSR is set, we actually have @@ -236,7 +255,10 @@ ppc_arch_setup (void) { ppc_get_hwcap (&ppc_hwcap); if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC) - init_registers_powerpc_64 (); + { + init_registers_powerpc_linux64 (); + the_low_target.num_regs = ppc_linux_num_regs; + } return; } @@ -244,10 +266,14 @@ ppc_arch_setup (void) /* OK, we have a 32-bit inferior. */ init_registers_ppc (); + the_low_target.num_regs = ppc_num_regs; ppc_get_hwcap (&ppc_hwcap); if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC) - init_registers_powerpc_32 (); + { + init_registers_powerpc_linux32 (); + the_low_target.num_regs = ppc_linux_num_regs; + } /* On 32-bit machines, check for SPE registers. Set the low target's regmap field as appropriately. */ @@ -292,6 +318,10 @@ static void ppc_fill_gregset (void *buf) for (i = 64; i < 70; i++) ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]); + + if (the_low_target.num_regs >= 73) + for (i = 71; i < 73; i++) + ppc_collect_ptrace_register (i, (char *) buf + ppc_regmap[i]); } #ifndef PTRACE_GETVRREGS diff -urNp gdb-orig/gdb/gdbserver/Makefile.in gdb-head/gdb/gdbserver/Makefile.in --- gdb-orig/gdb/gdbserver/Makefile.in 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/gdbserver/Makefile.in 2008-04-22 23:17:19.226298629 +0200 @@ -222,7 +222,7 @@ clean: rm -f reg-ppc.c reg-sh.c reg-spu.c reg-x86-64.c reg-i386-linux.c rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-xtensa.c rm -f arm-with-iwmmxt.c mips-linux.c mips64-linux.c - rm -f powerpc-32.c powerpc-64.c powerpc-e500.c + rm -f powerpc-linux32.c powerpc-linux64.c powerpc-e500.c rm -f xml-builtin.c stamp-xml maintainer-clean realclean distclean: clean @@ -366,15 +366,15 @@ reg-ppc.c : $(srcdir)/../regformats/reg- reg-ppc64.o : reg-ppc64.c $(regdef_h) reg-ppc64.c : $(srcdir)/../regformats/reg-ppc64.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-ppc64.dat reg-ppc64.c -powerpc-32.o : powerpc-32.c $(regdef_h) -powerpc-32.c : $(srcdir)/../regformats/rs6000/powerpc-32.dat $(regdat_sh) - $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-32.dat powerpc-32.c +powerpc-linux32.o : powerpc-linux32.c $(regdef_h) +powerpc-linux32.c : $(srcdir)/../regformats/rs6000/powerpc-linux32.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-linux32.dat powerpc-linux32.c powerpc-e500.o : powerpc-e500.c $(regdef_h) powerpc-e500.c : $(srcdir)/../regformats/rs6000/powerpc-e500.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-e500.dat powerpc-e500.c -powerpc-64.o : powerpc-64.c $(regdef_h) -powerpc-64.c : $(srcdir)/../regformats/rs6000/powerpc-64.dat $(regdat_sh) - $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-64.dat powerpc-64.c +powerpc-linux64.o : powerpc-linux64.c $(regdef_h) +powerpc-linux64.c : $(srcdir)/../regformats/rs6000/powerpc-linux64.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-linux64.dat powerpc-linux64.c reg-s390.o : reg-s390.c $(regdef_h) reg-s390.c : $(srcdir)/../regformats/reg-s390.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-s390.dat reg-s390.c diff -urNp gdb-orig/gdb/ppc-linux-nat.c gdb-head/gdb/ppc-linux-nat.c --- gdb-orig/gdb/ppc-linux-nat.c 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/ppc-linux-nat.c 2008-04-22 23:17:19.233297624 +0200 @@ -43,6 +43,14 @@ #include "gregset.h" #include "ppc-tdep.h" +/* This sometimes isn't defined. */ +#ifndef PT_ORIG_R3 +#define PT_ORIG_R3 34 +#endif +#ifndef PT_TRAP +#define PT_TRAP 40 +#endif + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a configure time check. Some older glibc's (for instance 2.2.1) don't have a specific powerpc version of ptrace.h, and fall back on @@ -200,6 +208,10 @@ ppc_register_u_addr (struct gdbarch *gdb #endif if (regno == tdep->ppc_ps_regnum) u_addr = PT_MSR * wordsize; + if (regno == tdep->ppc_orig_r3_regnum) + u_addr = PT_ORIG_R3 * wordsize; + if (regno == tdep->ppc_trap_regnum) + u_addr = PT_TRAP * wordsize; if (tdep->ppc_fpscr_regnum >= 0 && regno == tdep->ppc_fpscr_regnum) { @@ -476,6 +488,10 @@ fetch_ppc_registers (struct regcache *re fetch_register (regcache, tid, tdep->ppc_xer_regnum); if (tdep->ppc_mq_regnum != -1) fetch_register (regcache, tid, tdep->ppc_mq_regnum); + if (tdep->ppc_orig_r3_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_orig_r3_regnum); + if (tdep->ppc_trap_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_trap_regnum); if (tdep->ppc_fpscr_regnum != -1) fetch_register (regcache, tid, tdep->ppc_fpscr_regnum); if (have_ptrace_getvrregs) @@ -676,9 +692,12 @@ store_register (const struct regcache *r regaddr += sizeof (long); if (errno == EIO - && regno == tdep->ppc_fpscr_regnum) + && (regno == tdep->ppc_fpscr_regnum + || regno == tdep->ppc_orig_r3_regnum + || regno == tdep->ppc_trap_regnum)) { - /* Some older kernel versions don't allow fpscr to be written. */ + /* Some older kernel versions don't allow fpscr, orig_r3 + or trap to be written. */ continue; } @@ -763,6 +782,10 @@ store_ppc_registers (const struct regcac store_register (regcache, tid, tdep->ppc_xer_regnum); if (tdep->ppc_mq_regnum != -1) store_register (regcache, tid, tdep->ppc_mq_regnum); + if (tdep->ppc_orig_r3_regnum != -1) + store_register (regcache, tid, tdep->ppc_orig_r3_regnum); + if (tdep->ppc_trap_regnum != -1) + store_register (regcache, tid, tdep->ppc_trap_regnum); if (tdep->ppc_fpscr_regnum != -1) store_register (regcache, tid, tdep->ppc_fpscr_regnum); if (have_ptrace_getvrregs) @@ -964,16 +987,31 @@ ppc_linux_read_description (struct targe return tdesc_powerpc_e500; else { - /* EIO means that the PTRACE_GETEVRREGS request isn't supported. */ - if (errno == EIO) - return NULL; - else - /* Anything else needs to be reported. */ + /* EIO means that the PTRACE_GETEVRREGS request isn't supported. + Anything else needs to be reported. */ + if (errno != EIO) perror_with_name (_("Unable to fetch SPE registers")); } } - return NULL; + /* Check for 64-bit inferior process. This is the case when the host is + 64-bit, and in addition the top bit of the MSR register is set. */ +#ifdef __powerpc64__ + { + long msr; + + int tid = TIDGET (inferior_ptid); + if (tid == 0) + tid = PIDGET (inferior_ptid); + + errno = 0; + msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0); + if (errno == 0 && msr < 0) + return tdesc_powerpc_linux64; + } +#endif + + return tdesc_powerpc_linux32; } void _initialize_ppc_linux_nat (void); diff -urNp gdb-orig/gdb/ppc-linux-tdep.c gdb-head/gdb/ppc-linux-tdep.c --- gdb-orig/gdb/ppc-linux-tdep.c 2008-04-22 23:14:47.096017000 +0200 +++ gdb-head/gdb/ppc-linux-tdep.c 2008-04-22 23:17:19.239296763 +0200 @@ -656,7 +656,11 @@ static const struct ppc_reg_offsets ppc3 /* AltiVec registers. */ /* .vr0_offset = */ 0, /* .vscr_offset = */ 512 + 12, - /* .vrsave_offset = */ 528 + /* .vrsave_offset = */ 528, + + /* Linux-specific registers. */ + /* .orig_r3_offset = */ 136, + /* .trap_offset = */ 160 }; static const struct ppc_reg_offsets ppc64_linux_reg_offsets = @@ -681,7 +685,11 @@ static const struct ppc_reg_offsets ppc6 /* AltiVec registers. */ /* .vr0_offset = */ 0, /* .vscr_offset = */ 512 + 12, - /* .vrsave_offset = */ 528 + /* .vrsave_offset = */ 528, + + /* Linux-specific registers. */ + /* .orig_r3_offset = */ 272, + /* .trap_offset = */ 320 }; static const struct regset ppc32_linux_gregset = { @@ -895,6 +903,50 @@ static struct tramp_frame ppc64_linux_si ppc64_linux_sighandler_cache_init }; + +static void +ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch), pc); + + /* Set special TRAP register to -1 to prevent the kernel from + messing with the PC 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 TRAP and + ORIG_R3 registers will be automatically restored, and the + kernel continues to restart the system call at this point. */ + regcache_cooked_write_unsigned (regcache, tdep->ppc_trap_regnum, -1); +} + + +static const struct target_desc * +ppc_linux_core_read_description (struct gdbarch *gdbarch, + struct target_ops *target, + bfd *abfd) +{ + asection *section = bfd_get_section_by_name (abfd, ".reg"); + if (! section) + return NULL; + + switch (bfd_section_size (abfd, section)) + { + case 48 * 4: + return tdesc_powerpc_linux32; + + case 48 * 8: + return tdesc_powerpc_linux64; + + default: + return NULL; + } +} + + static void ppc_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -914,6 +966,9 @@ ppc_linux_init_abi (struct gdbarch_info set_gdbarch_convert_from_func_ptr_addr (gdbarch, ppc_linux_convert_from_func_ptr_addr); + /* Handle inferior calls during interrupted system calls. */ + set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc); + if (tdep->wordsize == 4) { /* Until November 2001, gcc did not comply with the 32 bit SysV @@ -951,6 +1006,7 @@ ppc_linux_init_abi (struct gdbarch_info tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame); } set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section); + set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description); /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, diff -urNp gdb-orig/gdb/ppcnbsd-tdep.c gdb-head/gdb/ppcnbsd-tdep.c --- gdb-orig/gdb/ppcnbsd-tdep.c 2008-04-22 23:14:47.218999000 +0200 +++ gdb-head/gdb/ppcnbsd-tdep.c 2008-04-22 23:17:19.244296045 +0200 @@ -231,5 +231,9 @@ _initialize_ppcnbsd_tdep (void) ppcnbsd_reg_offsets.vr0_offset = 0; ppcnbsd_reg_offsets.vrsave_offset = 512; ppcnbsd_reg_offsets.vscr_offset = 524; + + /* Linux-specific registers. */ + ppcnbsd_reg_offsets.orig_r3_offset = -1; + ppcnbsd_reg_offsets.trap_offset = -1; } } diff -urNp gdb-orig/gdb/ppcobsd-tdep.c gdb-head/gdb/ppcobsd-tdep.c --- gdb-orig/gdb/ppcobsd-tdep.c 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/ppcobsd-tdep.c 2008-04-22 23:17:19.248295470 +0200 @@ -325,6 +325,10 @@ _initialize_ppcobsd_tdep (void) ppcobsd_reg_offsets.vr0_offset = 0; ppcobsd_reg_offsets.vscr_offset = 512; ppcobsd_reg_offsets.vrsave_offset = 520; + + /* Linux-specific registers. */ + ppcobsd_reg_offsets.orig_r3_offset = -1; + ppcobsd_reg_offsets.trap_offset = -1; } if (ppcobsd_fpreg_offsets.fpscr_offset == 0) diff -urNp gdb-orig/gdb/ppc-tdep.h gdb-head/gdb/ppc-tdep.h --- gdb-orig/gdb/ppc-tdep.h 2008-04-22 23:14:47.173006000 +0200 +++ gdb-head/gdb/ppc-tdep.h 2008-04-22 23:17:19.264293173 +0200 @@ -105,6 +105,10 @@ struct ppc_reg_offsets int vr0_offset; int vscr_offset; int vrsave_offset; + + /* Linux-specific registers. Size in gpr_size. */ + int orig_r3_offset; + int trap_offset; }; /* Supply register REGNUM in the general-purpose register set REGSET @@ -197,6 +201,10 @@ struct gdbarch_tdep /* Multiplier-Quotient Register (older POWER architectures only). */ int ppc_mq_regnum; + /* Linux-specific registers. */ + int ppc_orig_r3_regnum; /* GPR3 at syscall entry. */ + int ppc_trap_regnum; /* Syscall trap code. */ + /* Altivec registers. */ int ppc_vr0_regnum; /* First AltiVec register */ int ppc_vrsave_regnum; /* Last AltiVec register */ @@ -258,6 +266,8 @@ enum { PPC_VR0_REGNUM = 106, PPC_VSCR_REGNUM = 138, PPC_VRSAVE_REGNUM = 139, + PPC_ORIG_R3_REGNUM = 140, + PPC_TRAP_REGNUM = 141, PPC_NUM_REGS }; @@ -268,6 +278,8 @@ enum { /* Estimate for the maximum number of instrctions in a function epilogue. */ #define PPC_MAX_EPILOGUE_INSTRUCTIONS 52 +extern struct target_desc *tdesc_powerpc_linux32; +extern struct target_desc *tdesc_powerpc_linux64; extern struct target_desc *tdesc_powerpc_e500; #endif /* ppc-tdep.h */ diff -urNp gdb-orig/gdb/regformats/rs6000/powerpc-32.dat gdb-head/gdb/regformats/rs6000/powerpc-32.dat --- gdb-orig/gdb/regformats/rs6000/powerpc-32.dat 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/regformats/rs6000/powerpc-32.dat 1970-01-01 01:00:00.000000000 +0100 @@ -1,109 +0,0 @@ -# DO NOT EDIT: generated from rs6000/powerpc-32.xml -name:powerpc_32 -xmltarget:powerpc-32.xml -expedite:r1,pc -32:r0 -32:r1 -32:r2 -32:r3 -32:r4 -32:r5 -32:r6 -32:r7 -32:r8 -32:r9 -32:r10 -32:r11 -32:r12 -32:r13 -32:r14 -32:r15 -32:r16 -32:r17 -32:r18 -32:r19 -32:r20 -32:r21 -32:r22 -32:r23 -32:r24 -32:r25 -32:r26 -32:r27 -32:r28 -32:r29 -32:r30 -32:r31 -64:f0 -64:f1 -64:f2 -64:f3 -64:f4 -64:f5 -64:f6 -64:f7 -64:f8 -64:f9 -64:f10 -64:f11 -64:f12 -64:f13 -64:f14 -64:f15 -64:f16 -64:f17 -64:f18 -64:f19 -64:f20 -64:f21 -64:f22 -64:f23 -64:f24 -64:f25 -64:f26 -64:f27 -64:f28 -64:f29 -64:f30 -64:f31 -32:pc -32:msr -32:cr -32:lr -32:ctr -32:xer -32:fpscr -128:vr0 -128:vr1 -128:vr2 -128:vr3 -128:vr4 -128:vr5 -128:vr6 -128:vr7 -128:vr8 -128:vr9 -128:vr10 -128:vr11 -128:vr12 -128:vr13 -128:vr14 -128:vr15 -128:vr16 -128:vr17 -128:vr18 -128:vr19 -128:vr20 -128:vr21 -128:vr22 -128:vr23 -128:vr24 -128:vr25 -128:vr26 -128:vr27 -128:vr28 -128:vr29 -128:vr30 -128:vr31 -32:vscr -32:vrsave diff -urNp gdb-orig/gdb/regformats/rs6000/powerpc-64.dat gdb-head/gdb/regformats/rs6000/powerpc-64.dat --- gdb-orig/gdb/regformats/rs6000/powerpc-64.dat 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/regformats/rs6000/powerpc-64.dat 1970-01-01 01:00:00.000000000 +0100 @@ -1,109 +0,0 @@ -# DO NOT EDIT: generated from rs6000/powerpc-64.xml -name:powerpc_64 -xmltarget:powerpc-64.xml -expedite:r1,pc -64:r0 -64:r1 -64:r2 -64:r3 -64:r4 -64:r5 -64:r6 -64:r7 -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:r16 -64:r17 -64:r18 -64:r19 -64:r20 -64:r21 -64:r22 -64:r23 -64:r24 -64:r25 -64:r26 -64:r27 -64:r28 -64:r29 -64:r30 -64:r31 -64:f0 -64:f1 -64:f2 -64:f3 -64:f4 -64:f5 -64:f6 -64:f7 -64:f8 -64:f9 -64:f10 -64:f11 -64:f12 -64:f13 -64:f14 -64:f15 -64:f16 -64:f17 -64:f18 -64:f19 -64:f20 -64:f21 -64:f22 -64:f23 -64:f24 -64:f25 -64:f26 -64:f27 -64:f28 -64:f29 -64:f30 -64:f31 -64:pc -64:msr -32:cr -64:lr -64:ctr -32:xer -32:fpscr -128:vr0 -128:vr1 -128:vr2 -128:vr3 -128:vr4 -128:vr5 -128:vr6 -128:vr7 -128:vr8 -128:vr9 -128:vr10 -128:vr11 -128:vr12 -128:vr13 -128:vr14 -128:vr15 -128:vr16 -128:vr17 -128:vr18 -128:vr19 -128:vr20 -128:vr21 -128:vr22 -128:vr23 -128:vr24 -128:vr25 -128:vr26 -128:vr27 -128:vr28 -128:vr29 -128:vr30 -128:vr31 -32:vscr -32:vrsave diff -urNp gdb-orig/gdb/regformats/rs6000/powerpc-linux32.dat gdb-head/gdb/regformats/rs6000/powerpc-linux32.dat --- gdb-orig/gdb/regformats/rs6000/powerpc-linux32.dat 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/regformats/rs6000/powerpc-linux32.dat 2008-04-22 23:17:19.289289583 +0200 @@ -0,0 +1,111 @@ +# DO NOT EDIT: generated from rs6000/powerpc-linux32.xml +name:powerpc_linux32 +xmltarget:powerpc-linux32.xml +expedite:r1,pc +32:r0 +32:r1 +32:r2 +32:r3 +32:r4 +32:r5 +32:r6 +32:r7 +32:r8 +32:r9 +32:r10 +32:r11 +32:r12 +32:r13 +32:r14 +32:r15 +32:r16 +32:r17 +32:r18 +32:r19 +32:r20 +32:r21 +32:r22 +32:r23 +32:r24 +32:r25 +32:r26 +32:r27 +32:r28 +32:r29 +32:r30 +32:r31 +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 +64:f16 +64:f17 +64:f18 +64:f19 +64:f20 +64:f21 +64:f22 +64:f23 +64:f24 +64:f25 +64:f26 +64:f27 +64:f28 +64:f29 +64:f30 +64:f31 +32:pc +32:msr +32:cr +32:lr +32:ctr +32:xer +32:fpscr +32:orig_r3 +32:trap +128:vr0 +128:vr1 +128:vr2 +128:vr3 +128:vr4 +128:vr5 +128:vr6 +128:vr7 +128:vr8 +128:vr9 +128:vr10 +128:vr11 +128:vr12 +128:vr13 +128:vr14 +128:vr15 +128:vr16 +128:vr17 +128:vr18 +128:vr19 +128:vr20 +128:vr21 +128:vr22 +128:vr23 +128:vr24 +128:vr25 +128:vr26 +128:vr27 +128:vr28 +128:vr29 +128:vr30 +128:vr31 +32:vscr +32:vrsave diff -urNp gdb-orig/gdb/regformats/rs6000/powerpc-linux64.dat gdb-head/gdb/regformats/rs6000/powerpc-linux64.dat --- gdb-orig/gdb/regformats/rs6000/powerpc-linux64.dat 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/regformats/rs6000/powerpc-linux64.dat 2008-04-22 23:17:19.293289009 +0200 @@ -0,0 +1,111 @@ +# DO NOT EDIT: generated from rs6000/powerpc-linux64.xml +name:powerpc_linux64 +xmltarget:powerpc-linux64.xml +expedite:r1,pc +64:r0 +64:r1 +64:r2 +64:r3 +64:r4 +64:r5 +64:r6 +64:r7 +64:r8 +64:r9 +64:r10 +64:r11 +64:r12 +64:r13 +64:r14 +64:r15 +64:r16 +64:r17 +64:r18 +64:r19 +64:r20 +64:r21 +64:r22 +64:r23 +64:r24 +64:r25 +64:r26 +64:r27 +64:r28 +64:r29 +64:r30 +64:r31 +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 +64:f16 +64:f17 +64:f18 +64:f19 +64:f20 +64:f21 +64:f22 +64:f23 +64:f24 +64:f25 +64:f26 +64:f27 +64:f28 +64:f29 +64:f30 +64:f31 +64:pc +64:msr +32:cr +64:lr +64:ctr +32:xer +32:fpscr +64:orig_r3 +64:trap +128:vr0 +128:vr1 +128:vr2 +128:vr3 +128:vr4 +128:vr5 +128:vr6 +128:vr7 +128:vr8 +128:vr9 +128:vr10 +128:vr11 +128:vr12 +128:vr13 +128:vr14 +128:vr15 +128:vr16 +128:vr17 +128:vr18 +128:vr19 +128:vr20 +128:vr21 +128:vr22 +128:vr23 +128:vr24 +128:vr25 +128:vr26 +128:vr27 +128:vr28 +128:vr29 +128:vr30 +128:vr31 +32:vscr +32:vrsave diff -urNp gdb-orig/gdb/rs6000-aix-tdep.c gdb-head/gdb/rs6000-aix-tdep.c --- gdb-orig/gdb/rs6000-aix-tdep.c 2008-04-21 20:51:47.000000000 +0200 +++ gdb-head/gdb/rs6000-aix-tdep.c 2008-04-22 23:17:19.297288434 +0200 @@ -52,7 +52,11 @@ static struct ppc_reg_offsets rs6000_aix /* AltiVec registers. */ -1, /* vr0_offset */ -1, /* vscr_offset */ - -1 /* vrsave_offset */ + -1, /* vrsave_offset */ + + /* Linux-specific registers. */ + -1, /* orig_r3_offset */ + -1 /* trap_offset */ }; static struct ppc_reg_offsets rs6000_aix64_reg_offsets = @@ -77,7 +81,11 @@ static struct ppc_reg_offsets rs6000_aix /* AltiVec registers. */ -1, /* vr0_offset */ -1, /* vscr_offset */ - -1 /* vrsave_offset */ + -1, /* vrsave_offset */ + + /* Linux-specific registers. */ + -1, /* orig_r3_offset */ + -1 /* trap_offset */ }; diff -urNp gdb-orig/gdb/rs6000-tdep.c gdb-head/gdb/rs6000-tdep.c --- gdb-orig/gdb/rs6000-tdep.c 2008-04-22 23:14:47.314986000 +0200 +++ gdb-head/gdb/rs6000-tdep.c 2008-04-22 23:17:19.325284414 +0200 @@ -64,6 +64,7 @@ #include "rs6000-tdep.h" #include "features/rs6000/powerpc-32.c" +#include "features/rs6000/powerpc-linux32.c" #include "features/rs6000/powerpc-403.c" #include "features/rs6000/powerpc-403gc.c" #include "features/rs6000/powerpc-505.c" @@ -72,6 +73,7 @@ #include "features/rs6000/powerpc-603.c" #include "features/rs6000/powerpc-604.c" #include "features/rs6000/powerpc-64.c" +#include "features/rs6000/powerpc-linux64.c" #include "features/rs6000/powerpc-7400.c" #include "features/rs6000/powerpc-750.c" #include "features/rs6000/powerpc-860.c" @@ -448,6 +450,12 @@ ppc_greg_offset (struct gdbarch *gdbarch if (regnum == tdep->ppc_ctr_regnum) return offsets->ctr_offset; + if (regnum == tdep->ppc_orig_r3_regnum) + return offsets->orig_r3_offset; + + if (regnum == tdep->ppc_trap_regnum) + return offsets->trap_offset; + *regsize = offsets->xr_size; if (regnum == tdep->ppc_cr_regnum) return offsets->cr_offset; @@ -526,6 +534,10 @@ ppc_supply_gregset (const struct regset gregs, offsets->lr_offset, gpr_size); ppc_supply_reg (regcache, tdep->ppc_ctr_regnum, gregs, offsets->ctr_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_orig_r3_regnum, + gregs, offsets->orig_r3_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_trap_regnum, + gregs, offsets->trap_offset, gpr_size); ppc_supply_reg (regcache, tdep->ppc_cr_regnum, gregs, offsets->cr_offset, offsets->xr_size); ppc_supply_reg (regcache, tdep->ppc_xer_regnum, @@ -654,6 +666,10 @@ ppc_collect_gregset (const struct regset gregs, offsets->lr_offset, gpr_size); ppc_collect_reg (regcache, tdep->ppc_ctr_regnum, gregs, offsets->ctr_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_orig_r3_regnum, + gregs, offsets->orig_r3_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_trap_regnum, + gregs, offsets->trap_offset, gpr_size); ppc_collect_reg (regcache, tdep->ppc_cr_regnum, gregs, offsets->cr_offset, offsets->xr_size); ppc_collect_reg (regcache, tdep->ppc_xer_regnum, @@ -3267,6 +3283,7 @@ rs6000_gdbarch_init (struct gdbarch_info int soft_float; enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0; + int have_linux_regs = 0; int tdesc_wordsize = -1; const struct target_desc *tdesc = info.target_desc; struct tdesc_arch_data *tdesc_data = NULL; @@ -3406,6 +3423,26 @@ rs6000_gdbarch_init (struct gdbarch_info wordsize = tdesc_wordsize; feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.linux"); + if (feature != NULL) + { + valid_p = 1; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_ORIG_R3_REGNUM, "orig_r3"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_TRAP_REGNUM, "trap"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_linux_regs = 1; + } + else + have_linux_regs = 0; + + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.power.fpu"); if (feature != NULL) { @@ -3648,6 +3685,9 @@ rs6000_gdbarch_init (struct gdbarch_info tdep->ppc_xer_regnum = PPC_XER_REGNUM; tdep->ppc_mq_regnum = have_mq ? PPC_MQ_REGNUM : -1; + tdep->ppc_orig_r3_regnum = have_linux_regs ? PPC_ORIG_R3_REGNUM : -1; + tdep->ppc_trap_regnum = have_linux_regs ? PPC_TRAP_REGNUM : -1; + tdep->ppc_fp0_regnum = have_fpu ? PPC_F0_REGNUM : -1; tdep->ppc_fpscr_regnum = have_fpu ? PPC_FPSCR_REGNUM : -1; tdep->ppc_vr0_regnum = have_altivec ? PPC_VR0_REGNUM : -1; @@ -3914,6 +3954,7 @@ _initialize_rs6000_tdep (void) /* Initialize the standard target descriptions. */ initialize_tdesc_powerpc_32 (); + initialize_tdesc_powerpc_linux32 (); initialize_tdesc_powerpc_403 (); initialize_tdesc_powerpc_403gc (); initialize_tdesc_powerpc_505 (); @@ -3922,6 +3963,7 @@ _initialize_rs6000_tdep (void) initialize_tdesc_powerpc_603 (); initialize_tdesc_powerpc_604 (); initialize_tdesc_powerpc_64 (); + initialize_tdesc_powerpc_linux64 (); initialize_tdesc_powerpc_7400 (); initialize_tdesc_powerpc_750 (); initialize_tdesc_powerpc_860 (); -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com