Consolidate x86 debug register code for BSD native targets.
Move the debug register support code from amd64bsd-nat.c and i386bsd-nat.c into a shared x86bsd-nat.c. Instead of setting up x86_dr_low in amd64fbsd-nat.c and i386fbsd-nat.c, add a x86bsd_target function that creates a new target that inherits from inf_ptrace and sets up x86 debug registers if supported. In addition to initializing x86_dr_low, the x86bsd target installs a custom mourn_inferior target operation to clean up the x86 debug register state. Previously this was only done on amd64. Now it will be done for both i386 and amd64. The i386bsd_target and amd64bsd_target functions create targets that inherit from x86bsd rather than inf_ptrace. gdb/ChangeLog: * Makefile.in [HFILES_NO_SRCDIR]: Replace 'amd64bsd-nat.h' with 'x86bsd-nat.h'. * amd64bsd-nat.c: Include 'x86bsd-nat.h' instead of 'amd64bsd-nat.h'. (amd64bsd_xsave_len): Rename and move to x86bsd-nat.c. (amd64bsd_fetch_inferior_registers): Replace 'amd64bsd_xsave_len' with 'x86bsd_xsave_len'. (amd64bsd_store_inferior_registers): Likewise. (amd64bsd_target): Inherit from x86bsd_target. (amd64bsd_dr_get): Rename and move to x86bsd-nat.c. (amd64bsd_dr_set): Likewise. (amd64bsd_dr_set_control): Likewise. (amd64bsd_dr_set_addr): Likewise. (amd64bsd_dr_get_addr): Likewise. (amd64bsd_dr_get_status): Likewise. (amd64bsd_dr_get_control): Likewise. * amd64fbsd-nat.c: Include 'x86bsd-nat.h' instead of 'amd64bsd-nat.h'. (super_mourn_inferior): Move to x86bsd-nat.c. (amd64fbsd_mourn_inferior): Rename and move to x86bsd-nat.c. (amd64fbsd_read_description): Replace 'amd64bsd_xsave_len' with 'x86bsd_xsave_len'. (_initialize_amd64fbsd_nat): Remove x86 watchpoint setup and mourn_inferior' target op. * config/i386/fbsd.mh (NATDEPFILES): Add x86bsd-nat.o. * config/i386/fbsd64.mh: Likewise. * config/i386/nbsd64.mh: Likewise. * config/i386/nbsdelf.mh: Likewise. * config/i386/obsd.mh: Likewise. * config/i386/obsd64.mh: Likewise. * i386bsd-nat.c: Include 'x86bsd-nat.h'. (i386bsd_xsave_len): Rename and move to x86bsd-nat.c. (i386bsd_fetch_inferior_registers): Replace 'i386bsd_xsave_len' with 'x86bsd_xsave_len'. (i386bsd_store_inferior_registers): Likewise. (i386bsd_target): Inherit from x86bsd_target. (i386bsd_dr_get): Rename and move to x86bsd-nat.c. (i386bsd_dr_set): Likewise. (i386bsd_dr_set_control): Likewise. (i386bsd_dr_set_addr): Likewise. (i386bsd_dr_get_addr): Likewise. (i386bsd_dr_get_status): Likewise. (i386bsd_dr_get_control): Likewise. * i386bsd-nat.h (i386bsd_xsave_len): Remove. (i386bsd_dr_set_control): Remove. (i386bsd_dr_set_addr): Remove. (i386bsd_dr_get_addr): Remove. (i386bsd_dr_get_status): Remove. (i386bsd_dr_get_control): Remove. * i386fbsd-nat.c: Include 'x86bsd-nat.h'. (i386fbsd_read_description): Replace 'i386bsd_xsave_len' with 'x86bsd_xsave_len'. (_initialize_i386fbsd_nat): Remove x86 watchpoint setup and mourn_inferior' target op. * x86bsd-nat.c: New file. * x86bsd-nat.h: New file.
This commit is contained in:
parent
98a4fc78f9
commit
a3405d124e
15 changed files with 246 additions and 255 deletions
|
@ -1,3 +1,62 @@
|
|||
2016-07-01 John Baldwin <jhb@FreeBSD.org>
|
||||
|
||||
* Makefile.in [HFILES_NO_SRCDIR]: Replace 'amd64bsd-nat.h' with
|
||||
'x86bsd-nat.h'.
|
||||
* amd64bsd-nat.c: Include 'x86bsd-nat.h' instead of
|
||||
'amd64bsd-nat.h'.
|
||||
(amd64bsd_xsave_len): Rename and move to x86bsd-nat.c.
|
||||
(amd64bsd_fetch_inferior_registers): Replace 'amd64bsd_xsave_len'
|
||||
with 'x86bsd_xsave_len'.
|
||||
(amd64bsd_store_inferior_registers): Likewise.
|
||||
(amd64bsd_target): Inherit from x86bsd_target.
|
||||
(amd64bsd_dr_get): Rename and move to x86bsd-nat.c.
|
||||
(amd64bsd_dr_set): Likewise.
|
||||
(amd64bsd_dr_set_control): Likewise.
|
||||
(amd64bsd_dr_set_addr): Likewise.
|
||||
(amd64bsd_dr_get_addr): Likewise.
|
||||
(amd64bsd_dr_get_status): Likewise.
|
||||
(amd64bsd_dr_get_control): Likewise.
|
||||
* amd64fbsd-nat.c: Include 'x86bsd-nat.h' instead of
|
||||
'amd64bsd-nat.h'.
|
||||
(super_mourn_inferior): Move to x86bsd-nat.c.
|
||||
(amd64fbsd_mourn_inferior): Rename and move to x86bsd-nat.c.
|
||||
(amd64fbsd_read_description): Replace 'amd64bsd_xsave_len' with
|
||||
'x86bsd_xsave_len'.
|
||||
(_initialize_amd64fbsd_nat): Remove x86 watchpoint setup and
|
||||
mourn_inferior' target op.
|
||||
* config/i386/fbsd.mh (NATDEPFILES): Add x86bsd-nat.o.
|
||||
* config/i386/fbsd64.mh: Likewise.
|
||||
* config/i386/nbsd64.mh: Likewise.
|
||||
* config/i386/nbsdelf.mh: Likewise.
|
||||
* config/i386/obsd.mh: Likewise.
|
||||
* config/i386/obsd64.mh: Likewise.
|
||||
* i386bsd-nat.c: Include 'x86bsd-nat.h'.
|
||||
(i386bsd_xsave_len): Rename and move to x86bsd-nat.c.
|
||||
(i386bsd_fetch_inferior_registers): Replace 'i386bsd_xsave_len'
|
||||
with 'x86bsd_xsave_len'.
|
||||
(i386bsd_store_inferior_registers): Likewise.
|
||||
(i386bsd_target): Inherit from x86bsd_target.
|
||||
(i386bsd_dr_get): Rename and move to x86bsd-nat.c.
|
||||
(i386bsd_dr_set): Likewise.
|
||||
(i386bsd_dr_set_control): Likewise.
|
||||
(i386bsd_dr_set_addr): Likewise.
|
||||
(i386bsd_dr_get_addr): Likewise.
|
||||
(i386bsd_dr_get_status): Likewise.
|
||||
(i386bsd_dr_get_control): Likewise.
|
||||
* i386bsd-nat.h (i386bsd_xsave_len): Remove.
|
||||
(i386bsd_dr_set_control): Remove.
|
||||
(i386bsd_dr_set_addr): Remove.
|
||||
(i386bsd_dr_get_addr): Remove.
|
||||
(i386bsd_dr_get_status): Remove.
|
||||
(i386bsd_dr_get_control): Remove.
|
||||
* i386fbsd-nat.c: Include 'x86bsd-nat.h'.
|
||||
(i386fbsd_read_description): Replace 'i386bsd_xsave_len' with
|
||||
'x86bsd_xsave_len'.
|
||||
(_initialize_i386fbsd_nat): Remove x86 watchpoint setup and
|
||||
mourn_inferior' target op.
|
||||
* x86bsd-nat.c: New file.
|
||||
* x86bsd-nat.h: New file.
|
||||
|
||||
2016-07-01 Pedro Alves <palves@redhat.com>
|
||||
Tom Tromey <tom@tromey.com>
|
||||
|
||||
|
|
|
@ -912,7 +912,7 @@ common/gdb_signals.h nat/gdb_thread_db.h common/gdb_vecs.h \
|
|||
common/x86-xstate.h nat/linux-ptrace.h nat/mips-linux-watch.h \
|
||||
proc-utils.h aarch64-tdep.h arm-tdep.h ax-gdb.h ppcfbsd-tdep.h \
|
||||
ppcnbsd-tdep.h cli-out.h gdb_expat.h breakpoint.h infcall.h obsd-tdep.h \
|
||||
exec.h m32r-tdep.h osabi.h gdbcore.h amd64bsd-nat.h \
|
||||
exec.h m32r-tdep.h osabi.h gdbcore.h x86bsd-nat.h \
|
||||
i386bsd-nat.h xml-support.h xml-tdesc.h alphabsd-tdep.h gdb_obstack.h \
|
||||
ia64-tdep.h ada-lang.h varobj.h varobj-iter.h frv-tdep.h \
|
||||
nto-tdep.h serial.h \
|
||||
|
|
|
@ -31,14 +31,10 @@
|
|||
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
#include "amd64bsd-nat.h"
|
||||
#include "x86bsd-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). */
|
||||
|
||||
|
@ -67,9 +63,9 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops,
|
|||
#ifdef PT_GETXSTATE_INFO
|
||||
void *xstateregs;
|
||||
|
||||
if (amd64bsd_xsave_len != 0)
|
||||
if (x86bsd_xsave_len != 0)
|
||||
{
|
||||
xstateregs = alloca (amd64bsd_xsave_len);
|
||||
xstateregs = alloca (x86bsd_xsave_len);
|
||||
if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get extended state status"));
|
||||
|
@ -120,9 +116,9 @@ amd64bsd_store_inferior_registers (struct target_ops *ops,
|
|||
#ifdef PT_GETXSTATE_INFO
|
||||
void *xstateregs;
|
||||
|
||||
if (amd64bsd_xsave_len != 0)
|
||||
if (x86bsd_xsave_len != 0)
|
||||
{
|
||||
xstateregs = alloca (amd64bsd_xsave_len);
|
||||
xstateregs = alloca (x86bsd_xsave_len);
|
||||
if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get extended state status"));
|
||||
|
@ -130,7 +126,7 @@ amd64bsd_store_inferior_registers (struct target_ops *ops,
|
|||
amd64_collect_xsave (regcache, regnum, xstateregs, 0);
|
||||
|
||||
if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1)
|
||||
(PTRACE_TYPE_ARG3) xstateregs, x86bsd_xsave_len) == -1)
|
||||
perror_with_name (_("Couldn't write extended state status"));
|
||||
return;
|
||||
}
|
||||
|
@ -156,80 +152,8 @@ amd64bsd_target (void)
|
|||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = inf_ptrace_target ();
|
||||
t = x86bsd_target ();
|
||||
t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
|
||||
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, get_ptrace_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, get_ptrace_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, get_ptrace_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 */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "fbsd-nat.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
#include "amd64bsd-nat.h"
|
||||
#include "x86bsd-nat.h"
|
||||
#include "x86-nat.h"
|
||||
|
||||
|
||||
|
@ -140,17 +140,6 @@ amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
|
|||
}
|
||||
|
||||
|
||||
static void (*super_mourn_inferior) (struct target_ops *ops);
|
||||
|
||||
static void
|
||||
amd64fbsd_mourn_inferior (struct target_ops *ops)
|
||||
{
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
x86_cleanup_dregs ();
|
||||
#endif
|
||||
super_mourn_inferior (ops);
|
||||
}
|
||||
|
||||
/* Implement the to_read_description method. */
|
||||
|
||||
static const struct target_desc *
|
||||
|
@ -175,13 +164,13 @@ amd64fbsd_read_description (struct target_ops *ops)
|
|||
if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
|
||||
{
|
||||
amd64bsd_xsave_len = info.xsave_len;
|
||||
x86bsd_xsave_len = info.xsave_len;
|
||||
xcr0 = info.xsave_mask;
|
||||
}
|
||||
xsave_probed = 1;
|
||||
}
|
||||
|
||||
if (amd64bsd_xsave_len != 0)
|
||||
if (x86bsd_xsave_len != 0)
|
||||
{
|
||||
if (is64)
|
||||
return amd64_target_description (xcr0);
|
||||
|
@ -209,22 +198,6 @@ _initialize_amd64fbsd_nat (void)
|
|||
|
||||
/* Add some extra features to the common *BSD/i386 target. */
|
||||
t = amd64bsd_target ();
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
|
||||
x86_use_watchpoints (t);
|
||||
|
||||
x86_dr_low.set_control = amd64bsd_dr_set_control;
|
||||
x86_dr_low.set_addr = amd64bsd_dr_set_addr;
|
||||
x86_dr_low.get_addr = amd64bsd_dr_get_addr;
|
||||
x86_dr_low.get_status = amd64bsd_dr_get_status;
|
||||
x86_dr_low.get_control = amd64bsd_dr_get_control;
|
||||
x86_set_debug_register_length (8);
|
||||
|
||||
#endif /* HAVE_PT_GETDBREGS */
|
||||
|
||||
super_mourn_inferior = t->to_mourn_inferior;
|
||||
t->to_mourn_inferior = amd64fbsd_mourn_inferior;
|
||||
t->to_read_description = amd64fbsd_read_description;
|
||||
|
||||
fbsd_nat_add_target (t);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Host: FreeBSD/i386
|
||||
NATDEPFILES= fork-child.o inf-ptrace.o \
|
||||
fbsd-nat.o x86-nat.o x86-dregs.o i386bsd-nat.o i386fbsd-nat.o \
|
||||
bsd-kvm.o
|
||||
fbsd-nat.o x86-nat.o x86-dregs.o x86bsd-nat.o i386bsd-nat.o \
|
||||
i386fbsd-nat.o bsd-kvm.o
|
||||
NAT_FILE= nm-fbsd.h
|
||||
HAVE_NATIVE_GCORE_HOST = 1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Host: FreeBSD/amd64
|
||||
NATDEPFILES= fork-child.o inf-ptrace.o \
|
||||
fbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o \
|
||||
bsd-kvm.o x86-nat.o x86-dregs.o
|
||||
bsd-kvm.o x86-nat.o x86-dregs.o x86bsd-nat.o
|
||||
HAVE_NATIVE_GCORE_HOST = 1
|
||||
|
||||
LOADLIBES= -lkvm
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Host: NetBSD/amd64
|
||||
NATDEPFILES= fork-child.o inf-ptrace.o \
|
||||
nbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64nbsd-nat.o
|
||||
nbsd-nat.o amd64-nat.o x86bsd-nat.o amd64bsd-nat.o amd64nbsd-nat.o
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Host: NetBSD/i386 ELF
|
||||
NATDEPFILES= fork-child.o inf-ptrace.o \
|
||||
nbsd-nat.o i386bsd-nat.o i386nbsd-nat.o bsd-kvm.o
|
||||
nbsd-nat.o x86bsd-nat.o i386bsd-nat.o i386nbsd-nat.o bsd-kvm.o
|
||||
|
||||
LOADLIBES= -lkvm
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Host: OpenBSD/i386 ELF
|
||||
NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
|
||||
i386bsd-nat.o i386obsd-nat.o bsd-kvm.o
|
||||
x86bsd-nat.o i386bsd-nat.o i386obsd-nat.o bsd-kvm.o
|
||||
|
||||
LOADLIBES= -lkvm
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Host: OpenBSD/amd64
|
||||
NATDEPFILES= fork-child.o inf-ptrace.o obsd-nat.o \
|
||||
amd64-nat.o amd64bsd-nat.o amd64obsd-nat.o bsd-kvm.o
|
||||
amd64-nat.o x86bsd-nat.o amd64bsd-nat.o amd64obsd-nat.o bsd-kvm.o
|
||||
|
||||
LOADLIBES= -lkvm
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "i386-tdep.h"
|
||||
#include "i387-tdep.h"
|
||||
#include "x86bsd-nat.h"
|
||||
#include "i386bsd-nat.h"
|
||||
#include "inf-ptrace.h"
|
||||
|
||||
|
@ -81,10 +82,6 @@ static int i386bsd_r_reg_offset[] =
|
|||
so that we try PT_GETXMMREGS the first time around. */
|
||||
static int have_ptrace_xmmregs = -1;
|
||||
#endif
|
||||
|
||||
#ifdef PT_GETXSTATE_INFO
|
||||
size_t i386bsd_xsave_len;
|
||||
#endif
|
||||
|
||||
|
||||
/* Supply the general-purpose registers in GREGS, to REGCACHE. */
|
||||
|
@ -155,11 +152,11 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops,
|
|||
#endif
|
||||
|
||||
#ifdef PT_GETXSTATE_INFO
|
||||
if (i386bsd_xsave_len != 0)
|
||||
if (x86bsd_xsave_len != 0)
|
||||
{
|
||||
void *xstateregs;
|
||||
|
||||
xstateregs = alloca (i386bsd_xsave_len);
|
||||
xstateregs = alloca (x86bsd_xsave_len);
|
||||
if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get extended state status"));
|
||||
|
@ -225,11 +222,11 @@ i386bsd_store_inferior_registers (struct target_ops *ops,
|
|||
#endif
|
||||
|
||||
#ifdef PT_GETXSTATE_INFO
|
||||
if (i386bsd_xsave_len != 0)
|
||||
if (x86bsd_xsave_len != 0)
|
||||
{
|
||||
void *xstateregs;
|
||||
|
||||
xstateregs = alloca (i386bsd_xsave_len);
|
||||
xstateregs = alloca (x86bsd_xsave_len);
|
||||
if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get extended state status"));
|
||||
|
@ -237,7 +234,7 @@ i386bsd_store_inferior_registers (struct target_ops *ops,
|
|||
i387_collect_xsave (regcache, -1, xstateregs, 0);
|
||||
|
||||
if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) xstateregs, i386bsd_xsave_len) == -1)
|
||||
(PTRACE_TYPE_ARG3) xstateregs, x86bsd_xsave_len) == -1)
|
||||
perror_with_name (_("Couldn't write extended state status"));
|
||||
return;
|
||||
}
|
||||
|
@ -283,91 +280,13 @@ i386bsd_target (void)
|
|||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = inf_ptrace_target ();
|
||||
t = x86bsd_target ();
|
||||
t->to_fetch_registers = i386bsd_fetch_inferior_registers;
|
||||
t->to_store_registers = i386bsd_store_inferior_registers;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/* Support for debug registers. */
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
|
||||
/* Not all versions of FreeBSD/i386 that support the debug registers
|
||||
have this macro. */
|
||||
#ifndef DBREG_DRX
|
||||
#define DBREG_DRX(d, x) ((&d->dr0)[x])
|
||||
#endif
|
||||
|
||||
static unsigned long
|
||||
i386bsd_dr_get (ptid_t ptid, int regnum)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't read debug registers"));
|
||||
|
||||
return DBREG_DRX ((&dbregs), regnum);
|
||||
}
|
||||
|
||||
static void
|
||||
i386bsd_dr_set (int regnum, unsigned int value)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, get_ptrace_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) &= ~(0x0000fc00);
|
||||
|
||||
DBREG_DRX ((&dbregs), regnum) = value;
|
||||
|
||||
if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't write debug registers"));
|
||||
}
|
||||
|
||||
void
|
||||
i386bsd_dr_set_control (unsigned long control)
|
||||
{
|
||||
i386bsd_dr_set (7, control);
|
||||
}
|
||||
|
||||
void
|
||||
i386bsd_dr_set_addr (int regnum, CORE_ADDR addr)
|
||||
{
|
||||
gdb_assert (regnum >= 0 && regnum <= 4);
|
||||
|
||||
i386bsd_dr_set (regnum, addr);
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
i386bsd_dr_get_addr (int regnum)
|
||||
{
|
||||
return i386bsd_dr_get (inferior_ptid, regnum);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
i386bsd_dr_get_status (void)
|
||||
{
|
||||
return i386bsd_dr_get (inferior_ptid, 6);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
i386bsd_dr_get_control (void)
|
||||
{
|
||||
return i386bsd_dr_get (inferior_ptid, 7);
|
||||
}
|
||||
|
||||
#endif /* PT_GETDBREGS */
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_i386bsd_nat (void);
|
||||
|
||||
|
|
|
@ -25,19 +25,4 @@
|
|||
|
||||
extern struct target_ops *i386bsd_target (void);
|
||||
|
||||
/* Low level i386 XSAVE info. */
|
||||
extern size_t i386bsd_xsave_len;
|
||||
|
||||
/* low level i386 debug register functions used in i386fbsd-nat.c. */
|
||||
|
||||
extern void i386bsd_dr_set_control (unsigned long control);
|
||||
|
||||
extern void i386bsd_dr_set_addr (int regnum, CORE_ADDR addr);
|
||||
|
||||
extern CORE_ADDR i386bsd_dr_get_addr (int regnum);
|
||||
|
||||
extern unsigned long i386bsd_dr_get_status (void);
|
||||
|
||||
extern unsigned long i386bsd_dr_get_control (void);
|
||||
|
||||
#endif /* i386bsd-nat.h */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "fbsd-nat.h"
|
||||
#include "i386-tdep.h"
|
||||
#include "x86-nat.h"
|
||||
#include "x86bsd-nat.h"
|
||||
#include "i386bsd-nat.h"
|
||||
|
||||
/* Resume execution of the inferior process. If STEP is nonzero,
|
||||
|
@ -132,13 +133,13 @@ i386fbsd_read_description (struct target_ops *ops)
|
|||
if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
|
||||
{
|
||||
i386bsd_xsave_len = info.xsave_len;
|
||||
x86bsd_xsave_len = info.xsave_len;
|
||||
xcr0 = info.xsave_mask;
|
||||
}
|
||||
xsave_probed = 1;
|
||||
}
|
||||
|
||||
if (i386bsd_xsave_len != 0)
|
||||
if (x86bsd_xsave_len != 0)
|
||||
{
|
||||
return i386_target_description (xcr0);
|
||||
}
|
||||
|
@ -158,19 +159,6 @@ _initialize_i386fbsd_nat (void)
|
|||
/* Add some extra features to the common *BSD/i386 target. */
|
||||
t = i386bsd_target ();
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
|
||||
x86_use_watchpoints (t);
|
||||
|
||||
x86_dr_low.set_control = i386bsd_dr_set_control;
|
||||
x86_dr_low.set_addr = i386bsd_dr_set_addr;
|
||||
x86_dr_low.get_addr = i386bsd_dr_get_addr;
|
||||
x86_dr_low.get_status = i386bsd_dr_get_status;
|
||||
x86_dr_low.get_control = i386bsd_dr_get_control;
|
||||
x86_set_debug_register_length (4);
|
||||
|
||||
#endif /* HAVE_PT_GETDBREGS */
|
||||
|
||||
#ifdef PT_GETXSTATE_INFO
|
||||
t->to_read_description = i386fbsd_read_description;
|
||||
#endif
|
||||
|
|
150
gdb/x86bsd-nat.c
Normal file
150
gdb/x86bsd-nat.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* Native-dependent code for X86 BSD's.
|
||||
|
||||
Copyright (C) 2003-2016 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
|
||||
/* We include <signal.h> to make sure `struct fxsave64' is defined on
|
||||
NetBSD, since NetBSD's <machine/reg.h> needs it. */
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#include "x86-nat.h"
|
||||
#include "x86bsd-nat.h"
|
||||
#include "inf-ptrace.h"
|
||||
|
||||
|
||||
#ifdef PT_GETXSTATE_INFO
|
||||
size_t x86bsd_xsave_len;
|
||||
#endif
|
||||
|
||||
/* Support for debug registers. */
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
static void (*super_mourn_inferior) (struct target_ops *ops);
|
||||
|
||||
/* Implement the "to_mourn_inferior" target_ops method. */
|
||||
|
||||
static void
|
||||
x86bsd_mourn_inferior (struct target_ops *ops)
|
||||
{
|
||||
x86_cleanup_dregs ();
|
||||
super_mourn_inferior (ops);
|
||||
}
|
||||
|
||||
/* Not all versions of FreeBSD/i386 that support the debug registers
|
||||
have this macro. */
|
||||
#ifndef DBREG_DRX
|
||||
#define DBREG_DRX(d, x) ((&d->dr0)[x])
|
||||
#endif
|
||||
|
||||
static unsigned long
|
||||
x86bsd_dr_get (ptid_t ptid, int regnum)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't read debug registers"));
|
||||
|
||||
return DBREG_DRX ((&dbregs), regnum);
|
||||
}
|
||||
|
||||
static void
|
||||
x86bsd_dr_set (int regnum, unsigned long value)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, get_ptrace_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, get_ptrace_pid (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't write debug registers"));
|
||||
}
|
||||
|
||||
static void
|
||||
x86bsd_dr_set_control (unsigned long control)
|
||||
{
|
||||
x86bsd_dr_set (7, control);
|
||||
}
|
||||
|
||||
static void
|
||||
x86bsd_dr_set_addr (int regnum, CORE_ADDR addr)
|
||||
{
|
||||
gdb_assert (regnum >= 0 && regnum <= 4);
|
||||
|
||||
x86bsd_dr_set (regnum, addr);
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
x86bsd_dr_get_addr (int regnum)
|
||||
{
|
||||
return x86bsd_dr_get (inferior_ptid, regnum);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
x86bsd_dr_get_status (void)
|
||||
{
|
||||
return x86bsd_dr_get (inferior_ptid, 6);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
x86bsd_dr_get_control (void)
|
||||
{
|
||||
return x86bsd_dr_get (inferior_ptid, 7);
|
||||
}
|
||||
|
||||
#endif /* PT_GETDBREGS */
|
||||
|
||||
/* Create a prototype *BSD/x86 target. The client can override it
|
||||
with local methods. */
|
||||
|
||||
struct target_ops *
|
||||
x86bsd_target (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = inf_ptrace_target ();
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
x86_use_watchpoints (t);
|
||||
|
||||
x86_dr_low.set_control = x86bsd_dr_set_control;
|
||||
x86_dr_low.set_addr = x86bsd_dr_set_addr;
|
||||
x86_dr_low.get_addr = x86bsd_dr_get_addr;
|
||||
x86_dr_low.get_status = x86bsd_dr_get_status;
|
||||
x86_dr_low.get_control = x86bsd_dr_get_control;
|
||||
x86_set_debug_register_length (sizeof (void *));
|
||||
super_mourn_inferior = t->to_mourn_inferior;
|
||||
t->to_mourn_inferior = x86bsd_mourn_inferior;
|
||||
#endif /* HAVE_PT_GETDBREGS */
|
||||
|
||||
return t;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* Native-dependent code for AMD64 BSD's.
|
||||
/* Native-dependent code for x86 BSD's.
|
||||
|
||||
Copyright (C) 2011-2016 Free Software Foundation, Inc.
|
||||
|
||||
|
@ -17,22 +17,15 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef AMD64BSD_NAT_H
|
||||
#define AMD64BSD_NAT_H
|
||||
#ifndef X86BSD_NAT_H
|
||||
#define X86BSD_NAT_H
|
||||
|
||||
/* Low level amd64 XSAVE info. */
|
||||
extern size_t amd64bsd_xsave_len;
|
||||
/* Low level x86 XSAVE info. */
|
||||
extern size_t x86bsd_xsave_len;
|
||||
|
||||
/* Low level amd64 debug register functions. */
|
||||
/* Create a prototype *BSD/x86 target. The client can override it
|
||||
with local methods. */
|
||||
|
||||
extern void amd64bsd_dr_set_control (unsigned long control);
|
||||
extern struct target_ops *x86bsd_target (void);
|
||||
|
||||
extern void amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr);
|
||||
|
||||
extern CORE_ADDR amd64bsd_dr_get_addr (int regnum);
|
||||
|
||||
extern unsigned long amd64bsd_dr_get_status (void);
|
||||
|
||||
extern unsigned long amd64bsd_dr_get_control (void);
|
||||
|
||||
#endif /* amd64bsd-nat.h */
|
||||
#endif /* x86bsd-nat.h */
|
Loading…
Add table
Reference in a new issue