target: add to_record_stop_replaying target method
[deliverable/binutils-gdb.git] / gdb / aarch64-linux-nat.c
index b23026aae091d7335e30aa7007634d06f175f221..d7ac19eb5a366d35d35811c1491ff962d61b256d 100644 (file)
@@ -30,6 +30,7 @@
 #include "aarch64-tdep.h"
 #include "aarch64-linux-tdep.h"
 #include "aarch32-linux-nat.h"
+#include "nat/aarch64-linux.h"
 #include "nat/aarch64-linux-hw-point.h"
 
 #include "elf/external.h"
@@ -89,7 +90,7 @@ aarch64_add_process (pid_t pid)
 {
   struct aarch64_process_info *proc;
 
-  proc = xcalloc (1, sizeof (*proc));
+  proc = XCNEW (struct aarch64_process_info);
   proc->pid = pid;
 
   proc->next = aarch64_process_list;
@@ -141,7 +142,7 @@ aarch64_forget_process (pid_t pid)
 
 /* Get debug registers state for process PID.  */
 
-static struct aarch64_debug_reg_state *
+struct aarch64_debug_reg_state *
 aarch64_get_debug_reg_state (pid_t pid)
 {
   return &aarch64_process_info_get (pid)->state;
@@ -425,60 +426,6 @@ supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
                          AARCH64_LINUX_SIZEOF_FPREGSET);
 }
 
-/* Called when resuming a thread.
-   The hardware debug registers are updated when there is any change.  */
-
-static void
-aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
-{
-  struct arch_lwp_info *info = lwp_arch_private_info (lwp);
-
-  /* NULL means this is the main thread still going through the shell,
-     or, no watchpoint has been set yet.  In that case, there's
-     nothing to do.  */
-  if (info == NULL)
-    return;
-
-  if (DR_HAS_CHANGED (info->dr_changed_bp)
-      || DR_HAS_CHANGED (info->dr_changed_wp))
-    {
-      ptid_t ptid = ptid_of_lwp (lwp);
-      int tid = ptid_get_lwp (ptid);
-      struct aarch64_debug_reg_state *state
-       = aarch64_get_debug_reg_state (ptid_get_pid (ptid));
-
-      if (show_debug_regs)
-       fprintf_unfiltered (gdb_stdlog, "prepare_to_resume thread %d\n", tid);
-
-      /* Watchpoints.  */
-      if (DR_HAS_CHANGED (info->dr_changed_wp))
-       {
-         aarch64_linux_set_debug_regs (state, tid, 1);
-         DR_CLEAR_CHANGED (info->dr_changed_wp);
-       }
-
-      /* Breakpoints.  */
-      if (DR_HAS_CHANGED (info->dr_changed_bp))
-       {
-         aarch64_linux_set_debug_regs (state, tid, 0);
-         DR_CLEAR_CHANGED (info->dr_changed_bp);
-       }
-    }
-}
-
-static void
-aarch64_linux_new_thread (struct lwp_info *lp)
-{
-  struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
-
-  /* Mark that all the hardware breakpoint/watchpoint register pairs
-     for this thread need to be initialized.  */
-  DR_MARK_ALL_CHANGED (info->dr_changed_bp, aarch64_num_bp_regs);
-  DR_MARK_ALL_CHANGED (info->dr_changed_wp, aarch64_num_wp_regs);
-
-  lp->arch_private = info;
-}
-
 /* linux_nat_new_fork hook.   */
 
 static void
@@ -596,6 +543,34 @@ aarch64_linux_read_description (struct target_ops *ops)
   return tdesc_aarch64;
 }
 
+/* Convert a native/host siginfo object, into/from the siginfo in the
+   layout of the inferiors' architecture.  Returns true if any
+   conversion was done; false otherwise.  If DIRECTION is 1, then copy
+   from INF to NATIVE.  If DIRECTION is 0, copy from NATIVE to
+   INF.  */
+
+static int
+aarch64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
+{
+  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
+
+  /* Is the inferior 32-bit?  If so, then do fixup the siginfo
+     object.  */
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    {
+      if (direction == 0)
+       aarch64_compat_siginfo_from_siginfo ((struct compat_siginfo *) inf,
+                                            native);
+      else
+       aarch64_siginfo_from_compat_siginfo (native,
+                                            (struct compat_siginfo *) inf);
+
+      return 1;
+    }
+
+  return 0;
+}
+
 /* Returns the number of hardware watchpoints of type TYPE that we can
    set.  Value is positive if we can set CNT watchpoints, zero if
    setting watchpoints of type TYPE is not supported, and negative if
@@ -770,38 +745,7 @@ static int
 aarch64_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
                                           CORE_ADDR addr, int len)
 {
-  CORE_ADDR aligned_addr;
-
-  /* Can not set watchpoints for zero or negative lengths.  */
-  if (len <= 0)
-    return 0;
-
-  /* Must have hardware watchpoint debug register(s).  */
-  if (aarch64_num_wp_regs == 0)
-    return 0;
-
-  /* We support unaligned watchpoint address and arbitrary length,
-     as long as the size of the whole watched area after alignment
-     doesn't exceed size of the total area that all watchpoint debug
-     registers can watch cooperatively.
-
-     This is a very relaxed rule, but unfortunately there are
-     limitations, e.g. false-positive hits, due to limited support of
-     hardware debug registers in the kernel.  See comment above
-     aarch64_align_watchpoint for more information.  */
-
-  aligned_addr = addr & ~(AARCH64_HWP_MAX_LEN_PER_REG - 1);
-  if (aligned_addr + aarch64_num_wp_regs * AARCH64_HWP_MAX_LEN_PER_REG
-      < addr + len)
-    return 0;
-
-  /* All tests passed so we are likely to be able to set the watchpoint.
-     The reason that it is 'likely' rather than 'must' is because
-     we don't check the current usage of the watchpoint registers, and
-     there may not be enough registers available for this watchpoint.
-     Ideally we should check the cached debug register state, however
-     the checking is costly.  */
-  return 1;
+  return aarch64_linux_region_ok_for_watchpoint (addr, len);
 }
 
 /* Implement the "to_stopped_data_address" target_ops method.  */
@@ -863,6 +807,14 @@ aarch64_linux_watchpoint_addr_within_range (struct target_ops *target,
   return start <= addr && start + length - 1 >= addr;
 }
 
+/* Implement the "to_can_do_single_step" target_ops method.  */
+
+static int
+aarch64_linux_can_do_single_step (struct target_ops *target)
+{
+  return 1;
+}
+
 /* Define AArch64 maintenance commands.  */
 
 static void
@@ -914,6 +866,7 @@ _initialize_aarch64_linux_nat (void)
   t->to_stopped_data_address = aarch64_linux_stopped_data_address;
   t->to_watchpoint_addr_within_range =
     aarch64_linux_watchpoint_addr_within_range;
+  t->to_can_do_single_step = aarch64_linux_can_do_single_step;
 
   /* Override the GNU/Linux inferior startup hook.  */
   super_post_startup_inferior = t->to_post_startup_inferior;
@@ -925,4 +878,7 @@ _initialize_aarch64_linux_nat (void)
   linux_nat_set_new_fork (t, aarch64_linux_new_fork);
   linux_nat_set_forget_process (t, aarch64_forget_process);
   linux_nat_set_prepare_to_resume (t, aarch64_linux_prepare_to_resume);
+
+  /* Add our siginfo layout converter.  */
+  linux_nat_set_siginfo_fixup (t, aarch64_linux_siginfo_fixup);
 }
This page took 0.025058 seconds and 4 git commands to generate.