diff mbox series

[1/8] nptl: Add <thread_pointer.h> for defining __thread_pointer

Message ID 48b399368593be9675a23e7e2dc53f64c46a94d2.1638880889.git.fweimer@redhat.com
State New
Headers show
Series Extensible rseq integration | expand

Commit Message

Florian Weimer Dec. 7, 2021, 1 p.m. UTC
<tls.h> already contains a definition that is quite similar,
but it is not consistent across architectures.

Only architectures for which rseq support is added are covered.
---
v2: As posted before.

 sysdeps/nptl/thread_pointer.h         | 28 ++++++++++++++++++++
 sysdeps/powerpc/nptl/thread_pointer.h | 33 +++++++++++++++++++++++
 sysdeps/x86/nptl/thread_pointer.h     | 38 +++++++++++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 sysdeps/nptl/thread_pointer.h
 create mode 100644 sysdeps/powerpc/nptl/thread_pointer.h
 create mode 100644 sysdeps/x86/nptl/thread_pointer.h

Comments

Szabolcs Nagy Dec. 8, 2021, 11:05 a.m. UTC | #1
The 12/07/2021 14:00, Florian Weimer via Libc-alpha wrote:
> <tls.h> already contains a definition that is quite similar,
> but it is not consistent across architectures.
> 
> Only architectures for which rseq support is added are covered.

This looks ok.

It's an annoying gcc bug that __builtin_thread_pointer
does not work consistently across targets.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>

> ---
> v2: As posted before.
> 
>  sysdeps/nptl/thread_pointer.h         | 28 ++++++++++++++++++++
>  sysdeps/powerpc/nptl/thread_pointer.h | 33 +++++++++++++++++++++++
>  sysdeps/x86/nptl/thread_pointer.h     | 38 +++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+)
>  create mode 100644 sysdeps/nptl/thread_pointer.h
>  create mode 100644 sysdeps/powerpc/nptl/thread_pointer.h
>  create mode 100644 sysdeps/x86/nptl/thread_pointer.h
> 
> diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h
> new file mode 100644
> index 0000000000..92f2f3093e
> --- /dev/null
> +++ b/sysdeps/nptl/thread_pointer.h
> @@ -0,0 +1,28 @@
> +/* __thread_pointer definition.  Generic version.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_THREAD_POINTER_H
> +#define _SYS_THREAD_POINTER_H
> +
> +static inline void *
> +__thread_pointer (void)
> +{
> +  return __builtin_thread_pointer ();
> +}
> +
> +#endif /* _SYS_THREAD_POINTER_H */
> diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
> new file mode 100644
> index 0000000000..8fd5ba671f
> --- /dev/null
> +++ b/sysdeps/powerpc/nptl/thread_pointer.h
> @@ -0,0 +1,33 @@
> +/* __thread_pointer definition.  powerpc version.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_THREAD_POINTER_H
> +#define _SYS_THREAD_POINTER_H
> +
> +static inline void *
> +__thread_pointer (void)
> +{
> +#ifdef __powerpc64__
> +  register void *__result asm ("r13");
> +#else
> +  register void *__result asm ("r2");
> +#endif
> +  return __result;
> +}
> +
> +#endif /* _SYS_THREAD_POINTER_H */
> diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h
> new file mode 100644
> index 0000000000..6b71b6f7e1
> --- /dev/null
> +++ b/sysdeps/x86/nptl/thread_pointer.h
> @@ -0,0 +1,38 @@
> +/* __thread_pointer definition.  x86 version.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library.  If not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_THREAD_POINTER_H
> +#define _SYS_THREAD_POINTER_H
> +
> +static inline void *
> +__thread_pointer (void)
> +{
> +#if __GNUC_PREREQ (11, 1)
> +  return __builtin_thread_pointer ();
> +#else
> +  void *__result;
> +# ifdef __x86_64__
> +  __asm__ ("mov %%fs:0, %0" : "=r" (__result));
> +# else
> +  __asm__ ("mov %%gs:0, %0" : "=r" (__result));
> +# endif
> +  return __result;
> +#endif /* !GCC 11 */
> +}
> +
> +#endif /* _SYS_THREAD_POINTER_H */
> -- 
> 2.33.1
> 
>
Florian Weimer Dec. 8, 2021, 5:55 p.m. UTC | #2
* Szabolcs Nagy:

> The 12/07/2021 14:00, Florian Weimer via Libc-alpha wrote:
>> <tls.h> already contains a definition that is quite similar,
>> but it is not consistent across architectures.
>> 
>> Only architectures for which rseq support is added are covered.
>
> This looks ok.
>
> It's an annoying gcc bug that __builtin_thread_pointer
> does not work consistently across targets.
>
> Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>

We don't need m68k for rseq, so I haven't added it, but I saw that
__thread_pointer is actually a system call there.  Maybe that's why it's
not a universal GCC feature.  Furthermore, for many ABIs, the thread
pointer is somewhat implicit.  On x86, it took some discussion to figure
out that we actually have a canonical notion of a thread pointer.  On
some other targets, the thread pointer is stored explicitly in a
(system) register, but it actually points to nowhere, so that local-exec
TLS access can make better use of immediate instruction operands.

It's also annoying that __has_builtin (__builtin_thread_pointer)
evaluates to true even for GCC targets where actually using
__builtin_thread_pointer () results in a compiler error.

In the future, we could install this as <sys/thread_pointer.h> if people
think it's useful (not just in an rseq context).

Thanks,
Florian
Szabolcs Nagy Dec. 9, 2021, 11:52 a.m. UTC | #3
The 12/08/2021 18:55, Florian Weimer wrote:
> * Szabolcs Nagy:
> > The 12/07/2021 14:00, Florian Weimer via Libc-alpha wrote:
> >> <tls.h> already contains a definition that is quite similar,
> >> but it is not consistent across architectures.
> >> 
> >> Only architectures for which rseq support is added are covered.
> >
> > This looks ok.
> >
> > It's an annoying gcc bug that __builtin_thread_pointer
> > does not work consistently across targets.
> >
> > Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
> 
> We don't need m68k for rseq, so I haven't added it, but I saw that
> __thread_pointer is actually a system call there.  Maybe that's why it's
> not a universal GCC feature.  Furthermore, for many ABIs, the thread
> pointer is somewhat implicit.  On x86, it took some discussion to figure
> out that we actually have a canonical notion of a thread pointer.  On
> some other targets, the thread pointer is stored explicitly in a
> (system) register, but it actually points to nowhere, so that local-exec
> TLS access can make better use of immediate instruction operands.

i think local-exec tls access has to expose
some notion of thread pointer to the compiler
(from which a tls variable is at fixed offset).

whatever that notion is, __builtin_thread_pointer
can be defined based on that and if there is
nothing exposed then presumably tls access
relies on libc apis so __builtin_thread_pointer
can also rely on a libc api (or syscall).

tp is useful as a thread identifier and for fixed
offset tcb abis. (especially within libc and
compiler runtimes)

> 
> It's also annoying that __has_builtin (__builtin_thread_pointer)
> evaluates to true even for GCC targets where actually using
> __builtin_thread_pointer () results in a compiler error.
> 
> In the future, we could install this as <sys/thread_pointer.h> if people
> think it's useful (not just in an rseq context).

yeah, i would prefer gcc to be fixed.
diff mbox series

Patch

diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h
new file mode 100644
index 0000000000..92f2f3093e
--- /dev/null
+++ b/sysdeps/nptl/thread_pointer.h
@@ -0,0 +1,28 @@ 
+/* __thread_pointer definition.  Generic version.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+  return __builtin_thread_pointer ();
+}
+
+#endif /* _SYS_THREAD_POINTER_H */
diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
new file mode 100644
index 0000000000..8fd5ba671f
--- /dev/null
+++ b/sysdeps/powerpc/nptl/thread_pointer.h
@@ -0,0 +1,33 @@ 
+/* __thread_pointer definition.  powerpc version.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+#ifdef __powerpc64__
+  register void *__result asm ("r13");
+#else
+  register void *__result asm ("r2");
+#endif
+  return __result;
+}
+
+#endif /* _SYS_THREAD_POINTER_H */
diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h
new file mode 100644
index 0000000000..6b71b6f7e1
--- /dev/null
+++ b/sysdeps/x86/nptl/thread_pointer.h
@@ -0,0 +1,38 @@ 
+/* __thread_pointer definition.  x86 version.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+#if __GNUC_PREREQ (11, 1)
+  return __builtin_thread_pointer ();
+#else
+  void *__result;
+# ifdef __x86_64__
+  __asm__ ("mov %%fs:0, %0" : "=r" (__result));
+# else
+  __asm__ ("mov %%gs:0, %0" : "=r" (__result));
+# endif
+  return __result;
+#endif /* !GCC 11 */
+}
+
+#endif /* _SYS_THREAD_POINTER_H */