Message ID | 48b399368593be9675a23e7e2dc53f64c46a94d2.1638880889.git.fweimer@redhat.com |
---|---|
State | New |
Headers | show |
Series | Extensible rseq integration | expand |
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 > >
* 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
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 --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 */