public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures.
@ 2022-04-12 23:46 John Baldwin
  2022-04-12 23:46 ` [PATCH v2 01/14] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

Changes since V1:

- I changed the register number for TPIDR on Aarch64 to a fixed value
  locally in GDB itself.  (I had misparsed Luis's original reply to
  using a fixed register on 32-bit ARM.)  This does work in my testing
  on both FreeBSD and Linux, but it is a debatable point if new
  extensions should use fixed register numbers (as on amd64/i386) or
  variable register numbers with base register numbers in the per-arch
  tdep class (as Aarch64 has done more recently).

  An advantage of fixed register numbers is that regcache_map_entry
  arrays used with regsets can be const globals and shared between
  *-tdep.c and *-nat.c files.  A disadvantage is that fixed numbers
  leave gaps in some of the internal arrays stored in a tdesc.  I'm
  also not sure that they can be used as easily in gdbserver.  At
  least for TPIDR on on Linux Aarch64 I had to lookup gdbserver's
  register number dynmically vs using the constant.

- I added support for TPIDR on Linux Aarch64.  There are some XXX
  comments as I didn't add any tests to see if NT_ARM_TLS is supported
  or not but just assume it is always present (since other places that
  use NT_ARM_TLS seem to assume it is always present).  The Linux
  changes do not try to change TLS variable resolution, but simply
  report the register's value.  I did do light testing on a RPi both
  for core dumps, native, and gdbserver showing that $tpidr showed a
  sensible value for all three cases for a simple test program which
  prints out the address of a TLS variable in the main executable (and
  verified that the tpidr register value was "close" to the printed
  address).

John Baldwin (14):
  fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET.
  Create pseudo sections for NT_ARM_TLS notes on FreeBSD.
  Add an arm-tls feature which includes the tpidruro register from CP15.
  Read the tpidruro register from NT_ARM_TLS core dump notes on
    FreeBSD/arm.
  Support TLS variables on FreeBSD/arm.
  Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes.
  Add an aarch64-tls feature which includes the tpidr register.
  Read the tpidr register from NT_ARM_TLS core dump notes on
    FreeBSD/Aarch64.
  Support TLS variables on FreeBSD/Aarch64.
  Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64
    processes.
  NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64.
  Read the tpidr register from NT_ARM_TLS core dump notes on Linux
    Aarch64.
  gdbserver: Read the tpidr register from NT_ARM_TLS on Linux.
  Read the tpidr register from NT_ARM_TLS on Linux.

 bfd/ChangeLog                    |  4 ++
 bfd/elf.c                        |  3 ++
 gdb/NEWS                         |  3 ++
 gdb/aarch64-fbsd-nat.c           | 26 +++++++++++
 gdb/aarch64-fbsd-tdep.c          | 61 ++++++++++++++++++++++++++
 gdb/aarch64-fbsd-tdep.h          |  4 ++
 gdb/aarch64-linux-nat.c          | 57 +++++++++++++++++++++++-
 gdb/aarch64-linux-tdep.c         | 20 ++++++++-
 gdb/aarch64-linux-tdep.h         |  4 ++
 gdb/aarch64-tdep.c               | 30 ++++++++++---
 gdb/aarch64-tdep.h               | 10 ++++-
 gdb/arch/aarch32.c               |  2 +
 gdb/arch/aarch64.c               |  7 ++-
 gdb/arch/aarch64.h               |  9 +++-
 gdb/arch/arm.c                   |  6 ++-
 gdb/arch/arm.h                   |  7 +--
 gdb/arm-fbsd-nat.c               | 15 ++++++-
 gdb/arm-fbsd-tdep.c              | 57 +++++++++++++++++++++---
 gdb/arm-fbsd-tdep.h              |  6 ++-
 gdb/arm-linux-nat.c              |  6 +--
 gdb/arm-linux-tdep.c             |  4 +-
 gdb/arm-netbsd-nat.c             |  4 +-
 gdb/arm-tdep.c                   | 20 ++++++---
 gdb/arm-tdep.h                   |  2 +-
 gdb/fbsd-nat.c                   | 75 ++++++++++++++++++++++++++++++++
 gdb/fbsd-nat.h                   | 38 ++++++++++++++++
 gdb/features/Makefile            |  2 +
 gdb/features/aarch64-tls.c       | 14 ++++++
 gdb/features/aarch64-tls.xml     | 11 +++++
 gdb/features/arm/arm-tls.c       | 14 ++++++
 gdb/features/arm/arm-tls.xml     | 11 +++++
 gdbserver/linux-aarch64-ipa.cc   |  8 ++--
 gdbserver/linux-aarch64-low.cc   | 28 +++++++++++-
 gdbserver/linux-aarch64-tdesc.cc | 11 ++---
 gdbserver/linux-aarch64-tdesc.h  |  2 +-
 gdbserver/netbsd-aarch64-low.cc  |  2 +-
 36 files changed, 533 insertions(+), 50 deletions(-)
 create mode 100644 gdb/features/aarch64-tls.c
 create mode 100644 gdb/features/aarch64-tls.xml
 create mode 100644 gdb/features/arm/arm-tls.c
 create mode 100644 gdb/features/arm/arm-tls.xml

-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 01/14] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 02/14] Create pseudo sections for NT_ARM_TLS notes on FreeBSD John Baldwin
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

FreeBSD's kernel has recently added PT_GETREGSET and PT_SETREGSET
operations to fetch a register set named by an ELF note type.  These
helper routines provide helpers to check for a register set's
existence, fetch registers for a register set, and store registers to
a register set.
---
 gdb/fbsd-nat.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/fbsd-nat.h | 38 +++++++++++++++++++++++++
 2 files changed, 113 insertions(+)

diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 8e5107c26f8..a501d9212c0 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -49,6 +49,11 @@
 
 #include <list>
 
+#ifndef PT_GETREGSET
+#define	PT_GETREGSET	42	/* Get a target register set */
+#define	PT_SETREGSET	43	/* Set a target register set */
+#endif
+
 /* Return the name of a file that can be opened to get the symbols for
    the child process identified by PID.  */
 
@@ -1774,6 +1779,76 @@ fbsd_nat_target::store_register_set (struct regcache *regcache, int regnum,
 
 /* See fbsd-nat.h.  */
 
+bool
+fbsd_nat_target::have_regset (ptid_t ptid, int note)
+{
+  pid_t pid = get_ptrace_pid (ptid);
+  struct iovec iov;
+
+  iov.iov_base = nullptr;
+  iov.iov_len = 0;
+  if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+    return 0;
+  return iov.iov_len;
+}
+
+/* See fbsd-nat.h.  */
+
+bool
+fbsd_nat_target::fetch_regset (struct regcache *regcache, int regnum, int note,
+			       const struct regset *regset, void *regs,
+			       size_t size)
+{
+  const struct regcache_map_entry *map
+    = (const struct regcache_map_entry *) regset->regmap;
+  pid_t pid = get_ptrace_pid (regcache->ptid ());
+
+  if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
+					     size))
+    {
+      struct iovec iov;
+
+      iov.iov_base = regs;
+      iov.iov_len = size;
+      if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+	perror_with_name (_("Couldn't get registers"));
+
+      regcache->supply_regset (regset, regnum, regs, size);
+      return true;
+    }
+  return false;
+}
+
+bool
+fbsd_nat_target::store_regset (struct regcache *regcache, int regnum, int note,
+			       const struct regset *regset, void *regs,
+			       size_t size)
+{
+  const struct regcache_map_entry *map
+    = (const struct regcache_map_entry *) regset->regmap;
+  pid_t pid = get_ptrace_pid (regcache->ptid ());
+
+  if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(),
+					     size))
+    {
+      struct iovec iov;
+
+      iov.iov_base = regs;
+      iov.iov_len = size;
+      if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+	perror_with_name (_("Couldn't get registers"));
+
+      regcache->collect_regset (regset, regnum, regs, size);
+
+      if (ptrace (PT_SETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
+	perror_with_name (_("Couldn't write registers"));
+      return true;
+    }
+  return false;
+}
+
+/* See fbsd-nat.h.  */
+
 bool
 fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo)
 {
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index 82f7ee47949..ba359c62314 100644
--- a/gdb/fbsd-nat.h
+++ b/gdb/fbsd-nat.h
@@ -151,6 +151,17 @@ class fbsd_nat_target : public inf_ptrace_target
   bool store_register_set (struct regcache *regcache, int regnum, int fetch_op,
 			   int store_op, const struct regset *regset,
 			   void *regs, size_t size);
+
+  /* Helper routines which use PT_GETREGSET and PT_SETREGSET for the
+     specified NOTE instead of regset-specific fetch and store
+     ops.  */
+
+  bool fetch_regset (struct regcache *regcache, int regnum, int note,
+		     const struct regset *regset, void *regs, size_t size);
+
+  bool store_regset (struct regcache *regcache, int regnum, int note,
+		     const struct regset *regset, void *regs, size_t size);
+
 protected:
   /* Wrapper versions of the above helpers which accept a register set
      type such as 'struct reg' or 'struct fpreg'.  */
@@ -172,6 +183,33 @@ class fbsd_nat_target : public inf_ptrace_target
     return store_register_set (regcache, regnum, fetch_op, store_op, regset,
 			       &regs, sizeof (regs));
   }
+
+  /* Helper routine for use in read_description in subclasses.  This
+     routine checks if the register set for the specified NOTE is
+     present for a given PTID.  If the register set is present, the
+     the size of the register set is returned.  If the register set is
+     not present, zero is returned.  */
+
+  bool have_regset (ptid_t ptid, int note);
+
+  /* Wrapper versions of the PT_GETREGSET and PT_REGSET helpers which
+     accept a register set type.  */
+
+  template <class Regset>
+  bool fetch_regset (struct regcache *regcache, int regnum, int note,
+		     const struct regset *regset)
+  {
+    Regset regs;
+    return fetch_regset (regcache, regnum, note, regset, &regs, sizeof (regs));
+  }
+
+  template <class Regset>
+  bool store_regset (struct regcache *regcache, int regnum, int note,
+		     const struct regset *regset)
+  {
+    Regset regs;
+    return store_regset (regcache, regnum, note, regset, &regs, sizeof (regs));
+  }
 };
 
 /* Fetch the signal information for PTID and store it in *SIGINFO.
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 02/14] Create pseudo sections for NT_ARM_TLS notes on FreeBSD.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
  2022-04-12 23:46 ` [PATCH v2 01/14] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 03/14] Add an arm-tls feature which includes the tpidruro register from CP15 John Baldwin
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

bfd/ChangeLog:

	* elf.c (elfcore_grok_freebsd_note): Handle NT_ARM_TLS notes.
---
 bfd/ChangeLog | 4 ++++
 bfd/elf.c     | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 98f0bab4211..fd1a8f01d62 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,7 @@
+2022-03-11  John Baldwin  <jhb@FreeBSD.org>
+
+	* elf.c (elfcore_grok_freebsd_note): Handle NT_ARM_TLS notes.
+
 2022-04-01  John Baldwin  <jhb@FreeBSD.org>
 
 	* elf-bfd.h (elfcore_write_x86_segbases): New.
diff --git a/bfd/elf.c b/bfd/elf.c
index 37c53cfdf32..e9148dbecab 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -11037,6 +11037,9 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
       return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
 					      note);
 
+    case NT_ARM_TLS:
+      return elfcore_grok_aarch_tls (abfd, note);
+
     case NT_ARM_VFP:
       return elfcore_grok_arm_vfp (abfd, note);
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 03/14] Add an arm-tls feature which includes the tpidruro register from CP15.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
  2022-04-12 23:46 ` [PATCH v2 01/14] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
  2022-04-12 23:46 ` [PATCH v2 02/14] Create pseudo sections for NT_ARM_TLS notes on FreeBSD John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 04/14] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm John Baldwin
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/arch/aarch32.c           |  2 ++
 gdb/arch/arm.c               |  6 +++++-
 gdb/arch/arm.h               |  7 ++++---
 gdb/arm-fbsd-tdep.c          |  4 ++--
 gdb/arm-linux-nat.c          |  6 +++---
 gdb/arm-linux-tdep.c         |  4 ++--
 gdb/arm-netbsd-nat.c         |  4 ++--
 gdb/arm-tdep.c               | 20 +++++++++++++++-----
 gdb/arm-tdep.h               |  2 +-
 gdb/features/Makefile        |  1 +
 gdb/features/arm/arm-tls.c   | 14 ++++++++++++++
 gdb/features/arm/arm-tls.xml | 11 +++++++++++
 12 files changed, 62 insertions(+), 19 deletions(-)
 create mode 100644 gdb/features/arm/arm-tls.c
 create mode 100644 gdb/features/arm/arm-tls.xml

diff --git a/gdb/arch/aarch32.c b/gdb/arch/aarch32.c
index 0c544d381f1..4d6ffb44a15 100644
--- a/gdb/arch/aarch32.c
+++ b/gdb/arch/aarch32.c
@@ -19,6 +19,7 @@
 #include "aarch32.h"
 
 #include "../features/arm/arm-core.c"
+#include "../features/arm/arm-tls.c"
 #include "../features/arm/arm-vfpv3.c"
 
 /* See aarch32.h.  */
@@ -38,6 +39,7 @@ aarch32_create_target_description ()
   /* Create a vfpv3 feature, then a blank NEON feature.  */
   regnum = create_feature_arm_arm_vfpv3 (tdesc.get (), regnum);
   tdesc_create_feature (tdesc.get (), "org.gnu.gdb.arm.neon");
+  regnum = create_feature_arm_arm_tls (tdesc.get (), regnum);
 
   return tdesc.release ();
 }
diff --git a/gdb/arch/arm.c b/gdb/arch/arm.c
index 126e46a950a..15b600e22f4 100644
--- a/gdb/arch/arm.c
+++ b/gdb/arch/arm.c
@@ -22,6 +22,7 @@
 #include "arm.h"
 
 #include "../features/arm/arm-core.c"
+#include "../features/arm/arm-tls.c"
 #include "../features/arm/arm-vfpv2.c"
 #include "../features/arm/arm-vfpv3.c"
 #include "../features/arm/xscale-iwmmxt.c"
@@ -373,7 +374,7 @@ shifted_reg_val (struct regcache *regcache, unsigned long inst,
 /* See arch/arm.h.  */
 
 target_desc *
-arm_create_target_description (arm_fp_type fp_type)
+arm_create_target_description (arm_fp_type fp_type, bool tls)
 {
   target_desc_up tdesc = allocate_target_description ();
 
@@ -409,6 +410,9 @@ arm_create_target_description (arm_fp_type fp_type)
       error (_("Invalid Arm FP type: %d"), fp_type);
     }
 
+  if (tls)
+    regnum = create_feature_arm_arm_tls (tdesc.get (), regnum);
+
   return tdesc.release ();
 }
 
diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h
index f75470e7572..32f29b20d33 100644
--- a/gdb/arch/arm.h
+++ b/gdb/arch/arm.h
@@ -49,6 +49,7 @@ enum gdb_regnum {
   ARM_D0_REGNUM,		/* VFP double-precision registers.  */
   ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
   ARM_FPSCR_REGNUM,
+  ARM_TPIDRURO_REGNUM,
 
   /* Other useful registers.  */
   ARM_FP_REGNUM = 11,		/* Frame register in ARM code, if used.  */
@@ -65,8 +66,8 @@ enum arm_register_counts {
   ARM_NUM_ARG_REGS = 4,
   /* Number of floating point argument registers.  */
   ARM_NUM_FP_ARG_REGS = 4,
-  /* Number of registers (old, defined as ARM_FPSCR_REGNUM + 1.  */
-  ARM_NUM_REGS = ARM_FPSCR_REGNUM + 1
+  /* Number of registers (old, defined as ARM_TPIDRURO_REGNUM + 1.  */
+  ARM_NUM_REGS = ARM_TPIDRURO_REGNUM + 1
 };
 
 /* Enum describing the different kinds of breakpoints.  */
@@ -193,7 +194,7 @@ unsigned long shifted_reg_val (struct regcache *regcache,
 
 /* Create an Arm target description with the given FP hardware type.  */
 
-target_desc *arm_create_target_description (arm_fp_type fp_type);
+target_desc *arm_create_target_description (arm_fp_type fp_type, bool tls);
 
 /* Create an Arm M-profile target description with the given hardware type.  */
 
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index bf337b13f98..06745a36186 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -188,9 +188,9 @@ arm_fbsd_read_description_auxv (struct target_ops *target)
 	return aarch32_read_description ();
       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPD32))
 	       == (HWCAP_VFPv3 | HWCAP_VFPD32))
-	return arm_read_description (ARM_FP_TYPE_VFPV3);
+	return arm_read_description (ARM_FP_TYPE_VFPV3, false);
       else
-	return arm_read_description (ARM_FP_TYPE_VFPV2);
+	return arm_read_description (ARM_FP_TYPE_VFPV2, false);
     }
 
   return nullptr;
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index f0f09acf2f9..2abaf5a675d 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -550,7 +550,7 @@ arm_linux_nat_target::read_description ()
     }
 
   if (arm_hwcap & HWCAP_IWMMXT)
-    return arm_read_description (ARM_FP_TYPE_IWMMXT);
+    return arm_read_description (ARM_FP_TYPE_IWMMXT, false);
 
   if (arm_hwcap & HWCAP_VFP)
     {
@@ -567,9 +567,9 @@ arm_linux_nat_target::read_description ()
       if (arm_hwcap & HWCAP_NEON)
 	return aarch32_read_description ();
       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
-	return arm_read_description (ARM_FP_TYPE_VFPV3);
+	return arm_read_description (ARM_FP_TYPE_VFPV3, false);
 
-      return arm_read_description (ARM_FP_TYPE_VFPV2);
+      return arm_read_description (ARM_FP_TYPE_VFPV2, false);
     }
 
   return this->beneath ()->read_description ();
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index c8e882ab096..f299e9665d5 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -741,9 +741,9 @@ arm_linux_core_read_description (struct gdbarch *gdbarch,
       if (arm_hwcap & HWCAP_NEON)
 	return aarch32_read_description ();
       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3)
-	return arm_read_description (ARM_FP_TYPE_VFPV3);
+	return arm_read_description (ARM_FP_TYPE_VFPV3, false);
 
-      return arm_read_description (ARM_FP_TYPE_VFPV2);
+      return arm_read_description (ARM_FP_TYPE_VFPV2, false);
     }
 
   return nullptr;
diff --git a/gdb/arm-netbsd-nat.c b/gdb/arm-netbsd-nat.c
index 591a0ab1d54..764bbe8cd3d 100644
--- a/gdb/arm-netbsd-nat.c
+++ b/gdb/arm-netbsd-nat.c
@@ -346,13 +346,13 @@ arm_netbsd_nat_target::read_description ()
 
   if (sysctlbyname("machdep.fpu_present", &flag, &len, NULL, 0) != 0
       || !flag)
-    return arm_read_description (ARM_FP_TYPE_NONE);
+    return arm_read_description (ARM_FP_TYPE_NONE, false);
 
   len = sizeof(flag);
   if (sysctlbyname("machdep.neon_present", &flag, &len, NULL, 0) == 0 && flag)
     return aarch32_read_description ();
 
-  return arm_read_description (ARM_FP_TYPE_VFPV3);
+  return arm_read_description (ARM_FP_TYPE_VFPV3, false);
 }
 
 void _initialize_arm_netbsd_nat ();
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 4d0f3492410..65589346756 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -239,7 +239,7 @@ static const char **valid_disassembly_styles;
 static const char *disassembly_style;
 
 /* All possible arm target descriptors.  */
-static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID];
+static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID][2];
 static struct target_desc *tdesc_arm_mprofile_list[ARM_M_TYPE_INVALID];
 
 /* This is used to keep the bfd arch_info in sync with the disassembly
@@ -9413,6 +9413,16 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    }
 	}
 
+      /* Check for the TLS register feature.  */
+      feature = tdesc_find_feature (tdesc, "org.gnu.gdb.arm.tls");
+      if (feature != nullptr)
+	{
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					      ARM_TPIDRURO_REGNUM, "tpidruro");
+	  if (!valid_p)
+	    return NULL;
+	}
+
       /* Check for MVE after all the checks for GPR's, VFP and Neon.
 	 MVE (Helium) is an M-profile extension.  */
       if (is_m)
@@ -13728,14 +13738,14 @@ arm_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 /* See arm-tdep.h.  */
 
 const target_desc *
-arm_read_description (arm_fp_type fp_type)
+arm_read_description (arm_fp_type fp_type, bool tls)
 {
-  struct target_desc *tdesc = tdesc_arm_list[fp_type];
+  struct target_desc *tdesc = tdesc_arm_list[fp_type][tls];
 
   if (tdesc == nullptr)
     {
-      tdesc = arm_create_target_description (fp_type);
-      tdesc_arm_list[fp_type] = tdesc;
+      tdesc = arm_create_target_description (fp_type, tls);
+      tdesc_arm_list[fp_type][tls] = tdesc;
     }
 
   return tdesc;
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 8a9f618539f..c14ac86a9bd 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -301,7 +301,7 @@ extern void
 				       const struct regcache *regcache);
 
 /* Get the correct Arm target description with given FP hardware type.  */
-const target_desc *arm_read_description (arm_fp_type fp_type);
+const target_desc *arm_read_description (arm_fp_type fp_type, bool tls);
 
 /* Get the correct Arm M-Profile target description with given hardware
    type.  */
diff --git a/gdb/features/Makefile b/gdb/features/Makefile
index a2bb2a5922f..3fadc5091fa 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -207,6 +207,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
 	arm/arm-m-profile.xml \
 	arm/arm-m-profile-mve.xml \
 	arm/arm-m-profile-with-fpa.xml \
+	arm/arm-tls.xml \
 	arm/arm-vfpv2.xml \
 	arm/arm-vfpv3.xml \
 	arm/xscale-iwmmxt.xml \
diff --git a/gdb/features/arm/arm-tls.c b/gdb/features/arm/arm-tls.c
new file mode 100644
index 00000000000..d1214dda8ec
--- /dev/null
+++ b/gdb/features/arm/arm-tls.c
@@ -0,0 +1,14 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: arm-tls.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_arm_arm_tls (struct target_desc *result, long regnum)
+{
+  struct tdesc_feature *feature;
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.tls");
+  tdesc_create_reg (feature, "tpidruro", regnum++, 1, NULL, 32, "data_ptr");
+  return regnum;
+}
diff --git a/gdb/features/arm/arm-tls.xml b/gdb/features/arm/arm-tls.xml
new file mode 100644
index 00000000000..3cdf73e776f
--- /dev/null
+++ b/gdb/features/arm/arm-tls.xml
@@ -0,0 +1,11 @@
+<?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.arm.tls">
+  <reg name="tpidruro" bitsize="32" type="data_ptr"/>
+</feature>
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 04/14] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (2 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 03/14] Add an arm-tls feature which includes the tpidruro register from CP15 John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 05/14] Support TLS variables " John Baldwin
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/arm-fbsd-nat.c  |  2 +-
 gdb/arm-fbsd-tdep.c | 28 ++++++++++++++++++++++------
 gdb/arm-fbsd-tdep.h |  6 +++++-
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/gdb/arm-fbsd-nat.c b/gdb/arm-fbsd-nat.c
index 3106d73cc3a..c32924de735 100644
--- a/gdb/arm-fbsd-nat.c
+++ b/gdb/arm-fbsd-nat.c
@@ -72,7 +72,7 @@ arm_fbsd_nat_target::read_description ()
 {
   const struct target_desc *desc;
 
-  desc = arm_fbsd_read_description_auxv (this);
+  desc = arm_fbsd_read_description_auxv (this, false);
   if (desc == NULL)
     desc = this->beneath ()->read_description ();
   return desc;
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index 06745a36186..e11b17664eb 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -44,6 +44,12 @@ static const struct regcache_map_entry arm_fbsd_gregmap[] =
     { 0 }
   };
 
+static const struct regcache_map_entry arm_fbsd_tlsregmap[] =
+  {
+    { 1, ARM_TPIDRURO_REGNUM, 4 },
+    { 0 }
+  };
+
 static const struct regcache_map_entry arm_fbsd_vfpregmap[] =
   {
     { 32, ARM_D0_REGNUM, 8 }, /* d0 ... d31 */
@@ -144,6 +150,12 @@ const struct regset arm_fbsd_gregset =
     regcache_supply_regset, regcache_collect_regset
   };
 
+const struct regset arm_fbsd_tlsregset =
+  {
+    arm_fbsd_tlsregmap,
+    regcache_supply_regset, regcache_collect_regset
+  };
+
 const struct regset arm_fbsd_vfpregset =
   {
     arm_fbsd_vfpregmap,
@@ -162,6 +174,8 @@ arm_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
   cb (".reg", ARM_FBSD_SIZEOF_GREGSET, ARM_FBSD_SIZEOF_GREGSET,
       &arm_fbsd_gregset, NULL, cb_data);
+  cb (".reg-aarch-tls", ARM_FBSD_SIZEOF_TLSREGSET, ARM_FBSD_SIZEOF_TLSREGSET,
+      &arm_fbsd_tlsregset, NULL, cb_data);
 
   /* While FreeBSD/arm cores do contain a NT_FPREGSET / ".reg2"
      register set, it is not populated with register values by the
@@ -175,12 +189,12 @@ arm_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
    vector.  */
 
 const struct target_desc *
-arm_fbsd_read_description_auxv (struct target_ops *target)
+arm_fbsd_read_description_auxv (struct target_ops *target, bool tls)
 {
   CORE_ADDR arm_hwcap = 0;
 
   if (target_auxv_search (target, AT_FREEBSD_HWCAP, &arm_hwcap) != 1)
-    return nullptr;
+    return arm_read_description (ARM_FP_TYPE_NONE, tls);
 
   if (arm_hwcap & HWCAP_VFP)
     {
@@ -188,12 +202,12 @@ arm_fbsd_read_description_auxv (struct target_ops *target)
 	return aarch32_read_description ();
       else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPD32))
 	       == (HWCAP_VFPv3 | HWCAP_VFPD32))
-	return arm_read_description (ARM_FP_TYPE_VFPV3, false);
+	return arm_read_description (ARM_FP_TYPE_VFPV3, tls);
       else
-	return arm_read_description (ARM_FP_TYPE_VFPV2, false);
+	return arm_read_description (ARM_FP_TYPE_VFPV2, tls);
     }
 
-  return nullptr;
+  return arm_read_description (ARM_FP_TYPE_NONE, tls);
 }
 
 /* Implement the "core_read_description" gdbarch method.  */
@@ -203,7 +217,9 @@ arm_fbsd_core_read_description (struct gdbarch *gdbarch,
 				struct target_ops *target,
 				bfd *abfd)
 {
-  return arm_fbsd_read_description_auxv (target);
+  asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
+
+  return arm_fbsd_read_description_auxv (target, tls != nullptr);
 }
 
 /* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
diff --git a/gdb/arm-fbsd-tdep.h b/gdb/arm-fbsd-tdep.h
index 633dafad75d..00b55cf5bd0 100644
--- a/gdb/arm-fbsd-tdep.h
+++ b/gdb/arm-fbsd-tdep.h
@@ -26,11 +26,15 @@
    PC, and CPSR registers.  */
 #define ARM_FBSD_SIZEOF_GREGSET  (17 * 4)
 
+/* The TLS regset consists of a single register.  */
+#define	ARM_FBSD_SIZEOF_TLSREGSET	(4)
+
 /* The VFP regset consists of 32 D registers plus FPSCR, and the whole
    structure is padded to 64-bit alignment.  */
 #define	ARM_FBSD_SIZEOF_VFPREGSET	(33 * 8)
 
 extern const struct regset arm_fbsd_gregset;
+extern const struct regset arm_fbsd_tlsregset;
 extern const struct regset arm_fbsd_vfpregset;
 
 /* Flags passed in AT_HWCAP. */
@@ -40,6 +44,6 @@ extern const struct regset arm_fbsd_vfpregset;
 #define	HWCAP_VFPD32		0x00080000
 
 extern const struct target_desc *
-arm_fbsd_read_description_auxv (struct target_ops *target);
+arm_fbsd_read_description_auxv (struct target_ops *target, bool tls);
 
 #endif /* ARM_FBSD_TDEP_H */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 05/14] Support TLS variables on FreeBSD/arm.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (3 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 04/14] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 06/14] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes John Baldwin
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

Derive the pointer to the DTV array from the tpidruro register.
---
 gdb/arm-fbsd-tdep.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index e11b17664eb..97d41a77f40 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -27,6 +27,7 @@
 #include "auxv.h"
 #include "fbsd-tdep.h"
 #include "gdbcore.h"
+#include "inferior.h"
 #include "osabi.h"
 #include "solib-svr4.h"
 #include "trad-frame.h"
@@ -222,6 +223,29 @@ arm_fbsd_core_read_description (struct gdbarch *gdbarch,
   return arm_fbsd_read_description_auxv (target, tls != nullptr);
 }
 
+/* Implement the get_thread_local_address gdbarch method.  */
+
+static CORE_ADDR
+arm_fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
+				   CORE_ADDR lm_addr, CORE_ADDR offset)
+{
+  struct regcache *regcache;
+
+  regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+				       ptid, gdbarch);
+
+  target_fetch_registers (regcache, ARM_TPIDRURO_REGNUM);
+
+  ULONGEST tpidruro;
+  if (regcache->cooked_read (ARM_TPIDRURO_REGNUM, &tpidruro) != REG_VALID)
+    error (_("Unable to fetch %%tpidruro"));
+
+  /* %tpidruro points to the TCB whose first member is the dtv
+      pointer.  */
+  CORE_ADDR dtv_addr = tpidruro;
+  return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
+}
+
 /* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
 
 static void
@@ -247,6 +271,11 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (gdbarch, arm_fbsd_iterate_over_regset_sections);
   set_gdbarch_core_read_description (gdbarch, arm_fbsd_core_read_description);
 
+  set_gdbarch_fetch_tls_load_module_address (gdbarch,
+					     svr4_fetch_objfile_link_map);
+  set_gdbarch_get_thread_local_address (gdbarch,
+					arm_fbsd_get_thread_local_address);
+
   /* Single stepping.  */
   set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 06/14] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (4 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 05/14] Support TLS variables " John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 07/14] Add an aarch64-tls feature which includes the tpidr register John Baldwin
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

This permits resolving TLS variables.
---
 gdb/arm-fbsd-nat.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/gdb/arm-fbsd-nat.c b/gdb/arm-fbsd-nat.c
index c32924de735..6b5befc3a05 100644
--- a/gdb/arm-fbsd-nat.c
+++ b/gdb/arm-fbsd-nat.c
@@ -18,8 +18,11 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "inferior.h"
 #include "target.h"
 
+#include "elf/common.h"
+
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <machine/reg.h>
@@ -49,6 +52,9 @@ arm_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
   fetch_register_set<struct vfpreg> (regcache, regnum, PT_GETVFPREGS,
 				     &arm_fbsd_vfpregset);
 #endif
+#ifdef PT_GETREGSET
+  fetch_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tlsregset);
+#endif
 }
 
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
@@ -63,6 +69,9 @@ arm_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
   store_register_set<struct vfpreg> (regcache, regnum, PT_GETVFPREGS,
 				     PT_SETVFPREGS, &arm_fbsd_vfpregset);
 #endif
+#ifdef PT_GETREGSET
+  store_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tlsregset);
+#endif
 }
 
 /* Implement the to_read_description method.  */
@@ -71,8 +80,12 @@ const struct target_desc *
 arm_fbsd_nat_target::read_description ()
 {
   const struct target_desc *desc;
+  bool tls = false;
 
-  desc = arm_fbsd_read_description_auxv (this, false);
+#ifdef PT_GETREGSET
+  tls = have_regset (inferior_ptid, NT_ARM_TLS) != 0;
+#endif
+  desc = arm_fbsd_read_description_auxv (this, tls);
   if (desc == NULL)
     desc = this->beneath ()->read_description ();
   return desc;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 07/14] Add an aarch64-tls feature which includes the tpidr register.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (5 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 06/14] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 08/14] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64 John Baldwin
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/aarch64-linux-nat.c          |  3 ++-
 gdb/aarch64-linux-tdep.c         |  2 +-
 gdb/aarch64-tdep.c               | 30 +++++++++++++++++++++++-------
 gdb/aarch64-tdep.h               | 10 +++++++++-
 gdb/arch/aarch64.c               |  7 ++++++-
 gdb/arch/aarch64.h               |  9 +++++++--
 gdb/features/Makefile            |  1 +
 gdb/features/aarch64-tls.c       | 14 ++++++++++++++
 gdb/features/aarch64-tls.xml     | 11 +++++++++++
 gdbserver/linux-aarch64-tdesc.cc |  2 +-
 gdbserver/netbsd-aarch64-low.cc  |  2 +-
 11 files changed, 76 insertions(+), 15 deletions(-)
 create mode 100644 gdb/features/aarch64-tls.c
 create mode 100644 gdb/features/aarch64-tls.xml

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 7bb82d17cc8..4da274c285a 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -646,7 +646,8 @@ aarch64_linux_nat_target::read_description ()
   bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
   bool mte_p = hwcap2 & HWCAP2_MTE;
 
-  return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p);
+  return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p,
+				   false);
 }
 
 /* Convert a native/host siginfo object, into/from the siginfo in the
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 55094b3d88b..8cfb64d9f4a 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -763,7 +763,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
   bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
   bool mte_p = hwcap2 & HWCAP2_MTE;
   return aarch64_read_description (aarch64_linux_core_read_vq (gdbarch, abfd),
-				   pauth_p, mte_p);
+				   pauth_p, mte_p, false);
 }
 
 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index fb1434c97a3..e1046eae59f 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -58,7 +58,7 @@
 #define HA_MAX_NUM_FLDS		4
 
 /* All possible aarch64 target descriptors.  */
-static target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */];
+static target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */][2 /* tls */];
 
 /* The standard register names, and all the valid aliases for them.  */
 static const struct
@@ -3327,21 +3327,23 @@ aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch)
    If VQ is zero then it is assumed SVE is not supported.
    (It is not possible to set VQ to zero on an SVE system).
 
-   MTE_P indicates the presence of the Memory Tagging Extension feature. */
+   MTE_P indicates the presence of the Memory Tagging Extension feature.
+
+   TLS_P indicates the presence of the Thread Local Storage feature.  */
 
 const target_desc *
-aarch64_read_description (uint64_t vq, bool pauth_p, bool mte_p)
+aarch64_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);
-      tdesc_aarch64_list[vq][pauth_p][mte_p] = tdesc;
+      tdesc = aarch64_create_target_description (vq, pauth_p, mte_p, tls_p);
+      tdesc_aarch64_list[vq][pauth_p][mte_p][tls_p] = tdesc;
     }
 
   return tdesc;
@@ -3462,7 +3464,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      value.  */
   const struct target_desc *tdesc = info.target_desc;
   if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc))
-    tdesc = aarch64_read_description (vq, false, false);
+    tdesc = aarch64_read_description (vq, false, false, false);
   gdb_assert (tdesc);
 
   feature_core = tdesc_find_feature (tdesc,"org.gnu.gdb.aarch64.core");
@@ -3471,6 +3473,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   feature_pauth = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.pauth");
   const struct tdesc_feature *feature_mte
     = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.mte");
+  const struct tdesc_feature *feature_tls
+    = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.tls");
 
   if (feature_core == nullptr)
     return nullptr;
@@ -3525,6 +3529,17 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       num_pseudo_regs += 32;	/* add the Bn scalar register pseudos */
     }
 
+  /* Add the TLS register.  */
+  if (feature_tls != nullptr)
+    {
+      /* Validate the descriptor provides the mandatory TLS register
+	 and allocate its number.  */
+      valid_p = tdesc_numbered_register (feature_tls, tdesc_data.get (),
+					 AARCH64_TPIDR_REGNUM, "tpidr");
+
+      num_regs = AARCH64_TPIDR_REGNUM + 1;
+    }
+
   /* Add the pauth registers.  */
   if (feature_pauth != NULL)
     {
@@ -3573,6 +3588,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1
 				: pauth_ra_state_offset + num_regs;
   tdep->mte_reg_base = first_mte_regnum;
+  tdep->tls_p = feature_tls != nullptr;
 
   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 60a9d5a29c2..924c2aa7f0b 100644
--- a/gdb/aarch64-tdep.h
+++ b/gdb/aarch64-tdep.h
@@ -111,10 +111,18 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep
   {
     return mte_reg_base != -1;
   }
+
+  /* True if the target supports the TLS register.  */
+  bool tls_p = false;
+
+  bool has_tls() const
+  {
+    return tls_p;
+  }
 };
 
 const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p,
-					     bool mte_p);
+					     bool mte_p, bool tls_p);
 
 extern int aarch64_process_record (struct gdbarch *gdbarch,
 			       struct regcache *regcache, CORE_ADDR addr);
diff --git a/gdb/arch/aarch64.c b/gdb/arch/aarch64.c
index 485d667ccde..733a3fd6d2a 100644
--- a/gdb/arch/aarch64.c
+++ b/gdb/arch/aarch64.c
@@ -24,11 +24,13 @@
 #include "../features/aarch64-sve.c"
 #include "../features/aarch64-pauth.c"
 #include "../features/aarch64-mte.c"
+#include "../features/aarch64-tls.c"
 
 /* See arch/aarch64.h.  */
 
 target_desc *
-aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p)
+aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p,
+				   bool tls_p)
 {
   target_desc_up tdesc = allocate_target_description ();
 
@@ -52,5 +54,8 @@ aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p)
   if (mte_p)
     regnum = create_feature_aarch64_mte (tdesc.get (), regnum);
 
+  if (tls_p)
+    regnum = create_feature_aarch64_tls (tdesc.get (), regnum);
+
   return tdesc.release ();
 }
diff --git a/gdb/arch/aarch64.h b/gdb/arch/aarch64.h
index e416e346e9a..64a0cae8822 100644
--- a/gdb/arch/aarch64.h
+++ b/gdb/arch/aarch64.h
@@ -29,6 +29,7 @@ struct aarch64_features
   bool sve = false;
   bool pauth = false;
   bool mte = false;
+  bool tls = false;
 };
 
 /* Create the aarch64 target description.  A non zero VQ value indicates both
@@ -36,10 +37,12 @@ struct aarch64_features
    an SVE Z register.  HAS_PAUTH_P indicates the presence of the PAUTH
    feature.
 
-   MTE_P indicates the presence of the Memory Tagging Extension feature.  */
+   MTE_P indicates the presence of the Memory Tagging Extension feature.
+
+   TLS_P indicates the presence of the Thread Local Storage feature.  */
 
 target_desc *aarch64_create_target_description (uint64_t vq, bool has_pauth_p,
-						bool mte_p);
+						bool mte_p, bool tls_p);
 
 /* Register numbers of various important registers.
    Note that on SVE, the Z registers reuse the V register numbers and the V
@@ -63,6 +66,7 @@ enum aarch64_regnum
 							   register.  */
   AARCH64_SVE_FFR_REGNUM,	/* SVE First Fault Register.  */
   AARCH64_SVE_VG_REGNUM,	/* SVE Vector Granule.  */
+  AARCH64_TPIDR_REGNUM,		/* Thread/Process ID Register.  */
 
   /* Other useful registers.  */
   AARCH64_LAST_X_ARG_REGNUM = AARCH64_X0_REGNUM + 7,
@@ -91,6 +95,7 @@ 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:
 
diff --git a/gdb/features/Makefile b/gdb/features/Makefile
index 3fadc5091fa..b9efd3e63ed 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -198,6 +198,7 @@ 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
new file mode 100644
index 00000000000..30d730dffba
--- /dev/null
+++ b/gdb/features/aarch64-tls.c
@@ -0,0 +1,14 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: aarch64-tls.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_aarch64_tls (struct target_desc *result, long regnum)
+{
+  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");
+  return regnum;
+}
diff --git a/gdb/features/aarch64-tls.xml b/gdb/features/aarch64-tls.xml
new file mode 100644
index 00000000000..f6437785f71
--- /dev/null
+++ b/gdb/features/aarch64-tls.xml
@@ -0,0 +1,11 @@
+<?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/gdbserver/linux-aarch64-tdesc.cc b/gdbserver/linux-aarch64-tdesc.cc
index e982ab85067..14d6a4f80eb 100644
--- a/gdbserver/linux-aarch64-tdesc.cc
+++ b/gdbserver/linux-aarch64-tdesc.cc
@@ -42,7 +42,7 @@ aarch64_linux_read_description (uint64_t vq, bool pauth_p, bool mte_p)
 
   if (tdesc == NULL)
     {
-      tdesc = aarch64_create_target_description (vq, pauth_p, mte_p);
+      tdesc = aarch64_create_target_description (vq, pauth_p, mte_p, false);
 
       static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
       static const char *expedite_regs_aarch64_sve[] = { "x29", "sp", "pc",
diff --git a/gdbserver/netbsd-aarch64-low.cc b/gdbserver/netbsd-aarch64-low.cc
index 202bf1cdac6..b371e599232 100644
--- a/gdbserver/netbsd-aarch64-low.cc
+++ b/gdbserver/netbsd-aarch64-low.cc
@@ -96,7 +96,7 @@ void
 netbsd_aarch64_target::low_arch_setup ()
 {
   target_desc *tdesc
-    = aarch64_create_target_description (0, false);
+    = aarch64_create_target_description (0, false, false, false);
 
   static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
   init_target_desc (tdesc, expedite_regs_aarch64);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 08/14] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (6 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 07/14] Add an aarch64-tls feature which includes the tpidr register John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 09/14] Support TLS variables " John Baldwin
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/aarch64-fbsd-tdep.c | 32 ++++++++++++++++++++++++++++++++
 gdb/aarch64-fbsd-tdep.h |  4 ++++
 2 files changed, 36 insertions(+)

diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index 32f441892a8..91fccb36105 100644
--- a/gdb/aarch64-fbsd-tdep.c
+++ b/gdb/aarch64-fbsd-tdep.c
@@ -49,6 +49,12 @@ static const struct regcache_map_entry aarch64_fbsd_fpregmap[] =
     { 0 }
   };
 
+static const struct regcache_map_entry aarch64_fbsd_tls_regmap[] =
+  {
+    { 1, AARCH64_TPIDR_REGNUM, 8 },
+    { 0 }
+  };
+
 /* In a signal frame, sp points to a 'struct sigframe' which is
    defined as:
 
@@ -134,6 +140,12 @@ const struct regset aarch64_fbsd_fpregset =
     regcache_supply_regset, regcache_collect_regset
   };
 
+const struct regset aarch64_fbsd_tls_regset =
+  {
+    aarch64_fbsd_tls_regmap,
+    regcache_supply_regset, regcache_collect_regset
+  };
+
 /* Implement the "iterate_over_regset_sections" gdbarch method.  */
 
 static void
@@ -142,10 +154,28 @@ aarch64_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
 					   void *cb_data,
 					   const struct regcache *regcache)
 {
+  aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
   cb (".reg", AARCH64_FBSD_SIZEOF_GREGSET, AARCH64_FBSD_SIZEOF_GREGSET,
       &aarch64_fbsd_gregset, NULL, cb_data);
   cb (".reg2", AARCH64_FBSD_SIZEOF_FPREGSET, AARCH64_FBSD_SIZEOF_FPREGSET,
       &aarch64_fbsd_fpregset, NULL, cb_data);
+
+  if (tdep->has_tls ())
+    cb (".reg-aarch-tls", AARCH64_FBSD_SIZEOF_TLSREGSET,
+	AARCH64_FBSD_SIZEOF_TLSREGSET, &aarch64_fbsd_tls_regset,
+	"TLS register", cb_data);
+}
+
+/* Implement the "core_read_description" gdbarch method.  */
+
+static const struct target_desc *
+aarch64_fbsd_core_read_description (struct gdbarch *gdbarch,
+				    struct target_ops *target, bfd *abfd)
+{
+  asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
+
+  return aarch64_read_description (0, false, false, tls != nullptr);
 }
 
 /* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
@@ -168,6 +198,8 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_iterate_over_regset_sections
     (gdbarch, aarch64_fbsd_iterate_over_regset_sections);
+  set_gdbarch_core_read_description (gdbarch,
+				     aarch64_fbsd_core_read_description);
 }
 
 void _initialize_aarch64_fbsd_tdep ();
diff --git a/gdb/aarch64-fbsd-tdep.h b/gdb/aarch64-fbsd-tdep.h
index fc8fbee8843..eaf0774f595 100644
--- a/gdb/aarch64-fbsd-tdep.h
+++ b/gdb/aarch64-fbsd-tdep.h
@@ -32,7 +32,11 @@
    alignment.  */
 #define AARCH64_FBSD_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
 
+/* The TLS regset consists of a single register.  */
+#define	AARCH64_FBSD_SIZEOF_TLSREGSET (X_REGISTER_SIZE)
+
 extern const struct regset aarch64_fbsd_gregset;
 extern const struct regset aarch64_fbsd_fpregset;
+extern const struct regset aarch64_fbsd_tls_regset;
 
 #endif /* AARCH64_FBSD_TDEP_H */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 09/14] Support TLS variables on FreeBSD/Aarch64.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (7 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 08/14] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64 John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 10/14] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes John Baldwin
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

Derive the pointer to the DTV array from the tpidr register.
---
 gdb/aarch64-fbsd-tdep.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index 91fccb36105..bd422a8c687 100644
--- a/gdb/aarch64-fbsd-tdep.c
+++ b/gdb/aarch64-fbsd-tdep.c
@@ -23,6 +23,7 @@
 #include "fbsd-tdep.h"
 #include "aarch64-tdep.h"
 #include "aarch64-fbsd-tdep.h"
+#include "inferior.h"
 #include "osabi.h"
 #include "solib-svr4.h"
 #include "target.h"
@@ -178,6 +179,29 @@ aarch64_fbsd_core_read_description (struct gdbarch *gdbarch,
   return aarch64_read_description (0, false, false, tls != nullptr);
 }
 
+/* Implement the get_thread_local_address gdbarch method.  */
+
+static CORE_ADDR
+aarch64_fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
+				       CORE_ADDR lm_addr, CORE_ADDR offset)
+{
+  struct regcache *regcache;
+
+  regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+				       ptid, gdbarch);
+
+  target_fetch_registers (regcache, AARCH64_TPIDR_REGNUM);
+
+  ULONGEST tpidr;
+  if (regcache->cooked_read (AARCH64_TPIDR_REGNUM, &tpidr) != REG_VALID)
+    error (_("Unable to fetch %%tpidr"));
+
+  /* %tpidr points to the TCB whose first member is the dtv
+      pointer.  */
+  CORE_ADDR dtv_addr = tpidr;
+  return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
+}
+
 /* Implement the 'init_osabi' method of struct gdb_osabi_handler.  */
 
 static void
@@ -200,6 +224,11 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (gdbarch, aarch64_fbsd_iterate_over_regset_sections);
   set_gdbarch_core_read_description (gdbarch,
 				     aarch64_fbsd_core_read_description);
+
+  set_gdbarch_fetch_tls_load_module_address (gdbarch,
+					     svr4_fetch_objfile_link_map);
+  set_gdbarch_get_thread_local_address (gdbarch,
+					aarch64_fbsd_get_thread_local_address);
 }
 
 void _initialize_aarch64_fbsd_tdep ();
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 10/14] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (8 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 09/14] Support TLS variables " John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 11/14] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

This permits resolving TLS variables.
---
 gdb/aarch64-fbsd-nat.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
index 99e2bf35276..6a6b6618fd6 100644
--- a/gdb/aarch64-fbsd-nat.c
+++ b/gdb/aarch64-fbsd-nat.c
@@ -24,12 +24,15 @@
 #include "target.h"
 #include "nat/aarch64-hw-point.h"
 
+#include "elf/common.h"
+
 #include <sys/param.h>
 #include <sys/ptrace.h>
 #include <machine/armreg.h>
 #include <machine/reg.h>
 
 #include "fbsd-nat.h"
+#include "aarch64-tdep.h"
 #include "aarch64-fbsd-tdep.h"
 #include "aarch64-nat.h"
 #include "inf-ptrace.h"
@@ -50,6 +53,8 @@ struct aarch64_fbsd_nat_target final : public fbsd_nat_target
   void fetch_registers (struct regcache *, int) override;
   void store_registers (struct regcache *, int) override;
 
+  const struct target_desc *read_description () override;
+
 #ifdef HAVE_DBREG
   /* Hardware breakpoints and watchpoints.  */
   bool stopped_by_watchpoint () override;
@@ -84,6 +89,12 @@ aarch64_fbsd_nat_target::fetch_registers (struct regcache *regcache,
 				  &aarch64_fbsd_gregset);
   fetch_register_set<struct fpreg> (regcache, regnum, PT_GETFPREGS,
 				    &aarch64_fbsd_fpregset);
+
+  gdbarch *gdbarch = regcache->arch ();
+  aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  if (tdep->has_tls ())
+    fetch_regset<uint64_t> (regcache, regnum, NT_ARM_TLS,
+			    &aarch64_fbsd_tls_regset);
 }
 
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
@@ -97,6 +108,21 @@ aarch64_fbsd_nat_target::store_registers (struct regcache *regcache,
 				  &aarch64_fbsd_gregset);
   store_register_set<struct fpreg> (regcache, regnum, PT_GETFPREGS,
 				    PT_SETFPREGS, &aarch64_fbsd_fpregset);
+
+  gdbarch *gdbarch = regcache->arch ();
+  aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  if (tdep->has_tls ())
+    store_regset<uint64_t> (regcache, regnum, NT_ARM_TLS,
+			    &aarch64_fbsd_tls_regset);
+}
+
+/* Implement the target read_description method.  */
+
+const struct target_desc *
+aarch64_fbsd_nat_target::read_description ()
+{
+  bool tls = have_regset (inferior_ptid, NT_ARM_TLS) != 0;
+  return aarch64_read_description (0, false, false, tls);
 }
 
 #ifdef HAVE_DBREG
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 11/14] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (9 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 10/14] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-13  2:31   ` Eli Zaretskii
  2022-04-12 23:46 ` [PATCH v2 12/14] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64 John Baldwin
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/NEWS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gdb/NEWS b/gdb/NEWS
index 760cb2b7abc..c9c3bf5fa42 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,9 @@
 
 *** Changes since GDB 12
 
+* Support for Thread Local Storage (TLS) variables on FreeBSD arm and
+  aarch64 architectures.
+
 * GDB now supports hardware watchpoints on FreeBSD/Aarch64.
 
 * Remove support for building against Python 2, it is now only possible to
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 12/14] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (10 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 11/14] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 13/14] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux John Baldwin
  2022-04-12 23:46 ` [PATCH v2 14/14] " John Baldwin
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

---
 gdb/aarch64-linux-tdep.c | 20 +++++++++++++++++++-
 gdb/aarch64-linux-tdep.h |  4 ++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 8cfb64d9f4a..e29b29523bb 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -479,6 +479,12 @@ static const struct regcache_map_entry aarch64_linux_fpregmap[] =
     { 0 }
   };
 
+static const struct regcache_map_entry aarch64_linux_tls_regmap[] =
+  {
+    { 1, AARCH64_TPIDR_REGNUM, 8 },
+    { 0 }
+  };
+
 /* Register set definitions.  */
 
 const struct regset aarch64_linux_gregset =
@@ -493,6 +499,12 @@ const struct regset aarch64_linux_fpregset =
     regcache_supply_regset, regcache_collect_regset
   };
 
+const struct regset aarch64_linux_tls_regset =
+  {
+    aarch64_linux_tls_regmap,
+    regcache_supply_regset, regcache_collect_regset
+  };
+
 /* The fields in an SVE header at the start of a SVE regset.  */
 
 #define SVE_HEADER_SIZE_LENGTH		4
@@ -749,6 +761,11 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 	  AARCH64_LINUX_SIZEOF_MTE_REGSET, &aarch64_linux_mte_regset,
 	  "MTE registers", cb_data);
     }
+
+  if (tdep->has_tls ())
+    cb (".reg-aarch-tls", AARCH64_LINUX_SIZEOF_TLSREGSET,
+	AARCH64_LINUX_SIZEOF_TLSREGSET, &aarch64_linux_tls_regset,
+	"TLS register", cb_data);
 }
 
 /* Implement the "core_read_description" gdbarch method.  */
@@ -757,13 +774,14 @@ 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);
 
   bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
   bool mte_p = hwcap2 & HWCAP2_MTE;
   return aarch64_read_description (aarch64_linux_core_read_vq (gdbarch, abfd),
-				   pauth_p, mte_p, false);
+				   pauth_p, mte_p, tls != nullptr);
 }
 
 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
index 8ae33efc605..6f5a671cb6e 100644
--- a/gdb/aarch64-linux-tdep.h
+++ b/gdb/aarch64-linux-tdep.h
@@ -39,8 +39,12 @@
 /* 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;
+extern const struct regset aarch64_linux_tls_regset;
 
 /* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h.  */
 #define AARCH64_HWCAP_PACA (1 << 30)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 13/14] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (11 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 12/14] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64 John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  2022-04-12 23:46 ` [PATCH v2 14/14] " John Baldwin
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

XXX: This currently assumes NT_ARM_TLS is always available rather than
doing a runtime test.
---
 gdbserver/linux-aarch64-ipa.cc   |  8 ++++----
 gdbserver/linux-aarch64-low.cc   | 28 +++++++++++++++++++++++++++-
 gdbserver/linux-aarch64-tdesc.cc | 11 ++++++-----
 gdbserver/linux-aarch64-tdesc.h  |  2 +-
 4 files changed, 38 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..b265f91a657 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -287,6 +287,22 @@ 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)
+{
+  collect_register (regcache, AARCH64_TPIDR_REGNUM, buf);
+}
+
+/* Store TLS register to regcache.  */
+
+static void
+aarch64_store_tlsregset (struct regcache *regcache, const void *buf)
+{
+  supply_register (regcache, AARCH64_TPIDR_REGNUM, buf);
+}
+
 bool
 aarch64_target::low_supports_breakpoints ()
 {
@@ -719,6 +735,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 +790,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 +826,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 */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 14/14] Read the tpidr register from NT_ARM_TLS on Linux.
  2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
                   ` (12 preceding siblings ...)
  2022-04-12 23:46 ` [PATCH v2 13/14] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux John Baldwin
@ 2022-04-12 23:46 ` John Baldwin
  13 siblings, 0 replies; 16+ messages in thread
From: John Baldwin @ 2022-04-12 23:46 UTC (permalink / raw)
  To: gdb-patches

XXX: This currently assumes NT_ARM_TLS is always available rather than
doing a runtime test.
---
 gdb/aarch64-linux-nat.c | 56 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 4da274c285a..96ed282410c 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -431,6 +431,48 @@ store_mteregs_to_thread (struct regcache *regcache)
     perror_with_name (_("unable to store MTE registers."));
 }
 
+/* Fill GDB's register array with the TLS register values from
+   the current thread.  */
+
+static void
+fetch_tlsregs_from_thread (struct regcache *regcache)
+{
+  uint64_t tpidr = 0;
+  struct iovec iovec;
+
+  iovec.iov_base = &tpidr;
+  iovec.iov_len = sizeof (tpidr);
+
+  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."));
+
+  regcache->raw_supply (AARCH64_TPIDR_REGNUM, &tpidr);
+}
+
+/* Store to the current thread the valid TLS register set in GDB's
+   register array.  */
+
+static void
+store_tlsregs_to_thread (struct regcache *regcache)
+{
+  uint64_t tpidr = 0;
+
+  if (REG_VALID != regcache->get_register_status (AARCH64_TPIDR_REGNUM))
+    return;
+
+  regcache->raw_collect (AARCH64_TPIDR_REGNUM, (char *) &tpidr);
+
+  struct iovec iovec;
+
+  iovec.iov_base = &tpidr;
+  iovec.iov_len = sizeof (tpidr);
+
+  int tid = get_ptrace_pid (regcache->ptid ());
+  if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
+    perror_with_name (_("unable to store TLS register."));
+}
+
 /* Implement the "fetch_registers" target_ops method.  */
 
 void
@@ -453,6 +495,9 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
 
       if (tdep->has_mte ())
 	fetch_mteregs_from_thread (regcache);
+
+      if (tdep->has_tls ())
+	fetch_tlsregs_from_thread (regcache);
     }
   else if (regno < AARCH64_V0_REGNUM)
     fetch_gregs_from_thread (regcache);
@@ -472,6 +517,9 @@ aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
   if (tdep->has_mte ()
       && (regno == tdep->mte_reg_base))
     fetch_mteregs_from_thread (regcache);
+
+  if (tdep->has_tls () && regno == AARCH64_TPIDR_REGNUM)
+    fetch_tlsregs_from_thread (regcache);
 }
 
 /* Implement the "store_registers" target_ops method.  */
@@ -493,6 +541,9 @@ aarch64_linux_nat_target::store_registers (struct regcache *regcache,
 
       if (tdep->has_mte ())
 	store_mteregs_to_thread (regcache);
+
+      if (tdep->has_tls ())
+	store_tlsregs_to_thread (regcache);
     }
   else if (regno < AARCH64_V0_REGNUM)
     store_gregs_to_thread (regcache);
@@ -505,6 +556,9 @@ aarch64_linux_nat_target::store_registers (struct regcache *regcache,
   if (tdep->has_mte ()
       && (regno == tdep->mte_reg_base))
     store_mteregs_to_thread (regcache);
+
+  if (tdep->has_tls () && regno == AARCH64_TPIDR_REGNUM)
+    store_tlsregs_to_thread (regcache);
 }
 
 /* Fill register REGNO (if it is a general-purpose register) in
@@ -647,7 +701,7 @@ aarch64_linux_nat_target::read_description ()
   bool mte_p = hwcap2 & HWCAP2_MTE;
 
   return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p,
-				   false);
+				   true);
 }
 
 /* Convert a native/host siginfo object, into/from the siginfo in the
-- 
2.34.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 11/14] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64.
  2022-04-12 23:46 ` [PATCH v2 11/14] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
@ 2022-04-13  2:31   ` Eli Zaretskii
  0 siblings, 0 replies; 16+ messages in thread
From: Eli Zaretskii @ 2022-04-13  2:31 UTC (permalink / raw)
  To: John Baldwin; +Cc: gdb-patches

> From: John Baldwin <jhb@FreeBSD.org>
> Date: Tue, 12 Apr 2022 16:46:44 -0700
> X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, FORGED_SPF_HELO,
>  GIT_PATCH_0, KAM_DMARC_STATUS, KHOP_HELO_FCRDNS, SPF_HELO_PASS, SPF_SOFTFAIL,
>  TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4
> 
> ---
>  gdb/NEWS | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 760cb2b7abc..c9c3bf5fa42 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -3,6 +3,9 @@
>  
>  *** Changes since GDB 12
>  
> +* Support for Thread Local Storage (TLS) variables on FreeBSD arm and
> +  aarch64 architectures.
> +
>  * GDB now supports hardware watchpoints on FreeBSD/Aarch64.
>  
>  * Remove support for building against Python 2, it is now only possible to

Thanks, this is OK.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-04-13  2:32 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-12 23:46 [PATCH v2 00/14] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
2022-04-12 23:46 ` [PATCH v2 01/14] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
2022-04-12 23:46 ` [PATCH v2 02/14] Create pseudo sections for NT_ARM_TLS notes on FreeBSD John Baldwin
2022-04-12 23:46 ` [PATCH v2 03/14] Add an arm-tls feature which includes the tpidruro register from CP15 John Baldwin
2022-04-12 23:46 ` [PATCH v2 04/14] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm John Baldwin
2022-04-12 23:46 ` [PATCH v2 05/14] Support TLS variables " John Baldwin
2022-04-12 23:46 ` [PATCH v2 06/14] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes John Baldwin
2022-04-12 23:46 ` [PATCH v2 07/14] Add an aarch64-tls feature which includes the tpidr register John Baldwin
2022-04-12 23:46 ` [PATCH v2 08/14] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64 John Baldwin
2022-04-12 23:46 ` [PATCH v2 09/14] Support TLS variables " John Baldwin
2022-04-12 23:46 ` [PATCH v2 10/14] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes John Baldwin
2022-04-12 23:46 ` [PATCH v2 11/14] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
2022-04-13  2:31   ` Eli Zaretskii
2022-04-12 23:46 ` [PATCH v2 12/14] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64 John Baldwin
2022-04-12 23:46 ` [PATCH v2 13/14] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux John Baldwin
2022-04-12 23:46 ` [PATCH v2 14/14] " John Baldwin

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