public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
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);


  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).