Move debug_reg_change_callback and aarch64_notify_debug_reg_change to nat/aarch64...
[deliverable/binutils-gdb.git] / gdb / nat / aarch64-linux-hw-point.c
index 1d9664ea1c02a31ed830e7ef93289e0f8a6a6e17..ba235e54c783b74c403ab3dd05417b65bba94065 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "common-defs.h"
 #include "break-common.h"
+#include "nat/linux-nat.h"
 #include "aarch64-linux-hw-point.h"
 
 #include <sys/uio.h>
@@ -220,6 +221,93 @@ aarch64_align_watchpoint (CORE_ADDR addr, int len, CORE_ADDR *aligned_addr_p,
     *next_len_p = len;
 }
 
+struct aarch64_dr_update_callback_param
+{
+  int is_watchpoint;
+  unsigned int idx;
+};
+
+/* Callback for iterate_over_lwps.  Records the
+   information about the change of one hardware breakpoint/watchpoint
+   setting for the thread LWP.
+   The information is passed in via PTR.
+   N.B.  The actual updating of hardware debug registers is not
+   carried out until the moment the thread is resumed.  */
+
+static int
+debug_reg_change_callback (struct lwp_info *lwp, void *ptr)
+{
+  struct aarch64_dr_update_callback_param *param_p
+    = (struct aarch64_dr_update_callback_param *) ptr;
+  int pid = ptid_get_pid (ptid_of_lwp (lwp));
+  int idx = param_p->idx;
+  int is_watchpoint = param_p->is_watchpoint;
+  struct arch_lwp_info *info = lwp_arch_private_info (lwp);
+  dr_changed_t *dr_changed_ptr;
+  dr_changed_t dr_changed;
+
+  if (info == NULL)
+    {
+      info = XCNEW (struct arch_lwp_info);
+      lwp_set_arch_private_info (lwp, info);
+    }
+
+  if (show_debug_regs)
+    {
+      debug_printf ("debug_reg_change_callback: \n\tOn entry:\n");
+      debug_printf ("\tpid%d, dr_changed_bp=0x%s, "
+                   "dr_changed_wp=0x%s\n", pid,
+                   phex (info->dr_changed_bp, 8),
+                   phex (info->dr_changed_wp, 8));
+    }
+
+  dr_changed_ptr = is_watchpoint ? &info->dr_changed_wp
+    : &info->dr_changed_bp;
+  dr_changed = *dr_changed_ptr;
+
+  gdb_assert (idx >= 0
+             && (idx <= (is_watchpoint ? aarch64_num_wp_regs
+                         : aarch64_num_bp_regs)));
+
+  /* The actual update is done later just before resuming the lwp,
+     we just mark that one register pair needs updating.  */
+  DR_MARK_N_CHANGED (dr_changed, idx);
+  *dr_changed_ptr = dr_changed;
+
+  /* If the lwp isn't stopped, force it to momentarily pause, so
+     we can update its debug registers.  */
+  if (!lwp_is_stopped (lwp))
+    linux_stop_lwp (lwp);
+
+  if (show_debug_regs)
+    {
+      debug_printf ("\tOn exit:\n\tpid%d, dr_changed_bp=0x%s, "
+                   "dr_changed_wp=0x%s\n", pid,
+                   phex (info->dr_changed_bp, 8),
+                   phex (info->dr_changed_wp, 8));
+    }
+
+  return 0;
+}
+
+/* Notify each thread that their IDXth breakpoint/watchpoint register
+   pair needs to be updated.  The message will be recorded in each
+   thread's arch-specific data area, the actual updating will be done
+   when the thread is resumed.  */
+
+static void
+aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
+                                int is_watchpoint, unsigned int idx)
+{
+  struct aarch64_dr_update_callback_param param;
+  ptid_t pid_ptid = pid_to_ptid (ptid_get_pid (current_lwp_ptid ()));
+
+  param.is_watchpoint = is_watchpoint;
+  param.idx = idx;
+
+  iterate_over_lwps (pid_ptid, debug_reg_change_callback, (void *) &param);
+}
+
 /* Record the insertion of one breakpoint/watchpoint, as represented
    by ADDR and CTRL, in the process' arch-specific data area *STATE.  */
 
This page took 0.03561 seconds and 4 git commands to generate.