Introduce show_debug_regs
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-aarch64-low.c
index 1b0da6cb8c8542d9a325399fe5200f0455256742..ca096b02c93ca49ccaac9bd164a2f345c8278dc0 100644 (file)
@@ -26,6 +26,7 @@
 #include <signal.h>
 #include <sys/user.h>
 #include <sys/ptrace.h>
+#include <asm/ptrace.h>
 #include <sys/uio.h>
 
 #include "gdb_proc_service.h"
@@ -208,49 +209,6 @@ struct arch_lwp_info
 static int aarch64_num_bp_regs;
 static int aarch64_num_wp_regs;
 
-/* Hardware breakpoint/watchpoint types.
-   The values map to their encodings in the bit 4 and bit 3 of the
-   hardware breakpoint/watchpoint control registers.  */
-
-enum target_point_type
-{
-  hw_execute = 0,              /* Execute HW breakpoint */
-  hw_read = 1,                 /* Read    HW watchpoint */
-  hw_write = 2,                        /* Common  HW watchpoint */
-  hw_access = 3,               /* Access  HW watchpoint */
-  point_type_unsupported
-};
-
-#define Z_PACKET_SW_BP '0'
-#define Z_PACKET_HW_BP '1'
-#define Z_PACKET_WRITE_WP '2'
-#define Z_PACKET_READ_WP '3'
-#define Z_PACKET_ACCESS_WP '4'
-
-/* Map the protocol breakpoint/watchpoint type TYPE to
-   enum target_point_type.  */
-
-static enum target_point_type
-Z_packet_to_point_type (char type)
-{
-  switch (type)
-    {
-    case Z_PACKET_SW_BP:
-      /* Leave the handling of the sw breakpoint with the gdb client.  */
-      return point_type_unsupported;
-    case Z_PACKET_HW_BP:
-      return hw_execute;
-    case Z_PACKET_WRITE_WP:
-      return hw_write;
-    case Z_PACKET_READ_WP:
-      return hw_read;
-    case Z_PACKET_ACCESS_WP:
-      return hw_access;
-    default:
-      return point_type_unsupported;
-    }
-}
-
 static int
 aarch64_cannot_store_register (int regno)
 {
@@ -309,9 +267,6 @@ aarch64_store_fpregset (struct regcache *regcache, const void *buf)
     supply_register (regcache, AARCH64_V0_REGNO + i, &regset->vregs[i]);
 }
 
-/* Debugging of hardware breakpoint/watchpoint support.  */
-extern int debug_hw_points;
-
 /* Enable miscellaneous debugging output.  The name is historical - it
    was originally used to debug LinuxThreads support.  */
 extern int debug_threads;
@@ -323,7 +278,7 @@ aarch64_get_pc (struct regcache *regcache)
 
   collect_register_by_name (regcache, "pc", &pc);
   if (debug_threads)
-    fprintf (stderr, "stop pc is %08lx\n", pc);
+    debug_printf ("stop pc is %08lx\n", pc);
   return pc;
 }
 
@@ -358,7 +313,7 @@ aarch64_breakpoint_at (CORE_ADDR where)
 static void
 aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state,
                              const char *func, CORE_ADDR addr,
-                             int len, enum target_point_type type)
+                             int len, enum target_hw_bp_type type)
 {
   int i;
 
@@ -448,12 +403,31 @@ aarch64_watchpoint_length (unsigned int ctrl)
    breakpoint/watchpoint control register.  */
 
 static unsigned int
-aarch64_point_encode_ctrl_reg (enum target_point_type type, int len)
+aarch64_point_encode_ctrl_reg (enum target_hw_bp_type type, int len)
 {
-  unsigned int ctrl;
+  unsigned int ctrl, ttype;
+
+  /* type */
+  switch (type)
+    {
+    case hw_write:
+      ttype = 2;
+      break;
+    case hw_read:
+      ttype = 1;
+      break;
+    case hw_access:
+      ttype = 3;
+      break;
+    case hw_execute:
+      ttype = 0;
+      break;
+    default:
+      perror_with_name (_("Unrecognized breakpoint/watchpoint type"));
+    }
 
   /* type */
-  ctrl = type << 3;
+  ctrl = ttype << 3;
   /* length bitmask */
   ctrl |= ((1 << len) - 1) << 5;
   /* enabled at el0 */
@@ -638,7 +612,8 @@ struct aarch64_dr_update_callback_param
 static int
 debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
 {
-  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct thread_info *thread = (struct thread_info *) entry;
+  struct lwp_info *lwp = get_thread_lwp (thread);
   struct aarch64_dr_update_callback_param *param_p
     = (struct aarch64_dr_update_callback_param *) ptr;
   int pid = param_p->pid;
@@ -648,12 +623,12 @@ debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
   dr_changed_t *dr_changed_ptr;
   dr_changed_t dr_changed;
 
-  if (debug_hw_points)
+  if (show_debug_regs)
     {
       fprintf (stderr, "debug_reg_change_callback: \n\tOn entry:\n");
       fprintf (stderr, "\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
               "dr_changed_wp=0x%llx\n",
-              pid, lwpid_of (lwp), info->dr_changed_bp,
+              pid, lwpid_of (thread), info->dr_changed_bp,
               info->dr_changed_wp);
     }
 
@@ -662,7 +637,7 @@ debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
   dr_changed = *dr_changed_ptr;
 
   /* Only update the threads of this process.  */
-  if (pid_of (lwp) == pid)
+  if (pid_of (thread) == pid)
     {
       gdb_assert (idx >= 0
                  && (idx <= (is_watchpoint ? aarch64_num_wp_regs
@@ -699,11 +674,12 @@ debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
        linux_stop_lwp (lwp);
     }
 
-  if (debug_hw_points)
+  if (show_debug_regs)
     {
       fprintf (stderr, "\tOn exit:\n\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
               "dr_changed_wp=0x%llx\n",
-              pid, lwpid_of (lwp), info->dr_changed_bp, info->dr_changed_wp);
+              pid, lwpid_of (thread), info->dr_changed_bp,
+              info->dr_changed_wp);
     }
 
   return 0;
@@ -721,12 +697,12 @@ aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
   struct aarch64_dr_update_callback_param param;
 
   /* Only update the threads of this process.  */
-  param.pid = pid_of (get_thread_lwp (current_inferior));
+  param.pid = pid_of (current_inferior);
 
   param.is_watchpoint = is_watchpoint;
   param.idx = idx;
 
-  find_inferior (&all_lwps, debug_reg_change_callback, (void *) &param);
+  find_inferior (&all_threads, debug_reg_change_callback, (void *) &param);
 }
 
 
@@ -747,7 +723,7 @@ aarch64_get_debug_reg_state ()
 
 static int
 aarch64_dr_state_insert_one_point (struct aarch64_debug_reg_state *state,
-                                  enum target_point_type type,
+                                  enum target_hw_bp_type type,
                                   CORE_ADDR addr, int len)
 {
   int i, idx, num_regs, is_watchpoint;
@@ -820,7 +796,7 @@ aarch64_dr_state_insert_one_point (struct aarch64_debug_reg_state *state,
 
 static int
 aarch64_dr_state_remove_one_point (struct aarch64_debug_reg_state *state,
-                                  enum target_point_type type,
+                                  enum target_hw_bp_type type,
                                   CORE_ADDR addr, int len)
 {
   int i, num_regs, is_watchpoint;
@@ -874,7 +850,7 @@ aarch64_dr_state_remove_one_point (struct aarch64_debug_reg_state *state,
 }
 
 static int
-aarch64_handle_breakpoint (enum target_point_type type, CORE_ADDR addr,
+aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr,
                           int len, int is_insert)
 {
   struct aarch64_debug_reg_state *state;
@@ -896,7 +872,7 @@ aarch64_handle_breakpoint (enum target_point_type type, CORE_ADDR addr,
    from that it is an aligned watchpoint to be handled.  */
 
 static int
-aarch64_handle_aligned_watchpoint (enum target_point_type type,
+aarch64_handle_aligned_watchpoint (enum target_hw_bp_type type,
                                   CORE_ADDR addr, int len, int is_insert)
 {
   struct aarch64_debug_reg_state *state;
@@ -917,7 +893,7 @@ aarch64_handle_aligned_watchpoint (enum target_point_type type,
    Return 0 if succeed.  */
 
 static int
-aarch64_handle_unaligned_watchpoint (enum target_point_type type,
+aarch64_handle_unaligned_watchpoint (enum target_hw_bp_type type,
                                     CORE_ADDR addr, int len, int is_insert)
 {
   struct aarch64_debug_reg_state *state
@@ -938,7 +914,7 @@ aarch64_handle_unaligned_watchpoint (enum target_point_type type,
        ret = aarch64_dr_state_remove_one_point (state, type, aligned_addr,
                                                 aligned_len);
 
-      if (debug_hw_points)
+      if (show_debug_regs)
        fprintf (stderr,
  "handle_unaligned_watchpoint: is_insert: %d\n"
  "                             aligned_addr: 0x%s, aligned_len: %d\n"
@@ -954,7 +930,7 @@ aarch64_handle_unaligned_watchpoint (enum target_point_type type,
 }
 
 static int
-aarch64_handle_watchpoint (enum target_point_type type, CORE_ADDR addr,
+aarch64_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr,
                           int len, int is_insert)
 {
   if (aarch64_point_is_aligned (1 /* is_watchpoint */ , addr, len))
@@ -963,6 +939,22 @@ aarch64_handle_watchpoint (enum target_point_type type, CORE_ADDR addr,
     return aarch64_handle_unaligned_watchpoint (type, addr, len, is_insert);
 }
 
+static int
+aarch64_supports_z_point_type (char z_type)
+{
+  switch (z_type)
+    {
+    case Z_PACKET_HW_BP:
+    case Z_PACKET_WRITE_WP:
+    case Z_PACKET_READ_WP:
+    case Z_PACKET_ACCESS_WP:
+      return 1;
+    default:
+      /* Leave the handling of sw breakpoints with the gdb client.  */
+      return 0;
+    }
+}
+
 /* Insert a hardware breakpoint/watchpoint.
    It actually only records the info of the to-be-inserted bp/wp;
    the actual insertion will happen when threads are resumed.
@@ -972,19 +964,18 @@ aarch64_handle_watchpoint (enum target_point_type type, CORE_ADDR addr,
    Return -1 if an error occurs.  */
 
 static int
-aarch64_insert_point (char type, CORE_ADDR addr, int len)
+aarch64_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
+                     int len, struct raw_breakpoint *bp)
 {
   int ret;
-  enum target_point_type targ_type;
+  enum target_hw_bp_type targ_type;
 
-  if (debug_hw_points)
+  if (show_debug_regs)
     fprintf (stderr, "insert_point on entry (addr=0x%08lx, len=%d)\n",
             (unsigned long) addr, len);
 
-  /* Determine the type from the packet.  */
-  targ_type = Z_packet_to_point_type (type);
-  if (targ_type == point_type_unsupported)
-    return 1;
+  /* Determine the type from the raw breakpoint type.  */
+  targ_type = raw_bkpt_type_to_target_hw_bp_type (type);
 
   if (targ_type != hw_execute)
     ret =
@@ -993,7 +984,7 @@ aarch64_insert_point (char type, CORE_ADDR addr, int len)
     ret =
       aarch64_handle_breakpoint (targ_type, addr, len, 1 /* is_insert */);
 
-  if (debug_hw_points > 1)
+  if (show_debug_regs > 1)
     aarch64_show_debug_reg_state (aarch64_get_debug_reg_state (),
                                  "insert_point", addr, len, targ_type);
 
@@ -1009,19 +1000,18 @@ aarch64_insert_point (char type, CORE_ADDR addr, int len)
    Return -1 if an error occurs.  */
 
 static int
-aarch64_remove_point (char type, CORE_ADDR addr, int len)
+aarch64_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
+                     int len, struct raw_breakpoint *bp)
 {
   int ret;
-  enum target_point_type targ_type;
+  enum target_hw_bp_type targ_type;
 
-  if (debug_hw_points)
+  if (show_debug_regs)
     fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
             (unsigned long) addr, len);
 
-  /* Determine the type from the packet.  */
-  targ_type = Z_packet_to_point_type (type);
-  if (targ_type == point_type_unsupported)
-    return 1;
+  /* Determine the type from the raw breakpoint type.  */
+  targ_type = raw_bkpt_type_to_target_hw_bp_type (type);
 
   /* Set up state pointers.  */
   if (targ_type != hw_execute)
@@ -1031,7 +1021,7 @@ aarch64_remove_point (char type, CORE_ADDR addr, int len)
     ret =
       aarch64_handle_breakpoint (targ_type, addr, len, 0 /* is_insert */);
 
-  if (debug_hw_points > 1)
+  if (show_debug_regs > 1)
     aarch64_show_debug_reg_state (aarch64_get_debug_reg_state (),
                                  "remove_point", addr, len, targ_type);
 
@@ -1048,7 +1038,7 @@ aarch64_stopped_data_address (void)
   int pid, i;
   struct aarch64_debug_reg_state *state;
 
-  pid = lwpid_of (get_thread_lwp (current_inferior));
+  pid = lwpid_of (current_inferior);
 
   /* Get the siginfo.  */
   if (ptrace (PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0)
@@ -1145,7 +1135,8 @@ aarch64_linux_new_thread (void)
 static void
 aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
 {
-  ptid_t ptid = ptid_of (lwp);
+  struct thread_info *thread = get_lwp_thread (lwp);
+  ptid_t ptid = ptid_of (thread);
   struct arch_lwp_info *info = lwp->arch_private;
 
   if (DR_HAS_CHANGED (info->dr_changed_bp)
@@ -1156,8 +1147,8 @@ aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
       struct aarch64_debug_reg_state *state
        = &proc->private->arch_private->debug_reg_state;
 
-      if (debug_hw_points)
-       fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (lwp));
+      if (show_debug_regs)
+       fprintf (stderr, "prepare_to_resume thread %ld\n", lwpid_of (thread));
 
       /* Watchpoints.  */
       if (DR_HAS_CHANGED (info->dr_changed_wp))
@@ -1195,7 +1186,7 @@ aarch64_arch_setup (void)
 
   current_process ()->tdesc = tdesc_aarch64;
 
-  pid = lwpid_of (get_thread_lwp (current_inferior));
+  pid = lwpid_of (current_inferior);
   iov.iov_base = &dreg_state;
   iov.iov_len = sizeof (dreg_state);
 
@@ -1292,6 +1283,7 @@ struct linux_target_ops the_low_target =
   NULL,
   0,
   aarch64_breakpoint_at,
+  aarch64_supports_z_point_type,
   aarch64_insert_point,
   aarch64_remove_point,
   aarch64_stopped_by_watchpoint,
This page took 0.028886 seconds and 4 git commands to generate.