summaryrefslogtreecommitdiff
path: root/gdb/aarch64-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/aarch64-tdep.c')
-rw-r--r--gdb/aarch64-tdep.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index cf20bb40b78..024385a9fd8 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3465,8 +3465,18 @@ aarch64_features_from_target_desc (const struct target_desc *tdesc)
= (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);
+
+ const struct tdesc_feature *tls_feature
+ = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.tls");
+
+ if (tls_feature != nullptr)
+ {
+ /* We have TLS registers. Find out how many. */
+ if (tdesc_unnumbered_register (tls_feature, "tpidr2"))
+ features.tls = 2;
+ else
+ features.tls = 1;
+ }
return features;
}
@@ -3526,7 +3536,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
bool valid_p = true;
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;
+ int first_mte_regnum = -1, first_tls_regnum = -1;
uint64_t vq = aarch64_get_tdesc_vq (info.target_desc);
if (vq > AARCH64_MAX_SVE_VQ)
@@ -3614,15 +3624,38 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
/* Add the TLS register. */
+ int tls_register_count = 0;
if (feature_tls != nullptr)
{
- tls_regnum = num_regs;
- /* Validate the descriptor provides the mandatory TLS register
- and allocate its number. */
- valid_p = tdesc_numbered_register (feature_tls, tdesc_data.get (),
- tls_regnum, "tpidr");
+ first_tls_regnum = num_regs;
- num_regs++;
+ /* Look for the TLS registers. tpidr is required, but tpidr2 is
+ optional. */
+ valid_p
+ = tdesc_numbered_register (feature_tls, tdesc_data.get (),
+ first_tls_regnum, "tpidr");
+
+ if (valid_p)
+ {
+ tls_register_count++;
+
+ bool has_tpidr2
+ = tdesc_numbered_register (feature_tls, tdesc_data.get (),
+ first_tls_regnum + tls_register_count,
+ "tpidr2");
+
+ /* Figure out how many TLS registers we have. */
+ if (has_tpidr2)
+ tls_register_count++;
+
+ num_regs += tls_register_count;
+ }
+ else
+ {
+ warning (_("Provided TLS register feature doesn't contain "
+ "required tpidr register."));
+ return nullptr;
+ }
}
/* Add the pauth registers. */
@@ -3675,7 +3708,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->pauth_reg_base = first_pauth_regnum;
tdep->ra_sign_state_regnum = -1;
tdep->mte_reg_base = first_mte_regnum;
- tdep->tls_regnum = tls_regnum;
+ tdep->tls_regnum_base = first_tls_regnum;
+ tdep->tls_register_count = tls_register_count;
set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, aarch64_frame_align);