+static unsigned long
+i386_linux_dr_get (int regnum)
+{
+ int tid;
+ unsigned long value;
+
+ /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+ multi-threaded processes here. For now, pretend there is just
+ one thread. */
+ tid = PIDGET (inferior_ptid);
+
+ /* FIXME: kettenis/2001-03-27: 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. */
+ errno = 0;
+ value = ptrace (PT_READ_U, tid,
+ offsetof (struct user, u_debugreg[regnum]), 0);
+ if (errno != 0)
+#if 0
+ perror_with_name ("Couldn't read debug register");
+#else
+ return 0;
+#endif
+
+ return value;
+}
+
+static void
+i386_linux_dr_set (int regnum, unsigned long value)
+{
+ int tid;
+
+ /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+ multi-threaded processes here. For now, pretend there is just
+ one thread. */
+ tid = PIDGET (inferior_ptid);
+
+ errno = 0;
+ ptrace (PT_WRITE_U, tid,
+ offsetof (struct user, u_debugreg[regnum]), value);
+ if (errno != 0)
+ perror_with_name ("Couldn't write debug register");
+}
+
+void
+i386_linux_dr_set_control (unsigned long control)
+{
+ i386_linux_dr_set (DR_CONTROL, control);
+}
+
+void
+i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+ gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+ i386_linux_dr_set (DR_FIRSTADDR + regnum, addr);
+}
+
+void
+i386_linux_dr_reset_addr (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+ i386_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
+}
+
+unsigned long
+i386_linux_dr_get_status (void)
+{
+ return i386_linux_dr_get (DR_STATUS);
+}
+\f
+