/* Debug register code for x86 (i386 and x86-64).

   Copyright (C) 2001-2021 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 "gdbsupport/common-defs.h"
#include "x86-dregs.h"
#include "gdbsupport/break-common.h"

/* Support for hardware watchpoints and breakpoints using the x86
   debug registers.

   This provides several functions for inserting and removing
   hardware-assisted breakpoints and watchpoints, testing if one or
   more of the watchpoints triggered and at what address, checking
   whether a given region can be watched, etc.

   The functions below implement debug registers sharing by reference
   counts, and allow to watch regions up to 16 bytes long.  */

/* Accessor macros for low-level function vector.  */

/* Can we update the inferior's debug registers?  */
#define x86_dr_low_can_set_addr() (x86_dr_low.set_addr != NULL)

/* Update the inferior's debug register REGNUM from STATE.  */
#define x86_dr_low_set_addr(new_state, i) \
  (x86_dr_low.set_addr ((i), (new_state)->dr_mirror[(i)]))

/* Return the inferior's debug register REGNUM.  */
#define x86_dr_low_get_addr(i) (x86_dr_low.get_addr ((i)))

/* Can we update the inferior's DR7 control register?  */
#define x86_dr_low_can_set_control() (x86_dr_low.set_control != NULL)

/* Update the inferior's DR7 debug control register from STATE.  */
#define x86_dr_low_set_control(new_state) \
  (x86_dr_low.set_control ((new_state)->dr_control_mirror))

/* Return the value of the inferior's DR7 debug control register.  */
#define x86_dr_low_get_control() (x86_dr_low.get_control ())

/* Return the value of the inferior's DR6 debug status register.  */
#define x86_dr_low_get_status() (x86_dr_low.get_status ())

/* Return the debug register size, in bytes.  */
#define x86_get_debug_register_length() \
  (x86_dr_low.debug_register_length)

/* Support for 8-byte wide hw watchpoints.  */
#define TARGET_HAS_DR_LEN_8 (x86_get_debug_register_length () == 8)

/* DR7 Debug Control register fields.  */

/* How many bits to skip in DR7 to get to R/W and LEN fields.  */
#define DR_CONTROL_SHIFT	16
/* How many bits in DR7 per R/W and LEN field for each watchpoint.  */
#define DR_CONTROL_SIZE		4

/* Watchpoint/breakpoint read/write fields in DR7.  */
#define DR_RW_EXECUTE	(0x0)	/* Break on instruction execution.  */
#define DR_RW_WRITE	(0x1)	/* Break on data writes.  */
#define DR_RW_READ	(0x3)	/* Break on data reads or writes.  */

/* This is here for completeness.  No platform supports this
   functionality yet (as of March 2001).  Note that the DE flag in the
   CR4 register needs to be set to support this.  */
#ifndef DR_RW_IORW
#define DR_RW_IORW	(0x2)	/* Break on I/O reads or writes.  */
#endif

/* Watchpoint/breakpoint length fields in DR7.  The 2-bit left shift
   is so we could OR this with the read/write field defined above.  */
#define DR_LEN_1	(0x0 << 2) /* 1-byte region watch or breakpoint.  */
#define DR_LEN_2	(0x1 << 2) /* 2-byte region watch.  */
#define DR_LEN_4	(0x3 << 2) /* 4-byte region watch.  */
#define DR_LEN_8	(0x2 << 2) /* 8-byte region watch (AMD64).  */

/* Local and Global Enable flags in DR7.

   When the Local Enable flag is set, the breakpoint/watchpoint is
   enabled only for the current task; the processor automatically
   clears this flag on every task switch.  When the Global Enable flag
   is set, the breakpoint/watchpoint is enabled for all tasks; the
   processor never clears this flag.

   Currently, all watchpoint are locally enabled.  If you need to
   enable them globally, read the comment which pertains to this in
   x86_insert_aligned_watchpoint below.  */
#define DR_LOCAL_ENABLE_SHIFT	0 /* Extra shift to the local enable bit.  */
#define DR_GLOBAL_ENABLE_SHIFT	1 /* Extra shift to the global enable bit.  */
#define DR_ENABLE_SIZE		2 /* Two enable bits per debug register.  */

/* Local and global exact breakpoint enable flags (a.k.a. slowdown
   flags).  These are only required on i386, to allow detection of the
   exact instruction which caused a watchpoint to break; i486 and
   later processors do that automatically.  We set these flags for
   backwards compatibility.  */
#define DR_LOCAL_SLOWDOWN	(0x100)
#define DR_GLOBAL_SLOWDOWN	(0x200)

/* Fields reserved by Intel.  This includes the GD (General Detect
   Enable) flag, which causes a debug exception to be generated when a
   MOV instruction accesses one of the debug registers.

   FIXME: My Intel manual says we should use 0xF800, not 0xFC00.  */
#define DR_CONTROL_RESERVED	(0xFC00)

/* Auxiliary helper macros.  */

/* A value that masks all fields in DR7 that are reserved by Intel.  */
#define X86_DR_CONTROL_MASK	(~DR_CONTROL_RESERVED)

/* The I'th debug register is vacant if its Local and Global Enable
   bits are reset in the Debug Control register.  */
#define X86_DR_VACANT(state, i) \
  (((state)->dr_control_mirror & (3 << (DR_ENABLE_SIZE * (i)))) == 0)

/* Locally enable the break/watchpoint in the I'th debug register.  */
#define X86_DR_LOCAL_ENABLE(state, i) \
  do { \
    (state)->dr_control_mirror |= \
      (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i))); \
  } while (0)

/* Globally enable the break/watchpoint in the I'th debug register.  */
#define X86_DR_GLOBAL_ENABLE(state, i) \
  do { \
    (state)->dr_control_mirror |= \
      (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i))); \
  } while (0)

/* Disable the break/watchpoint in the I'th debug register.  */
#define X86_DR_DISABLE(state, i) \
  do { \
    (state)->dr_control_mirror &= \
      ~(3 << (DR_ENABLE_SIZE * (i))); \
  } while (0)

/* Set in DR7 the RW and LEN fields for the I'th debug register.  */
#define X86_DR_SET_RW_LEN(state, i, rwlen) \
  do { \
    (state)->dr_control_mirror &= \
      ~(0x0f << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))); \
    (state)->dr_control_mirror |= \
      ((rwlen) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))); \
  } while (0)

/* Get from DR7 the RW and LEN fields for the I'th debug register.  */
#define X86_DR_GET_RW_LEN(dr7, i) \
  (((dr7) \
    >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f)

/* Did the watchpoint whose address is in the I'th register break?  */
#define X86_DR_WATCH_HIT(dr6, i) ((dr6) & (1 << (i)))

/* Types of operations supported by x86_handle_nonaligned_watchpoint.  */
typedef enum { WP_INSERT, WP_REMOVE, WP_COUNT } x86_wp_op_t;

/* Print the values of the mirrored debug registers.  */

static void
x86_show_dr (struct x86_debug_reg_state *state,
	     const char *func, CORE_ADDR addr,
	     int len, enum target_hw_bp_type type)
{
  int i;

  debug_printf ("%s", func);
  if (addr || len)
    debug_printf (" (addr=%s, len=%d, type=%s)",
		  phex (addr, 8), len,
		  type == hw_write ? "data-write"
		  : (type == hw_read ? "data-read"
		     : (type == hw_access ? "data-read/write"
			: (type == hw_execute ? "instruction-execute"
			   /* FIXME: if/when I/O read/write
			      watchpoints are supported, add them
			      here.  */
			   : "??unknown??"))));
  debug_printf (":\n");

  debug_printf ("\tCONTROL (DR7): 0x%s\n", phex (state->dr_control_mirror, 8));
  debug_printf ("\tSTATUS (DR6): 0x%s\n", phex (state->dr_status_mirror, 8));

  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      debug_printf ("\tDR%d: addr=0x%s, ref.count=%d\n",
		    i, phex (state->dr_mirror[i],
			     x86_get_debug_register_length ()),
		    state->dr_ref_count[i]);
    }
}

/* Return the value of a 4-bit field for DR7 suitable for watching a
   region of LEN bytes for accesses of type TYPE.  LEN is assumed to
   have the value of 1, 2, or 4.  */

static unsigned
x86_length_and_rw_bits (int len, enum target_hw_bp_type type)
{
  unsigned rw;

  switch (type)
    {
      case hw_execute:
	rw = DR_RW_EXECUTE;
	break;
      case hw_write:
	rw = DR_RW_WRITE;
	break;
      case hw_read:
	internal_error (__FILE__, __LINE__,
			_("The i386 doesn't support "
			  "data-read watchpoints.\n"));
      case hw_access:
	rw = DR_RW_READ;
	break;
#if 0
	/* Not yet supported.  */
      case hw_io_access:
	rw = DR_RW_IORW;
	break;
#endif
      default:
	internal_error (__FILE__, __LINE__, _("\
Invalid hardware breakpoint type %d in x86_length_and_rw_bits.\n"),
			(int) type);
    }

  switch (len)
    {
      case 1:
	return (DR_LEN_1 | rw);
      case 2:
	return (DR_LEN_2 | rw);
      case 4:
	return (DR_LEN_4 | rw);
      case 8:
	if (TARGET_HAS_DR_LEN_8)
	  return (DR_LEN_8 | rw);
	/* FALL THROUGH */
      default:
	internal_error (__FILE__, __LINE__, _("\
Invalid hardware breakpoint length %d in x86_length_and_rw_bits.\n"), len);
    }
}

/* Insert a watchpoint at address ADDR, which is assumed to be aligned
   according to the length of the region to watch.  LEN_RW_BITS is the
   value of the bits from DR7 which describes the length and access
   type of the region to be watched by this watchpoint.  Return 0 on
   success, -1 on failure.  */

static int
x86_insert_aligned_watchpoint (struct x86_debug_reg_state *state,
			       CORE_ADDR addr, unsigned len_rw_bits)
{
  int i;

  if (!x86_dr_low_can_set_addr () || !x86_dr_low_can_set_control ())
    return -1;

  /* First, look for an occupied debug register with the same address
     and the same RW and LEN definitions.  If we find one, we can
     reuse it for this watchpoint as well (and save a register).  */
  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      if (!X86_DR_VACANT (state, i)
	  && state->dr_mirror[i] == addr
	  && X86_DR_GET_RW_LEN (state->dr_control_mirror, i) == len_rw_bits)
	{
	  state->dr_ref_count[i]++;
	  return 0;
	}
    }

  /* Next, look for a vacant debug register.  */
  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      if (X86_DR_VACANT (state, i))
	break;
    }

  /* No more debug registers!  */
  if (i >= DR_NADDR)
    return -1;

  /* Now set up the register I to watch our region.  */

  /* Record the info in our local mirrored array.  */
  state->dr_mirror[i] = addr;
  state->dr_ref_count[i] = 1;
  X86_DR_SET_RW_LEN (state, i, len_rw_bits);
  /* Note: we only enable the watchpoint locally, i.e. in the current
     task.  Currently, no x86 target allows or supports global
     watchpoints; however, if any target would want that in the
     future, GDB should probably provide a command to control whether
     to enable watchpoints globally or locally, and the code below
     should use global or local enable and slow-down flags as
     appropriate.  */
  X86_DR_LOCAL_ENABLE (state, i);
  state->dr_control_mirror |= DR_LOCAL_SLOWDOWN;
  state->dr_control_mirror &= X86_DR_CONTROL_MASK;

  return 0;
}

/* Remove a watchpoint at address ADDR, which is assumed to be aligned
   according to the length of the region to watch.  LEN_RW_BITS is the
   value of the bits from DR7 which describes the length and access
   type of the region watched by this watchpoint.  Return 0 on
   success, -1 on failure.  */

static int
x86_remove_aligned_watchpoint (struct x86_debug_reg_state *state,
			       CORE_ADDR addr, unsigned len_rw_bits)
{
  int i, retval = -1;
  int all_vacant = 1;

  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      if (!X86_DR_VACANT (state, i)
	  && state->dr_mirror[i] == addr
	  && X86_DR_GET_RW_LEN (state->dr_control_mirror, i) == len_rw_bits)
	{
	  if (--state->dr_ref_count[i] == 0) /* No longer in use?  */
	    {
	      /* Reset our mirror.  */
	      state->dr_mirror[i] = 0;
	      X86_DR_DISABLE (state, i);
	      /* Even though not strictly necessary, clear out all
		 bits in DR_CONTROL related to this debug register.
		 Debug output is clearer when we don't have stale bits
		 in place.  This also allows the assertion below.  */
	      X86_DR_SET_RW_LEN (state, i, 0);
	    }
	  retval = 0;
	}

      if (!X86_DR_VACANT (state, i))
	all_vacant = 0;
    }

  if (all_vacant)
    {
      /* Even though not strictly necessary, clear out all of
	 DR_CONTROL, so that when we have no debug registers in use,
	 we end up with DR_CONTROL == 0.  The Linux support relies on
	 this for an optimization.  Plus, it makes for clearer debug
	 output.  */
      state->dr_control_mirror &= ~DR_LOCAL_SLOWDOWN;

      gdb_assert (state->dr_control_mirror == 0);
    }
  return retval;
}

/* Insert or remove a (possibly non-aligned) watchpoint, or count the
   number of debug registers required to watch a region at address
   ADDR whose length is LEN for accesses of type TYPE.  Return 0 on
   successful insertion or removal, a positive number when queried
   about the number of registers, or -1 on failure.  If WHAT is not a
   valid value, bombs through internal_error.  */

static int
x86_handle_nonaligned_watchpoint (struct x86_debug_reg_state *state,
				  x86_wp_op_t what, CORE_ADDR addr, int len,
				  enum target_hw_bp_type type)
{
  int retval = 0;
  int max_wp_len = TARGET_HAS_DR_LEN_8 ? 8 : 4;

  static const int size_try_array[8][8] =
  {
    {1, 1, 1, 1, 1, 1, 1, 1},	/* Trying size one.  */
    {2, 1, 2, 1, 2, 1, 2, 1},	/* Trying size two.  */
    {2, 1, 2, 1, 2, 1, 2, 1},	/* Trying size three.  */
    {4, 1, 2, 1, 4, 1, 2, 1},	/* Trying size four.  */
    {4, 1, 2, 1, 4, 1, 2, 1},	/* Trying size five.  */
    {4, 1, 2, 1, 4, 1, 2, 1},	/* Trying size six.  */
    {4, 1, 2, 1, 4, 1, 2, 1},	/* Trying size seven.  */
    {8, 1, 2, 1, 4, 1, 2, 1},	/* Trying size eight.  */
  };

  while (len > 0)
    {
      int align = addr % max_wp_len;
      /* Four (eight on AMD64) is the maximum length a debug register
	 can watch.  */
      int attempt = (len > max_wp_len ? (max_wp_len - 1) : len - 1);
      int size = size_try_array[attempt][align];

      if (what == WP_COUNT)
	{
	  /* size_try_array[] is defined such that each iteration
	     through the loop is guaranteed to produce an address and a
	     size that can be watched with a single debug register.
	     Thus, for counting the registers required to watch a
	     region, we simply need to increment the count on each
	     iteration.  */
	  retval++;
	}
      else
	{
	  unsigned len_rw = x86_length_and_rw_bits (size, type);

	  if (what == WP_INSERT)
	    retval = x86_insert_aligned_watchpoint (state, addr, len_rw);
	  else if (what == WP_REMOVE)
	    retval = x86_remove_aligned_watchpoint (state, addr, len_rw);
	  else
	    internal_error (__FILE__, __LINE__, _("\
Invalid value %d of operation in x86_handle_nonaligned_watchpoint.\n"),
			    (int) what);
	  if (retval)
	    break;
	}

      addr += size;
      len -= size;
    }

  return retval;
}

/* Update the inferior debug registers state, in STATE, with the
   new debug registers state, in NEW_STATE.  */

static void
x86_update_inferior_debug_regs (struct x86_debug_reg_state *state,
				struct x86_debug_reg_state *new_state)
{
  int i;

  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      if (X86_DR_VACANT (new_state, i) != X86_DR_VACANT (state, i))
	x86_dr_low_set_addr (new_state, i);
      else
	gdb_assert (new_state->dr_mirror[i] == state->dr_mirror[i]);
    }

  if (new_state->dr_control_mirror != state->dr_control_mirror)
    x86_dr_low_set_control (new_state);

  *state = *new_state;
}

/* Insert a watchpoint to watch a memory region which starts at
   address ADDR and whose length is LEN bytes.  Watch memory accesses
   of the type TYPE.  Return 0 on success, -1 on failure.  */

int
x86_dr_insert_watchpoint (struct x86_debug_reg_state *state,
			  enum target_hw_bp_type type,
			  CORE_ADDR addr, int len)
{
  int retval;
  /* Work on a local copy of the debug registers, and on success,
     commit the change back to the inferior.  */
  struct x86_debug_reg_state local_state = *state;

  if (type == hw_read)
    return 1; /* unsupported */

  if (((len != 1 && len != 2 && len != 4)
       && !(TARGET_HAS_DR_LEN_8 && len == 8))
      || addr % len != 0)
    {
      retval = x86_handle_nonaligned_watchpoint (&local_state,
						 WP_INSERT,
						 addr, len, type);
    }
  else
    {
      unsigned len_rw = x86_length_and_rw_bits (len, type);

      retval = x86_insert_aligned_watchpoint (&local_state,
					      addr, len_rw);
    }

  if (retval == 0)
    x86_update_inferior_debug_regs (state, &local_state);

  if (show_debug_regs)
    x86_show_dr (state, "insert_watchpoint", addr, len, type);

  return retval;
}

/* Remove a watchpoint that watched the memory region which starts at
   address ADDR, whose length is LEN bytes, and for accesses of the
   type TYPE.  Return 0 on success, -1 on failure.  */

int
x86_dr_remove_watchpoint (struct x86_debug_reg_state *state,
			  enum target_hw_bp_type type,
			  CORE_ADDR addr, int len)
{
  int retval;
  /* Work on a local copy of the debug registers, and on success,
     commit the change back to the inferior.  */
  struct x86_debug_reg_state local_state = *state;

  if (((len != 1 && len != 2 && len != 4)
       && !(TARGET_HAS_DR_LEN_8 && len == 8))
      || addr % len != 0)
    {
      retval = x86_handle_nonaligned_watchpoint (&local_state,
						 WP_REMOVE,
						 addr, len, type);
    }
  else
    {
      unsigned len_rw = x86_length_and_rw_bits (len, type);

      retval = x86_remove_aligned_watchpoint (&local_state,
					      addr, len_rw);
    }

  if (retval == 0)
    x86_update_inferior_debug_regs (state, &local_state);

  if (show_debug_regs)
    x86_show_dr (state, "remove_watchpoint", addr, len, type);

  return retval;
}

/* Return non-zero if we can watch a memory region that starts at
   address ADDR and whose length is LEN bytes.  */

int
x86_dr_region_ok_for_watchpoint (struct x86_debug_reg_state *state,
				 CORE_ADDR addr, int len)
{
  int nregs;

  /* Compute how many aligned watchpoints we would need to cover this
     region.  */
  nregs = x86_handle_nonaligned_watchpoint (state, WP_COUNT,
					     addr, len, hw_write);
  return nregs <= DR_NADDR ? 1 : 0;
}

/* If the inferior has some break/watchpoint that triggered, set the
   address associated with that break/watchpoint and return non-zero.
   Otherwise, return zero.  */

int
x86_dr_stopped_data_address (struct x86_debug_reg_state *state,
			     CORE_ADDR *addr_p)
{
  CORE_ADDR addr = 0;
  int i;
  int rc = 0;
  /* The current thread's DR_STATUS.  We always need to read this to
     check whether some watchpoint caused the trap.  */
  unsigned status;
  /* We need DR_CONTROL as well, but only iff DR_STATUS indicates a
     data breakpoint trap.  Only fetch it when necessary, to avoid an
     unnecessary extra syscall when no watchpoint triggered.  */
  int control_p = 0;
  unsigned control = 0;

  /* In non-stop/async, threads can be running while we change the
     global dr_mirror (and friends).  Say, we set a watchpoint, and
     let threads resume.  Now, say you delete the watchpoint, or
     add/remove watchpoints such that dr_mirror changes while threads
     are running.  On targets that support non-stop,
     inserting/deleting watchpoints updates the global dr_mirror only.
     It does not update the real thread's debug registers; that's only
     done prior to resume.  Instead, if threads are running when the
     mirror changes, a temporary and transparent stop on all threads
     is forced so they can get their copy of the debug registers
     updated on re-resume.  Now, say, a thread hit a watchpoint before
     having been updated with the new dr_mirror contents, and we
     haven't yet handled the corresponding SIGTRAP.  If we trusted
     dr_mirror below, we'd mistake the real trapped address (from the
     last time we had updated debug registers in the thread) with
     whatever was currently in dr_mirror.  So to fix this, dr_mirror
     always represents intention, what we _want_ threads to have in
     debug registers.  To get at the address and cause of the trap, we
     need to read the state the thread still has in its debug
     registers.

     In sum, always get the current debug register values the current
     thread has, instead of trusting the global mirror.  If the thread
     was running when we last changed watchpoints, the mirror no
     longer represents what was set in this thread's debug
     registers.  */
  status = x86_dr_low_get_status ();

  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      if (!X86_DR_WATCH_HIT (status, i))
	continue;

      if (!control_p)
	{
	  control = x86_dr_low_get_control ();
	  control_p = 1;
	}

      /* This second condition makes sure DRi is set up for a data
	 watchpoint, not a hardware breakpoint.  The reason is that
	 GDB doesn't call the target_stopped_data_address method
	 except for data watchpoints.  In other words, I'm being
	 paranoiac.  */
      if (X86_DR_GET_RW_LEN (control, i) != 0)
	{
	  addr = x86_dr_low_get_addr (i);
	  rc = 1;
	  if (show_debug_regs)
	    x86_show_dr (state, "watchpoint_hit", addr, -1, hw_write);
	}
    }

  if (show_debug_regs && addr == 0)
    x86_show_dr (state, "stopped_data_addr", 0, 0, hw_write);

  if (rc)
    *addr_p = addr;
  return rc;
}

/* Return non-zero if the inferior has some watchpoint that triggered.
   Otherwise return zero.  */

int
x86_dr_stopped_by_watchpoint (struct x86_debug_reg_state *state)
{
  CORE_ADDR addr = 0;
  return x86_dr_stopped_data_address (state, &addr);
}

/* Return non-zero if the inferior has some hardware breakpoint that
   triggered.  Otherwise return zero.  */

int
x86_dr_stopped_by_hw_breakpoint (struct x86_debug_reg_state *state)
{
  CORE_ADDR addr = 0;
  int i;
  int rc = 0;
  /* The current thread's DR_STATUS.  We always need to read this to
     check whether some watchpoint caused the trap.  */
  unsigned status;
  /* We need DR_CONTROL as well, but only iff DR_STATUS indicates a
     breakpoint trap.  Only fetch it when necessary, to avoid an
     unnecessary extra syscall when no watchpoint triggered.  */
  int control_p = 0;
  unsigned control = 0;

  /* As above, always read the current thread's debug registers rather
     than trusting dr_mirror.  */
  status = x86_dr_low_get_status ();

  ALL_DEBUG_ADDRESS_REGISTERS (i)
    {
      if (!X86_DR_WATCH_HIT (status, i))
	continue;

      if (!control_p)
	{
	  control = x86_dr_low_get_control ();
	  control_p = 1;
	}

      if (X86_DR_GET_RW_LEN (control, i) == 0)
	{
	  addr = x86_dr_low_get_addr (i);
	  rc = 1;
	  if (show_debug_regs)
	    x86_show_dr (state, "watchpoint_hit", addr, -1, hw_execute);
	}
    }

  return rc;
}
