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

   Copyright (C) 2001-2020 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;
}
