int wordsize = sizeof (PTRACE_XFER_TYPE);
/* General purpose registers occupy 1 slot each in the buffer */
- if (regno >= tdep->ppc_gp0_regnum && regno <= tdep->ppc_gplast_regnum )
- u_addr = ((PT_R0 + regno) * wordsize);
+ 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 (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
- u_addr = (PT_FPR0 * wordsize) + ((regno - FP0_REGNUM) * 8);
+ if (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 == PC_REGNUM)
static void
fetch_register (int tid, int regno)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
/* This isn't really an address. But ptrace thinks of it as one. */
char mess[128]; /* For messages */
int i;
/* Now supply the register. Be careful to map between ptrace's and
the current_regcache's idea of the current wordsize. */
- if ((regno >= FP0_REGNUM && regno < FP0_REGNUM +32)
+ if ((regno >= tdep->ppc_fp0_regnum
+ && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
|| gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
/* FPs are always 64 bits. Little endian values are always found
at the left-hand end of the register. */
int i;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
- fetch_register (tid, i);
+ for (i = 0; i < ppc_num_gprs; i++)
+ fetch_register (tid, tdep->ppc_gp0_regnum + i);
+ if (tdep->ppc_fp0_regnum >= 0)
+ for (i = 0; i < ppc_num_fprs; i++)
+ fetch_register (tid, tdep->ppc_fp0_regnum + i);
+ fetch_register (tid, PC_REGNUM);
+ if (tdep->ppc_ps_regnum != -1)
+ fetch_register (tid, tdep->ppc_ps_regnum);
+ if (tdep->ppc_cr_regnum != -1)
+ fetch_register (tid, tdep->ppc_cr_regnum);
+ if (tdep->ppc_lr_regnum != -1)
+ fetch_register (tid, tdep->ppc_lr_regnum);
+ if (tdep->ppc_ctr_regnum != -1)
+ fetch_register (tid, tdep->ppc_ctr_regnum);
+ if (tdep->ppc_xer_regnum != -1)
+ fetch_register (tid, tdep->ppc_xer_regnum);
if (tdep->ppc_mq_regnum != -1)
fetch_register (tid, tdep->ppc_mq_regnum);
+ if (tdep->ppc_fpscr_regnum != -1)
+ fetch_register (tid, tdep->ppc_fpscr_regnum);
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
fetch_altivec_registers (tid);
static void
store_register (int tid, int regno)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr = ppc_register_u_addr (regno);
char mess[128]; /* For messages */
/* First collect the register value from the regcache. Be careful
to to convert the regcache's wordsize into ptrace's wordsize. */
memset (buf, 0, sizeof buf);
- if ((regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
+ if ((regno >= tdep->ppc_fp0_regnum
+ && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
|| TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
/* Floats are always 64-bit. Little endian registers are always
at the left-hand end of the register cache. */
int i;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- for (i = 0; i <= tdep->ppc_fpscr_regnum; i++)
- store_register (tid, i);
+ for (i = 0; i < ppc_num_gprs; i++)
+ store_register (tid, tdep->ppc_gp0_regnum + i);
+ if (tdep->ppc_fp0_regnum >= 0)
+ for (i = 0; i < ppc_num_fprs; i++)
+ store_register (tid, tdep->ppc_fp0_regnum + i);
+ store_register (tid, PC_REGNUM);
+ if (tdep->ppc_ps_regnum != -1)
+ store_register (tid, tdep->ppc_ps_regnum);
+ if (tdep->ppc_cr_regnum != -1)
+ store_register (tid, tdep->ppc_cr_regnum);
+ if (tdep->ppc_lr_regnum != -1)
+ store_register (tid, tdep->ppc_lr_regnum);
+ if (tdep->ppc_ctr_regnum != -1)
+ store_register (tid, tdep->ppc_ctr_regnum);
+ if (tdep->ppc_xer_regnum != -1)
+ store_register (tid, tdep->ppc_xer_regnum);
if (tdep->ppc_mq_regnum != -1)
store_register (tid, tdep->ppc_mq_regnum);
+ if (tdep->ppc_fpscr_regnum != -1)
+ store_register (tid, tdep->ppc_fpscr_regnum);
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
store_altivec_registers (tid);
void
supply_gregset (gdb_gregset_t *gregsetp)
{
- ppc_linux_supply_gregset ((char *) gregsetp);
+ /* 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 (PTRACE_XFER_TYPE);
+ ppc_linux_supply_gregset (current_regcache, -1, gregsetp,
+ sizeof (gdb_gregset_t), wordsize);
+}
+
+static void
+right_fill_reg (int regnum, void *reg)
+{
+ /* 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 (PTRACE_XFER_TYPE);
+ /* Right fill the register. */
+ regcache_raw_collect (current_regcache, regnum,
+ ((bfd_byte *) reg
+ + wordsize
+ - register_size (current_gdbarch, regnum)));
}
void
int regi;
elf_greg_t *regp = (elf_greg_t *) gregsetp;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const int elf_ngreg = 48;
+
+
+ /* Start with zeros. */
+ memset (regp, 0, elf_ngreg * sizeof (*regp));
for (regi = 0; regi < 32; regi++)
{
if ((regno == -1) || regno == regi)
- regcache_collect (regi, regp + PT_R0 + regi);
+ right_fill_reg (regi, (regp + PT_R0 + regi));
}
if ((regno == -1) || regno == PC_REGNUM)
- regcache_collect (PC_REGNUM, regp + PT_NIP);
+ right_fill_reg (PC_REGNUM, regp + PT_NIP);
if ((regno == -1) || regno == tdep->ppc_lr_regnum)
- regcache_collect (tdep->ppc_lr_regnum, regp + PT_LNK);
+ right_fill_reg (tdep->ppc_lr_regnum, regp + PT_LNK);
if ((regno == -1) || regno == tdep->ppc_cr_regnum)
regcache_collect (tdep->ppc_cr_regnum, regp + PT_CCR);
if ((regno == -1) || regno == tdep->ppc_xer_regnum)
regcache_collect (tdep->ppc_xer_regnum, regp + PT_XER);
if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
- regcache_collect (tdep->ppc_ctr_regnum, regp + PT_CTR);
+ right_fill_reg (tdep->ppc_ctr_regnum, regp + PT_CTR);
#ifdef PT_MQ
if (((regno == -1) || regno == tdep->ppc_mq_regnum)
&& (tdep->ppc_mq_regnum != -1))
- regcache_collect (tdep->ppc_mq_regnum, regp + PT_MQ);
+ right_fill_reg (tdep->ppc_mq_regnum, regp + PT_MQ);
#endif
if ((regno == -1) || regno == tdep->ppc_ps_regnum)
- regcache_collect (tdep->ppc_ps_regnum, regp + PT_MSR);
+ right_fill_reg (tdep->ppc_ps_regnum, regp + PT_MSR);
}
void
supply_fpregset (gdb_fpregset_t * fpregsetp)
{
- ppc_linux_supply_fpregset ((char *) fpregsetp);
+ ppc_linux_supply_fpregset (NULL, current_regcache, -1, fpregsetp,
+ sizeof (gdb_fpregset_t));
}
/* Given a pointer to a floating point register set in /proc format
{
int regi;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ bfd_byte *fpp = (void *) fpregsetp;
for (regi = 0; regi < 32; regi++)
{
- if ((regno == -1) || (regno == FP0_REGNUM + regi))
- regcache_collect (FP0_REGNUM + regi, (char *) (*fpregsetp + regi));
+ if ((regno == -1) || (regno == tdep->ppc_fp0_regnum + regi))
+ regcache_collect (tdep->ppc_fp0_regnum + regi, fpp + 8 * regi);
}
if ((regno == -1) || regno == tdep->ppc_fpscr_regnum)
- regcache_collect (tdep->ppc_fpscr_regnum, (char *) (*fpregsetp + regi));
+ right_fill_reg (tdep->ppc_fpscr_regnum, (fpp + 8 * 32));
}