/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
- Copyright (C) 1995-2018 Free Software Foundation, Inc.
+ Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of GDB.
/* Pseudo registers can not be read. ptrace does not provide a way to
read (or set) PS_REGNUM, and there's no point in reading or setting
- ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
- ptrace(). */
+ ZERO_REGNUM, it's always 0. We also can not set BADVADDR, CAUSE,
+ or FCRIR via ptrace(). */
static int
mips_cannot_fetch_register (int regno)
tdesc = current_process ()->tdesc;
+ /* On n32 we can't access 64-bit registers via PTRACE_PEEKUSR. */
+ if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE))
+ return 1;
+
if (find_regno (tdesc, "r0") == regno)
return 1;
tdesc = current_process ()->tdesc;
+ /* On n32 we can't access 64-bit registers via PTRACE_POKEUSR. */
+ if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE))
+ return 1;
+
if (find_regno (tdesc, "r0") == regno)
return 1;
return 0;
}
+static int
+mips_fetch_register (struct regcache *regcache, int regno)
+{
+ const struct target_desc *tdesc = current_process ()->tdesc;
+
+ if (find_regno (tdesc, "r0") == regno)
+ {
+ supply_register_zeroed (regcache, regno);
+ return 1;
+ }
+
+ return 0;
+}
+
static CORE_ADDR
mips_get_pc (struct regcache *regcache)
{
mips_linux_prepare_to_resume (struct lwp_info *lwp)
{
ptid_t ptid = ptid_of (get_lwp_thread (lwp));
- struct process_info *proc = find_process_pid (ptid_get_pid (ptid));
+ struct process_info *proc = find_process_pid (ptid.pid ());
struct arch_process_info *priv = proc->priv->arch_private;
if (lwp->arch_private->watch_registers_changed)
if (mips_linux_watch_get_num_valid (&priv->watch_mirror) > 0)
{
/* Write the mirrored watch register values. */
- int tid = ptid_get_lwp (ptid);
+ int tid = ptid.lwp ();
if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid,
&priv->watch_mirror, NULL))
return PS_OK;
}
-#ifdef HAVE_PTRACE_GETREGS
-
static void
mips_collect_register (struct regcache *regcache,
int use_64bit, int regno, union mips_register *reg)
supply_register (regcache, regno, reg->buf + offset);
}
+#ifdef HAVE_PTRACE_GETREGS
+
static void
mips_collect_register_32bit (struct regcache *regcache,
int use_64bit, int regno, unsigned char *buf)
use_64bit = (register_size (regcache->tdesc, 0) == 8);
- for (i = 0; i < 32; i++)
+ supply_register_by_name_zeroed (regcache, "r0");
+
+ for (i = 1; i < 32; i++)
mips_supply_register (regcache, use_64bit, i, regset + i);
mips_supply_register (regcache, use_64bit,
}
#endif /* HAVE_PTRACE_GETREGS */
+/* Take care of 32-bit registers with 64-bit ptrace, POKEUSER side. */
+
+static void
+mips_collect_ptrace_register (struct regcache *regcache,
+ int regno, char *buf)
+{
+ int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8;
+
+ if (use_64bit && register_size (regcache->tdesc, regno) == 4)
+ {
+ union mips_register reg;
+
+ mips_collect_register (regcache, 0, regno, ®);
+ memcpy (buf, ®, sizeof (reg));
+ }
+ else
+ collect_register (regcache, regno, buf);
+}
+
+/* Take care of 32-bit registers with 64-bit ptrace, PEEKUSER side. */
+
+static void
+mips_supply_ptrace_register (struct regcache *regcache,
+ int regno, const char *buf)
+{
+ int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8;
+
+ if (use_64bit && register_size (regcache->tdesc, regno) == 4)
+ {
+ union mips_register reg;
+
+ memcpy (®, buf, sizeof (reg));
+ mips_supply_register (regcache, 0, regno, ®);
+ }
+ else
+ supply_register (regcache, regno, buf);
+}
+
static struct regset_info mips_regsets[] = {
#ifdef HAVE_PTRACE_GETREGS
{ PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS,
mips_regs_info,
mips_cannot_fetch_register,
mips_cannot_store_register,
- NULL, /* fetch_register */
+ mips_fetch_register,
mips_get_pc,
mips_set_pc,
NULL, /* breakpoint_kind_from_pc */
mips_remove_point,
mips_stopped_by_watchpoint,
mips_stopped_data_address,
- NULL,
- NULL,
+ mips_collect_ptrace_register,
+ mips_supply_ptrace_register,
NULL, /* siginfo_fixup */
mips_linux_new_process,
mips_linux_delete_process,