/* 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;
}
