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:
John Baldwin 2016-06-27 13:19:09 -07:00
parent 98a4fc78f9
commit a3405d124e
15 changed files with 246 additions and 255 deletions

View file

@ -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>

View file

@ -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 \

View file

@ -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 */

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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 */

View file

@ -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
View 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;
}

View file

@ -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 */