892 lines
39 KiB
Diff
892 lines
39 KiB
Diff
From nobody Fri Mar 28 10:36:27 2008
|
|
From: "Ulrich Weigand" <uweigand@de.ibm.com>
|
|
Subject: [rfc] Fix inferior calls during interrupted system calls on PowerPC
|
|
To: gdb-patches@sourceware.org
|
|
Date: Thu, 27 Mar 2008 20:33:51 +0100 (CET)
|
|
|
|
Hello,
|
|
|
|
PowerPC still suffers from a problem that was fixed on other
|
|
platforms a while ago: if GDB wants to perform an inferior
|
|
call while the inferior is blocked in an (interrupted) system
|
|
call, the Linux kernel gets confused.
|
|
|
|
With recent kernel versions (>= 2.6.23 I think), it is possible
|
|
to correctly handle this situation using a similar approach to
|
|
what is currently done on i386: there, GDB informs the kernel
|
|
that it wants to do an inferior call by writing to the "special"
|
|
ORIG_EAX register -- this causes the kernel to not attempt to
|
|
"restart" the system call. After the inferior call is finished,
|
|
the original contents of ORIG_EAX are restored.
|
|
|
|
On PowerPC, the same mechanism is possible, except that there
|
|
are two registers that need to be restored, ORIG_R3 and TRAP.
|
|
When initiating an inferior call, only TRAP has to be reset.
|
|
|
|
The patch below implements this by adding two new registers,
|
|
ORIG_R3 and TRAP to the PowerPC Linux register sets. As these
|
|
are only available on Linux, I've added two new XML features
|
|
powerpc-linux32 and powerpc-linux64 that include these new
|
|
registers.
|
|
|
|
Native code in ppc-linux-nat.c will register that it supports
|
|
those by returning the appropriate feature from ppc_linux_read_description.
|
|
|
|
Similarly, the new ppc_linux_core_read_description routine will
|
|
handle Linux core files.
|
|
|
|
gdbserver is switched to always use powerpc-linux32/64 instead
|
|
of powerpc-32/64. This still leaves the new registers out on
|
|
any non-AltiVec platforms. I guess for powerpc-e500 we could
|
|
create a similar powerpc-linuxe500 feature, if this is required.
|
|
I'm not sure how to handle the default (non-AltiVec, non-SPE)
|
|
case which does not yet use XML. Simply adding registers to
|
|
the .dat files is probably not a good idea as it might break
|
|
old GDBs that connect to the new gdbserver ...
|
|
|
|
Any suggestion how we should handle that? Any other comments
|
|
on this approach are welcome ...
|
|
|
|
Note that the patch below assumes that the AltiVec auto-detection
|
|
patch is already applied.
|
|
|
|
Tested on powerpc-linux and powerpc64-linux, both natively and
|
|
using a local gdbserver. Fixes all interrupt.exp failures.
|
|
|
|
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.
|
|
|
|
|
|
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-03-27 00:05:36.394145047 +0100
|
|
@@ -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-03-27 00:05:36.397144616 +0100
|
|
@@ -0,0 +1,21 @@
|
|
+<?xml version="1.0"?>
|
|
+<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc.
|
|
+
|
|
+ Copying and distribution of this file, with or without modification,
|
|
+ are permitted in any medium without royalty provided the copyright
|
|
+ notice and this notice are preserved. -->
|
|
+
|
|
+<!-- PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only
|
|
+ view of the PowerPC. Includes Linux-only special "registers". -->
|
|
+
|
|
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
|
|
+<target>
|
|
+ <architecture>powerpc:common</architecture>
|
|
+ <xi:include href="power-core.xml"/>
|
|
+ <xi:include href="power-fpu.xml"/>
|
|
+ <feature name="org.gnu.gdb.power.linux">
|
|
+ <reg name="orig_r3" bitsize="32"/>
|
|
+ <reg name="trap" bitsize="32"/>
|
|
+ </feature>
|
|
+ <xi:include href="power-altivec.xml"/>
|
|
+</target>
|
|
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-03-27 00:05:36.403143754 +0100
|
|
@@ -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/ppc-linux-nat.c gdb-head/gdb/ppc-linux-nat.c
|
|
--- gdb-orig/gdb/ppc-linux-nat.c 2008-03-27 00:52:46.050416072 +0100
|
|
+++ gdb-head/gdb/ppc-linux-nat.c 2008-03-27 00:05:36.427140307 +0100
|
|
@@ -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-03-27 00:52:46.093409899 +0100
|
|
+++ gdb-head/gdb/ppc-linux-tdep.c 2008-03-27 00:05:36.471133987 +0100
|
|
@@ -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-03-27 00:52:46.098409181 +0100
|
|
+++ gdb-head/gdb/ppcnbsd-tdep.c 2008-03-27 00:05:36.513127954 +0100
|
|
@@ -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-03-27 00:52:46.102408607 +0100
|
|
+++ gdb-head/gdb/ppcobsd-tdep.c 2008-03-27 00:05:36.517127379 +0100
|
|
@@ -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-03-27 00:52:46.107407889 +0100
|
|
+++ gdb-head/gdb/ppc-tdep.h 2008-03-27 00:05:36.522126661 +0100
|
|
@@ -102,6 +102,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
|
|
@@ -194,6 +198,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 */
|
|
@@ -255,6 +263,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
|
|
};
|
|
|
|
@@ -265,6 +275,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/rs6000-aix-tdep.c gdb-head/gdb/rs6000-aix-tdep.c
|
|
--- gdb-orig/gdb/rs6000-aix-tdep.c 2008-03-27 00:52:46.126405161 +0100
|
|
+++ gdb-head/gdb/rs6000-aix-tdep.c 2008-03-27 00:05:52.840308201 +0100
|
|
@@ -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-03-27 00:52:46.138403438 +0100
|
|
+++ gdb-head/gdb/rs6000-tdep.c 2008-03-27 00:05:52.852306477 +0100
|
|
@@ -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;
|
|
@@ -3415,6 +3432,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)
|
|
{
|
|
@@ -3657,6 +3694,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;
|
|
@@ -3923,6 +3963,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 ();
|
|
@@ -3931,6 +3972,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
|
|
|