* ppcnbsd-tdep.h: Update copyright year. Include <stddef.h>

(ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg)
(ppcnbsd_fill_fpreg): Remove prototypes.
(struct regset): Add forward declaration.
(ppcnbsd_gregset, ppcnbsd_fpregset): Extern declarations.
* ppcnbsd-tdep.c: Update copyright year.  Include "gdbtypes.h",
"regset.h" and "gdb_string.h".  Don't include "breakpoint.h",
"value.h", target.h and nbsd-tdep.h".  Reorder includes.
(REG_FIXREG_OFFSET, REG_LR_OFFSET, REG_CR_OFFSET, REG_XER_OFFSET)
(REG_CTR_OFFSET, REG_PC_OFFSET, SIZEOF_STRUCT_REG)
(FPREG_FPR_OFFSET, FPREG_FPSCR_OFFSET, SIZEOF_STRUCT_FPREG):
Remove macros.
(ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg)
(ppcnbsd_fill_fpreg): Remove functions.
(fetch_core_registers, fetch_elfcore_registers): Remove functions.
(ppcnbsd_core_fns, ppcnbsd_elfcore_fns): Remove variables.
(ppcnbsd_reg_offsets): New variable.
(ppcnbsd_gregset, ppcnbsd_fpregset): New variables.
(ppcnbsd_sigtramp_cache_init): Deal with new signal trampoline
introduced in NetBSD 2.0.
(ppcnbsd_sigtramp): Provide complete signal trampoline.
(ppcnbsd2_sigtramp): New variable.
(ppcnbsd_init_abi): Set svr4_fetch_link_map_offsets to
svr4_ilp32_fetch_link_map_offsets.  Set regset_from_core_section.
Add ppcnbs2_sigtramp unwinder.
(_initialize_ppcnbsd_tdep): Don't use deprecated_add_core_fns.
Initialize ppcnbsd_reg_offsets.
* ppcnbsd-nat.c: Update copyright year.  Reorder includes.
(getregs_supplies): Use regnum instead of regno.
(getfpregs_supplies): Likewise.
(ppcnbsd_fetch_inferior_registers): Likewise.  Call
ppc_supply_gregset and ppc_suppply_fpregset instead of
ppcnbsd_supply_reg and ppcnbsd_supply_fpreg
(ppcnbsd_store_inferior_registers): Likewise.  Call
ppc_collect_gregset and ppc_collect_fpregset instead of
ppcnbsd_fill_reg and ppcnbsd_fill_fpreg.
(ppcnbsd_supply_pcb): Use `gdb_byte *' instead of `char *'.
(_initialize_ppcnbsd_nat): Add some whitespace.
* Makefile.in (ppcnbsd-nat.o, ppcnbsd-tdep.o): Update dependencies.
* config/powerpc/nbsd.mh (NATDEPFILES): Remove infptrace.o.
(NAT_FILE): Remove.
* config/powerpc/nbsd.mt (TDEPFILES): Remove nbsd-tdep.o.
This commit is contained in:
Mark Kettenis
2006-05-12 20:53:15 +00:00
parent f6b66e9075
commit def18405fb
7 changed files with 243 additions and 299 deletions

View File

@ -1,3 +1,48 @@
2006-05-12 Mark Kettenis <kettenis@gnu.org>
* ppcnbsd-tdep.h: Update copyright year. Include <stddef.h>
(ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg)
(ppcnbsd_fill_fpreg): Remove prototypes.
(struct regset): Add forward declaration.
(ppcnbsd_gregset, ppcnbsd_fpregset): Extern declarations.
* ppcnbsd-tdep.c: Update copyright year. Include "gdbtypes.h",
"regset.h" and "gdb_string.h". Don't include "breakpoint.h",
"value.h", target.h and nbsd-tdep.h". Reorder includes.
(REG_FIXREG_OFFSET, REG_LR_OFFSET, REG_CR_OFFSET, REG_XER_OFFSET)
(REG_CTR_OFFSET, REG_PC_OFFSET, SIZEOF_STRUCT_REG)
(FPREG_FPR_OFFSET, FPREG_FPSCR_OFFSET, SIZEOF_STRUCT_FPREG):
Remove macros.
(ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg)
(ppcnbsd_fill_fpreg): Remove functions.
(fetch_core_registers, fetch_elfcore_registers): Remove functions.
(ppcnbsd_core_fns, ppcnbsd_elfcore_fns): Remove variables.
(ppcnbsd_reg_offsets): New variable.
(ppcnbsd_gregset, ppcnbsd_fpregset): New variables.
(ppcnbsd_sigtramp_cache_init): Deal with new signal trampoline
introduced in NetBSD 2.0.
(ppcnbsd_sigtramp): Provide complete signal trampoline.
(ppcnbsd2_sigtramp): New variable.
(ppcnbsd_init_abi): Set svr4_fetch_link_map_offsets to
svr4_ilp32_fetch_link_map_offsets. Set regset_from_core_section.
Add ppcnbs2_sigtramp unwinder.
(_initialize_ppcnbsd_tdep): Don't use deprecated_add_core_fns.
Initialize ppcnbsd_reg_offsets.
* ppcnbsd-nat.c: Update copyright year. Reorder includes.
(getregs_supplies): Use regnum instead of regno.
(getfpregs_supplies): Likewise.
(ppcnbsd_fetch_inferior_registers): Likewise. Call
ppc_supply_gregset and ppc_suppply_fpregset instead of
ppcnbsd_supply_reg and ppcnbsd_supply_fpreg
(ppcnbsd_store_inferior_registers): Likewise. Call
ppc_collect_gregset and ppc_collect_fpregset instead of
ppcnbsd_fill_reg and ppcnbsd_fill_fpreg.
(ppcnbsd_supply_pcb): Use `gdb_byte *' instead of `char *'.
(_initialize_ppcnbsd_nat): Add some whitespace.
* Makefile.in (ppcnbsd-nat.o, ppcnbsd-tdep.o): Update dependencies.
* config/powerpc/nbsd.mh (NATDEPFILES): Remove infptrace.o.
(NAT_FILE): Remove.
* config/powerpc/nbsd.mt (TDEPFILES): Remove nbsd-tdep.o.
2006-05-11 Alfred M. Szmidt <ams@gnu.org> 2006-05-11 Alfred M. Szmidt <ams@gnu.org>
* gnu-nat.c (inf_validate_procs): Don't use lvalue in assignments. * gnu-nat.c (inf_validate_procs): Don't use lvalue in assignments.

View File

@ -2416,13 +2416,13 @@ ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) \ ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) \
$(gdbcore_h) $(regcache_h) $(bsd_kvm_h) $(ppc_tdep_h) \ $(gdbcore_h) $(regcache_h) $(bsd_kvm_h) $(ppc_tdep_h) \
$(ppcnbsd_tdep_h) $(inf_ptrace_h) $(ppcnbsd_tdep_h) $(inf_ptrace_h)
ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \ ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(gdb_types_h) \
$(target_h) $(breakpoint_h) $(value_h) $(osabi_h) $(ppc_tdep_h) \ $(osabi_h) $(regcache_h) $(regset_h) $(trad_frame_h) \
$(ppcnbsd_tdep_h) $(nbsd_tdep_h) $(tramp_frame_h) $(trad_frame_h) \ $(tramp_frame_h) $(gdb_assert_h) $(gdb_string_h) \
$(gdb_assert_h) $(solib_svr4_h) $(ppc_tdep_h) $(ppcnbsd_tdep_h) $(solib_svr4_h)
ppcobsd-nat.o: ppcobsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \ ppcobsd-nat.o: ppcobsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \
$(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(inf_ptrace_h) \ $(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(bsd_kvm_h) \
$(bsd_kvm_h) $(inf_ptrace_h)
ppcobsd-tdep.o: ppcobsd-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \ ppcobsd-tdep.o: ppcobsd-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \
$(frame_h) $(frame_unwind_h) $(osabi_h) $(regcache_h) $(regset_h) \ $(frame_h) $(frame_unwind_h) $(osabi_h) $(regcache_h) $(regset_h) \
$(symtab_h) $(trad_frame_h) $(gdb_assert_h) $(gdb_string_h) \ $(symtab_h) $(trad_frame_h) $(gdb_assert_h) $(gdb_string_h) \

View File

@ -1,5 +1,4 @@
# Host: PowerPC, running NetBSD # Host: NetBSD/powerpc
NATDEPFILES= fork-child.o inf-ptrace.o infptrace.o ppcnbsd-nat.o bsd-kvm.o NATDEPFILES= fork-child.o inf-ptrace.o ppcnbsd-nat.o bsd-kvm.o
NAT_FILE= config/nm-nbsd.h
LOADLIBES= -lkvm LOADLIBES= -lkvm

View File

@ -1,6 +1,6 @@
# Target: PowerPC, running NetBSD # Target: NetBSD/powerpc
TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o nbsd-tdep.o corelow.o \ TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o \
solib.o solib-svr4.o corelow.o solib.o solib-svr4.o
DEPRECATED_TM_FILE= tm-ppc-eabi.h DEPRECATED_TM_FILE= tm-ppc-eabi.h
SIM_OBS = remote-sim.o SIM_OBS = remote-sim.o

View File

@ -1,5 +1,7 @@
/* Native-dependent code for PowerPC's running NetBSD, for GDB. /* Native-dependent code for NetBSD/powerpc.
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc. Contributed by Wasabi Systems, Inc.
This file is part of GDB. This file is part of GDB.
@ -26,35 +28,37 @@
#include <machine/pcb.h> #include <machine/pcb.h>
#include "defs.h" #include "defs.h"
#include "inferior.h"
#include "gdb_assert.h"
#include "gdbcore.h" #include "gdbcore.h"
#include "inferior.h"
#include "regcache.h" #include "regcache.h"
#include "bsd-kvm.h"
#include "gdb_assert.h"
#include "ppc-tdep.h" #include "ppc-tdep.h"
#include "ppcnbsd-tdep.h" #include "ppcnbsd-tdep.h"
#include "bsd-kvm.h"
#include "inf-ptrace.h" #include "inf-ptrace.h"
/* Returns true if PT_GETREGS fetches this register. */ /* Returns true if PT_GETREGS fetches this register. */
static int static int
getregs_supplies (int regno) getregs_supplies (int regnum)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
return ((regno >= tdep->ppc_gp0_regnum return ((regnum >= tdep->ppc_gp0_regnum
&& regno < tdep->ppc_gp0_regnum + ppc_num_gprs) && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
|| regno == tdep->ppc_lr_regnum || regnum == tdep->ppc_lr_regnum
|| regno == tdep->ppc_cr_regnum || regnum == tdep->ppc_cr_regnum
|| regno == tdep->ppc_xer_regnum || regnum == tdep->ppc_xer_regnum
|| regno == tdep->ppc_ctr_regnum || regnum == tdep->ppc_ctr_regnum
|| regno == PC_REGNUM); || regnum == PC_REGNUM);
} }
/* Like above, but for PT_GETFPREGS. */ /* Like above, but for PT_GETFPREGS. */
static int static int
getfpregs_supplies (int regno) getfpregs_supplies (int regnum)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
@ -70,15 +74,15 @@ getfpregs_supplies (int regno)
combination to the problem. */ combination to the problem. */
gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
return ((regno >= tdep->ppc_fp0_regnum return ((regnum >= tdep->ppc_fp0_regnum
&& regno < tdep->ppc_fp0_regnum + ppc_num_fprs) && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
|| regno == tdep->ppc_fpscr_regnum); || regnum == tdep->ppc_fpscr_regnum);
} }
static void static void
ppcnbsd_fetch_inferior_registers (int regno) ppcnbsd_fetch_inferior_registers (int regnum)
{ {
if (regno == -1 || getregs_supplies (regno)) if (regnum == -1 || getregs_supplies (regnum))
{ {
struct reg regs; struct reg regs;
@ -86,12 +90,11 @@ ppcnbsd_fetch_inferior_registers (int regno)
(PTRACE_TYPE_ARG3) &regs, 0) == -1) (PTRACE_TYPE_ARG3) &regs, 0) == -1)
perror_with_name (_("Couldn't get registers")); perror_with_name (_("Couldn't get registers"));
ppcnbsd_supply_reg ((char *) &regs, regno); ppc_supply_gregset (&ppcnbsd_gregset, current_regcache,
if (regno != -1) regnum, &regs, sizeof regs);
return;
} }
if (regno == -1 || getfpregs_supplies (regno)) if (regnum == -1 || getfpregs_supplies (regnum))
{ {
struct fpreg fpregs; struct fpreg fpregs;
@ -99,16 +102,15 @@ ppcnbsd_fetch_inferior_registers (int regno)
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
perror_with_name (_("Couldn't get FP registers")); perror_with_name (_("Couldn't get FP registers"));
ppcnbsd_supply_fpreg ((char *) &fpregs, regno); ppc_supply_fpregset (&ppcnbsd_fpregset, current_regcache,
if (regno != -1) regnum, &fpregs, sizeof fpregs);
return;
} }
} }
static void static void
ppcnbsd_store_inferior_registers (int regno) ppcnbsd_store_inferior_registers (int regnum)
{ {
if (regno == -1 || getregs_supplies (regno)) if (regnum == -1 || getregs_supplies (regnum))
{ {
struct reg regs; struct reg regs;
@ -116,17 +118,15 @@ ppcnbsd_store_inferior_registers (int regno)
(PTRACE_TYPE_ARG3) &regs, 0) == -1) (PTRACE_TYPE_ARG3) &regs, 0) == -1)
perror_with_name (_("Couldn't get registers")); perror_with_name (_("Couldn't get registers"));
ppcnbsd_fill_reg ((char *) &regs, regno); ppc_collect_gregset (&ppcnbsd_gregset, current_regcache,
regnum, &regs, sizeof regs);
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_TYPE_ARG3) &regs, 0) == -1) (PTRACE_TYPE_ARG3) &regs, 0) == -1)
perror_with_name (_("Couldn't write registers")); perror_with_name (_("Couldn't write registers"));
if (regno != -1)
return;
} }
if (regno == -1 || getfpregs_supplies (regno)) if (regnum == -1 || getfpregs_supplies (regnum))
{ {
struct fpreg fpregs; struct fpreg fpregs;
@ -134,8 +134,9 @@ ppcnbsd_store_inferior_registers (int regno)
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
perror_with_name (_("Couldn't get FP registers")); perror_with_name (_("Couldn't get FP registers"));
ppcnbsd_fill_fpreg ((char *) &fpregs, regno); ppc_collect_fpregset (&ppcnbsd_fpregset, current_regcache,
regnum, &fpregs, sizeof fpregs);
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
perror_with_name (_("Couldn't set FP registers")); perror_with_name (_("Couldn't set FP registers"));
@ -154,19 +155,19 @@ ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
if (pcb->pcb_sp == 0) if (pcb->pcb_sp == 0)
return 0; return 0;
read_memory (pcb->pcb_sp, (char *) &sf, sizeof sf); read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr); regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
for (i = 0 ; i < 19 ; i++) for (i = 0 ; i < 19 ; i++)
regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i, regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
&sf.fixreg[i]); &sf.fixreg[i]);
read_memory(sf.sp, (char *)&cf, sizeof(cf)); read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
read_memory(cf.sp, (char *)&cf, sizeof(cf)); read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr); regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
regcache_raw_supply (regcache, PC_REGNUM, &cf.lr); regcache_raw_supply (regcache, PC_REGNUM, &cf.lr);
@ -180,8 +181,10 @@ void
_initialize_ppcnbsd_nat (void) _initialize_ppcnbsd_nat (void)
{ {
struct target_ops *t; struct target_ops *t;
/* Support debugging kernel virtual memory images. */ /* Support debugging kernel virtual memory images. */
bsd_kvm_add_target (ppcnbsd_supply_pcb); bsd_kvm_add_target (ppcnbsd_supply_pcb);
/* Add in local overrides. */ /* Add in local overrides. */
t = inf_ptrace_target (); t = inf_ptrace_target ();
t->to_fetch_registers = ppcnbsd_fetch_inferior_registers; t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;

View File

@ -1,6 +1,6 @@
/* Target-dependent code for PowerPC systems running NetBSD. /* Target-dependent code for NetBSD/powerpc.
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc. Contributed by Wasabi Systems, Inc.
@ -22,225 +22,58 @@
Boston, MA 02110-1301, USA. */ Boston, MA 02110-1301, USA. */
#include "defs.h" #include "defs.h"
#include "gdbcore.h" #include "gdbtypes.h"
#include "regcache.h"
#include "target.h"
#include "breakpoint.h"
#include "value.h"
#include "osabi.h" #include "osabi.h"
#include "regcache.h"
#include "regset.h"
#include "trad-frame.h"
#include "tramp-frame.h"
#include "gdb_assert.h"
#include "gdb_string.h"
#include "ppc-tdep.h" #include "ppc-tdep.h"
#include "ppcnbsd-tdep.h" #include "ppcnbsd-tdep.h"
#include "nbsd-tdep.h"
#include "tramp-frame.h"
#include "trad-frame.h"
#include "gdb_assert.h"
#include "solib-svr4.h" #include "solib-svr4.h"
#define REG_FIXREG_OFFSET(x) ((x) * 4) /* Register offsets from <machine/reg.h>. */
#define REG_LR_OFFSET (32 * 4) struct ppc_reg_offsets ppcnbsd_reg_offsets;
#define REG_CR_OFFSET (33 * 4)
#define REG_XER_OFFSET (34 * 4)
#define REG_CTR_OFFSET (35 * 4)
#define REG_PC_OFFSET (36 * 4)
#define SIZEOF_STRUCT_REG (37 * 4)
#define FPREG_FPR_OFFSET(x) ((x) * 8) /* Core file support. */
#define FPREG_FPSCR_OFFSET (32 * 8)
#define SIZEOF_STRUCT_FPREG (33 * 8)
void /* NetBSD/powerpc register set. */
ppcnbsd_supply_reg (char *regs, int regno)
struct regset ppcnbsd_gregset =
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); &ppcnbsd_reg_offsets,
int i; ppc_supply_gregset
for (i = 0; i < ppc_num_gprs; i++)
{
if (regno == tdep->ppc_gp0_regnum + i || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_gp0_regnum + i,
regs + REG_FIXREG_OFFSET (i));
}
if (regno == tdep->ppc_lr_regnum || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum,
regs + REG_LR_OFFSET);
if (regno == tdep->ppc_cr_regnum || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum,
regs + REG_CR_OFFSET);
if (regno == tdep->ppc_xer_regnum || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum,
regs + REG_XER_OFFSET);
if (regno == tdep->ppc_ctr_regnum || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum,
regs + REG_CTR_OFFSET);
if (regno == PC_REGNUM || regno == -1)
regcache_raw_supply (current_regcache, PC_REGNUM,
regs + REG_PC_OFFSET);
}
void
ppcnbsd_fill_reg (char *regs, int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
int i;
for (i = 0; i < ppc_num_gprs; i++)
{
if (regno == tdep->ppc_gp0_regnum + i || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + i,
regs + REG_FIXREG_OFFSET (i));
}
if (regno == tdep->ppc_lr_regnum || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_lr_regnum,
regs + REG_LR_OFFSET);
if (regno == tdep->ppc_cr_regnum || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_cr_regnum,
regs + REG_CR_OFFSET);
if (regno == tdep->ppc_xer_regnum || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_xer_regnum,
regs + REG_XER_OFFSET);
if (regno == tdep->ppc_ctr_regnum || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_ctr_regnum,
regs + REG_CTR_OFFSET);
if (regno == PC_REGNUM || regno == -1)
regcache_raw_collect (current_regcache, PC_REGNUM, regs + REG_PC_OFFSET);
}
void
ppcnbsd_supply_fpreg (char *fpregs, int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
int i;
/* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
point registers. Traditionally, GDB's register set has still
listed the floating point registers for such machines, so this
code is harmless. However, the new E500 port actually omits the
floating point registers entirely from the register set --- they
don't even have register numbers assigned to them.
It's not clear to me how best to update this code, so this assert
will alert the first person to encounter the NetBSD/E500
combination to the problem. */
gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
for (i = 0; i < ppc_num_fprs; i++)
{
if (regno == tdep->ppc_fp0_regnum + i || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_fp0_regnum + i,
fpregs + FPREG_FPR_OFFSET (i));
}
if (regno == tdep->ppc_fpscr_regnum || regno == -1)
regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum,
fpregs + FPREG_FPSCR_OFFSET);
}
void
ppcnbsd_fill_fpreg (char *fpregs, int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
int i;
/* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
point registers. Traditionally, GDB's register set has still
listed the floating point registers for such machines, so this
code is harmless. However, the new E500 port actually omits the
floating point registers entirely from the register set --- they
don't even have register numbers assigned to them.
It's not clear to me how best to update this code, so this assert
will alert the first person to encounter the NetBSD/E500
combination to the problem. */
gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
for (i = 0; i < ppc_num_fprs; i++)
{
if (regno == tdep->ppc_fp0_regnum + i || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_fp0_regnum + i,
fpregs + FPREG_FPR_OFFSET (i));
}
if (regno == tdep->ppc_fpscr_regnum || regno == -1)
regcache_raw_collect (current_regcache, tdep->ppc_fpscr_regnum,
fpregs + FPREG_FPSCR_OFFSET);
}
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
CORE_ADDR ignore)
{
char *regs, *fpregs;
/* We get everything from one section. */
if (which != 0)
return;
regs = core_reg_sect;
fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
/* Integer registers. */
ppcnbsd_supply_reg (regs, -1);
/* Floating point registers. */
ppcnbsd_supply_fpreg (fpregs, -1);
}
static void
fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
CORE_ADDR ignore)
{
switch (which)
{
case 0: /* Integer registers. */
if (core_reg_size != SIZEOF_STRUCT_REG)
warning (_("Wrong size register set in core file."));
else
ppcnbsd_supply_reg (core_reg_sect, -1);
break;
case 2: /* Floating point registers. */
if (core_reg_size != SIZEOF_STRUCT_FPREG)
warning (_("Wrong size FP register set in core file."));
else
ppcnbsd_supply_fpreg (core_reg_sect, -1);
break;
default:
/* Don't know what kind of register request this is; just ignore it. */
break;
}
}
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 */
}; };
static struct core_fns ppcnbsd_elfcore_fns = struct regset ppcnbsd_fpregset =
{ {
bfd_target_elf_flavour, /* core_flavour */ &ppcnbsd_reg_offsets,
default_check_format, /* check_format */ ppc_supply_fpregset
default_core_sniffer, /* core_sniffer */
fetch_elfcore_registers, /* core_read_registers */
NULL /* next */
}; };
/* NetBSD is confused. It appears that 1.5 was using the correct SVr4 /* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
static const struct regset *
ppcnbsd_regset_from_core_section (struct gdbarch *gdbarch,
const char *sect_name, size_t sect_size)
{
if (strcmp (sect_name, ".reg") == 0 && sect_size >= 148)
return &ppcnbsd_gregset;
if (strcmp (sect_name, ".reg2") == 0 && sect_size >= 264)
return &ppcnbsd_fpregset;
return NULL;
}
/* NetBSD is confused. It appears that 1.5 was using the correct SVR4
convention but, 1.6 switched to the below broken convention. For convention but, 1.6 switched to the below broken convention. For
the moment use the broken convention. Ulgh!. */ the moment use the broken convention. Ulgh!. */
@ -249,6 +82,7 @@ ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype,
struct regcache *regcache, gdb_byte *readbuf, struct regcache *regcache, gdb_byte *readbuf,
const gdb_byte *writebuf) const gdb_byte *writebuf)
{ {
#if 0
if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
|| TYPE_CODE (valtype) == TYPE_CODE_UNION) || TYPE_CODE (valtype) == TYPE_CODE_UNION)
&& !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8) && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
@ -259,9 +93,15 @@ ppcnbsd_return_value (struct gdbarch *gdbarch, struct type *valtype,
|| TYPE_LENGTH (valtype) == 8)) || TYPE_LENGTH (valtype) == 8))
return RETURN_VALUE_STRUCT_CONVENTION; return RETURN_VALUE_STRUCT_CONVENTION;
else else
#endif
return ppc_sysv_abi_broken_return_value (gdbarch, valtype, regcache, return ppc_sysv_abi_broken_return_value (gdbarch, valtype, regcache,
readbuf, writebuf); readbuf, writebuf);
} }
/* Signal trampolines. */
static const struct tramp_frame ppcnbsd2_sigtramp;
static void static void
ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self, ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
@ -269,54 +109,73 @@ ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
struct trad_frame_cache *this_cache, struct trad_frame_cache *this_cache,
CORE_ADDR func) CORE_ADDR func)
{ {
CORE_ADDR base;
CORE_ADDR offset;
int i;
struct gdbarch *gdbarch = get_frame_arch (next_frame); struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
CORE_ADDR addr, base;
int i;
base = frame_unwind_register_unsigned (next_frame, SP_REGNUM); base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
offset = base + 0x18 + 2 * tdep->wordsize; if (self == &ppcnbsd2_sigtramp)
for (i = 0; i < ppc_num_gprs; i++) addr = base + 0x10 + 2 * tdep->wordsize;
else
addr = base + 0x18 + 2 * tdep->wordsize;
for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
{ {
int regnum = i + tdep->ppc_gp0_regnum; int regnum = i + tdep->ppc_gp0_regnum;
trad_frame_set_reg_addr (this_cache, regnum, offset); trad_frame_set_reg_addr (this_cache, regnum, addr);
offset += tdep->wordsize;
} }
trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, offset); trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
offset += tdep->wordsize; addr += tdep->wordsize;
trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, offset); trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
offset += tdep->wordsize; addr += tdep->wordsize;
trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, offset); trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
offset += tdep->wordsize; addr += tdep->wordsize;
trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, offset); trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
offset += tdep->wordsize; addr += tdep->wordsize;
trad_frame_set_reg_addr (this_cache, PC_REGNUM, offset); /* SRR0? */ trad_frame_set_reg_addr (this_cache, PC_REGNUM, addr); /* SRR0? */
offset += tdep->wordsize; addr += tdep->wordsize;
/* Construct the frame ID using the function start. */ /* Construct the frame ID using the function start. */
trad_frame_set_id (this_cache, frame_id_build (base, func)); trad_frame_set_id (this_cache, frame_id_build (base, func));
} }
/* Given the NEXT frame, examine the instructions at and around this static const struct tramp_frame ppcnbsd_sigtramp =
frame's resume address (aka PC) to see of they look like a signal {
trampoline. Return the address of the trampolines first
instruction, or zero if it isn't a signal trampoline. */
static const struct tramp_frame ppcnbsd_sigtramp = {
SIGTRAMP_FRAME, SIGTRAMP_FRAME,
4, /* insn size */ 4,
{ /* insn */ {
{ 0x38610018, -1 }, /* addi r3,r1,24 */ { 0x3821fff0, -1 }, /* add r1,r1,-16 */
{ 0x38000127, -1 }, /* li r0,295 */ { 0x4e800021, -1 }, /* blrl */
{ 0x44000002, -1 }, /* sc */ { 0x38610018, -1 }, /* addi r3,r1,24 */
{ 0x38000001, -1 }, /* li r0,1 */ { 0x38000127, -1 }, /* li r0,295 */
{ 0x44000002, -1 }, /* sc */ { 0x44000002, -1 }, /* sc */
{ 0x38000001, -1 }, /* li r0,1 */
{ 0x44000002, -1 }, /* sc */
{ TRAMP_SENTINEL_INSN, -1 } { TRAMP_SENTINEL_INSN, -1 }
}, },
ppcnbsd_sigtramp_cache_init ppcnbsd_sigtramp_cache_init
}; };
/* NetBSD 2.0 introduced a slightly different signal trampoline. */
static const struct tramp_frame ppcnbsd2_sigtramp =
{
SIGTRAMP_FRAME,
4,
{
{ 0x3821fff0, -1 }, /* add r1,r1,-16 */
{ 0x4e800021, -1 }, /* blrl */
{ 0x38610010, -1 }, /* addi r3,r1,16 */
{ 0x38000127, -1 }, /* li r0,295 */
{ 0x44000002, -1 }, /* sc */
{ 0x38000001, -1 }, /* li r0,1 */
{ 0x44000002, -1 }, /* sc */
{ TRAMP_SENTINEL_INSN, -1 }
},
ppcnbsd_sigtramp_cache_init
};
static void static void
ppcnbsd_init_abi (struct gdbarch_info info, ppcnbsd_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch) struct gdbarch *gdbarch)
@ -324,10 +183,21 @@ ppcnbsd_init_abi (struct gdbarch_info info,
/* For NetBSD, this is an on again, off again thing. Some systems /* For NetBSD, this is an on again, off again thing. Some systems
do use the broken struct convention, and some don't. */ do use the broken struct convention, and some don't. */
set_gdbarch_return_value (gdbarch, ppcnbsd_return_value); set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
set_solib_svr4_fetch_link_map_offsets (gdbarch,
nbsd_ilp32_solib_svr4_fetch_link_map_offsets); /* NetBSD uses SVR4-style shared libraries. */
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
set_gdbarch_regset_from_core_section
(gdbarch, ppcnbsd_regset_from_core_section);
tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp); tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
} }
/* Provide a prototype to silence -Wmissing-prototypes. */
void _initialize_ppcnbsd_tdep (void);
void void
_initialize_ppcnbsd_tdep (void) _initialize_ppcnbsd_tdep (void)
@ -335,6 +205,27 @@ _initialize_ppcnbsd_tdep (void)
gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF, gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF,
ppcnbsd_init_abi); ppcnbsd_init_abi);
deprecated_add_core_fns (&ppcnbsd_core_fns); /* Avoid initializing the register offsets again if they were
deprecated_add_core_fns (&ppcnbsd_elfcore_fns); already initailized by ppcnbsd-nat.c. */
if (ppcnbsd_reg_offsets.pc_offset == 0)
{
/* General-purpose registers. */
ppcnbsd_reg_offsets.r0_offset = 0;
ppcnbsd_reg_offsets.lr_offset = 128;
ppcnbsd_reg_offsets.cr_offset = 132;
ppcnbsd_reg_offsets.xer_offset = 136;
ppcnbsd_reg_offsets.ctr_offset = 140;
ppcnbsd_reg_offsets.pc_offset = 144;
ppcnbsd_reg_offsets.ps_offset = -1;
ppcnbsd_reg_offsets.mq_offset = -1;
/* Floating-point registers. */
ppcnbsd_reg_offsets.f0_offset = 0;
ppcnbsd_reg_offsets.fpscr_offset = 256;
/* AltiVec registers. */
ppcnbsd_reg_offsets.vr0_offset = 0;
ppcnbsd_reg_offsets.vrsave_offset = 512;
ppcnbsd_reg_offsets.vscr_offset = 524;
}
} }

View File

@ -1,5 +1,6 @@
/* Common target dependent code for GDB on PowerPC systems running NetBSD. /* Target-dependent code for NetBSD/powerpc.
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -21,10 +22,15 @@
#ifndef PPCNBSD_TDEP_H #ifndef PPCNBSD_TDEP_H
#define PPCNBSD_TDEP_H #define PPCNBSD_TDEP_H
void ppcnbsd_supply_reg (char *, int); #include <stddef.h>
void ppcnbsd_fill_reg (char *, int);
void ppcnbsd_supply_fpreg (char *, int); struct regset;
void ppcnbsd_fill_fpreg (char *, int);
#endif /* PPCNBSD_TDEP_H */ /* Register offsets for NetBSD/powerpc. */
extern struct ppc_reg_offsets ppcnbsd_reg_offsets;
/* Register sets for NetBSD/powerpc. */
extern struct regset ppcnbsd_gregset;
extern struct regset ppcnbsd_fpregset;
#endif /* ppcnbsd-tdep.h */