* [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,
®s, 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, ®s, 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, ®s, 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
* 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
* [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