From: John Baldwin Date: Tue, 3 May 2022 23:05:10 +0000 (-0700) Subject: gdbserver: Read the tpidr register from NT_ARM_TLS on Linux. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9c27bc99e4e1c4fbf51dc8f6186f0fdd5994a38b;p=binutils-gdb.git gdbserver: Read the tpidr register from NT_ARM_TLS on Linux. --- 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 /* 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 */