From: Luis Machado Date: Thu, 26 Mar 2020 14:58:01 +0000 (-0300) Subject: [Morello] Generate target descriptions based on runtime capability feature checks X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1bdd3dce2f7323570616499e72b386a3f00d8d51;p=thirdparty%2Fbinutils-gdb.git [Morello] Generate target descriptions based on runtime capability feature checks This patch adds code to do runtime checks for Morello, so GDB can pick the correct target description and register set. gdb/ChangeLog: 2020-10-20 Luis Machado * aarch64-linux-nat.c (aarch64_linux_nat_target::read_description): Check for HWCAP2_MORELLO. * aarch64-linux-tdep.c (aarch64_linux_core_read_description): Likewise. * aarch64-tdep.c (tdesc_aarch64_list): Add one more dimension. (aarch64_read_description): New parameter capability_p, use it to generate the proper target description. (aarch64_gdbarch_init): Update invocation of aarch64_read_description. * aarch64-tdep.h (aarch64_read_description): New parameter capability_p. * arch/aarch64.c (aarch64_create_target_description): New parameter capability_p. Use it. * arch/aarch64.h (aarch64_create_target_description): New parameter capability_p. gdbserver/ChangeLog: 2020-10-20 Luis Machado * linux-aarch64-ipa.cc (get_ipa_tdesc): Update. * linux-aarch64-low.cc (aarch64_target::low_arch_setup): Check for HWCAP2_MORELLO and use it. * linux-aarch64-tdesc.cc (tdesc_aarch64_list): Add one more dimension. (aarch64_linux_read_description): New parameter capability_p. Use it. * linux-aarch64-tdesc.h (aarch64_linux_read_description): New parameter capability_p. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5f9e9faca81..34b102220a6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2020-10-20 Luis Machado + + * aarch64-linux-nat.c (aarch64_linux_nat_target::read_description): + Check for HWCAP2_MORELLO. + * aarch64-linux-tdep.c (aarch64_linux_core_read_description): Likewise. + * aarch64-tdep.c (tdesc_aarch64_list): Add one more dimension. + (aarch64_read_description): New parameter capability_p, use it to + generate the proper target description. + (aarch64_gdbarch_init): Update invocation of aarch64_read_description. + * aarch64-tdep.h (aarch64_read_description): New parameter capability_p. + * arch/aarch64.c (aarch64_create_target_description): New parameter + capability_p. Use it. + * arch/aarch64.h (aarch64_create_target_description): New parameter + capability_p. + 2020-10-20 Luis Machado * aarch64-tdep.c (aarch64_c_register_names): New static array. diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 77d5863a56a..7adc6075b7a 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -651,9 +651,12 @@ aarch64_linux_nat_target::read_description () return aarch32_read_description (); CORE_ADDR hwcap = linux_get_hwcap (this); + CORE_ADDR hwcap2 = linux_get_hwcap2 (this); + bool pauth_p = hwcap & AARCH64_HWCAP_PACA; + bool capability_p = hwcap2 & HWCAP2_MORELLO; return aarch64_read_description (aarch64_sve_get_vq (tid), - hwcap & AARCH64_HWCAP_PACA); + pauth_p, capability_p); } /* Convert a native/host siginfo object, into/from the siginfo in the diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index 34ba0d87baa..3819b7ab09d 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -652,9 +652,12 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd) { CORE_ADDR hwcap = linux_get_hwcap (target); + CORE_ADDR hwcap2 = linux_get_hwcap2 (target); + bool pauth_p = hwcap & AARCH64_HWCAP_PACA; + bool capability_p = hwcap2 & HWCAP2_MORELLO; return aarch64_read_description (aarch64_linux_core_read_vq (gdbarch, abfd), - hwcap & AARCH64_HWCAP_PACA); + pauth_p, capability_p); } /* Implementation of `gdbarch_stap_is_single_operand', as defined in diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 5b424f17d34..0f25e97e4cc 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -64,7 +64,7 @@ #define HA_MAX_NUM_FLDS 4 /* All possible aarch64 target descriptors. */ -struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/]; +struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* capability */]; /* The standard register names, and all the valid aliases for them. */ static const struct @@ -3296,18 +3296,18 @@ aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch, (It is not possible to set VQ to zero on an SVE system). */ const target_desc * -aarch64_read_description (uint64_t vq, bool pauth_p) +aarch64_read_description (uint64_t vq, bool pauth_p, bool capability_p) { if (vq > AARCH64_MAX_SVE_VQ) error (_("VQ is %" PRIu64 ", maximum supported value is %d"), vq, AARCH64_MAX_SVE_VQ); - struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p]; + struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][capability_p]; if (tdesc == NULL) { - tdesc = aarch64_create_target_description (vq, pauth_p); - tdesc_aarch64_list[vq][pauth_p] = tdesc; + tdesc = aarch64_create_target_description (vq, pauth_p, capability_p); + tdesc_aarch64_list[vq][pauth_p][capability_p] = tdesc; } return tdesc; @@ -3403,11 +3403,15 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return best_arch->gdbarch; } + /* FIXME-Morello: Put a check in place so we can determine, from ELF, if + we are dealing with a capability-enabled binary or not. */ + bool have_capability = false; + /* 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)) - tdesc = aarch64_read_description (vq, false); + tdesc = aarch64_read_description (vq, false, have_capability); 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 d9b13512c1f..d0d85f4ce7b 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -117,7 +117,8 @@ struct gdbarch_tdep } }; -const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p); +const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p, + bool capability_p); extern int aarch64_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr); diff --git a/gdb/arch/aarch64.c b/gdb/arch/aarch64.c index e27b667644a..a2a571f2b23 100644 --- a/gdb/arch/aarch64.c +++ b/gdb/arch/aarch64.c @@ -28,7 +28,8 @@ /* See arch/aarch64.h. */ target_desc * -aarch64_create_target_description (uint64_t vq, bool pauth_p) +aarch64_create_target_description (uint64_t vq, bool pauth_p, + bool capability_p) { target_desc_up tdesc = allocate_target_description (); @@ -52,7 +53,8 @@ aarch64_create_target_description (uint64_t vq, bool pauth_p) the existing target description. Figure out how to do that. Maybe replace the general purpose register description with the capability registers. */ - regnum = create_feature_aarch64_capability (tdesc.get (), regnum); + if (capability_p) + regnum = create_feature_aarch64_capability (tdesc.get (), regnum); return tdesc.release (); } diff --git a/gdb/arch/aarch64.h b/gdb/arch/aarch64.h index 857bb22b037..1db0fac6b85 100644 --- a/gdb/arch/aarch64.h +++ b/gdb/arch/aarch64.h @@ -27,7 +27,8 @@ an SVE Z register. HAS_PAUTH_P indicates the presence of the PAUTH feature. */ -target_desc *aarch64_create_target_description (uint64_t vq, bool has_pauth_p); +target_desc *aarch64_create_target_description (uint64_t vq, bool has_pauth_p, + bool capability_p); /* Register numbers of various important registers. Note that on SVE, the Z registers reuse the V register numbers and the V diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index e93e4eab9b5..d4f6c68e4a7 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,13 @@ +2020-10-20 Luis Machado + + * linux-aarch64-ipa.cc (get_ipa_tdesc): Update. + * linux-aarch64-low.cc (aarch64_target::low_arch_setup): Check for + HWCAP2_MORELLO and use it. + * linux-aarch64-tdesc.cc (tdesc_aarch64_list): Add one more dimension. + (aarch64_linux_read_description): New parameter capability_p. Use it. + * linux-aarch64-tdesc.h (aarch64_linux_read_description): New parameter + capability_p. + 2020-10-13 Kamil Rytarowski x * netbsd-low.cc (netbsd_tdesc): Remove. diff --git a/gdbserver/linux-aarch64-ipa.cc b/gdbserver/linux-aarch64-ipa.cc index 694dfd77dfa..73404a0f72e 100644 --- a/gdbserver/linux-aarch64-ipa.cc +++ b/gdbserver/linux-aarch64-ipa.cc @@ -152,7 +152,7 @@ get_raw_reg (const unsigned char *raw_regs, int regnum) const struct target_desc * get_ipa_tdesc (int idx) { - return aarch64_linux_read_description (0, false); + return aarch64_linux_read_description (0, false, false); } /* Allocate buffer for the jump pads. The branch instruction has a reach @@ -205,5 +205,5 @@ void initialize_low_tracepoint (void) { /* SVE and pauth not yet supported. */ - aarch64_linux_read_description (0, false); + aarch64_linux_read_description (0, false, false); } diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc index 08208ae4f45..d9fa43a67e0 100644 --- a/gdbserver/linux-aarch64-low.cc +++ b/gdbserver/linux-aarch64-low.cc @@ -641,9 +641,12 @@ aarch64_target::low_arch_setup () { uint64_t vq = aarch64_sve_get_vq (tid); unsigned long hwcap = linux_get_hwcap (8); + unsigned long hwcap2 = linux_get_hwcap2 (8); bool pauth_p = hwcap & AARCH64_HWCAP_PACA; + bool capability_p = hwcap2 & HWCAP2_MORELLO; - current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p); + current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p, + capability_p); } else current_process ()->tdesc = aarch32_linux_read_description (); diff --git a/gdbserver/linux-aarch64-tdesc.cc b/gdbserver/linux-aarch64-tdesc.cc index 897fbb43bd2..5f4cf719373 100644 --- a/gdbserver/linux-aarch64-tdesc.cc +++ b/gdbserver/linux-aarch64-tdesc.cc @@ -27,22 +27,23 @@ #include /* All possible aarch64 target descriptors. */ -struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/]; +struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* capability */]; /* Create the aarch64 target description. */ const target_desc * -aarch64_linux_read_description (uint64_t vq, bool pauth_p) +aarch64_linux_read_description (uint64_t vq, bool pauth_p, + bool capability_p) { if (vq > AARCH64_MAX_SVE_VQ) error (_("VQ is %" PRIu64 ", maximum supported value is %d"), vq, AARCH64_MAX_SVE_VQ); - struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p]; + struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][capability_p]; if (tdesc == NULL) { - tdesc = aarch64_create_target_description (vq, pauth_p); + tdesc = aarch64_create_target_description (vq, pauth_p, capability_p); static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL }; static const char *expedite_regs_aarch64_sve[] = { "x29", "sp", "pc", @@ -53,7 +54,7 @@ aarch64_linux_read_description (uint64_t vq, bool pauth_p) else init_target_desc (tdesc, expedite_regs_aarch64_sve); - tdesc_aarch64_list[vq][pauth_p] = tdesc; + tdesc_aarch64_list[vq][pauth_p][capability_p] = tdesc; } return tdesc; diff --git a/gdbserver/linux-aarch64-tdesc.h b/gdbserver/linux-aarch64-tdesc.h index 0165e633d4c..c398921bbb3 100644 --- a/gdbserver/linux-aarch64-tdesc.h +++ b/gdbserver/linux-aarch64-tdesc.h @@ -20,6 +20,7 @@ #ifndef GDBSERVER_LINUX_AARCH64_TDESC_H #define GDBSERVER_LINUX_AARCH64_TDESC_H -const target_desc * aarch64_linux_read_description (uint64_t vq, bool pauth_p); +const target_desc * aarch64_linux_read_description (uint64_t vq, bool pauth_p, + bool capability_p); #endif /* GDBSERVER_LINUX_AARCH64_TDESC_H */