* [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures.
@ 2022-04-27 15:14 John Baldwin
2022-04-27 15:14 ` [PATCH v3 01/13] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
` (12 more replies)
0 siblings, 13 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
Changes since V2:
- Both arm and Aarch64 use a dynamically allocated register number
whose value is stored in the arch-specific tdep structure as
requested by Luis.
- I dropped the XXX comments about missing tests for NT_ARM_TLS on
Linux on the assumption that it is ok to just assume they are
always present given it was added to the kernel in 2012.
- I went ahead and pushed the binutils change to handle NT_ARM_TLS
notes on FreeBSD as it was approved previously.
The NEWS blurb has been approved previously.
I have tested this on FreeBSD/armv7, FreeBSD/aarch64, and Linux Aarch64.
John Baldwin (13):
fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET.
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.
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.
NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64.
gdb/NEWS | 3 ++
gdb/aarch64-fbsd-nat.c | 54 +++++++++++++++++++++++
gdb/aarch64-fbsd-tdep.c | 67 ++++++++++++++++++++++++++++
gdb/aarch64-fbsd-tdep.h | 3 ++
gdb/aarch64-linux-nat.c | 69 ++++++++++++++++++++++++++++-
gdb/aarch64-linux-tdep.c | 21 ++++++++-
gdb/aarch64-linux-tdep.h | 3 ++
gdb/aarch64-tdep.c | 33 ++++++++++----
gdb/aarch64-tdep.h | 10 ++++-
gdb/arch/aarch32.c | 2 +
gdb/arch/aarch64.c | 7 ++-
gdb/arch/aarch64.h | 8 +++-
gdb/arch/arm.c | 6 ++-
gdb/arch/arm.h | 2 +-
gdb/arm-fbsd-nat.c | 52 +++++++++++++++++++++-
gdb/arm-fbsd-tdep.c | 65 ++++++++++++++++++++++++---
gdb/arm-fbsd-tdep.h | 5 ++-
gdb/arm-linux-nat.c | 6 +--
gdb/arm-linux-tdep.c | 4 +-
gdb/arm-netbsd-nat.c | 4 +-
gdb/arm-tdep.c | 25 ++++++++---
gdb/arm-tdep.h | 4 +-
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 | 32 +++++++++++++-
gdbserver/linux-aarch64-tdesc.cc | 11 ++---
gdbserver/linux-aarch64-tdesc.h | 2 +-
gdbserver/netbsd-aarch64-low.cc | 2 +-
34 files changed, 624 insertions(+), 49 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] 15+ messages in thread
* [PATCH v3 01/13] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 02/13] Add an arm-tls feature which includes the tpidruro register from CP15 John Baldwin
` (11 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 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] 15+ messages in thread
* [PATCH v3 02/13] Add an arm-tls feature which includes the tpidruro register from CP15.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
2022-04-27 15:14 ` [PATCH v3 01/13] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 03/13] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm John Baldwin
` (10 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/arch/aarch32.c | 2 ++
gdb/arch/arm.c | 6 +++++-
gdb/arch/arm.h | 2 +-
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 | 25 ++++++++++++++++++++-----
gdb/arm-tdep.h | 4 +++-
gdb/features/Makefile | 1 +
gdb/features/arm/arm-tls.c | 14 ++++++++++++++
gdb/features/arm/arm-tls.xml | 11 +++++++++++
12 files changed, 66 insertions(+), 17 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 bc6e5ce3f09..14f0a7a7f6c 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"
@@ -374,7 +375,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 ();
@@ -410,6 +411,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 0728bea1501..4ad329f6f1f 100644
--- a/gdb/arch/arm.h
+++ b/gdb/arch/arm.h
@@ -207,7 +207,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 7274752c2b9..cb7589af83a 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -240,7 +240,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
@@ -9606,6 +9606,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
int m_profile_psp_ns_regnum = -1;
int m_profile_msp_s_regnum = -1;
int m_profile_psp_s_regnum = -1;
+ int tls_regnum = 0;
/* If we have an object to base this architecture on, try to determine
its ABI. */
@@ -9973,6 +9974,19 @@ 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 (),
+ register_count, "tpidruro");
+ if (!valid_p)
+ return nullptr;
+
+ tls_regnum = register_count;
+ register_count++;
+ }
+
/* Check for MVE after all the checks for GPR's, VFP and Neon.
MVE (Helium) is an M-profile extension. */
if (is_m)
@@ -10128,6 +10142,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->have_s_pseudos = have_s_pseudos;
tdep->have_q_pseudos = have_q_pseudos;
tdep->have_neon = have_neon;
+ tdep->tls_regnum = tls_regnum;
/* Adjust the MVE feature settings. */
if (have_mve)
@@ -14416,14 +14431,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 864406e98d2..0fc4774a20c 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -134,6 +134,8 @@ struct arm_gdbarch_tdep : gdbarch_tdep
int m_profile_msp_s_regnum = ARM_SP_REGNUM; /* M-profile MSP_S register number. */
int m_profile_psp_s_regnum = ARM_SP_REGNUM; /* M-profile PSP_S register number. */
+ int tls_regnum = 0; /* Number of the tpidruro register. */
+
bool is_m = false; /* Does the target follow the "M" profile. */
bool have_sec_ext = false; /* Do we have security extensions? */
CORE_ADDR lowest_pc = 0; /* Lowest address at which instructions
@@ -317,7 +319,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 737d9cbd3db..5f1826baa6f 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -208,6 +208,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
arm/arm-m-profile-mve.xml \
arm/arm-m-system.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] 15+ messages in thread
* [PATCH v3 03/13] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
2022-04-27 15:14 ` [PATCH v3 01/13] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
2022-04-27 15:14 ` [PATCH v3 02/13] Add an arm-tls feature which includes the tpidruro register from CP15 John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 04/13] Support TLS variables " John Baldwin
` (9 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/arm-fbsd-nat.c | 2 +-
gdb/arm-fbsd-tdep.c | 32 ++++++++++++++++++++++++++------
gdb/arm-fbsd-tdep.h | 5 ++++-
3 files changed, 31 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..a27dfb2fb4a 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -163,6 +163,24 @@ 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);
+ if (tdep->tls_regnum > 0)
+ {
+ const struct regcache_map_entry arm_fbsd_tlsregmap[] =
+ {
+ { 1, tdep->tls_regnum, 4 },
+ { 0 }
+ };
+
+ const struct regset arm_fbsd_tlsregset =
+ {
+ arm_fbsd_tlsregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+ 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
kernel but just contains all zeroes. */
@@ -175,12 +193,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 +206,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 +221,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..193eb76df3c 100644
--- a/gdb/arm-fbsd-tdep.h
+++ b/gdb/arm-fbsd-tdep.h
@@ -26,6 +26,9 @@
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)
@@ -40,6 +43,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] 15+ messages in thread
* [PATCH v3 04/13] Support TLS variables on FreeBSD/arm.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (2 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 03/13] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 05/13] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes John Baldwin
` (8 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
Derive the pointer to the DTV array from the tpidruro register.
---
gdb/arm-fbsd-tdep.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index a27dfb2fb4a..483820c1092 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"
@@ -226,6 +227,30 @@ 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)
+{
+ arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ struct regcache *regcache;
+
+ regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+ ptid, gdbarch);
+
+ target_fetch_registers (regcache, tdep->tls_regnum);
+
+ ULONGEST tpidruro;
+ if (regcache->cooked_read (tdep->tls_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
@@ -251,6 +276,14 @@ 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);
+ if (tdep->tls_regnum > 0)
+ {
+ 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] 15+ messages in thread
* [PATCH v3 05/13] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (3 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 04/13] Support TLS variables " John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 06/13] Add an aarch64-tls feature which includes the tpidr register John Baldwin
` (7 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
This permits resolving TLS variables.
---
gdb/arm-fbsd-nat.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/gdb/arm-fbsd-nat.c b/gdb/arm-fbsd-nat.c
index c32924de735..a306e1e2ee0 100644
--- a/gdb/arm-fbsd-nat.c
+++ b/gdb/arm-fbsd-nat.c
@@ -18,13 +18,17 @@
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>
#include "fbsd-nat.h"
+#include "arm-tdep.h"
#include "arm-fbsd-tdep.h"
#include "inf-ptrace.h"
@@ -49,6 +53,27 @@ 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
+ gdbarch *gdbarch = regcache->arch ();
+ arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+ if (tdep->tls_regnum > 0)
+ {
+ const struct regcache_map_entry arm_fbsd_tlsregmap[] =
+ {
+ { 1, tdep->tls_regnum, 4 },
+ { 0 }
+ };
+
+ const struct regset arm_fbsd_tlsregset =
+ {
+ arm_fbsd_tlsregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+ 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 +88,27 @@ 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
+ gdbarch *gdbarch = regcache->arch ();
+ arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+
+ if (tdep->tls_regnum > 0)
+ {
+ const struct regcache_map_entry arm_fbsd_tlsregmap[] =
+ {
+ { 1, tdep->tls_regnum, 4 },
+ { 0 }
+ };
+
+ const struct regset arm_fbsd_tlsregset =
+ {
+ arm_fbsd_tlsregmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+ store_regset<uint32_t> (regcache, regnum, NT_ARM_TLS, &arm_fbsd_tlsregset);
+ }
+#endif
}
/* Implement the to_read_description method. */
@@ -71,8 +117,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] 15+ messages in thread
* [PATCH v3 06/13] Add an aarch64-tls feature which includes the tpidr register.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (4 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 05/13] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 07/13] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64 John Baldwin
` (6 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/aarch64-linux-nat.c | 3 ++-
gdb/aarch64-linux-tdep.c | 2 +-
gdb/aarch64-tdep.c | 33 ++++++++++++++++++++++++--------
gdb/aarch64-tdep.h | 10 +++++++++-
gdb/arch/aarch64.c | 7 ++++++-
gdb/arch/aarch64.h | 8 ++++++--
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, 77 insertions(+), 16 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 98eaeaf8ca4..9d06ebfe27c 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;
@@ -3416,7 +3418,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
bool valid_p = true;
int i, num_regs = 0, num_pseudo_regs = 0;
int first_pauth_regnum = -1, pauth_ra_state_offset = -1;
- int first_mte_regnum = -1;
+ int first_mte_regnum = -1, tls_regnum = -1;
/* Use the vector length passed via the target info. Here -1 is used for no
SVE, and 0 is unset. If unset then use the vector length from the existing
@@ -3448,7 +3450,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");
@@ -3457,6 +3459,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;
@@ -3511,6 +3515,18 @@ 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)
+ {
+ tls_regnum = num_regs;
+ /* Validate the descriptor provides the mandatory TLS register
+ and allocate its number. */
+ valid_p = tdesc_numbered_register (feature_tls, tdesc_data.get (),
+ tls_regnum, "tpidr");
+
+ num_regs++;
+ }
+
/* Add the pauth registers. */
if (feature_pauth != NULL)
{
@@ -3559,6 +3575,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_regnum = tls_regnum;
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..e4cdebb6311 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;
}
+
+ /* TLS register. This is -1 if the TLS register is not available. */
+ int tls_regnum = 0;
+
+ bool has_tls() const
+ {
+ return tls_regnum != -1;
+ }
};
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..8496a0341f7 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
@@ -91,6 +94,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 5f1826baa6f..15d623c2681 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] 15+ messages in thread
* [PATCH v3 07/13] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (5 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 06/13] Add an aarch64-tls feature which includes the tpidr register John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 08/13] Support TLS variables " John Baldwin
` (5 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/aarch64-fbsd-tdep.c | 34 ++++++++++++++++++++++++++++++++++
gdb/aarch64-fbsd-tdep.h | 3 +++
2 files changed, 37 insertions(+)
diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index 32f441892a8..ed1b84387f0 100644
--- a/gdb/aarch64-fbsd-tdep.c
+++ b/gdb/aarch64-fbsd-tdep.c
@@ -142,10 +142,42 @@ 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 ())
+ {
+ const struct regcache_map_entry aarch64_fbsd_tls_regmap[] =
+ {
+ { 1, tdep->tls_regnum, 8 },
+ { 0 }
+ };
+
+ const struct regset aarch64_fbsd_tls_regset =
+ {
+ aarch64_fbsd_tls_regmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+ 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 +200,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..7419ea6be03 100644
--- a/gdb/aarch64-fbsd-tdep.h
+++ b/gdb/aarch64-fbsd-tdep.h
@@ -32,6 +32,9 @@
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;
--
2.34.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 08/13] Support TLS variables on FreeBSD/Aarch64.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (6 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 07/13] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64 John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 09/13] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes John Baldwin
` (4 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
Derive the pointer to the DTV array from the tpidr register.
---
gdb/aarch64-fbsd-tdep.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index ed1b84387f0..fdf0795b9bf 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"
@@ -180,6 +181,30 @@ 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)
+{
+ aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ struct regcache *regcache;
+
+ regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
+ ptid, gdbarch);
+
+ target_fetch_registers (regcache, tdep->tls_regnum);
+
+ ULONGEST tpidr;
+ if (regcache->cooked_read (tdep->tls_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
@@ -202,6 +227,14 @@ 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);
+
+ if (tdep->has_tls ())
+ {
+ 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] 15+ messages in thread
* [PATCH v3 09/13] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (7 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 08/13] Support TLS variables " John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 10/13] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64 John Baldwin
` (3 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
This permits resolving TLS variables.
---
gdb/aarch64-fbsd-nat.c | 54 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
index 99e2bf35276..910bf5bb190 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,26 @@ 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 ())
+ {
+ const struct regcache_map_entry aarch64_fbsd_tls_regmap[] =
+ {
+ { 1, tdep->tls_regnum, 8 },
+ { 0 }
+ };
+
+ const struct regset aarch64_fbsd_tls_regset =
+ {
+ aarch64_fbsd_tls_regmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+ 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 +122,35 @@ 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 ())
+ {
+ const struct regcache_map_entry aarch64_fbsd_tls_regmap[] =
+ {
+ { 1, tdep->tls_regnum, 8 },
+ { 0 }
+ };
+
+ const struct regset aarch64_fbsd_tls_regset =
+ {
+ aarch64_fbsd_tls_regmap,
+ regcache_supply_regset, regcache_collect_regset
+ };
+
+ 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] 15+ messages in thread
* [PATCH v3 10/13] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (8 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 09/13] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 11/13] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux John Baldwin
` (2 subsequent siblings)
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/aarch64-linux-tdep.c | 21 ++++++++++++++++++++-
gdb/aarch64-linux-tdep.h | 3 +++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 8cfb64d9f4a..dbebcd4f0e0 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -749,6 +749,24 @@ 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 ())
+ {
+ const struct regcache_map_entry tls_regmap[] =
+ {
+ { 1, tdep->tls_regnum, 8 },
+ { 0 }
+ };
+
+ const struct regset aarch64_linux_tls_regset =
+ {
+ tls_regmap, regcache_supply_regset, regcache_collect_regset
+ };
+
+ cb (".reg-aarch-tls", AARCH64_LINUX_SIZEOF_TLSREGSET,
+ AARCH64_LINUX_SIZEOF_TLSREGSET, &aarch64_linux_tls_regset,
+ "TLS register", cb_data);
+ }
}
/* Implement the "core_read_description" gdbarch method. */
@@ -757,13 +775,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..9a7e4339dba 100644
--- a/gdb/aarch64-linux-tdep.h
+++ b/gdb/aarch64-linux-tdep.h
@@ -39,6 +39,9 @@
/* 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;
--
2.34.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 11/13] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (9 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 10/13] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64 John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 12/13] " John Baldwin
2022-04-27 15:14 ` [PATCH v3 13/13] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdbserver/linux-aarch64-ipa.cc | 8 ++++----
gdbserver/linux-aarch64-low.cc | 32 +++++++++++++++++++++++++++++++-
gdbserver/linux-aarch64-tdesc.cc | 11 ++++++-----
gdbserver/linux-aarch64-tdesc.h | 2 +-
4 files changed, 42 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..c924821c25c 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -287,6 +287,26 @@ aarch64_store_mteregset (struct regcache *regcache, const void *buf)
supply_register (regcache, mte_base, mte_regset);
}
+/* Fill BUF with TLS register from the regcache. */
+
+static void
+aarch64_fill_tlsregset (struct regcache *regcache, void *buf)
+{
+ int tls_regnum = find_regno (regcache->tdesc, "tpidr");
+
+ collect_register (regcache, tls_regnum, buf);
+}
+
+/* Store TLS register to regcache. */
+
+static void
+aarch64_store_tlsregset (struct regcache *regcache, const void *buf)
+{
+ int tls_regnum = find_regno (regcache->tdesc, "tpidr");
+
+ supply_register (regcache, tls_regnum, buf);
+}
+
bool
aarch64_target::low_supports_breakpoints ()
{
@@ -719,6 +739,10 @@ static struct regset_info aarch64_regsets[] =
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_TAGGED_ADDR_CTRL,
0, OPTIONAL_REGS,
aarch64_fill_mteregset, aarch64_store_mteregset },
+ /* TLS register. */
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_TLS,
+ 0, OPTIONAL_REGS,
+ aarch64_fill_tlsregset, aarch64_store_tlsregset },
NULL_REGSET
};
@@ -770,6 +794,10 @@ aarch64_adjust_register_sets (const struct aarch64_features &features)
if (features.mte)
regset->size = AARCH64_LINUX_SIZEOF_MTE;
break;
+ case NT_ARM_TLS:
+ if (features.tls)
+ regset->size = AARCH64_TLS_REGS_SIZE;
+ break;
default:
gdb_assert_not_reached ("Unknown register set found.");
}
@@ -802,9 +830,11 @@ aarch64_target::low_arch_setup ()
features.pauth = linux_get_hwcap (8) & AARCH64_HWCAP_PACA;
/* A-profile MTE is 64-bit only. */
features.mte = linux_get_hwcap2 (8) & HWCAP2_MTE;
+ features.tls = true;
current_process ()->tdesc
- = aarch64_linux_read_description (vq, features.pauth, features.mte);
+ = aarch64_linux_read_description (vq, features.pauth, features.mte,
+ features.tls);
/* Adjust the register sets we should use for this particular set of
features. */
diff --git a/gdbserver/linux-aarch64-tdesc.cc b/gdbserver/linux-aarch64-tdesc.cc
index 14d6a4f80eb..be96612d571 100644
--- a/gdbserver/linux-aarch64-tdesc.cc
+++ b/gdbserver/linux-aarch64-tdesc.cc
@@ -27,22 +27,23 @@
#include <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] 15+ messages in thread
* [PATCH v3 12/13] Read the tpidr register from NT_ARM_TLS on Linux.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (10 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 11/13] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:14 ` [PATCH v3 13/13] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
12 siblings, 0 replies; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/aarch64-linux-nat.c | 68 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 4da274c285a..10b0ca10984 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -431,6 +431,60 @@ 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)
+{
+ aarch64_gdbarch_tdep *tdep
+ = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
+ int regno = tdep->tls_regnum;
+
+ gdb_assert (regno != -1);
+
+ 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 (regno, &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)
+{
+ aarch64_gdbarch_tdep *tdep
+ = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
+ int regno = tdep->tls_regnum;
+
+ gdb_assert (regno != -1);
+
+ uint64_t tpidr = 0;
+
+ if (REG_VALID != regcache->get_register_status (regno))
+ return;
+
+ regcache->raw_collect (regno, (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 +507,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 +529,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 == tdep->tls_regnum)
+ fetch_tlsregs_from_thread (regcache);
}
/* Implement the "store_registers" target_ops method. */
@@ -493,6 +553,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 +568,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 == tdep->tls_regnum)
+ store_tlsregs_to_thread (regcache);
}
/* Fill register REGNO (if it is a general-purpose register) in
@@ -647,7 +713,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] 15+ messages in thread
* [PATCH v3 13/13] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64.
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
` (11 preceding siblings ...)
2022-04-27 15:14 ` [PATCH v3 12/13] " John Baldwin
@ 2022-04-27 15:14 ` John Baldwin
2022-04-27 15:46 ` Eli Zaretskii
12 siblings, 1 reply; 15+ messages in thread
From: John Baldwin @ 2022-04-27 15:14 UTC (permalink / raw)
To: gdb-patches
---
gdb/NEWS | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gdb/NEWS b/gdb/NEWS
index 982f4a1a18c..a72fee81550 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] 15+ messages in thread
* Re: [PATCH v3 13/13] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64.
2022-04-27 15:14 ` [PATCH v3 13/13] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
@ 2022-04-27 15:46 ` Eli Zaretskii
0 siblings, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2022-04-27 15:46 UTC (permalink / raw)
To: John Baldwin; +Cc: gdb-patches
> From: John Baldwin <jhb@FreeBSD.org>
> Date: Wed, 27 Apr 2022 08:14:16 -0700
>
> ---
> gdb/NEWS | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 982f4a1a18c..a72fee81550 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
This part is OK, thanks.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2022-04-27 15:46 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-27 15:14 [PATCH v3 00/13] Support for Thread Local Storage (TLS) variables on FreeBSD arm and aarch64 architectures John Baldwin
2022-04-27 15:14 ` [PATCH v3 01/13] fbsd-nat: Add helper routines for register sets using PT_[G]SETREGSET John Baldwin
2022-04-27 15:14 ` [PATCH v3 02/13] Add an arm-tls feature which includes the tpidruro register from CP15 John Baldwin
2022-04-27 15:14 ` [PATCH v3 03/13] Read the tpidruro register from NT_ARM_TLS core dump notes on FreeBSD/arm John Baldwin
2022-04-27 15:14 ` [PATCH v3 04/13] Support TLS variables " John Baldwin
2022-04-27 15:14 ` [PATCH v3 05/13] Fetch the NT_ARM_TLS register set for native FreeBSD/arm processes John Baldwin
2022-04-27 15:14 ` [PATCH v3 06/13] Add an aarch64-tls feature which includes the tpidr register John Baldwin
2022-04-27 15:14 ` [PATCH v3 07/13] Read the tpidr register from NT_ARM_TLS core dump notes on FreeBSD/Aarch64 John Baldwin
2022-04-27 15:14 ` [PATCH v3 08/13] Support TLS variables " John Baldwin
2022-04-27 15:14 ` [PATCH v3 09/13] Fetch the NT_ARM_TLS register set for native FreeBSD/Aarch64 processes John Baldwin
2022-04-27 15:14 ` [PATCH v3 10/13] Read the tpidr register from NT_ARM_TLS core dump notes on Linux Aarch64 John Baldwin
2022-04-27 15:14 ` [PATCH v3 11/13] gdbserver: Read the tpidr register from NT_ARM_TLS on Linux John Baldwin
2022-04-27 15:14 ` [PATCH v3 12/13] " John Baldwin
2022-04-27 15:14 ` [PATCH v3 13/13] NEWS: Add a note for TLS support on FreeBSD/arm and FreeBSD/Aarch64 John Baldwin
2022-04-27 15:46 ` Eli Zaretskii
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).