Use memmove to copy overlap memory.
[deliverable/binutils-gdb.git] / gdb / i386-nat.c
index 49339b0ee9543b501ff88365e476c4ebebddd0f5..82c51d70c20d2d3e41f55aa71a50f3517431967d 100644 (file)
@@ -1,6 +1,6 @@
 /* Native-dependent code for the i386.
 
-   Copyright (C) 2001, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2001, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -137,8 +137,11 @@ struct i386_dr_low_type i386_dr_low;
 #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++)
@@ -217,6 +220,7 @@ static void
 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);
@@ -240,8 +244,8 @@ i386_show_dr (const char *func, CORE_ADDR addr,
     {
       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++;
     }
 }
@@ -264,7 +268,8 @@ i386_length_and_rw_bits (int len, enum target_hw_bp_type type)
        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;
@@ -357,6 +362,10 @@ i386_insert_aligned_watchpoint (CORE_ADDR addr, unsigned len_rw_bits)
   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;
 }
 
@@ -479,6 +488,9 @@ i386_insert_watchpoint (CORE_ADDR addr, int len, int type)
 {
   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);
@@ -554,7 +566,10 @@ i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
             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;
@@ -577,31 +592,11 @@ i386_stopped_by_watchpoint (void)
   return i386_stopped_data_address (&current_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
-i386_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
+i386_insert_hw_breakpoint (struct gdbarch *gdbarch,
+                          struct bp_target_info *bp_tgt)
 {
   unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
   CORE_ADDR addr = bp_tgt->placed_address;
@@ -617,7 +612,8 @@ i386_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
    Return 0 on success, -1 on failure.  */
 
 static int
-i386_remove_hw_breakpoint (struct bp_target_info *bp_tgt)
+i386_remove_hw_breakpoint (struct gdbarch *gdbarch,
+                          struct bp_target_info *bp_tgt)
 {
   unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
   CORE_ADDR addr = bp_tgt->placed_address;
This page took 0.024373 seconds and 4 git commands to generate.