diff options
author | Mark Kettenis <kettenis@gnu.org> | 2006-05-15 21:53:20 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2006-05-15 21:53:20 +0000 |
commit | 8599da2d51649d4e39103345404d6eee11872929 (patch) | |
tree | 15a5fc2ada3930058fe8e6192551876ef0c88aa9 /gdb/ppcobsd-nat.c | |
parent | dc6641a55848bb8dfcb4d6dee66f63ca3d7977f4 (diff) | |
download | fsf-binutils-gdb-8599da2d51649d4e39103345404d6eee11872929.zip fsf-binutils-gdb-8599da2d51649d4e39103345404d6eee11872929.tar.gz fsf-binutils-gdb-8599da2d51649d4e39103345404d6eee11872929.tar.bz2 |
* ppcobsd-nat.c: Include "gdb_assert.h".
[PT_GETFPREGS] (getfpregs_supplies): New function.
(ppcobsd_fetch_registers, ppcobsd_fetch_registers): Hanlde OS
versions that have PT_GETFPREGS.
(_initialize_ppcobsd_nat) [PT_GETFPREGS]: Initialize
ppcobsd_fpreg_offsets.
* ppcobsd-tdep.h (ppcobsd_fpreg_offsets, ppcobsd_fpregset):
Declare.
* ppcobsd-tdep.c (ppcobsd_fpreg_offsets, ppcobsd_fpregset): New
variables.
(_initialize_ppcobsd_tdep): Initialize ppcobsd_fpreg_offsets.
* Makefile.in (ppcobsd-nat.o): Update dependencies.
Diffstat (limited to 'gdb/ppcobsd-nat.c')
-rw-r--r-- | gdb/ppcobsd-nat.c | 88 |
1 files changed, 81 insertions, 7 deletions
diff --git a/gdb/ppcobsd-nat.c b/gdb/ppcobsd-nat.c index dd7ca35..bdca4ca 100644 --- a/gdb/ppcobsd-nat.c +++ b/gdb/ppcobsd-nat.c @@ -1,6 +1,6 @@ /* Native-dependent code for OpenBSD/powerpc. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GDB. @@ -24,6 +24,7 @@ #include "inferior.h" #include "regcache.h" +#include "gdb_assert.h" #include <stddef.h> #include <sys/types.h> #include <sys/ptrace.h> @@ -37,8 +38,37 @@ #include "inf-ptrace.h" #include "bsd-kvm.h" -/* OpenBSD/powerpc doesn't have PT_GETFPREGS/PT_SETFPREGS like - NetBSD/powerpc and FreeBSD/powerpc. */ +/* OpenBSD/powerpc didn't have PT_GETFPREGS/PT_SETFPREGS until release + 4.0. On older releases the floating-point registers are handled by + PT_GETREGS/PT_SETREGS, but fpscr wasn't available.. */ + +#ifdef PT_GETFPREGS + +/* Returns true if PT_GETFPREGS fetches this register. */ + +static int +getfpregs_supplies (int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + + /* 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)); + + return ((regnum >= tdep->ppc_fp0_regnum + && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs) + || regnum == tdep->ppc_fpscr_regnum); +} + +#endif /* PT_GETFPREGS */ /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers. */ @@ -52,8 +82,26 @@ ppcobsd_fetch_registers (int regnum) (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); - ppcobsd_supply_gregset (&ppcobsd_gregset, current_regcache, -1, - ®s, sizeof regs); + ppc_supply_gregset (&ppcobsd_gregset, current_regcache, -1, + ®s, sizeof regs); +#ifndef PT_GETFPREGS + ppc_supply_fpregset (&ppcobsd_gregset, current_regcache, -1, + ®s, sizeof regs); +#endif + +#ifdef PT_GETFPREGS + if (regnum == -1 || getfpregs_supplies (regnum)) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't get floating point status")); + + ppc_supply_fpregset (&ppcobsd_fpregset, current_regcache, -1, + &fpregs, sizeof fpregs); + } +#endif } /* Store register REGNUM back into the inferior. If REGNUM is -1, do @@ -68,12 +116,34 @@ ppcobsd_store_registers (int regnum) (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); - ppcobsd_collect_gregset (&ppcobsd_gregset, current_regcache, - regnum, ®s, sizeof regs); + ppc_collect_gregset (&ppcobsd_gregset, current_regcache, + regnum, ®s, sizeof regs); +#ifndef PT_GETFPREGS + ppc_collect_fpregset (&ppcobsd_gregset, current_regcache, + regnum, ®s, sizeof regs); +#endif if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); + +#ifdef PT_GETFPREGS + if (regnum == -1 || getfpregs_supplies (regnum)) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't get floating point status")); + + ppc_collect_fpregset (&ppcobsd_fpregset, current_regcache, + regnum, &fpregs, sizeof fpregs); + + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't write floating point status")); + } +#endif } @@ -141,6 +211,10 @@ _initialize_ppcobsd_nat (void) /* Floating-point registers. */ ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr); ppcobsd_reg_offsets.fpscr_offset = -1; +#ifdef PT_GETFPREGS + ppcobsd_fpreg_offsets.f0_offset = offsetof (struct fpreg, fpr); + ppcobsd_fpreg_offsets.fpscr_offset = offsetof (struct fpreg, fpscr); +#endif /* AltiVec registers. */ ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg); |