]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Aarch64 SVE: Support changing vector lengths in GDB
authorAlan Hayward <alan.hayward@arm.com>
Thu, 13 Sep 2018 15:44:29 +0000 (16:44 +0100)
committerAlan Hayward <alan.hayward@arm.com>
Thu, 13 Sep 2018 15:44:29 +0000 (16:44 +0100)
Override the thread_architecture method to place the vector length in the
tdep_info and then find using info. Do not set this as a pointer as
this will cause issues in later patches.

2018-09-13  Alan Hayward  <alan.hayward@arm.com>

gdb/
* aarch64-linux-nat.c
(aarch64_linux_nat_target::thread_architecture): Add override.
* aarch64-tdep.c (aarch64_get_tdesc_vq): Check for nullptr.
(aarch64_gdbarch_init): Ensure differemt tdesc for each VQ.

gdb/aarch64-linux-nat.c
gdb/aarch64-tdep.c

index 592a8fb13b1ac0731a0c9cc510ad43a197a67d56..61da550dcdebe914c92e1cf532ec661494ac0ae9 100644 (file)
@@ -45,6 +45,7 @@
 
 /* Defines ps_err_e, struct ps_prochandle.  */
 #include "gdb_proc_service.h"
+#include "arch-utils.h"
 
 #ifndef TRAP_HWBKPT
 #define TRAP_HWBKPT 0x0004
@@ -94,6 +95,8 @@ public:
   /* Add our siginfo layout converter.  */
   bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
     override;
+
+  struct gdbarch *thread_architecture (ptid_t) override;
 };
 
 static aarch64_linux_nat_target the_aarch64_linux_nat_target;
@@ -900,6 +903,22 @@ aarch64_linux_nat_target::can_do_single_step ()
   return 1;
 }
 
+/* Implement the "thread_architecture" target_ops method.  */
+
+struct gdbarch *
+aarch64_linux_nat_target::thread_architecture (ptid_t ptid)
+{
+  /* Get the current VQ and use it to find the gdbarch.  */
+
+  uint64_t vq = aarch64_sve_get_vq (ptid.lwp ());
+
+  struct gdbarch_info info;
+  gdbarch_info_init (&info);
+  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu);
+  info.id = (int *) vq;
+  return gdbarch_find_by_info (info);
+}
+
 /* Define AArch64 maintenance commands.  */
 
 static void
index d2e6ac64d54c30c02bb42a48a79b086dbaaf2717..498864d70d59446fca149e652911184606f8f207 100644 (file)
@@ -2950,7 +2950,7 @@ aarch64_get_tdesc_vq (const struct target_desc *tdesc)
 {
   const struct tdesc_feature *feature_sve;
 
-  if (!tdesc_has_registers (tdesc))
+  if (tdesc == nullptr || !tdesc_has_registers (tdesc))
     return 0;
 
   feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve");
@@ -2986,10 +2986,23 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   const struct tdesc_feature *feature_sve;
   int num_regs = 0;
   int num_pseudo_regs = 0;
+  uint64_t vq = 0;
 
-  /* Ensure we always have a target description.  */
-  if (!tdesc_has_registers (tdesc))
-    tdesc = aarch64_read_description (0);
+  /* Use the vector length passed via the target info.  Otherwise use the vector
+     length from the existing tdesc.  Otherwise assume no SVE.  */
+  if (info.id != 0)
+    vq = (uint64_t) info.id;
+  else
+    vq = aarch64_get_tdesc_vq (tdesc);
+
+  if (vq > AARCH64_MAX_SVE_VQ)
+    internal_error (__FILE__, __LINE__, _("VQ out of bounds: %ld (max %d)"),
+                   vq, AARCH64_MAX_SVE_VQ);
+
+  /* Ensure we always have a target descriptor, and that it is for the current
+     VQ value.  */
+  if (!tdesc_has_registers (tdesc) || vq > 0)
+    tdesc = aarch64_read_description (vq);
   gdb_assert (tdesc);
 
   feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.core");
@@ -3063,15 +3076,14 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        best_arch != NULL;
        best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
     {
-      /* Found a match.  */
-      break;
-    }
-
-  if (best_arch != NULL)
-    {
-      if (tdesc_data != NULL)
-       tdesc_data_cleanup (tdesc_data);
-      return best_arch->gdbarch;
+      tdep = gdbarch_tdep (best_arch->gdbarch);
+      if (tdep && tdep->vq == vq)
+       {
+         /* Found a valid match.  */
+         if (tdesc_data != NULL)
+         tdesc_data_cleanup (tdesc_data);
+         return best_arch->gdbarch;
+       }
     }
 
   tdep = XCNEW (struct gdbarch_tdep);
@@ -3081,7 +3093,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->lowest_pc = 0x20;
   tdep->jb_pc = -1;            /* Longjump support not enabled by default.  */
   tdep->jb_elt_size = 8;
-  tdep->vq = aarch64_get_tdesc_vq (tdesc);
+  tdep->vq = vq;
 
   set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
   set_gdbarch_frame_align (gdbarch, aarch64_frame_align);