move sparc-sol-thread.c back into sol-thread.c.
[deliverable/binutils-gdb.git] / gdb / i386-nat.c
index 4c6c4e959f80817bef227bb8de428000b6d0169d..0a5deb06ca1869f9e7751cae5eab0f429fe4ed45 100644 (file)
@@ -1,7 +1,6 @@
 /* Native-dependent code for the i386.
 
-   Copyright (C) 2001, 2004, 2005, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    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 "i386-nat.h"
 #include "defs.h"
+#include "i386-nat.h"
 #include "breakpoint.h"
 #include "command.h"
 #include "gdbcmd.h"
 #include "target.h"
 #include "gdb_assert.h"
+#include "inferior.h"
 
 /* Support for hardware watchpoints and breakpoints using the i386
    debug registers.
@@ -43,11 +43,6 @@ struct i386_dr_low_type i386_dr_low;
 /* Support for 8-byte wide hw watchpoints.  */
 #define TARGET_HAS_DR_LEN_8 (i386_dr_low.debug_register_length == 8)
 
-/* 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).  */
-
 /* DR7 Debug Control register fields.  */
 
 /* How many bits to skip in DR7 to get to R/W and LEN fields.  */
@@ -158,44 +153,103 @@ struct i386_dr_low_type i386_dr_low;
 /* A macro to loop over all debug registers.  */
 #define ALL_DEBUG_REGISTERS(i) for (i = 0; i < DR_NADDR; i++)
 
+/* Per-process data.  We don't bind this to a per-inferior registry
+   because of targets like x86 GNU/Linux that need to keep track of
+   processes that aren't bound to any inferior (e.g., fork children,
+   checkpoints).  */
 
-/* Global state needed to track h/w watchpoints.  */
-
-struct i386_debug_reg_state
+struct i386_process_info
 {
-  /* Mirror the inferior's DRi registers.  We keep the status and
-     control registers separated because they don't hold addresses.
-     Note that since we can change these mirrors while threads are
-     running, we never trust them to explain a cause of a trap.
-     For that, we need to peek directly in the inferior registers.  */
-  CORE_ADDR dr_mirror[DR_NADDR];
-  unsigned dr_status_mirror, dr_control_mirror;
-
-  /* Reference counts for each debug register.  */
-  int dr_ref_count[DR_NADDR];
+  /* Linked list.  */
+  struct i386_process_info *next;
+
+  /* The process identifier.  */
+  pid_t pid;
+
+  /* Copy of i386 hardware debug registers.  */
+  struct i386_debug_reg_state state;
 };
 
-/* Clear the reference counts and forget everything we knew about the
-   debug registers.  */
+static struct i386_process_info *i386_process_list = NULL;
 
-static void
-i386_init_dregs (struct i386_debug_reg_state *state)
+/* Find process data for process PID.  */
+
+static struct i386_process_info *
+i386_find_process_pid (pid_t pid)
 {
-  int i;
+  struct i386_process_info *proc;
 
-  ALL_DEBUG_REGISTERS (i)
-    {
-      state->dr_mirror[i] = 0;
-      state->dr_ref_count[i] = 0;
-    }
-  state->dr_control_mirror = 0;
-  state->dr_status_mirror  = 0;
+  for (proc = i386_process_list; proc; proc = proc->next)
+    if (proc->pid == pid)
+      return proc;
+
+  return NULL;
 }
 
-static struct i386_debug_reg_state dr_mirror;
+/* Add process data for process PID.  Returns newly allocated info
+   object.  */
+
+static struct i386_process_info *
+i386_add_process (pid_t pid)
+{
+  struct i386_process_info *proc;
+
+  proc = xcalloc (1, sizeof (*proc));
+  proc->pid = pid;
+
+  proc->next = i386_process_list;
+  i386_process_list = proc;
+
+  return proc;
+}
+
+/* Get data specific info for process PID, creating it if necessary.
+   Never returns NULL.  */
+
+static struct i386_process_info *
+i386_process_info_get (pid_t pid)
+{
+  struct i386_process_info *proc;
+
+  proc = i386_find_process_pid (pid);
+  if (proc == NULL)
+    proc = i386_add_process (pid);
+
+  return proc;
+}
+
+/* Get debug registers state for process PID.  */
+
+struct i386_debug_reg_state *
+i386_debug_reg_state (pid_t pid)
+{
+  return &i386_process_info_get (pid)->state;
+}
+
+/* See declaration in i386-nat.h.  */
+
+void
+i386_forget_process (pid_t pid)
+{
+  struct i386_process_info *proc, **proc_link;
+
+  proc = i386_process_list;
+  proc_link = &i386_process_list;
 
-/* Reference counts for each debug register.  */
-static int dr_ref_count[DR_NADDR];
+  while (proc != NULL)
+    {
+      if (proc->pid == pid)
+       {
+         *proc_link = proc->next;
+
+         xfree (proc);
+         return;
+       }
+
+      proc_link = &proc->next;
+      proc = *proc_link;
+    }
+}
 
 /* Whether or not to print the mirrored debug registers.  */
 static int maint_show_dr;
@@ -247,7 +301,8 @@ static int i386_handle_nonaligned_watchpoint (struct i386_debug_reg_state *state
 void
 i386_cleanup_dregs (void)
 {
-  i386_init_dregs (&dr_mirror);
+  /* Starting from scratch has the same effect.  */
+  i386_forget_process (ptid_get_pid (inferior_ptid));
 }
 
 /* Print the values of the mirrored debug registers.  This is called
@@ -259,7 +314,7 @@ i386_show_dr (struct i386_debug_reg_state *state,
              const char *func, CORE_ADDR addr,
              int len, enum target_hw_bp_type type)
 {
-  int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
+  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
   int i;
 
   puts_unfiltered (func);
@@ -511,35 +566,22 @@ Invalid value %d of operation in i386_handle_nonaligned_watchpoint.\n"),
 static void
 i386_update_inferior_debug_regs (struct i386_debug_reg_state *new_state)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int i;
 
   ALL_DEBUG_REGISTERS (i)
     {
-      if (I386_DR_VACANT (new_state, i) != I386_DR_VACANT (&dr_mirror, i))
-       {
-         if (!I386_DR_VACANT (new_state, i))
-           {
-             i386_dr_low.set_addr (i, new_state->dr_mirror[i]);
-
-             /* 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));
-           }
-         else
-           {
-             if (i386_dr_low.reset_addr)
-               i386_dr_low.reset_addr (i);
-           }
-       }
+      if (I386_DR_VACANT (new_state, i) != I386_DR_VACANT (state, i))
+       i386_dr_low.set_addr (i, new_state->dr_mirror[i]);
       else
-       gdb_assert (new_state->dr_mirror[i] == dr_mirror.dr_mirror[i]);
+       gdb_assert (new_state->dr_mirror[i] == state->dr_mirror[i]);
     }
 
-  if (new_state->dr_control_mirror != dr_mirror.dr_control_mirror)
+  if (new_state->dr_control_mirror != state->dr_control_mirror)
     i386_dr_low.set_control (new_state->dr_control_mirror);
 
-  dr_mirror = *new_state;
+  *state = *new_state;
 }
 
 /* Insert a watchpoint to watch a memory region which starts at
@@ -550,10 +592,12 @@ static int
 i386_insert_watchpoint (CORE_ADDR addr, int len, int type,
                        struct expression *cond)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int retval;
   /* Work on a local copy of the debug registers, and on success,
      commit the change back to the inferior.  */
-  struct i386_debug_reg_state local_state = dr_mirror;
+  struct i386_debug_reg_state local_state = *state;
 
   if (type == hw_read)
     return 1; /* unsupported */
@@ -574,7 +618,7 @@ i386_insert_watchpoint (CORE_ADDR addr, int len, int type,
     i386_update_inferior_debug_regs (&local_state);
 
   if (maint_show_dr)
-    i386_show_dr (&dr_mirror, "insert_watchpoint", addr, len, type);
+    i386_show_dr (state, "insert_watchpoint", addr, len, type);
 
   return retval;
 }
@@ -586,10 +630,12 @@ static int
 i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
                        struct expression *cond)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int retval;
   /* Work on a local copy of the debug registers, and on success,
      commit the change back to the inferior.  */
-  struct i386_debug_reg_state local_state = dr_mirror;
+  struct i386_debug_reg_state local_state = *state;
 
   if (((len != 1 && len !=2 && len !=4) && !(TARGET_HAS_DR_LEN_8 && len == 8))
       || addr % len != 0)
@@ -607,7 +653,7 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
     i386_update_inferior_debug_regs (&local_state);
 
   if (maint_show_dr)
-    i386_show_dr (&dr_mirror, "remove_watchpoint", addr, len, type);
+    i386_show_dr (state, "remove_watchpoint", addr, len, type);
 
   return retval;
 }
@@ -618,11 +664,13 @@ i386_remove_watchpoint (CORE_ADDR addr, int len, int type,
 static int
 i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   int nregs;
 
   /* Compute how many aligned watchpoints we would need to cover this
      region.  */
-  nregs = i386_handle_nonaligned_watchpoint (&dr_mirror,
+  nregs = i386_handle_nonaligned_watchpoint (state,
                                             WP_COUNT, addr, len, hw_write);
   return nregs <= DR_NADDR ? 1 : 0;
 }
@@ -634,38 +682,73 @@ i386_region_ok_for_watchpoint (CORE_ADDR addr, int len)
 static int
 i386_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   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;
-  unsigned control;
-  struct i386_debug_reg_state *state = &dr_mirror;
-
-  dr_mirror.dr_status_mirror = i386_dr_low.get_status ();
-  status = dr_mirror.dr_status_mirror;
-  control = dr_mirror.dr_control_mirror;
+  /* 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
+     STATE (and friends).  Say, we set a watchpoint, and let threads
+     resume.  Now, say you delete the watchpoint, or add/remove
+     watchpoints such that STATE changes while threads are running.
+     On targets that support non-stop, inserting/deleting watchpoints
+     updates the STATE 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
+     STATE contents, and we haven't yet handled the corresponding
+     SIGTRAP.  If we trusted STATE 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 STATE.
+     So to fix this, STATE 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 = i386_dr_low.get_status ();
 
   ALL_DEBUG_REGISTERS(i)
     {
-      if (I386_DR_WATCH_HIT (status, i)
-         /* 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.  */
-         && I386_DR_GET_RW_LEN (control, i) != 0
-         /* This third condition makes sure DRi is not vacant, this
-            avoids false positives in windows-nat.c.  */
-         && !I386_DR_VACANT (state, i))
+      if (!I386_DR_WATCH_HIT (status, i))
+       continue;
+
+      if (!control_p)
+       {
+         control = i386_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 (I386_DR_GET_RW_LEN (control, i) != 0)
        {
-         addr = state->dr_mirror[i];
+         addr = i386_dr_low.get_addr (i);
          rc = 1;
          if (maint_show_dr)
-           i386_show_dr (&dr_mirror, "watchpoint_hit", addr, -1, hw_write);
+           i386_show_dr (state, "watchpoint_hit", addr, -1, hw_write);
        }
     }
   if (maint_show_dr && addr == 0)
-    i386_show_dr (&dr_mirror, "stopped_data_addr", 0, 0, hw_write);
+    i386_show_dr (state, "stopped_data_addr", 0, 0, hw_write);
 
   if (rc)
     *addr_p = addr;
@@ -685,13 +768,21 @@ static int
 i386_insert_hw_breakpoint (struct gdbarch *gdbarch,
                           struct bp_target_info *bp_tgt)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
   CORE_ADDR addr = bp_tgt->placed_address;
-  int retval = i386_insert_aligned_watchpoint (&dr_mirror,
+  /* Work on a local copy of the debug registers, and on success,
+     commit the change back to the inferior.  */
+  struct i386_debug_reg_state local_state = *state;
+  int retval = i386_insert_aligned_watchpoint (&local_state,
                                               addr, len_rw) ? EBUSY : 0;
 
+  if (retval == 0)
+    i386_update_inferior_debug_regs (&local_state);
+
   if (maint_show_dr)
-    i386_show_dr (&dr_mirror, "insert_hwbp", addr, 1, hw_execute);
+    i386_show_dr (state, "insert_hwbp", addr, 1, hw_execute);
 
   return retval;
 }
@@ -703,13 +794,21 @@ static int
 i386_remove_hw_breakpoint (struct gdbarch *gdbarch,
                           struct bp_target_info *bp_tgt)
 {
+  struct i386_debug_reg_state *state
+    = i386_debug_reg_state (ptid_get_pid (inferior_ptid));
   unsigned len_rw = i386_length_and_rw_bits (1, hw_execute);
   CORE_ADDR addr = bp_tgt->placed_address;
-  int retval = i386_remove_aligned_watchpoint (&dr_mirror,
+  /* Work on a local copy of the debug registers, and on success,
+     commit the change back to the inferior.  */
+  struct i386_debug_reg_state local_state = *state;
+  int retval = i386_remove_aligned_watchpoint (&local_state,
                                               addr, len_rw);
 
+  if (retval == 0)
+    i386_update_inferior_debug_regs (&local_state);
+
   if (maint_show_dr)
-    i386_show_dr (&dr_mirror, "remove_hwbp", addr, 1, hw_execute);
+    i386_show_dr (state, "remove_hwbp", addr, 1, hw_execute);
 
   return retval;
 }
This page took 0.028063 seconds and 4 git commands to generate.