diff options
author | Alan Hayward <alan.hayward@arm.com> | 2018-09-13 16:44:29 +0100 |
---|---|---|
committer | Alan Hayward <alan.hayward@arm.com> | 2018-09-13 16:44:29 +0100 |
commit | ce7ec4c76f96750377f9e2b880b9640810bb7e2e (patch) | |
tree | dd7594b6a4ed08d6261d23244185c16f523cc026 | |
parent | 9eae688f9a4d99a1a1d4414a2260a08df2f9e0e8 (diff) | |
download | gdb-ce7ec4c76f96750377f9e2b880b9640810bb7e2e.zip gdb-ce7ec4c76f96750377f9e2b880b9640810bb7e2e.tar.gz gdb-ce7ec4c76f96750377f9e2b880b9640810bb7e2e.tar.bz2 |
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.c | 19 | ||||
-rw-r--r-- | 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 592a8fb..61da550 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 d2e6ac6..498864d 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); |