summaryrefslogtreecommitdiff
path: root/gdb/i386bsd-nat.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2001-03-31 18:09:03 +0000
committerMark Kettenis <kettenis@gnu.org>2001-03-31 18:09:03 +0000
commit3e5d587416160bac4882b9dbe9e8e81fa054ce09 (patch)
treeb2435f75158a456a4eb059edc3eb37184c00bb71 /gdb/i386bsd-nat.c
parente9b15c420ebc9229dbc88299840173cf19e649c4 (diff)
downloadgdb-3e5d587416160bac4882b9dbe9e8e81fa054ce09.tar.gz
* 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.
Diffstat (limited to 'gdb/i386bsd-nat.c')
-rw-r--r--gdb/i386bsd-nat.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c
index e991ba0fa71..3fdda7b996e 100644
--- a/gdb/i386bsd-nat.c
+++ b/gdb/i386bsd-nat.c
@@ -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