+#include <sys/ptrace.h>
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+#include "ppc-tdep.h"
+#include "ppc-linux-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
+ a generic one. In such cases, sys/ptrace.h defines
+ PTRACE_GETFPXREGS and PTRACE_SETFPXREGS to the same numbers that
+ ppc kernel's asm/ptrace.h defines PTRACE_GETVRREGS and
+ PTRACE_SETVRREGS to be. This also makes a configury check pretty
+ much useless. */
+
+/* These definitions should really come from the glibc header files,
+ but Glibc doesn't know about the vrregs yet. */
+#ifndef PTRACE_GETVRREGS
+#define PTRACE_GETVRREGS 18
+#define PTRACE_SETVRREGS 19
+#endif
+
+
+/* Similarly for the ptrace requests for getting / setting the SPE
+ registers (ev0 -- ev31, acc, and spefscr). See the description of
+ gdb_evrregset_t for details. */
+#ifndef PTRACE_GETEVRREGS
+#define PTRACE_GETEVRREGS 20
+#define PTRACE_SETEVRREGS 21
+#endif
+
+/* Similarly for the hardware watchpoint support. */
+#ifndef PTRACE_GET_DEBUGREG
+#define PTRACE_GET_DEBUGREG 25
+#endif
+#ifndef PTRACE_SET_DEBUGREG
+#define PTRACE_SET_DEBUGREG 26
+#endif
+#ifndef PTRACE_GETSIGINFO
+#define PTRACE_GETSIGINFO 0x4202
+#endif
+
+/* This oddity is because the Linux kernel defines elf_vrregset_t as
+ an array of 33 16 bytes long elements. I.e. it leaves out vrsave.
+ However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return
+ the vrsave as an extra 4 bytes at the end. I opted for creating a
+ flat array of chars, so that it is easier to manipulate for gdb.
+
+ There are 32 vector registers 16 bytes longs, plus a VSCR register
+ which is only 4 bytes long, but is fetched as a 16 bytes
+ quantity. Up to here we have the elf_vrregset_t structure.
+ Appended to this there is space for the VRSAVE register: 4 bytes.
+ Even though this vrsave register is not included in the regset
+ typedef, it is handled by the ptrace requests.
+
+ Note that GNU/Linux doesn't support little endian PPC hardware,
+ therefore the offset at which the real value of the VSCR register
+ is located will be always 12 bytes.
+
+ The layout is like this (where x is the actual value of the vscr reg): */
+
+/* *INDENT-OFF* */
+/*
+ |.|.|.|.|.....|.|.|.|.||.|.|.|x||.|
+ <-------> <-------><-------><->
+ VR0 VR31 VSCR VRSAVE
+*/
+/* *INDENT-ON* */
+
+#define SIZEOF_VRREGS 33*16+4
+
+typedef char gdb_vrregset_t[SIZEOF_VRREGS];
+
+
+/* On PPC processors that support the the Signal Processing Extension
+ (SPE) APU, the general-purpose registers are 64 bits long.
+ However, the ordinary Linux kernel PTRACE_PEEKUSER / PTRACE_POKEUSER
+ ptrace calls only access the lower half of each register, to allow
+ them to behave the same way they do on non-SPE systems. There's a
+ separate pair of calls, PTRACE_GETEVRREGS / PTRACE_SETEVRREGS, that
+ read and write the top halves of all the general-purpose registers
+ at once, along with some SPE-specific registers.
+
+ GDB itself continues to claim the general-purpose registers are 32
+ bits long. It has unnamed raw registers that hold the upper halves
+ of the gprs, and the the full 64-bit SIMD views of the registers,
+ 'ev0' -- 'ev31', are pseudo-registers that splice the top and
+ bottom halves together.
+
+ This is the structure filled in by PTRACE_GETEVRREGS and written to
+ the inferior's registers by PTRACE_SETEVRREGS. */
+struct gdb_evrregset_t
+{
+ unsigned long evr[32];
+ unsigned long long acc;
+ unsigned long spefscr;
+};
+
+
+/* Non-zero if our kernel may support the PTRACE_GETVRREGS and
+ PTRACE_SETVRREGS requests, for reading and writing the Altivec
+ registers. Zero if we've tried one of them and gotten an
+ error. */
+int have_ptrace_getvrregs = 1;
+
+/* Non-zero if our kernel may support the PTRACE_GETEVRREGS and
+ PTRACE_SETEVRREGS requests, for reading and writing the SPE
+ registers. Zero if we've tried one of them and gotten an
+ error. */
+int have_ptrace_getsetevrregs = 1;
+
+/* *INDENT-OFF* */
+/* registers layout, as presented by the ptrace interface:
+PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
+PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_R13, PT_R14, PT_R15,
+PT_R16, PT_R17, PT_R18, PT_R19, PT_R20, PT_R21, PT_R22, PT_R23,
+PT_R24, PT_R25, PT_R26, PT_R27, PT_R28, PT_R29, PT_R30, PT_R31,
+PT_FPR0, PT_FPR0 + 2, PT_FPR0 + 4, PT_FPR0 + 6, PT_FPR0 + 8, PT_FPR0 + 10, PT_FPR0 + 12, PT_FPR0 + 14,
+PT_FPR0 + 16, PT_FPR0 + 18, PT_FPR0 + 20, PT_FPR0 + 22, PT_FPR0 + 24, PT_FPR0 + 26, PT_FPR0 + 28, PT_FPR0 + 30,
+PT_FPR0 + 32, PT_FPR0 + 34, PT_FPR0 + 36, PT_FPR0 + 38, PT_FPR0 + 40, PT_FPR0 + 42, PT_FPR0 + 44, PT_FPR0 + 46,
+PT_FPR0 + 48, PT_FPR0 + 50, PT_FPR0 + 52, PT_FPR0 + 54, PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
+PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
+/* *INDENT_ON * */
+
+static int
+ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
+{
+ int u_addr = -1;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
+ interface, and not the wordsize of the program's ABI. */
+ int wordsize = sizeof (long);
+
+ /* General purpose registers occupy 1 slot each in the buffer */
+ if (regno >= tdep->ppc_gp0_regnum
+ && regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
+ u_addr = ((regno - tdep->ppc_gp0_regnum + PT_R0) * wordsize);
+
+ /* Floating point regs: eight bytes each in both 32- and 64-bit
+ ptrace interfaces. Thus, two slots each in 32-bit interface, one
+ slot each in 64-bit interface. */
+ if (tdep->ppc_fp0_regnum >= 0
+ && regno >= tdep->ppc_fp0_regnum
+ && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
+ u_addr = (PT_FPR0 * wordsize) + ((regno - tdep->ppc_fp0_regnum) * 8);
+
+ /* UISA special purpose registers: 1 slot each */
+ if (regno == gdbarch_pc_regnum (gdbarch))
+ u_addr = PT_NIP * wordsize;
+ if (regno == tdep->ppc_lr_regnum)
+ u_addr = PT_LNK * wordsize;
+ if (regno == tdep->ppc_cr_regnum)
+ u_addr = PT_CCR * wordsize;
+ if (regno == tdep->ppc_xer_regnum)
+ u_addr = PT_XER * wordsize;
+ if (regno == tdep->ppc_ctr_regnum)
+ u_addr = PT_CTR * wordsize;
+#ifdef PT_MQ
+ if (regno == tdep->ppc_mq_regnum)
+ u_addr = PT_MQ * wordsize;
+#endif
+ if (regno == tdep->ppc_ps_regnum)
+ u_addr = PT_MSR * wordsize;
+ if (regno == PPC_ORIG_R3_REGNUM)
+ u_addr = PT_ORIG_R3 * wordsize;
+ if (regno == PPC_TRAP_REGNUM)
+ u_addr = PT_TRAP * wordsize;
+ if (tdep->ppc_fpscr_regnum >= 0
+ && regno == tdep->ppc_fpscr_regnum)
+ {
+ /* NOTE: cagney/2005-02-08: On some 64-bit GNU/Linux systems the
+ kernel headers incorrectly contained the 32-bit definition of
+ PT_FPSCR. For the 32-bit definition, floating-point
+ registers occupy two 32-bit "slots", and the FPSCR lives in
+ the secondhalf of such a slot-pair (hence +1). For 64-bit,
+ the FPSCR instead occupies the full 64-bit 2-word-slot and
+ hence no adjustment is necessary. Hack around this. */
+ if (wordsize == 8 && PT_FPSCR == (48 + 32 + 1))
+ u_addr = (48 + 32) * wordsize;
+ else
+ u_addr = PT_FPSCR * wordsize;
+ }
+ return u_addr;
+}
+
+/* The Linux kernel ptrace interface for AltiVec registers uses the
+ registers set mechanism, as opposed to the interface for all the
+ other registers, that stores/fetches each register individually. */
+static void
+fetch_altivec_register (struct regcache *regcache, int tid, int regno)
+{
+ int ret;
+ int offset = 0;
+ gdb_vrregset_t regs;
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
+
+ ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s);
+ if (ret < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getvrregs = 0;
+ return;
+ }
+ perror_with_name (_("Unable to fetch AltiVec register"));
+ }
+
+ /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
+ long on the hardware. We deal only with the lower 4 bytes of the
+ vector. VRSAVE is at the end of the array in a 4 bytes slot, so
+ there is no need to define an offset for it. */
+ if (regno == (tdep->ppc_vrsave_regnum - 1))
+ offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
+
+ regcache_raw_supply (regcache, regno,
+ regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset);
+}
+
+/* Fetch the top 32 bits of TID's general-purpose registers and the
+ SPE-specific registers, and place the results in EVRREGSET. If we
+ don't support PTRACE_GETEVRREGS, then just fill EVRREGSET with
+ zeros.
+
+ All the logic to deal with whether or not the PTRACE_GETEVRREGS and
+ PTRACE_SETEVRREGS requests are supported is isolated here, and in
+ set_spe_registers. */
+static void
+get_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
+{
+ if (have_ptrace_getsetevrregs)
+ {
+ if (ptrace (PTRACE_GETEVRREGS, tid, 0, evrregset) >= 0)
+ return;
+ else
+ {
+ /* EIO means that the PTRACE_GETEVRREGS request isn't supported;
+ we just return zeros. */
+ if (errno == EIO)
+ have_ptrace_getsetevrregs = 0;
+ else
+ /* Anything else needs to be reported. */
+ perror_with_name (_("Unable to fetch SPE registers"));
+ }
+ }
+
+ memset (evrregset, 0, sizeof (*evrregset));
+}
+
+/* Supply values from TID for SPE-specific raw registers: the upper
+ halves of the GPRs, the accumulator, and the spefscr. REGNO must
+ be the number of an upper half register, acc, spefscr, or -1 to
+ supply the values of all registers. */
+static void
+fetch_spe_register (struct regcache *regcache, int tid, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ struct gdb_evrregset_t evrregs;
+
+ gdb_assert (sizeof (evrregs.evr[0])
+ == register_size (gdbarch, tdep->ppc_ev0_upper_regnum));
+ gdb_assert (sizeof (evrregs.acc)
+ == register_size (gdbarch, tdep->ppc_acc_regnum));
+ gdb_assert (sizeof (evrregs.spefscr)
+ == register_size (gdbarch, tdep->ppc_spefscr_regnum));
+
+ get_spe_registers (tid, &evrregs);
+
+ if (regno == -1)
+ {
+ int i;
+
+ for (i = 0; i < ppc_num_gprs; i++)
+ regcache_raw_supply (regcache, tdep->ppc_ev0_upper_regnum + i,
+ &evrregs.evr[i]);
+ }
+ else if (tdep->ppc_ev0_upper_regnum <= regno
+ && regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
+ regcache_raw_supply (regcache, regno,
+ &evrregs.evr[regno - tdep->ppc_ev0_upper_regnum]);
+
+ if (regno == -1
+ || regno == tdep->ppc_acc_regnum)
+ regcache_raw_supply (regcache, tdep->ppc_acc_regnum, &evrregs.acc);
+
+ if (regno == -1
+ || regno == tdep->ppc_spefscr_regnum)
+ regcache_raw_supply (regcache, tdep->ppc_spefscr_regnum,
+ &evrregs.spefscr);
+}
+
+static void
+fetch_register (struct regcache *regcache, int tid, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ /* This isn't really an address. But ptrace thinks of it as one. */
+ CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno);
+ int bytes_transferred;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char buf[MAX_REGISTER_SIZE];