PR threads/10729
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-x86-low.c
index 1e0d684f8e40e0254e9654fc23062e21a88eddc7..841f0536132cdf22b9626639906e5c65998bdfb5 100644 (file)
@@ -461,30 +461,55 @@ x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
     error ("Couldn't write debug register");
 }
 
+static int
+update_debug_registers_callback (struct inferior_list_entry *entry,
+                                void *pid_p)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  int pid = *(int *) pid_p;
+
+  /* Only update the threads of this process.  */
+  if (pid_of (lwp) == pid)
+    {
+      /* The actual update is done later just before resuming the lwp,
+        we just mark that the registers need updating.  */
+      lwp->arch_private->debug_registers_changed = 1;
+
+      /* If the lwp isn't stopped, force it to momentarily pause, so
+        we can update its debug registers.  */
+      if (!lwp->stopped)
+       linux_stop_lwp (lwp);
+    }
+
+  return 0;
+}
+
 /* Update the inferior's debug register REGNUM from STATE.  */
 
 void
 i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum)
 {
-  struct inferior_list_entry *lp;
-  CORE_ADDR addr;
-  /* Only need to update the threads of this process.  */
+  /* Only update the threads of this process.  */
   int pid = pid_of (get_thread_lwp (current_inferior));
 
   if (! (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR))
     fatal ("Invalid debug register %d", regnum);
 
-  addr = state->dr_mirror[regnum];
+  find_inferior (&all_lwps, update_debug_registers_callback, &pid);
+}
 
-  for (lp = all_lwps.head; lp; lp = lp->next)
-    {
-      struct lwp_info *lwp = (struct lwp_info *) lp;
+/* Return the inferior's debug register REGNUM.  */
 
-      /* The actual update is done later, we just mark that the register
-        needs updating.  */
-      if (pid_of (lwp) == pid)
-       lwp->arch_private->debug_registers_changed = 1;
-    }
+CORE_ADDR
+i386_dr_low_get_addr (int regnum)
+{
+  struct lwp_info *lwp = get_thread_lwp (current_inferior);
+  ptid_t ptid = ptid_of (lwp);
+
+  /* DR6 and DR7 are retrieved with some other way.  */
+  gdb_assert (DR_FIRSTADDR <= regnum && regnum < DR_LASTADDR);
+
+  return x86_linux_dr_get (ptid, regnum);
 }
 
 /* Update the inferior's DR7 debug control register from STATE.  */
@@ -492,31 +517,33 @@ i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum)
 void
 i386_dr_low_set_control (const struct i386_debug_reg_state *state)
 {
-  struct inferior_list_entry *lp;
-  /* Only need to update the threads of this process.  */
+  /* Only update the threads of this process.  */
   int pid = pid_of (get_thread_lwp (current_inferior));
 
-  for (lp = all_lwps.head; lp; lp = lp->next)
-    {
-      struct lwp_info *lwp = (struct lwp_info *) lp;
+  find_inferior (&all_lwps, update_debug_registers_callback, &pid);
+}
 
-      /* The actual update is done later, we just mark that the register
-        needs updating.  */
-      if (pid_of (lwp) == pid)
-       lwp->arch_private->debug_registers_changed = 1;
-    }
+/* Return the inferior's DR7 debug control register.  */
+
+unsigned
+i386_dr_low_get_control (void)
+{
+  struct lwp_info *lwp = get_thread_lwp (current_inferior);
+  ptid_t ptid = ptid_of (lwp);
+
+  return x86_linux_dr_get (ptid, DR_CONTROL);
 }
 
 /* Get the value of the DR6 debug status register from the inferior
    and record it in STATE.  */
 
-void
-i386_dr_low_get_status (struct i386_debug_reg_state *state)
+unsigned
+i386_dr_low_get_status (void)
 {
   struct lwp_info *lwp = get_thread_lwp (current_inferior);
   ptid_t ptid = ptid_of (lwp);
 
-  state->dr_status_mirror = x86_linux_dr_get (ptid, DR_STATUS);
+  return x86_linux_dr_get (ptid, DR_STATUS);
 }
 \f
 /* Watchpoint support.  */
This page took 0.032044 seconds and 4 git commands to generate.