This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdb_string.h"
u_addr = (PT_FPR0 * wordsize) + ((regno - tdep->ppc_fp0_regnum) * 8);
/* UISA special purpose registers: 1 slot each */
- if (regno == PC_REGNUM)
+ if (regno == gdbarch_pc_regnum (current_gdbarch))
u_addr = PT_NIP * wordsize;
if (regno == tdep->ppc_lr_regnum)
u_addr = PT_LNK * wordsize;
if (tdep->ppc_fp0_regnum >= 0)
for (i = 0; i < ppc_num_fprs; i++)
fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i);
- fetch_register (regcache, tid, PC_REGNUM);
+ fetch_register (regcache, tid, gdbarch_pc_regnum (current_gdbarch));
if (tdep->ppc_ps_regnum != -1)
fetch_register (regcache, tid, tdep->ppc_ps_regnum);
if (tdep->ppc_cr_regnum != -1)
if (tdep->ppc_fp0_regnum >= 0)
for (i = 0; i < ppc_num_fprs; i++)
store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
- store_register (regcache, tid, PC_REGNUM);
+ store_register (regcache, tid, gdbarch_pc_regnum (current_gdbarch));
if (tdep->ppc_ps_regnum != -1)
store_register (regcache, tid, tdep->ppc_ps_regnum);
if (tdep->ppc_cr_regnum != -1)
store_ppc_registers (regcache, tid);
}
+/* Functions for transferring registers between a gregset_t or fpregset_t
+ (see sys/ucontext.h) and gdb's regcache. The word size is that used
+ by the ptrace interface, not the current program's ABI. eg. If a
+ powerpc64-linux gdb is being used to debug a powerpc32-linux app, we
+ read or write 64-bit gregsets. This is to suit the host libthread_db. */
+
void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *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 (long);
- ppc_linux_supply_gregset (regcache, -1, gregsetp,
- sizeof (gdb_gregset_t), wordsize);
-}
+ const struct regset *regset = ppc_linux_gregset (sizeof (long));
-static void
-right_fill_reg (const struct regcache *regcache, 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 (long);
- /* Right fill the register. */
- regcache_raw_collect (regcache, regnum,
- ((bfd_byte *) reg
- + wordsize
- - register_size (current_gdbarch, regnum)));
+ ppc_supply_gregset (regset, regcache, -1, gregsetp, sizeof (*gregsetp));
}
void
fill_gregset (const struct regcache *regcache,
gdb_gregset_t *gregsetp, int regno)
{
- int regi;
- elf_greg_t *regp = (elf_greg_t *) gregsetp;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- const int elf_ngreg = 48;
+ const struct regset *regset = ppc_linux_gregset (sizeof (long));
-
- /* Start with zeros. */
- memset (regp, 0, elf_ngreg * sizeof (*regp));
-
- for (regi = 0; regi < ppc_num_gprs; regi++)
- {
- if ((regno == -1) || regno == tdep->ppc_gp0_regnum + regi)
- right_fill_reg (regcache, tdep->ppc_gp0_regnum + regi,
- (regp + PT_R0 + regi));
- }
-
- if ((regno == -1) || regno == PC_REGNUM)
- right_fill_reg (regcache, PC_REGNUM, regp + PT_NIP);
- if ((regno == -1) || regno == tdep->ppc_lr_regnum)
- right_fill_reg (regcache, tdep->ppc_lr_regnum, regp + PT_LNK);
- if ((regno == -1) || regno == tdep->ppc_cr_regnum)
- regcache_raw_collect (regcache, tdep->ppc_cr_regnum,
- regp + PT_CCR);
- if ((regno == -1) || regno == tdep->ppc_xer_regnum)
- regcache_raw_collect (regcache, tdep->ppc_xer_regnum,
- regp + PT_XER);
- if ((regno == -1) || regno == tdep->ppc_ctr_regnum)
- right_fill_reg (regcache, tdep->ppc_ctr_regnum, regp + PT_CTR);
-#ifdef PT_MQ
- if (((regno == -1) || regno == tdep->ppc_mq_regnum)
- && (tdep->ppc_mq_regnum != -1))
- right_fill_reg (regcache, tdep->ppc_mq_regnum, regp + PT_MQ);
-#endif
- if ((regno == -1) || regno == tdep->ppc_ps_regnum)
- right_fill_reg (regcache, tdep->ppc_ps_regnum, regp + PT_MSR);
+ if (regno == -1)
+ memset (gregsetp, 0, sizeof (*gregsetp));
+ ppc_collect_gregset (regset, regcache, regno, gregsetp, sizeof (*gregsetp));
}
void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp)
{
- ppc_linux_supply_fpregset (NULL, regcache, -1, fpregsetp,
- sizeof (gdb_fpregset_t));
+ const struct regset *regset = ppc_linux_fpregset ();
+
+ ppc_supply_fpregset (regset, regcache, -1,
+ fpregsetp, sizeof (*fpregsetp));
}
-/* Given a pointer to a floating point register set in /proc format
- (fpregset_t *), update the register specified by REGNO from gdb's
- idea of the current floating point register set. If REGNO is -1,
- update them all. */
void
fill_fpregset (const struct regcache *regcache,
gdb_fpregset_t *fpregsetp, int regno)
{
- int regi;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- bfd_byte *fpp = (void *) fpregsetp;
-
- if (ppc_floating_point_unit_p (current_gdbarch))
- {
- for (regi = 0; regi < ppc_num_fprs; regi++)
- {
- if ((regno == -1) || (regno == tdep->ppc_fp0_regnum + regi))
- regcache_raw_collect (regcache, tdep->ppc_fp0_regnum + regi,
- fpp + 8 * regi);
- }
- if (regno == -1 || regno == tdep->ppc_fpscr_regnum)
- right_fill_reg (regcache, tdep->ppc_fpscr_regnum, (fpp + 8 * 32));
- }
+ const struct regset *regset = ppc_linux_fpregset ();
+
+ ppc_collect_fpregset (regset, regcache, regno,
+ fpregsetp, sizeof (*fpregsetp));
}
void _initialize_ppc_linux_nat (void);