/* Native-dependent code for SPARC.
- Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003-2019 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "inferior.h"
#include "regcache.h"
#include "target.h"
-#include "gdb_assert.h"
#include <signal.h>
-#include "gdb_string.h"
#include <sys/ptrace.h>
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
#ifdef HAVE_MACHINE_REG_H
#include <machine/reg.h>
#endif
#endif
/* Register set description. */
-const struct sparc_gregset *sparc_gregset;
-void (*sparc_supply_gregset) (const struct sparc_gregset *,
+const struct sparc_gregmap *sparc_gregmap;
+const struct sparc_fpregmap *sparc_fpregmap;
+void (*sparc_supply_gregset) (const struct sparc_gregmap *,
struct regcache *, int , const void *);
-void (*sparc_collect_gregset) (const struct sparc_gregset *,
+void (*sparc_collect_gregset) (const struct sparc_gregmap *,
const struct regcache *, int, void *);
-void (*sparc_supply_fpregset) (struct regcache *, int , const void *);
-void (*sparc_collect_fpregset) (const struct regcache *, int , void *);
-int (*sparc_gregset_supplies_p) (int);
-int (*sparc_fpregset_supplies_p) (int);
+void (*sparc_supply_fpregset) (const struct sparc_fpregmap *,
+ struct regcache *, int , const void *);
+void (*sparc_collect_fpregset) (const struct sparc_fpregmap *,
+ const struct regcache *, int , void *);
+int (*sparc_gregset_supplies_p) (struct gdbarch *, int);
+int (*sparc_fpregset_supplies_p) (struct gdbarch *, int);
/* Determine whether `gregset_t' contains register REGNUM. */
int
-sparc32_gregset_supplies_p (int regnum)
+sparc32_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
{
/* Integer registers. */
if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
/* Determine whether `fpregset_t' contains register REGNUM. */
int
-sparc32_fpregset_supplies_p (int regnum)
+sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
{
/* Floating-point registers. */
if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
void
sparc_fetch_inferior_registers (struct regcache *regcache, int regnum)
{
- int pid;
+ struct gdbarch *gdbarch = regcache->arch ();
+ pid_t pid;
/* NOTE: cagney/2002-12-03: This code assumes that the currently
selected light weight processes' registers can be written
belong to the selected thread (the LWP could be in the middle of
executing the thread switch code).
- These functions should instead be paramaterized with an explicit
+ These functions should instead be parameterized with an explicit
object (struct regcache, struct thread_info?) into which the LWPs
registers can be written. */
- pid = TIDGET (inferior_ptid);
- if (pid == 0)
- pid = PIDGET (inferior_ptid);
+ pid = get_ptrace_pid (regcache->ptid ());
if (regnum == SPARC_G0_REGNUM)
{
- regcache_raw_supply (regcache, SPARC_G0_REGNUM, NULL);
+ gdb_byte zero[8] = { 0 };
+
+ regcache->raw_supply (SPARC_G0_REGNUM, &zero);
return;
}
- if (regnum == -1 || sparc_gregset_supplies_p (regnum))
+ if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
{
gregset_t regs;
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);
+ sparc_supply_gregset (sparc_gregmap, regcache, -1, ®s);
if (regnum != -1)
return;
}
- if (regnum == -1 || sparc_fpregset_supplies_p (regnum))
+ if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
{
fpregset_t fpregs;
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);
+ sparc_supply_fpregset (sparc_fpregmap, regcache, -1, &fpregs);
}
}
void
sparc_store_inferior_registers (struct regcache *regcache, int regnum)
{
- int pid;
+ struct gdbarch *gdbarch = regcache->arch ();
+ pid_t pid;
/* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
about threaded assumptions. */
- pid = TIDGET (inferior_ptid);
- if (pid == 0)
- pid = PIDGET (inferior_ptid);
+ pid = get_ptrace_pid (regcache->ptid ());
- if (regnum == -1 || sparc_gregset_supplies_p (regnum))
+ if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
{
gregset_t regs;
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);
+ sparc_collect_gregset (sparc_gregmap, regcache, regnum, ®s);
if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1)
perror_with_name (_("Couldn't write registers"));
return;
}
- if (regnum == -1 || sparc_fpregset_supplies_p (regnum))
+ if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
{
fpregset_t fpregs, saved_fpregs;
perror_with_name (_("Couldn't get floating-point registers"));
memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
- sparc_collect_fpregset (regcache, regnum, &fpregs);
+ sparc_collect_fpregset (sparc_fpregmap, regcache, regnum, &fpregs);
/* Writing the floating-point registers will fail on NetBSD with
EINVAL if the inferior process doesn't have an FPU state
}
\f
-/* Fetch StackGhost Per-Process XOR cookie. */
+/* Implement the to_xfer_partial target_ops method for
+ TARGET_OBJECT_WCOOKIE. Fetch StackGhost Per-Process XOR cookie. */
-LONGEST
-sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
+enum target_xfer_status
+sparc_xfer_wcookie (enum target_object object,
const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+ const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
{
unsigned long wcookie = 0;
char *buf = (char *)&wcookie;
gdb_assert (readbuf && writebuf == NULL);
if (offset == sizeof (unsigned long))
- return 0; /* Signal EOF. */
+ return TARGET_XFER_EOF; /* Signal EOF. */
if (offset > sizeof (unsigned long))
- return -1;
+ return TARGET_XFER_E_IO;
#ifdef PT_WCOOKIE
/* If PT_WCOOKIE is defined (by <sys/ptrace.h>), assume we're
later). Since release 3.6, OpenBSD uses a fully randomized
cookie. */
{
- int pid;
-
- pid = TIDGET (inferior_ptid);
- if (pid == 0)
- pid = PIDGET (inferior_ptid);
+ int pid = inferior_ptid.pid ();
/* Sanity check. The proper type for a cookie is register_t, but
we can't assume that this type exists on all systems supported
len = sizeof (unsigned long) - offset;
memcpy (readbuf, buf + offset, len);
- return len;
+ *xfered_len = (ULONGEST) len;
+ return TARGET_XFER_OK;
}
-
-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);
void
_initialize_sparc_nat (void)
{
- /* Deafult to using SunOS 4 register sets. */
- if (sparc_gregset == NULL)
- sparc_gregset = &sparc32_sunos4_gregset;
+ /* Default to using SunOS 4 register sets. */
+ if (sparc_gregmap == NULL)
+ sparc_gregmap = &sparc32_sunos4_gregmap;
+ if (sparc_fpregmap == NULL)
+ sparc_fpregmap = &sparc32_sunos4_fpregmap;
if (sparc_supply_gregset == NULL)
sparc_supply_gregset = sparc32_supply_gregset;
if (sparc_collect_gregset == NULL)