/* Native-dependent code for SPARC.
- Copyright 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of GDB.
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., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "inferior.h"
#include "sparc-tdep.h"
#include "sparc-nat.h"
+#include "inf-ptrace.h"
/* With some trickery we can use the code in this file for most (if
not all) ptrace(2) based SPARC systems, which includes SunOS 4,
for all registers (including the floating-point registers). */
void
-fetch_inferior_registers (int regnum)
+sparc_fetch_inferior_registers (struct regcache *regcache, int regnum)
{
- struct regcache *regcache = current_regcache;
int pid;
/* NOTE: cagney/2002-12-03: This code assumes that the currently
{
gregset_t regs;
- if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1)
- perror_with_name ("Couldn't get registers");
+ if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
sparc_supply_gregset (sparc_gregset, regcache, -1, ®s);
if (regnum != -1)
{
fpregset_t fpregs;
- if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
- perror_with_name ("Couldn't get floating point status");
+ if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating point status"));
sparc_supply_fpregset (regcache, -1, &fpregs);
}
}
void
-store_inferior_registers (int regnum)
+sparc_store_inferior_registers (struct regcache *regcache, int regnum)
{
- struct regcache *regcache = current_regcache;
int pid;
/* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
{
gregset_t regs;
- if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1)
- perror_with_name ("Couldn't get registers");
+ if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't get registers"));
sparc_collect_gregset (sparc_gregset, regcache, regnum, ®s);
- if (ptrace (PTRACE_SETREGS, pid, (PTRACE_ARG3_TYPE) ®s, 0) == -1)
- perror_with_name ("Couldn't write registers");
+ if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
+ perror_with_name (_("Couldn't write registers"));
/* Deal with the stack regs. */
if (regnum == -1 || regnum == SPARC_SP_REGNUM
{
fpregset_t fpregs, saved_fpregs;
- if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
- perror_with_name ("Couldn't get floating-point registers");
+ if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't get floating-point registers"));
memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
sparc_collect_fpregset (regcache, regnum, &fpregs);
if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0)
{
if (ptrace (PTRACE_SETFPREGS, pid,
- (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
- perror_with_name ("Couldn't write floating-point registers");
+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+ perror_with_name (_("Couldn't write floating-point registers"));
}
if (regnum != -1)
LONGEST
sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
- const char *annex, void *readbuf, const void *writebuf,
- ULONGEST offset, LONGEST len)
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
unsigned long wcookie = 0;
char *buf = (char *)&wcookie;
gdb_assert (object == TARGET_OBJECT_WCOOKIE);
gdb_assert (readbuf && writebuf == NULL);
- if (offset >= sizeof (unsigned long))
+ if (offset == sizeof (unsigned long))
+ return 0; /* Signal EOF. */
+ if (offset > sizeof (unsigned long))
return -1;
#ifdef PT_WCOOKIE
/* If PT_WCOOKIE is defined (by <sys/ptrace.h>), assume we're
running on an OpenBSD release that uses StackGhost (3.1 or
- later). As of release 3.4, OpenBSD doesn't use a randomized
- cookie yet. */
- wcookie = 0x3;
+ later). Since release 3.6, OpenBSD uses a fully randomized
+ cookie. */
+ {
+ int pid;
+
+ pid = TIDGET (inferior_ptid);
+ if (pid == 0)
+ pid = PIDGET (inferior_ptid);
+
+ /* Sanity check. The proper type for a cookie is register_t, but
+ we can't assume that this type exists on all systems supported
+ by the code in this file. */
+ gdb_assert (sizeof (wcookie) == sizeof (register_t));
+
+ /* Fetch the cookie. */
+ if (ptrace (PT_WCOOKIE, pid, (PTRACE_TYPE_ARG3) &wcookie, 0) == -1)
+ {
+ if (errno != EINVAL)
+ perror_with_name (_("Couldn't get StackGhost cookie"));
+
+ /* Although PT_WCOOKIE is defined on OpenBSD 3.1 and later,
+ the request wasn't implemented until after OpenBSD 3.4. If
+ the kernel doesn't support the PT_WCOOKIE request, assume
+ we're running on a kernel that uses non-randomized cookies. */
+ wcookie = 0x3;
+ }
+ }
#endif /* PT_WCOOKIE */
if (len > sizeof (unsigned long) - offset)
return len;
}
+LONGEST (*inf_ptrace_xfer_partial) (struct target_ops *, enum target_object,
+ const char *, gdb_byte *, const gdb_byte *,
+ ULONGEST, LONGEST);
+
+static LONGEST
+sparc_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+{
+ if (object == TARGET_OBJECT_WCOOKIE)
+ return sparc_xfer_wcookie (ops, object, annex, readbuf, writebuf,
+ offset, len);
+
+ return inf_ptrace_xfer_partial (ops, object, annex, readbuf, writebuf,
+ offset, len);
+}
+\f
+/* Create a prototype generic SPARC target. The client can override
+ it with local methods. */
+
+struct target_ops *
+sparc_target (void)
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_target ();
+ t->to_fetch_registers = sparc_fetch_inferior_registers;
+ t->to_store_registers = sparc_store_inferior_registers;
+ inf_ptrace_xfer_partial = t->to_xfer_partial;
+ t->to_xfer_partial = sparc_xfer_partial;
+ return t;
+}
+
\f
/* Provide a prototype to silence -Wmissing-prototypes. */
void _initialize_sparc_nat (void);