* ppcnbsd-nat.c: Rewrite.

* ppcnbsd-tdep.c: New file.
* ppcnbsd-tdep.h: New file.
* config/powerpc/nbsd.mh (NATDEPFILES): Remove corelow.o,
solib.o, and solib-svr4.o.
* config/powerpc/nbsd.mt (TDEPFILES): Add ppcnbsd-tdep.o,
nbsd-tdep.o, and corelow.o.
This commit is contained in:
Jason Thorpe
2002-05-28 18:43:08 +00:00
parent 1d7c105379
commit 485721b1e7
6 changed files with 344 additions and 104 deletions

View File

@@ -1,6 +1,6 @@
/* Native-dependent code for PowerPC's running NetBSD, for GDB.
Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001
Free Software Foundation, Inc.
Copyright 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
This file is part of GDB.
@@ -22,124 +22,102 @@
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include "defs.h"
#include "inferior.h"
#include "gdbcore.h"
#include "ppc-tdep.h"
#include "regcache.h"
#define RF(dst, src) \
memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
#define RS(src, dst) \
memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
#include "ppc-tdep.h"
#include "ppcnbsd-tdep.h"
/* Returns true if PT_GETREGS fetches this register. */
static int
getregs_supplies (int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
return ((regno >= 0 && regno <= 31)
|| regno == tdep->ppc_lr_regnum
|| regno == tdep->ppc_cr_regnum
|| regno == tdep->ppc_xer_regnum
|| regno == tdep->ppc_ctr_regnum
|| regno == PC_REGNUM);
}
/* Like above, but for PT_GETFPREGS. */
static int
getfpregs_supplies (int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
return ((regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)
|| regno == tdep->ppc_fpscr_regnum);
}
void
fetch_inferior_registers (int regno)
{
struct reg inferior_registers;
#ifdef PT_GETFPREGS
struct fpreg inferior_fp_registers;
#endif
int i;
if (regno == -1 || getregs_supplies (regno))
{
struct reg regs;
ptrace (PT_GETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_registers, 0);
for (i = 0; i < 32; i++)
RF (i, inferior_registers.fixreg[i]);
RF (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, inferior_registers.lr);
RF (gdbarch_tdep (current_gdbarch)->ppc_cr_regnum, inferior_registers.cr);
RF (gdbarch_tdep (current_gdbarch)->ppc_xer_regnum, inferior_registers.xer);
RF (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum, inferior_registers.ctr);
RF (PC_REGNUM, inferior_registers.pc);
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &regs, 0) == -1)
perror_with_name ("Couldn't get registers");
#ifdef PT_GETFPREGS
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
for (i = 0; i < 32; i++)
RF (FP0_REGNUM + i, inferior_fp_registers.fpreg[i]);
#endif
ppcnbsd_supply_reg ((char *) &regs, regno);
if (regno != -1)
return;
}
registers_fetched ();
if (regno == -1 || getfpregs_supplies (regno))
{
struct fpreg fpregs;
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
perror_with_name ("Couldn't get FP registers");
ppcnbsd_supply_fpreg ((char *) &fpregs, regno);
if (regno != -1)
return;
}
}
void
store_inferior_registers (int regno)
{
struct reg inferior_registers;
#ifdef PT_SETFPREGS
struct fpreg inferior_fp_registers;
#endif
int i;
if (regno == -1 || getregs_supplies (regno))
{
struct reg regs;
for (i = 0; i < 32; i++)
RS (i, inferior_registers.fixreg[i]);
RS (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, inferior_registers.lr);
RS (gdbarch_tdep (current_gdbarch)->ppc_cr_regnum, inferior_registers.cr);
RS (gdbarch_tdep (current_gdbarch)->ppc_xer_regnum, inferior_registers.xer);
RS (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum, inferior_registers.ctr);
RS (PC_REGNUM, inferior_registers.pc);
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &regs, 0) == -1)
perror_with_name ("Couldn't get registers");
ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_registers, 0);
ppcnbsd_fill_reg ((char *) &regs, regno);
#ifdef PT_SETFPREGS
for (i = 0; i < 32; i++)
RS (FP0_REGNUM + i, inferior_fp_registers.fpreg[i]);
ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
#endif
}
struct md_core
{
struct reg intreg;
#ifdef PT_GETFPREGS
struct fpreg freg;
#endif
};
void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
CORE_ADDR ignore)
{
struct md_core *core_reg = (struct md_core *) core_reg_sect;
int i;
/* Integer registers */
for (i = 0; i < 32; i++)
RF (i, core_reg->intreg.fixreg[i]);
RF (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, core_reg->intreg.lr);
RF (gdbarch_tdep (current_gdbarch)->ppc_cr_regnum, core_reg->intreg.cr);
RF (gdbarch_tdep (current_gdbarch)->ppc_xer_regnum, core_reg->intreg.xer);
RF (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum, core_reg->intreg.ctr);
RF (PC_REGNUM, core_reg->intreg.pc);
#ifdef PT_FPGETREGS
/* Floating point registers */
for (i = 0; i < 32; i++)
RF (FP0_REGNUM + i, core_reg->freg.fpreg[i]);
#endif
registers_fetched ();
}
/* Register that we are able to handle ppcnbsd core file formats.
FIXME: is this really bfd_target_unknown_flavour? */
static struct core_fns ppcnbsd_core_fns =
{
bfd_target_unknown_flavour, /* core_flavour */
default_check_format, /* check_format */
default_core_sniffer, /* core_sniffer */
fetch_core_registers, /* core_read_registers */
NULL /* next */
};
void
_initialize_ppcnbsd_nat (void)
{
add_core_fns (&ppcnbsd_core_fns);
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &regs, 0) == -1)
perror_with_name ("Couldn't write registers");
if (regno != -1)
return;
}
if (regno == -1 || getfpregs_supplies (regno))
{
struct fpreg fpregs;
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
perror_with_name ("Couldn't get FP registers");
ppcnbsd_fill_fpreg ((char *) &fpregs, regno);
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
perror_with_name ("Couldn't set FP registers");
}
}