From: Luis Machado <luis.machado@arm.com>
To: gdb-patches@sourceware.org
Subject: [PING][PATCH] [AArch64] Add TPIDR2 register support for Linux
Date: Tue, 29 Nov 2022 22:19:18 +0000 [thread overview]
Message-ID: <c3d56fd1-6890-ed7c-c911-928a8f936c40@arm.com> (raw)
In-Reply-To: <20220923134648.114930-1-luis.machado@arm.com>
On 9/23/22 14:46, Luis Machado via Gdb-patches wrote:
> With the AArch64 Scalable Matrix Extension we have a new TPIDR2 register, and
> it will be added to the existing NT_ARM_TLS register set. Kernel patches are
> being reviewed here:
>
> https://lore.kernel.org/linux-arm-kernel/20220818170111.351889-1-broonie@kernel.org/
>
>>From GDB's perspective, we handle it in a similar way to the existing TPIDR
> register. But we need to consider cases of systems that only have TPIDR and
> systems that have both TPIDR and TPIDR2.
>
> With that in mind, the following patch adds the required code to support
> TPIDR2 and turns the org.gnu.gdb.aarch64.tls feature into a
> dynamically-generated target description as opposed to a static target
> description containing only TPIDR.
>
> That means we can remove the gdb/features/aarch64-tls.xml file and replace the
> existing gdb/features/aarch64-tls.c auto-generated file with a new file that
> dynamically generates the target description containing either TPIDR alone or
> TPIDR and TPIDR2.
>
> In the future, when *BSD's start to support this register, they can just
> enable it as is being done for the AArch64 Linux target.
>
> The core file read/write code has been updated to support TPIDR2 as well.
>
> On GDBserver's side, there is a small change to the find_regno function to
> expose a non-throwing version of it.
>
> It always seemed strange to me how find_regno causes the whole operation to
> abort if it doesn't find a particular register name. The patch moves code
> from find_regno into find_regno_no_throw and makes find_regno call
> find_regno_no_throw instead.
>
> This allows us to do register name lookups to find a particular register
> number without risking erroring out if nothing is found.
>
> The patch also adjusts the feature detection code for aarch64-fbsd, since
> the infrastructure is shared amongst all aarch64 targets. I haven't added
> code to support TPIDR2 in aarch64-fbsd though, as I'm not sure when/if
> that will happen.
> ---
> gdb/aarch64-fbsd-nat.c | 2 +-
> gdb/aarch64-fbsd-tdep.c | 2 +-
> gdb/aarch64-linux-nat.c | 38 +++++++++++++++-------------
> gdb/aarch64-linux-tdep.c | 25 ++++++++++++++-----
> gdb/aarch64-linux-tdep.h | 3 ---
> gdb/aarch64-tdep.c | 45 ++++++++++++++++++++++++++--------
> gdb/aarch64-tdep.h | 3 ++-
> gdb/arch/aarch64.c | 5 ++--
> gdb/arch/aarch64.h | 14 +++++++----
> gdb/features/Makefile | 1 -
> gdb/features/aarch64-tls.c | 35 +++++++++++++++++++++++---
> gdb/features/aarch64-tls.xml | 11 ---------
> gdb/nat/aarch64-linux.c | 17 +++++++++++++
> gdb/nat/aarch64-linux.h | 4 +++
> gdbserver/linux-aarch64-low.cc | 24 ++++++++++++++----
> gdbserver/regcache.cc | 17 +++++++++++--
> gdbserver/regcache.h | 5 ++++
> 17 files changed, 183 insertions(+), 68 deletions(-)
> delete mode 100644 gdb/features/aarch64-tls.xml
>
> diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
> index 708ddc40d58..40941f138d9 100644
> --- a/gdb/aarch64-fbsd-nat.c
> +++ b/gdb/aarch64-fbsd-nat.c
> @@ -149,7 +149,7 @@ const struct target_desc *
> aarch64_fbsd_nat_target::read_description ()
> {
> aarch64_features features;
> - features.tls = have_regset (inferior_ptid, NT_ARM_TLS) != 0;
> + features.tls = have_regset (inferior_ptid, NT_ARM_TLS)? 1 : 0;
> return aarch64_read_description (features);
> }
>
> diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
> index 4a6b4115234..c9971434777 100644
> --- a/gdb/aarch64-fbsd-tdep.c
> +++ b/gdb/aarch64-fbsd-tdep.c
> @@ -179,7 +179,7 @@ aarch64_fbsd_core_read_description (struct gdbarch *gdbarch,
> asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
>
> aarch64_features features;
> - features.tls = tls != nullptr;
> + features.tls = tls != nullptr? 1 : 0;
>
> return aarch64_read_description (features);
> }
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> index eda79ec6d35..03eec37a6c4 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -442,19 +442,19 @@ fetch_tlsregs_from_thread (struct regcache *regcache)
> = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
> int regno = tdep->tls_regnum;
>
> - gdb_assert (regno != -1);
> + gdb_assert (regno != -1 && tdep->tls_register_count > 0);
>
> - uint64_t tpidr = 0;
> + uint64_t tpidrs[tdep->tls_register_count] = { 0 };
> struct iovec iovec;
> -
> - iovec.iov_base = &tpidr;
> - iovec.iov_len = sizeof (tpidr);
> + iovec.iov_base = tpidrs;
> + iovec.iov_len = sizeof (tpidrs);
>
> int tid = get_ptrace_pid (regcache->ptid ());
> if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
> - perror_with_name (_("unable to fetch TLS register"));
> + perror_with_name (_("unable to fetch TLS registers"));
>
> - regcache->raw_supply (regno, &tpidr);
> + for (int i = 0; i < tdep->tls_register_count; i++)
> + regcache->raw_supply (regno + i, &tpidrs[i]);
> }
>
> /* Store to the current thread the valid TLS register set in GDB's
> @@ -467,19 +467,21 @@ store_tlsregs_to_thread (struct regcache *regcache)
> = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
> int regno = tdep->tls_regnum;
>
> - gdb_assert (regno != -1);
> + gdb_assert (regno != -1 && tdep->tls_register_count > 0);
>
> - uint64_t tpidr = 0;
> + uint64_t tpidrs[tdep->tls_register_count] = { 0 };
>
> - if (REG_VALID != regcache->get_register_status (regno))
> - return;
> + for (int i = 0; i < tdep->tls_register_count; i++)
> + {
> + if (REG_VALID != regcache->get_register_status (regno + i))
> + continue;
>
> - regcache->raw_collect (regno, (char *) &tpidr);
> + regcache->raw_collect (regno + i, (char *) &tpidrs[i]);
> + }
>
> struct iovec iovec;
> -
> - iovec.iov_base = &tpidr;
> - iovec.iov_len = sizeof (tpidr);
> + iovec.iov_base = &tpidrs;
> + iovec.iov_len = sizeof (tpidrs);
>
> int tid = get_ptrace_pid (regcache->ptid ());
> if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
> @@ -607,7 +609,9 @@ aarch64_store_registers (struct regcache *regcache, int regno)
> && (regno == tdep->mte_reg_base))
> store_mteregs_to_thread (regcache);
>
> - if (tdep->has_tls () && regno == tdep->tls_regnum)
> + if (tdep->has_tls ()
> + && regno >= tdep->tls_regnum
> + && regno < tdep->tls_regnum + tdep->tls_register_count)
> store_tlsregs_to_thread (regcache);
> }
>
> @@ -788,7 +792,7 @@ aarch64_linux_nat_target::read_description ()
> features.vq = aarch64_sve_get_vq (tid);
> features.pauth = hwcap & AARCH64_HWCAP_PACA;
> features.mte = hwcap2 & HWCAP2_MTE;
> - features.tls = true;
> + features.tls = aarch64_tls_register_count (tid);
>
> return aarch64_read_description (features);
> }
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index 15773c75da8..d6ca3ae7228 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -753,11 +753,17 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
> "MTE registers", cb_data);
> }
>
> + /* Handle the TLS registers. */
> if (tdep->has_tls ())
> {
> + gdb_assert (tdep->tls_regnum != -1 && tdep->tls_register_count > 0);
> + int sizeof_tls_regset
> + = AARCH64_TLS_REGISTER_SIZE * tdep->tls_register_count;
> +
> const struct regcache_map_entry tls_regmap[] =
> {
> - { 1, tdep->tls_regnum, 8 },
> + { tdep->tls_register_count, tdep->tls_regnum,
> + AARCH64_TLS_REGISTER_SIZE },
> { 0 }
> };
>
> @@ -766,9 +772,8 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
> tls_regmap, regcache_supply_regset, regcache_collect_regset
> };
>
> - cb (".reg-aarch-tls", AARCH64_LINUX_SIZEOF_TLSREGSET,
> - AARCH64_LINUX_SIZEOF_TLSREGSET, &aarch64_linux_tls_regset,
> - "TLS register", cb_data);
> + cb (".reg-aarch-tls", sizeof_tls_regset, sizeof_tls_regset,
> + &aarch64_linux_tls_regset, "TLS register", cb_data);
> }
> }
>
> @@ -778,7 +783,6 @@ static const struct target_desc *
> aarch64_linux_core_read_description (struct gdbarch *gdbarch,
> struct target_ops *target, bfd *abfd)
> {
> - asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
> CORE_ADDR hwcap = linux_get_hwcap (target);
> CORE_ADDR hwcap2 = linux_get_hwcap2 (target);
>
> @@ -786,7 +790,16 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
> features.vq = aarch64_linux_core_read_vq (gdbarch, abfd);
> features.pauth = hwcap & AARCH64_HWCAP_PACA;
> features.mte = hwcap2 & HWCAP2_MTE;
> - features.tls = tls != nullptr;
> +
> + /* Handle the TLS section. */
> + asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
> + if (tls != nullptr)
> + {
> + size_t size = bfd_section_size (tls);
> + /* Convert the size to the number of actual registers, by
> + dividing by 8. */
> + features.tls = size >> 3;
> + }
>
> return aarch64_read_description (features);
> }
> diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
> index 9a7e4339dba..8ae33efc605 100644
> --- a/gdb/aarch64-linux-tdep.h
> +++ b/gdb/aarch64-linux-tdep.h
> @@ -39,9 +39,6 @@
> /* The MTE regset consists of a 64-bit register. */
> #define AARCH64_LINUX_SIZEOF_MTE_REGSET (8)
>
> -/* The TLS regset consists of a single register. */
> -#define AARCH64_LINUX_SIZEOF_TLSREGSET (X_REGISTER_SIZE)
> -
> extern const struct regset aarch64_linux_gregset;
> extern const struct regset aarch64_linux_fpregset;
>
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index d0387044934..5d82f1993a4 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -3399,8 +3399,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;
> }
> @@ -3454,7 +3464,8 @@ 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;
> + int tls_register_count = 0;
> uint64_t vq = aarch64_get_tdesc_vq (info.target_desc);
>
> if (vq > AARCH64_MAX_SVE_VQ)
> @@ -3544,13 +3555,26 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> /* Add the TLS register. */
> 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");
> + const char *tls_register_names[2] = { "tpidr", "tpidr2" };
> + first_tls_regnum = num_regs;
> +
> + /* Look for the TLS registers. */
> + for (i = 0; i < ARRAY_SIZE (tls_register_names); i++)
> + {
> + valid_p
> + = tdesc_numbered_register (feature_tls, tdesc_data.get (),
> + first_tls_regnum + tls_register_count,
> + tls_register_names[i]);
> + if (valid_p)
> + tls_register_count++;
> + }
> + valid_p = true;
> +
> + if (tls_register_count == 0)
> + warning (_("Provided TLS register feature doesn't contain "
> + "any registers."));
>
> - num_regs++;
> + num_regs += tls_register_count;
> }
>
> /* Add the pauth registers. */
> @@ -3601,7 +3625,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> tdep->ra_sign_state_regnum = (feature_pauth == NULL) ? -1
> : ra_sign_state_offset + num_regs;
> tdep->mte_reg_base = first_mte_regnum;
> - tdep->tls_regnum = tls_regnum;
> + tdep->tls_regnum = 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);
> diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
> index d8513023c37..8166df0ada8 100644
> --- a/gdb/aarch64-tdep.h
> +++ b/gdb/aarch64-tdep.h
> @@ -111,8 +111,9 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base
> return mte_reg_base != -1;
> }
>
> - /* TLS register. This is -1 if the TLS register is not available. */
> + /* TLS registers. This is -1 if the TLS registers are not available. */
> int tls_regnum = 0;
> + int tls_register_count = 0;
>
> bool has_tls() const
> {
> diff --git a/gdb/arch/aarch64.c b/gdb/arch/aarch64.c
> index 0f73286f145..565c5e7a81c 100644
> --- a/gdb/arch/aarch64.c
> +++ b/gdb/arch/aarch64.c
> @@ -53,8 +53,9 @@ aarch64_create_target_description (const aarch64_features &features)
> if (features.mte)
> regnum = create_feature_aarch64_mte (tdesc.get (), regnum);
>
> - if (features.tls)
> - regnum = create_feature_aarch64_tls (tdesc.get (), regnum);
> + /* TLS registers. */
> + if (features.tls > 0)
> + regnum = create_feature_aarch64_tls (tdesc.get (), regnum, features.tls);
>
> return tdesc.release ();
> }
> diff --git a/gdb/arch/aarch64.h b/gdb/arch/aarch64.h
> index 8e3fd36726a..b1a6ce3ef0e 100644
> --- a/gdb/arch/aarch64.h
> +++ b/gdb/arch/aarch64.h
> @@ -33,7 +33,9 @@ struct aarch64_features
>
> bool pauth = false;
> bool mte = false;
> - bool tls = false;
> +
> + /* A positive TLS value indicates the number of TLS registers available. */
> + uint8_t tls = 0;
> };
>
> inline bool operator==(const aarch64_features &lhs, const aarch64_features &rhs)
> @@ -56,7 +58,9 @@ namespace std
> h = features.vq;
> h = h << 1 | features.pauth;
> h = h << 1 | features.mte;
> - h = h << 1 | features.tls;
> + /* Shift by two bits for now. We may need to increase this in the future
> + if more TLS registers get added. */
> + h = h << 2 | features.tls;
> return h;
> }
> };
> @@ -96,7 +100,9 @@ enum aarch64_regnum
> AARCH64_LAST_V_ARG_REGNUM = AARCH64_V0_REGNUM + 7
> };
>
> -#define V_REGISTER_SIZE 16
> +/* Sizes of various AArch64 registers. */
> +#define AARCH64_TLS_REGISTER_SIZE 8
> +#define V_REGISTER_SIZE 16
>
> /* Pseudo register base numbers. */
> #define AARCH64_Q0_REGNUM 0
> @@ -117,8 +123,6 @@ enum aarch64_regnum
> #define AARCH64_NUM_REGS AARCH64_FPCR_REGNUM + 1
> #define AARCH64_SVE_NUM_REGS AARCH64_SVE_VG_REGNUM + 1
>
> -#define AARCH64_TLS_REGS_SIZE (8)
> -
> /* There are a number of ways of expressing the current SVE vector size:
>
> VL : Vector Length.
> diff --git a/gdb/features/Makefile b/gdb/features/Makefile
> index 4bc85962dfe..037f900b58b 100644
> --- a/gdb/features/Makefile
> +++ b/gdb/features/Makefile
> @@ -198,7 +198,6 @@ FEATURE_XMLFILES = aarch64-core.xml \
> aarch64-fpu.xml \
> aarch64-pauth.xml \
> aarch64-mte.xml \
> - aarch64-tls.xml \
> arc/v1-core.xml \
> arc/v1-aux.xml \
> arc/v2-core.xml \
> diff --git a/gdb/features/aarch64-tls.c b/gdb/features/aarch64-tls.c
> index 30d730dffba..8a59d26b353 100644
> --- a/gdb/features/aarch64-tls.c
> +++ b/gdb/features/aarch64-tls.c
> @@ -1,14 +1,43 @@
> -/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
> - Original: aarch64-tls.xml */
> +/* Copyright (C) 2022 Free Software Foundation, Inc.
> +
> + This file is part of GDB.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
>
> #include "gdbsupport/tdesc.h"
>
> +/* This function is NOT auto generated from xml.
> +
> + Create the aarch64 description containing the TLS registers. TPIDR is
> + always available, but TPIDR2 is only available on some systems.
> +
> + COUNT is the number of registers in this set. The minimum is 1. */
> +
> static int
> -create_feature_aarch64_tls (struct target_desc *result, long regnum)
> +create_feature_aarch64_tls (struct target_desc *result, long regnum, int count)
> {
> + /* TPIDR is always present. */
> + gdb_assert (count >= 1);
> +
> struct tdesc_feature *feature;
>
> feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.tls");
> tdesc_create_reg (feature, "tpidr", regnum++, 1, NULL, 64, "data_ptr");
> +
> + /* Add TPIDR2. */
> + if (count > 1)
> + tdesc_create_reg (feature, "tpidr2", regnum++, 1, NULL, 64, "data_ptr");
> +
> return regnum;
> }
> diff --git a/gdb/features/aarch64-tls.xml b/gdb/features/aarch64-tls.xml
> deleted file mode 100644
> index f6437785f71..00000000000
> --- a/gdb/features/aarch64-tls.xml
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -<?xml version="1.0"?>
> -<!-- Copyright (C) 2022 Free Software Foundation, Inc.
> -
> - Copying and distribution of this file, with or without modification,
> - are permitted in any medium without royalty provided the copyright
> - notice and this notice are preserved. -->
> -
> -<!DOCTYPE feature SYSTEM "gdb-target.dtd">
> -<feature name="org.gnu.gdb.aarch64.tls">
> - <reg name="tpidr" bitsize="64" type="data_ptr"/>
> -</feature>
> diff --git a/gdb/nat/aarch64-linux.c b/gdb/nat/aarch64-linux.c
> index 421d1ecb53c..017c30948a9 100644
> --- a/gdb/nat/aarch64-linux.c
> +++ b/gdb/nat/aarch64-linux.c
> @@ -250,3 +250,20 @@ aarch64_ps_get_thread_area (struct ps_prochandle *ph,
>
> return PS_OK;
> }
> +
> +/* See nat/aarch64-linux.h */
> +
> +int
> +aarch64_tls_register_count (int tid)
> +{
> + uint64_t tls_regs[2];
> + struct iovec iovec;
> + iovec.iov_base = tls_regs;
> + iovec.iov_len = sizeof (tls_regs);
> +
> + if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
> + return 1;
> +
> + /* TPIDR2 is available. */
> + return 2;
> +}
> diff --git a/gdb/nat/aarch64-linux.h b/gdb/nat/aarch64-linux.h
> index 1777ce32522..517cbb33963 100644
> --- a/gdb/nat/aarch64-linux.h
> +++ b/gdb/nat/aarch64-linux.h
> @@ -129,4 +129,8 @@ ps_err_e aarch64_ps_get_thread_area (struct ps_prochandle *ph,
> lwpid_t lwpid, int idx, void **base,
> int is_64bit_p);
>
> +/* Return the number of TLS registers in the NT_ARM_TLS set. This is only
> + used for aarch64 state. */
> +int aarch64_tls_register_count (int tid);
> +
> #endif /* NAT_AARCH64_LINUX_H */
> diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
> index db508696261..b657a265ee7 100644
> --- a/gdbserver/linux-aarch64-low.cc
> +++ b/gdbserver/linux-aarch64-low.cc
> @@ -292,9 +292,16 @@ aarch64_store_mteregset (struct regcache *regcache, const void *buf)
> static void
> aarch64_fill_tlsregset (struct regcache *regcache, void *buf)
> {
> + gdb_byte *tls_buf = (gdb_byte *) buf;
> int tls_regnum = find_regno (regcache->tdesc, "tpidr");
>
> - collect_register (regcache, tls_regnum, buf);
> + collect_register (regcache, tls_regnum, tls_buf);
> +
> + /* Read TPIDR2, if it exists. */
> + gdb::optional<int> regnum = find_regno_no_throw (regcache->tdesc, "tpidr2");
> +
> + if (regnum.has_value ())
> + collect_register (regcache, *regnum, tls_buf + sizeof (uint64_t));
> }
>
> /* Store TLS register to regcache. */
> @@ -302,9 +309,16 @@ aarch64_fill_tlsregset (struct regcache *regcache, void *buf)
> static void
> aarch64_store_tlsregset (struct regcache *regcache, const void *buf)
> {
> + gdb_byte *tls_buf = (gdb_byte *) buf;
> int tls_regnum = find_regno (regcache->tdesc, "tpidr");
>
> - supply_register (regcache, tls_regnum, buf);
> + supply_register (regcache, tls_regnum, tls_buf);
> +
> + /* Write TPIDR2, if it exists. */
> + gdb::optional<int> regnum = find_regno_no_throw (regcache->tdesc, "tpidr2");
> +
> + if (regnum.has_value ())
> + supply_register (regcache, *regnum, tls_buf + sizeof (uint64_t));
> }
>
> bool
> @@ -795,8 +809,8 @@ aarch64_adjust_register_sets (const struct aarch64_features &features)
> regset->size = AARCH64_LINUX_SIZEOF_MTE;
> break;
> case NT_ARM_TLS:
> - if (features.tls)
> - regset->size = AARCH64_TLS_REGS_SIZE;
> + if (features.tls > 0)
> + regset->size = AARCH64_TLS_REGISTER_SIZE * features.tls;
> break;
> default:
> gdb_assert_not_reached ("Unknown register set found.");
> @@ -829,7 +843,7 @@ 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;
> + features.tls = aarch64_tls_register_count (tid);
>
> current_process ()->tdesc = aarch64_linux_read_description (features);
>
> diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc
> index 27491efc52d..0b0d0855db3 100644
> --- a/gdbserver/regcache.cc
> +++ b/gdbserver/regcache.cc
> @@ -244,14 +244,27 @@ registers_from_string (struct regcache *regcache, char *buf)
> hex2bin (buf, registers, len / 2);
> }
>
> -int
> -find_regno (const struct target_desc *tdesc, const char *name)
> +/* See regcache.h */
> +
> +gdb::optional<int>
> +find_regno_no_throw (const struct target_desc *tdesc, const char *name)
> {
> for (int i = 0; i < tdesc->reg_defs.size (); ++i)
> {
> if (strcmp (name, find_register_by_number (tdesc, i).name) == 0)
> return i;
> }
> + return {};
> +}
> +
> +int
> +find_regno (const struct target_desc *tdesc, const char *name)
> +{
> + gdb::optional<int> regnum = find_regno_no_throw (tdesc, name);
> +
> + if (regnum.has_value ())
> + return *regnum;
> +
> internal_error (__FILE__, __LINE__, "Unknown register %s requested",
> name);
> }
> diff --git a/gdbserver/regcache.h b/gdbserver/regcache.h
> index 731c18d16e2..b67eefbe04b 100644
> --- a/gdbserver/regcache.h
> +++ b/gdbserver/regcache.h
> @@ -110,6 +110,11 @@ int register_cache_size (const struct target_desc *tdesc);
>
> int register_size (const struct target_desc *tdesc, int n);
>
> +/* No throw version of find_regno. If NAME is not a known register, return
> + an empty value. */
> +gdb::optional<int> find_regno_no_throw (const struct target_desc *tdesc,
> + const char *name);
> +
> int find_regno (const struct target_desc *tdesc, const char *name);
>
> void supply_register (struct regcache *regcache, int n, const void *buf);
next prev parent reply other threads:[~2022-11-29 22:19 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-23 13:46 [PATCH] " Luis Machado
2022-09-23 16:42 ` John Baldwin
2022-10-04 8:53 ` [PING][PATCH] " Luis Machado
2022-10-10 12:19 ` Luis Machado
2022-10-17 10:03 ` Luis Machado
2022-10-25 13:52 ` Luis Machado
2022-11-10 1:01 ` Luis Machado
2022-11-29 22:19 ` Luis Machado [this message]
2022-12-05 20:36 ` [PATCH] " Simon Marchi
2022-12-06 9:50 ` Luis Machado
2022-12-06 13:16 ` [PATCH v3] [aarch64] " Luis Machado
2022-12-06 14:41 ` Simon Marchi
2022-12-07 10:30 ` [PATCH v4] " Luis Machado
2022-12-09 13:43 ` Luis Machado
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c3d56fd1-6890-ed7c-c911-928a8f936c40@arm.com \
--to=luis.machado@arm.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).