summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2018-09-13 16:44:29 +0100
committerAlan Hayward <alan.hayward@arm.com>2018-09-13 16:44:29 +0100
commitce7ec4c76f96750377f9e2b880b9640810bb7e2e (patch)
treedd7594b6a4ed08d6261d23244185c16f523cc026
parent9eae688f9a4d99a1a1d4414a2260a08df2f9e0e8 (diff)
downloadbinutils-gdb-ce7ec4c76f96750377f9e2b880b9640810bb7e2e.tar.gz
Aarch64 SVE: Support changing vector lengths in GDB
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.
-rw-r--r--gdb/aarch64-linux-nat.c19
-rw-r--r--gdb/aarch64-tdep.c40
2 files changed, 45 insertions, 14 deletions
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 592a8fb13b1..61da550dcde 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -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
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index d2e6ac64d54..498864d70d5 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -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);