From ce7ec4c76f96750377f9e2b880b9640810bb7e2e Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Thu, 13 Sep 2018 16:44:29 +0100 Subject: [PATCH] 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 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 | 19 +++++++++++++++++++ gdb/aarch64-tdep.c | 40 ++++++++++++++++++++++++++-------------- 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); -- 2.47.2