X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Famd64bsd-nat.c;h=66d42894bd41222a38e59caf8cb897ddfc9bc004;hb=b08b78e7d4bb56f395d3212eed6184ede236c760;hp=a1f9e828d12e34824c97cedabc9c3f6ed7b9bacf;hpb=6aba47ca06d9150c6196a374b745c2711b46e045;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/amd64bsd-nat.c b/gdb/amd64bsd-nat.c
index a1f9e828d1..66d42894bd 100644
--- a/gdb/amd64bsd-nat.c
+++ b/gdb/amd64bsd-nat.c
@@ -1,12 +1,12 @@
/* Native-dependent code for AMD64 BSD's.
- Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003-2015 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,
@@ -15,9 +15,7 @@
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 . */
#include "defs.h"
#include "inferior.h"
@@ -26,7 +24,6 @@
/* We include to make sure `struct fxsave64' is defined on
NetBSD, since NetBSD's needs it. */
-#include "gdb_assert.h"
#include
#include
#include
@@ -34,37 +31,59 @@
#include "amd64-tdep.h"
#include "amd64-nat.h"
+#include "amd64bsd-nat.h"
#include "inf-ptrace.h"
+#ifdef PT_GETXSTATE_INFO
+size_t amd64bsd_xsave_len;
+#endif
+
/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
for all registers (including the floating-point registers). */
static void
-amd64bsd_fetch_inferior_registers (int regnum)
+amd64bsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
- if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
{
struct reg regs;
- if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
(PTRACE_TYPE_ARG3) ®s, 0) == -1)
perror_with_name (_("Couldn't get registers"));
- amd64_supply_native_gregset (current_regcache, ®s, -1);
+ amd64_supply_native_gregset (regcache, ®s, -1);
if (regnum != -1)
return;
}
- if (regnum == -1 || !amd64_native_gregset_supplies_p (regnum))
+ if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
{
struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+#ifdef PT_GETXSTATE_INFO
+ char *xstateregs;
+
+ if (amd64bsd_xsave_len != 0)
+ {
+ xstateregs = alloca (amd64bsd_xsave_len);
+ if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
+ perror_with_name (_("Couldn't get extended state status"));
+
+ amd64_supply_xsave (regcache, -1, xstateregs);
+ return;
+ }
+#endif
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
perror_with_name (_("Couldn't get floating point status"));
- amd64_supply_fxsave (current_regcache, -1, &fpregs);
+ amd64_supply_fxsave (regcache, -1, &fpregs);
}
}
@@ -72,19 +91,22 @@ amd64bsd_fetch_inferior_registers (int regnum)
this for all registers (including the floating-point registers). */
static void
-amd64bsd_store_inferior_registers (int regnum)
+amd64bsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
- if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
{
struct reg regs;
- if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
(PTRACE_TYPE_ARG3) ®s, 0) == -1)
perror_with_name (_("Couldn't get registers"));
- amd64_collect_native_gregset (current_regcache, ®s, regnum);
+ amd64_collect_native_gregset (regcache, ®s, regnum);
- if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
(PTRACE_TYPE_ARG3) ®s, 0) == -1)
perror_with_name (_("Couldn't write registers"));
@@ -92,17 +114,35 @@ amd64bsd_store_inferior_registers (int regnum)
return;
}
- if (regnum == -1 || !amd64_native_gregset_supplies_p (regnum))
+ if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
{
struct fpreg fpregs;
-
- if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+#ifdef PT_GETXSTATE_INFO
+ char *xstateregs;
+
+ if (amd64bsd_xsave_len != 0)
+ {
+ xstateregs = alloca (amd64bsd_xsave_len);
+ if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
+ perror_with_name (_("Couldn't get extended state status"));
+
+ amd64_collect_xsave (regcache, regnum, xstateregs, 0);
+
+ if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1)
+ perror_with_name (_("Couldn't write extended state status"));
+ return;
+ }
+#endif
+
+ if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
perror_with_name (_("Couldn't get floating point status"));
- amd64_collect_fxsave (current_regcache, regnum, &fpregs);
+ amd64_collect_fxsave (regcache, regnum, &fpregs);
- if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
perror_with_name (_("Couldn't write floating point status"));
}
@@ -121,3 +161,75 @@ amd64bsd_target (void)
t->to_store_registers = amd64bsd_store_inferior_registers;
return t;
}
+
+
+/* Support for debug registers. */
+
+#ifdef HAVE_PT_GETDBREGS
+
+static unsigned long
+amd64bsd_dr_get (ptid_t ptid, int regnum)
+{
+ struct dbreg dbregs;
+
+ if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
+ perror_with_name (_("Couldn't read debug registers"));
+
+ return DBREG_DRX ((&dbregs), regnum);
+}
+
+static void
+amd64bsd_dr_set (int regnum, unsigned long value)
+{
+ struct dbreg dbregs;
+
+ if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
+ perror_with_name (_("Couldn't get debug registers"));
+
+ /* For some mysterious reason, some of the reserved bits in the
+ debug control register get set. Mask these off, otherwise the
+ ptrace call below will fail. */
+ DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);
+
+ DBREG_DRX ((&dbregs), regnum) = value;
+
+ if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
+ perror_with_name (_("Couldn't write debug registers"));
+}
+
+void
+amd64bsd_dr_set_control (unsigned long control)
+{
+ amd64bsd_dr_set (7, control);
+}
+
+void
+amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ gdb_assert (regnum >= 0 && regnum <= 4);
+
+ amd64bsd_dr_set (regnum, addr);
+}
+
+CORE_ADDR
+amd64bsd_dr_get_addr (int regnum)
+{
+ return amd64bsd_dr_get (inferior_ptid, regnum);
+}
+
+unsigned long
+amd64bsd_dr_get_status (void)
+{
+ return amd64bsd_dr_get (inferior_ptid, 6);
+}
+
+unsigned long
+amd64bsd_dr_get_control (void)
+{
+ return amd64bsd_dr_get (inferior_ptid, 7);
+}
+
+#endif /* PT_GETDBREGS */