diff options
-rw-r--r-- | gdb/aarch64-linux-nat.c | 11 | ||||
-rw-r--r-- | gdb/aarch64-tdep.c | 41 | ||||
-rw-r--r-- | gdb/aarch64-tdep.h | 2 | ||||
-rw-r--r-- | gdb/gdbarch.h | 13 |
4 files changed, 36 insertions, 31 deletions
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index a457fcd..eda79ec 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -900,11 +900,16 @@ aarch64_linux_nat_target::thread_architecture (ptid_t ptid) /* We reach here if the vector length for the thread is different from its value at process start. Lookup gdbarch via info (potentially creating a - new one), stashing the vector length inside id. Use -1 for when SVE - unavailable, to distinguish from an unset value of 0. */ + new one) by using a target description that corresponds to the new vq value + and the current architecture features. */ + + const struct target_desc *tdesc = gdbarch_target_desc (inf->gdbarch); + aarch64_features features = aarch64_features_from_target_desc (tdesc); + features.vq = vq; + struct gdbarch_info info; info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64); - info.id = (int *) (vq == 0 ? -1 : vq); + info.target_desc = aarch64_read_description (features); return gdbarch_find_by_info (info); } diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index f747ebd..ba9b2d8 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3392,6 +3392,27 @@ aarch64_get_tdesc_vq (const struct target_desc *tdesc) return sve_vq_from_vl (vl); } +/* Get the AArch64 features present in the given target description. */ + +aarch64_features +aarch64_features_from_target_desc (const struct target_desc *tdesc) +{ + aarch64_features features; + + if (tdesc == nullptr) + return features; + + features.vq = aarch64_get_tdesc_vq (tdesc); + features.pauth + = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth") != nullptr); + features.mte + = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.mte") != nullptr); + features.tls + = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.tls") != nullptr); + + return features; +} + /* Implement the "cannot_store_register" gdbarch method. */ static int @@ -3442,17 +3463,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int i, num_regs = 0, num_pseudo_regs = 0; int first_pauth_regnum = -1, ra_sign_state_offset = -1; int first_mte_regnum = -1, tls_regnum = -1; - - /* Use the vector length passed via the target info. Here -1 is used for no - SVE, and 0 is unset. If unset then use the vector length from the existing - tdesc. */ - uint64_t vq = 0; - if (info.id == (int *) -1) - vq = 0; - else if (info.id != 0) - vq = (uint64_t) info.id; - else - vq = aarch64_get_tdesc_vq (info.target_desc); + uint64_t vq = aarch64_get_tdesc_vq (info.target_desc); if (vq > AARCH64_MAX_SVE_VQ) internal_error (__FILE__, __LINE__, _("VQ out of bounds: %s (max %d)"), @@ -3472,12 +3483,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Ensure we always have a target descriptor, and that it is for the given VQ value. */ const struct target_desc *tdesc = info.target_desc; - if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc)) - { - aarch64_features features; - features.vq = vq; - tdesc = aarch64_read_description (features); - } + if (!tdesc_has_registers (tdesc)) + tdesc = aarch64_read_description ({}); gdb_assert (tdesc); feature_core = tdesc_find_feature (tdesc,"org.gnu.gdb.aarch64.core"); diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index 5bdd733..d851302 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -121,6 +121,8 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base }; const target_desc *aarch64_read_description (const aarch64_features &features); +aarch64_features +aarch64_features_from_target_desc (const struct target_desc *tdesc); extern int aarch64_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr); diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 9ac4181..2f1c739 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -251,17 +251,8 @@ struct gdbarch_info bfd *abfd = nullptr; - union - { - /* Architecture-specific target description data. Numerous targets - need only this, so give them an easy way to hold it. */ - struct tdesc_arch_data *tdesc_data; - - /* SPU file system ID. This is a single integer, so using the - generic form would only complicate code. Other targets may - reuse this member if suitable. */ - int *id; - }; + /* Architecture-specific target description data. */ + struct tdesc_arch_data *tdesc_data; enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; |