summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-05-03 16:05:10 -0700
committerJohn Baldwin <jhb@FreeBSD.org>2022-05-03 16:05:10 -0700
commit9c27bc99e4e1c4fbf51dc8f6186f0fdd5994a38b (patch)
tree6ab02ff6a7f93a3b4fb63a6dac4dfbbd65260a1e
parent224151d7748ef13df82878067266cfaa9861e360 (diff)
downloadbinutils-gdb-9c27bc99e4e1c4fbf51dc8f6186f0fdd5994a38b.tar.gz
gdbserver: Read the tpidr register from NT_ARM_TLS on Linux.
-rw-r--r--gdbserver/linux-aarch64-ipa.cc8
-rw-r--r--gdbserver/linux-aarch64-low.cc32
-rw-r--r--gdbserver/linux-aarch64-tdesc.cc11
-rw-r--r--gdbserver/linux-aarch64-tdesc.h2
4 files changed, 42 insertions, 11 deletions
diff --git a/gdbserver/linux-aarch64-ipa.cc b/gdbserver/linux-aarch64-ipa.cc
index 296c63534d8..dc907d3ff88 100644
--- a/gdbserver/linux-aarch64-ipa.cc
+++ b/gdbserver/linux-aarch64-ipa.cc
@@ -147,12 +147,12 @@ get_raw_reg (const unsigned char *raw_regs, int regnum)
/* 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
@@ -204,6 +204,6 @@ alloc_jump_pad_buffer (size_t size)
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);
}
diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
index 0091f998c63..c924821c25c 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -287,6 +287,26 @@ aarch64_store_mteregset (struct regcache *regcache, const void *buf)
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 ()
{
@@ -719,6 +739,10 @@ static struct regset_info aarch64_regsets[] =
{ 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
};
@@ -770,6 +794,10 @@ aarch64_adjust_register_sets (const struct aarch64_features &features)
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.");
}
@@ -802,9 +830,11 @@ aarch64_target::low_arch_setup ()
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. */
diff --git a/gdbserver/linux-aarch64-tdesc.cc b/gdbserver/linux-aarch64-tdesc.cc
index 14d6a4f80eb..be96612d571 100644
--- a/gdbserver/linux-aarch64-tdesc.cc
+++ b/gdbserver/linux-aarch64-tdesc.cc
@@ -27,22 +27,23 @@
#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",
@@ -53,7 +54,7 @@ aarch64_linux_read_description (uint64_t vq, bool pauth_p, bool mte_p)
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;
diff --git a/gdbserver/linux-aarch64-tdesc.h b/gdbserver/linux-aarch64-tdesc.h
index 66d6fa32f16..4ab658447a2 100644
--- a/gdbserver/linux-aarch64-tdesc.h
+++ b/gdbserver/linux-aarch64-tdesc.h
@@ -21,6 +21,6 @@
#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 */