/* Native-dependent code for the i386.
- Copyright (C) 2001, 2004, 2005, 2007, 2008, 2009
+ Copyright (C) 2001, 2004, 2005, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GDB.
/* Debug registers' indices. */
#define DR_NADDR 4 /* The number of debug address registers. */
#define DR_STATUS 6 /* Index of debug status register (DR6). */
-#define DR_CONTROL 7 /* Index of debug control register (DR7). */
+#define DR_CONTROL 7 /* Index of debug control register (DR7). */
/* DR7 Debug Control register fields. */
#define I386_DR_GET_RW_LEN(i) \
((dr_control_mirror >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f)
+/* Mask that this I'th watchpoint has triggered. */
+#define I386_DR_WATCH_MASK(i) (1 << (i))
+
/* Did the watchpoint whose address is in the I'th register break? */
-#define I386_DR_WATCH_HIT(i) (dr_status_mirror & (1 << (i)))
+#define I386_DR_WATCH_HIT(i) (dr_status_mirror & I386_DR_WATCH_MASK (i))
/* A macro to loop over all debug registers. */
#define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++)
i386_show_dr (const char *func, CORE_ADDR addr,
int len, enum target_hw_bp_type type)
{
+ int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
int i;
puts_unfiltered (func);
{
printf_unfiltered ("\
\tDR%d: addr=0x%s, ref.count=%d DR%d: addr=0x%s, ref.count=%d\n",
- i, paddr(dr_mirror[i]), dr_ref_count[i],
- i+1, paddr(dr_mirror[i+1]), dr_ref_count[i+1]);
+ i, phex (dr_mirror[i], addr_size), dr_ref_count[i],
+ i+1, phex (dr_mirror[i+1], addr_size), dr_ref_count[i+1]);
i++;
}
}
rw = DR_RW_WRITE;
break;
case hw_read:
- /* The i386 doesn't support data-read watchpoints. */
+ internal_error (__FILE__, __LINE__,
+ _("The i386 doesn't support "
+ "data-read watchpoints.\n"));
case hw_access:
rw = DR_RW_READ;
break;
case 8:
if (TARGET_HAS_DR_LEN_8)
return (DR_LEN_8 | rw);
+ /* ELSE FALL THROUGH */
default:
internal_error (__FILE__, __LINE__, _("\
Invalid hardware breakpoint length %d in i386_length_and_rw_bits.\n"), len);
i386_dr_low.set_addr (i, addr);
i386_dr_low.set_control (dr_control_mirror);
+ /* Only a sanity check for leftover bits (set possibly only by inferior). */
+ if (i386_dr_low.unset_status)
+ i386_dr_low.unset_status (I386_DR_WATCH_MASK (i));
+
return 0;
}
&& dr_mirror[i] == addr
&& I386_DR_GET_RW_LEN (i) == len_rw_bits)
{
- if (--dr_ref_count[i] == 0) /* no longer in use? */
+ if (--dr_ref_count[i] == 0) /* no longer in use? */
{
/* Reset our mirror. */
dr_mirror[i] = 0;
of the type TYPE. Return 0 on success, -1 on failure. */
static int
-i386_insert_watchpoint (CORE_ADDR addr, int len, int type)
+i386_insert_watchpoint (CORE_ADDR addr, int len, int type,
+ struct expression *cond)
{
int retval;
+ 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 = i386_handle_nonaligned_watchpoint (WP_INSERT, addr, len, type);
address ADDR, whose length is LEN bytes, and for accesses of the
type TYPE. Return 0 on success, -1 on failure. */
static int
-i386_remove_watchpoint (CORE_ADDR addr, int len, int type)
+i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
+ struct expression *cond)
{
int retval;
}
/* If the inferior has some watchpoint that triggered, set the
- address associated with that watchpoint and return non-zero.
+ address associated with that watchpoint and return non-zero.
Otherwise, return zero. */
static int
that GDB doesn't call the target_stopped_data_address
method except for data watchpoints. In other words, I'm
being paranoiac. */
- && I386_DR_GET_RW_LEN (i) != 0)
+ && I386_DR_GET_RW_LEN (i) != 0
+ /* This third condition makes sure DRi is not vacant, this
+ avoids false positives in windows-nat.c. */
+ && !I386_DR_VACANT (i))
{
addr = dr_mirror[i];
rc = 1;
return i386_stopped_data_address (¤t_target, &addr);
}
-/* Return non-zero if the inferior has some break/watchpoint that
- triggered. */
-
-static int
-i386_stopped_by_hwbp (void)
-{
- int i;
-
- dr_status_mirror = i386_dr_low.get_status ();
- if (maint_show_dr)
- i386_show_dr ("stopped_by_hwbp", 0, 0, hw_execute);
-
- ALL_DEBUG_REGISTERS(i)
- {
- if (I386_DR_WATCH_HIT (i))
- return 1;
- }
-
- return 0;
-}
-
/* Insert a hardware-assisted breakpoint at BP_TGT->placed_address.
Return 0 on success, EBUSY on failure. */
static int