-/* Support for debug registers. */
-
-static unsigned long i386_linux_dr[DR_CONTROL + 1];
-
-/* Get debug register REGNUM value from only the one LWP of PTID. */
-
-static unsigned long
-i386_linux_dr_get (ptid_t ptid, int regnum)
-{
- int tid;
- unsigned long value;
-
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (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 vector. For now, just return zero if the
- ptrace call fails. */
- errno = 0;
- value = ptrace (PTRACE_PEEKUSER, 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;
-}
-
-/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */
-
-static void
-i386_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
-{
- int tid;
-
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
- errno = 0;
- ptrace (PTRACE_POKEUSER, tid,
- offsetof (struct user, u_debugreg[regnum]), value);
- if (errno != 0)
- perror_with_name (_("Couldn't write debug register"));
-}
-
-/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */
-
-static void
-i386_linux_dr_set_control (unsigned long control)
-{
- struct lwp_info *lp;
-
- i386_linux_dr[DR_CONTROL] = control;
- ALL_LWPS (lp)
- i386_linux_dr_set (lp->ptid, DR_CONTROL, control);
-}
-
-/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */
-
-static void
-i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
-{
- struct lwp_info *lp;
-
- gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
-
- i386_linux_dr[DR_FIRSTADDR + regnum] = addr;
- ALL_LWPS (lp)
- i386_linux_dr_set (lp->ptid, DR_FIRSTADDR + regnum, addr);
-}
-
-/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */
-
-static void
-i386_linux_dr_reset_addr (int regnum)
-{
- i386_linux_dr_set_addr (regnum, 0);
-}
-
-/* Get DR_STATUS from only the one LWP of INFERIOR_PTID. */
-
-static unsigned long
-i386_linux_dr_get_status (void)
-{
- return i386_linux_dr_get (inferior_ptid, DR_STATUS);
-}
-
-/* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */
-
-static void
-i386_linux_dr_unset_status (unsigned long mask)
-{
- struct lwp_info *lp;
-
- ALL_LWPS (lp)
- {
- unsigned long value;
-
- value = i386_linux_dr_get (lp->ptid, DR_STATUS);
- value &= ~mask;
- i386_linux_dr_set (lp->ptid, DR_STATUS, value);
- }
-}
-
-static void
-i386_linux_new_thread (ptid_t ptid)
-{
- int i;
-
- for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
- i386_linux_dr_set (ptid, i, i386_linux_dr[i]);
-
- i386_linux_dr_set (ptid, DR_CONTROL, i386_linux_dr[DR_CONTROL]);
-}
-\f
-