forked from Imagelibrary/binutils-gdb
* i386bsd-nat.c: Include "gdb_assert.h".
[HAVE_PT_GETDBREGS] (DBREG_DRX): Define if not already defined. [HAVE_PT_GETDBREGS] (i386bsd_dr_set, i386bsd_dr_set_control, i386bsd_dr_set_addr, i386bsd_dr_reset_addr, i386bsd_dr_get_status): New functions. * config/i386/nm-fbsd.h [HAVE_PT_GETDBREGS] (I386_USE_GENERIC_WATCHPOINTS): Define. Include "i386/nm-i386.h". (I386_DR_LOW_SET_CONTROL, I386_DR_LOW_SET_ADDR, I386_DR_LOW_RESET_ADDR, I386_DR_LOW_GET_STATUS): New macros. (i386bsd_dr_set_control, i386bsd_dr_set_addr, i386bsd_dr_reset_addr, i386bsd_dr_get_status): New prototypes. * acconfig.h (HAVE_PT_GETDBREGS): New configure macro. * configure.in: Cleanup a few comments. Check for PT_GETDBREGS ptrace request. * config.in, configure: Regenerate.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
@@ -215,6 +216,80 @@ store_inferior_registers (int regno)
|
||||
}
|
||||
|
||||
|
||||
/* 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 void
|
||||
i386bsd_dr_set (int regnum, unsigned int value)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, inferior_pid, (PTRACE_ARG3_TYPE) &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. */
|
||||
dbregs.dr7 &= ~(0x0000fc00);
|
||||
|
||||
DBREG_DRX ((&dbregs), regnum) = value;
|
||||
|
||||
if (ptrace (PT_SETDBREGS, inferior_pid, (PTRACE_ARG3_TYPE) &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);
|
||||
}
|
||||
|
||||
void
|
||||
i386bsd_dr_reset_addr (int regnum)
|
||||
{
|
||||
gdb_assert (regnum >= 0 && regnum <= 4);
|
||||
|
||||
i386bsd_dr_set (regnum, 0);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
i386bsd_dr_get_status (void)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
/* FIXME: kettenis/2001-03-31: Calling perror_with_name if the
|
||||
ptrace call fails breaks debugging remote targets. The correct
|
||||
way to fix this is to add the hardware breakpoint and watchpoint
|
||||
stuff to the target vectore. For now, just return zero if the
|
||||
ptrace call fails. */
|
||||
if (ptrace (PT_GETDBREGS, inferior_pid, (PTRACE_ARG3_TYPE) &dbregs, 0) == -1)
|
||||
#if 0
|
||||
perror_with_name ("Couldn't read debug registers");
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return dbregs.dr6;
|
||||
}
|
||||
|
||||
#endif /* PT_GETDBREGS */
|
||||
|
||||
|
||||
/* Support for the user struct. */
|
||||
|
||||
/* Return the address register REGNO. BLOCKEND is the value of
|
||||
|
||||
Reference in New Issue
Block a user