/* Return target_desc to use for IPA, given the tdesc index passed by
gdbserver. Index is ignored, since we have only one tdesc
- at the moment. SVE, pauth and MTE not yet supported. */
+ at the moment. SVE, pauth, MTE and TLS not yet supported. */
const struct target_desc *
get_ipa_tdesc (int idx)
{
- return aarch64_linux_read_description (0, false, false);
+ return aarch64_linux_read_description (0, false, false, false);
}
/* Allocate buffer for the jump pads. The branch instruction has a reach
void
initialize_low_tracepoint (void)
{
- /* SVE, pauth and MTE not yet supported. */
- aarch64_linux_read_description (0, false, false);
+ /* SVE, pauth, MTE and TLS not yet supported. */
+ aarch64_linux_read_description (0, false, false, false);
}
supply_register (regcache, mte_base, mte_regset);
}
+/* Fill BUF with TLS register from the regcache. */
+
+static void
+aarch64_fill_tlsregset (struct regcache *regcache, void *buf)
+{
+ int tls_regnum = find_regno (regcache->tdesc, "tpidr");
+
+ collect_register (regcache, tls_regnum, buf);
+}
+
+/* Store TLS register to regcache. */
+
+static void
+aarch64_store_tlsregset (struct regcache *regcache, const void *buf)
+{
+ int tls_regnum = find_regno (regcache->tdesc, "tpidr");
+
+ supply_register (regcache, tls_regnum, buf);
+}
+
bool
aarch64_target::low_supports_breakpoints ()
{
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_TAGGED_ADDR_CTRL,
0, OPTIONAL_REGS,
aarch64_fill_mteregset, aarch64_store_mteregset },
+ /* TLS register. */
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_TLS,
+ 0, OPTIONAL_REGS,
+ aarch64_fill_tlsregset, aarch64_store_tlsregset },
NULL_REGSET
};
if (features.mte)
regset->size = AARCH64_LINUX_SIZEOF_MTE;
break;
+ case NT_ARM_TLS:
+ if (features.tls)
+ regset->size = AARCH64_TLS_REGS_SIZE;
+ break;
default:
gdb_assert_not_reached ("Unknown register set found.");
}
features.pauth = linux_get_hwcap (8) & AARCH64_HWCAP_PACA;
/* A-profile MTE is 64-bit only. */
features.mte = linux_get_hwcap2 (8) & HWCAP2_MTE;
+ features.tls = true;
current_process ()->tdesc
- = aarch64_linux_read_description (vq, features.pauth, features.mte);
+ = aarch64_linux_read_description (vq, features.pauth, features.mte,
+ features.tls);
/* Adjust the register sets we should use for this particular set of
features. */
#include <inttypes.h>
/* All possible aarch64 target descriptors. */
-struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */];
+struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */][2 /* tls */];
/* Create the aarch64 target description. */
const target_desc *
-aarch64_linux_read_description (uint64_t vq, bool pauth_p, bool mte_p)
+aarch64_linux_read_description (uint64_t vq, bool pauth_p, bool mte_p,
+ bool tls_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][mte_p];
+ struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][mte_p][tls_p];
if (tdesc == NULL)
{
- tdesc = aarch64_create_target_description (vq, pauth_p, mte_p, false);
+ tdesc = aarch64_create_target_description (vq, pauth_p, mte_p, tls_p);
static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
static const char *expedite_regs_aarch64_sve[] = { "x29", "sp", "pc",
else
init_target_desc (tdesc, expedite_regs_aarch64_sve);
- tdesc_aarch64_list[vq][pauth_p][mte_p] = tdesc;
+ tdesc_aarch64_list[vq][pauth_p][mte_p][tls_p] = tdesc;
}
return tdesc;
#define GDBSERVER_LINUX_AARCH64_TDESC_H
const target_desc * aarch64_linux_read_description (uint64_t vq, bool pauth_p,
- bool mte_p);
+ bool mte_p, bool tls_p);
#endif /* GDBSERVER_LINUX_AARCH64_TDESC_H */