This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] OpenBSD/powerpc PT_{GET|SET}FPREGS support
- From: Mark Kettenis <mark dot kettenis at xs4all dot nl>
- To: gdb-patches at sourceware dot org
- Date: Mon, 15 May 2006 23:53:26 +0200 (CEST)
- Subject: [commit] OpenBSD/powerpc PT_{GET|SET}FPREGS support
Just implemented these in the kernel, such that now we can actually
access the fpscr register.
Committed,
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* 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.
Index: ppcobsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/ppcobsd-nat.c,v
retrieving revision 1.7
diff -u -p -r1.7 ppcobsd-nat.c
--- ppcobsd-nat.c 17 Dec 2005 22:34:01 -0000 1.7
+++ ppcobsd-nat.c 15 May 2006 21:36:05 -0000
@@ -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);
Index: ppcobsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppcobsd-tdep.c,v
retrieving revision 1.11
diff -u -p -r1.11 ppcobsd-tdep.c
--- ppcobsd-tdep.c 17 Dec 2005 22:34:01 -0000 1.11
+++ ppcobsd-tdep.c 15 May 2006 21:36:06 -0000
@@ -1,6 +1,6 @@
/* Target-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.
@@ -39,6 +39,7 @@
/* Register offsets from <machine/reg.h>. */
struct ppc_reg_offsets ppcobsd_reg_offsets;
+struct ppc_reg_offsets ppcobsd_fpreg_offsets;
/* Core file support. */
@@ -102,6 +103,12 @@ struct regset ppcobsd_gregset =
ppcobsd_supply_gregset
};
+struct regset ppcobsd_fpregset =
+{
+ &ppcobsd_fpreg_offsets,
+ ppc_supply_fpregset
+};
+
/* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
@@ -341,4 +348,11 @@ _initialize_ppcobsd_tdep (void)
ppcobsd_reg_offsets.vscr_offset = 512;
ppcobsd_reg_offsets.vrsave_offset = 520;
}
+
+ if (ppcobsd_fpreg_offsets.fpscr_offset == 0)
+ {
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = 0;
+ ppcobsd_reg_offsets.fpscr_offset = 256;
+ }
}
Index: ppcobsd-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppcobsd-tdep.h,v
retrieving revision 1.2
diff -u -p -r1.2 ppcobsd-tdep.h
--- ppcobsd-tdep.h 17 Dec 2005 22:34:01 -0000 1.2
+++ ppcobsd-tdep.h 15 May 2006 21:36:06 -0000
@@ -1,6 +1,6 @@
/* Target-dependent code for OpenBSD/powerpc.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GDB.
@@ -29,9 +29,11 @@ struct regcache;
/* Register offsets for OpenBSD/powerpc. */
extern struct ppc_reg_offsets ppcobsd_reg_offsets;
+extern struct ppc_reg_offsets ppcobsd_fpreg_offsets;
/* Register sets for OpenBSD/powerpc. */
extern struct regset ppcobsd_gregset;
+extern struct regset ppcobsd_fpregset;
/* Supply register REGNUM in the general-purpose register set REGSET
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.815
diff -u -p -r1.815 Makefile.in
--- Makefile.in 15 May 2006 17:11:58 -0000 1.815
+++ Makefile.in 15 May 2006 21:36:08 -0000
@@ -2440,8 +2440,8 @@ ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h)
$(tramp_frame_h) $(gdb_assert_h) $(gdb_string_h) \
$(ppc_tdep_h) $(ppcnbsd_tdep_h) $(solib_svr4_h)
ppcobsd-nat.o: ppcobsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \
- $(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(bsd_kvm_h) \
- $(inf_ptrace_h)
+ $(regcache_h) $(gdb_assert_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) \
+ $(bsd_kvm_h) $(inf_ptrace_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) \
$(symtab_h) $(trad_frame_h) $(gdb_assert_h) $(gdb_string_h) \