From ba2d2bb24ea593c7fb17f51ef23f122064bb17d7 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 4 Jun 2018 11:39:41 +0100 Subject: [PATCH] Enable SVE for GDB Enable SVE support for GDB by reading the VQ when creating a target description. Also ensurse that SVE is taken into account when creating the tdep structure, and store the current VQ value directly in tdep. gdb/ * aarch64-linux-nat.c (aarch64_linux_read_description): Support SVE. * aarch64-tdep.c (aarch64_get_tdesc_vq): New function. (aarch64_gdbarch_init): Check for SVE. * aarch64-tdep.h (gdbarch_tdep::has_sve): New function. --- gdb/ChangeLog | 9 ++++- gdb/aarch64-linux-nat.c | 4 +- gdb/aarch64-tdep.c | 82 ++++++++++++++++++++++++++++++----------- gdb/aarch64-tdep.h | 9 +++++ 4 files changed, 80 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0096382e47a..1e74a7601a0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,4 +1,11 @@ -2018-06-01 Alan Hayward +2018-06-04 Alan Hayward + + * aarch64-linux-nat.c (aarch64_linux_read_description): Support SVE. + * aarch64-tdep.c (aarch64_get_tdesc_vq): New function. + (aarch64_gdbarch_init): Check for SVE. + * aarch64-tdep.h (gdbarch_tdep::has_sve): New function. + +2018-06-04 Alan Hayward * aarch64-tdep.c (aarch64_read_description): Use uint64_t for VQ. * aarch64-tdep.h (aarch64_read_description): Likewise. diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 94d18c315a1..1e4f937dc91 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -32,6 +32,7 @@ #include "aarch32-linux-nat.h" #include "nat/aarch64-linux.h" #include "nat/aarch64-linux-hw-point.h" +#include "nat/aarch64-sve-linux-ptrace.h" #include "elf/external.h" #include "elf/common.h" @@ -537,8 +538,7 @@ aarch64_linux_nat_target::read_description () if (ret == 0) return tdesc_arm_with_neon; else - /* SVE not yet supported. */ - return aarch64_read_description (0); + return aarch64_read_description (aarch64_sve_get_vq (tid)); } /* Convert a native/host siginfo object, into/from the siginfo in the diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index f8e77a8ba94..6674b7654e5 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -2873,6 +2873,26 @@ aarch64_read_description (uint64_t vq) return tdesc; } +/* Return the VQ used when creating the target description TDESC. */ + +static long +aarch64_get_tdesc_vq (const struct target_desc *tdesc) +{ + const struct tdesc_feature *feature_sve; + + if (!tdesc_has_registers (tdesc)) + return 0; + + feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve"); + + if (feature_sve == nullptr) + return 0; + + long vl = tdesc_register_size (feature_sve, aarch64_sve_register_names[0]); + return sve_vq_from_vl (vl); +} + + /* Initialize the current architecture based on INFO. If possible, re-use an architecture from ARCHES, which is a list of architectures already created during this debugging session. @@ -2890,48 +2910,67 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) const struct target_desc *tdesc = info.target_desc; int i; int valid_p = 1; - const struct tdesc_feature *feature; + const struct tdesc_feature *feature_core; + const struct tdesc_feature *feature_fpu; + const struct tdesc_feature *feature_sve; int num_regs = 0; int num_pseudo_regs = 0; - /* Ensure we always have a target descriptor. */ + /* Ensure we always have a target description. */ if (!tdesc_has_registers (tdesc)) - { - /* SVE is not yet supported. */ - tdesc = aarch64_read_description (0); - } - + tdesc = aarch64_read_description (0); gdb_assert (tdesc); - feature = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.core"); + feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.core"); + feature_fpu = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpu"); + feature_sve = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.sve"); - if (feature == NULL) + if (feature_core == NULL) return NULL; tdesc_data = tdesc_data_alloc (); - /* Validate the descriptor provides the mandatory core R registers + /* Validate the description provides the mandatory core R registers and allocate their numbers. */ for (i = 0; i < ARRAY_SIZE (aarch64_r_register_names); i++) - valid_p &= - tdesc_numbered_register (feature, tdesc_data, AARCH64_X0_REGNUM + i, - aarch64_r_register_names[i]); + valid_p &= tdesc_numbered_register (feature_core, tdesc_data, + AARCH64_X0_REGNUM + i, + aarch64_r_register_names[i]); num_regs = AARCH64_X0_REGNUM + i; - /* Look for the V registers. */ - feature = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpu"); - if (feature) + /* Add the V registers. */ + if (feature_fpu != NULL) { - /* Validate the descriptor provides the mandatory V registers - and allocate their numbers. */ + if (feature_sve != NULL) + error (_("Program contains both fpu and SVE features.")); + + /* Validate the description provides the mandatory V registers + and allocate their numbers. */ for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++) - valid_p &= - tdesc_numbered_register (feature, tdesc_data, AARCH64_V0_REGNUM + i, - aarch64_v_register_names[i]); + valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data, + AARCH64_V0_REGNUM + i, + aarch64_v_register_names[i]); num_regs = AARCH64_V0_REGNUM + i; + } + /* Add the SVE registers. */ + if (feature_sve != NULL) + { + /* Validate the description provides the mandatory SVE registers + and allocate their numbers. */ + for (i = 0; i < ARRAY_SIZE (aarch64_sve_register_names); i++) + valid_p &= tdesc_numbered_register (feature_sve, tdesc_data, + AARCH64_SVE_Z0_REGNUM + i, + aarch64_sve_register_names[i]); + + num_regs = AARCH64_SVE_Z0_REGNUM + i; + num_pseudo_regs += 32; /* add the Vn register pseudos. */ + } + + if (feature_fpu != NULL || feature_sve != NULL) + { num_pseudo_regs += 32; /* add the Qn scalar register pseudos */ num_pseudo_regs += 32; /* add the Dn scalar register pseudos */ num_pseudo_regs += 32; /* add the Sn scalar register pseudos */ @@ -2971,6 +3010,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); set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call); set_gdbarch_frame_align (gdbarch, aarch64_frame_align); diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index e41a5972d2e..b6b9b30e715 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -73,6 +73,15 @@ struct gdbarch_tdep /* syscall record. */ int (*aarch64_syscall_record) (struct regcache *regcache, unsigned long svc_number); + + /* The VQ value for SVE targets, or zero if SVE is not supported. */ + long vq; + + /* Returns true if the target supports SVE. */ + bool has_sve () const + { + return vq != 0; + } }; const target_desc *aarch64_read_description (uint64_t vq); -- 2.30.2