libsupc++: try cxa_thread_atexit_impl at runtime
Checks
Commit Message
g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
a platform that lacks __cxa_thread_atexit_impl, even if the program is
built and run using that toolchain on a (later) platform that offers
__cxa_thread_atexit_impl.
This patch adds runtime testing for __cxa_thread_atexit_impl on
platforms that support weak symbols.
Regstrapped on x86_64-linux-gnu, also tested with gcc-13 on i686- and
x86_64-, and with ac_cv_func___cxa_thread_atexit_impl=no, that, on a
distro that lacks __cxa_thread_atexit in libc, forces the newly-added
code to be exercised, and that enabled thread_local-order2.C to pass
where the runtime libc has __cxa_thread_atexit_impl. Ok to install?
for libstdc++-v3/ChangeLog
* libsupc++/atexit_thread.cc [__GXX_WEAK__]: Add dynamic
detection of __cxa_thread_atexit_impl.
---
libstdc++-v3/libsupc++/atexit_thread.cc | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
Comments
On Thu, 9 Nov 2023 at 01:56, Alexandre Oliva <oliva@adacore.com> wrote:
>
>
> g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
> a platform that lacks __cxa_thread_atexit_impl, even if the program is
> built and run using that toolchain on a (later) platform that offers
> __cxa_thread_atexit_impl.
>
> This patch adds runtime testing for __cxa_thread_atexit_impl on
> platforms that support weak symbols.
>
> Regstrapped on x86_64-linux-gnu, also tested with gcc-13 on i686- and
> x86_64-, and with ac_cv_func___cxa_thread_atexit_impl=no, that, on a
> distro that lacks __cxa_thread_atexit in libc, forces the newly-added
> code to be exercised, and that enabled thread_local-order2.C to pass
> where the runtime libc has __cxa_thread_atexit_impl. Ok to install?
Seems fine to me. Any objections, Jason?
>
>
> for libstdc++-v3/ChangeLog
>
> * libsupc++/atexit_thread.cc [__GXX_WEAK__]: Add dynamic
> detection of __cxa_thread_atexit_impl.
> ---
> libstdc++-v3/libsupc++/atexit_thread.cc | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
> index 9346d50f5dafe..cabd7c0a4a057 100644
> --- a/libstdc++-v3/libsupc++/atexit_thread.cc
> +++ b/libstdc++-v3/libsupc++/atexit_thread.cc
> @@ -138,11 +138,24 @@ namespace {
> }
> }
>
> +#if __GXX_WEAK__
> +extern "C"
> +int __attribute__ ((__weak__))
> +__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
> + void *arg, void *d);
> +#endif
> +
> +// ??? We can't make it an ifunc, can we?
> extern "C" int
> __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> - void *obj, void */*dso_handle*/)
> + void *obj, void *dso_handle)
> _GLIBCXX_NOTHROW
> {
> +#if __GXX_WEAK__
> + if (__cxa_thread_atexit_impl)
> + return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
> +#endif
> +
> // Do this initialization once.
> if (__gthread_active_p ())
> {
>
> --
> Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/
> Free Software Activist GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive
>
On Nov 9, 2023, Jonathan Wakely <jwakely@redhat.com> wrote:
> On Thu, 9 Nov 2023 at 01:56, Alexandre Oliva <oliva@adacore.com> wrote:
>> g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
>> a platform that lacks __cxa_thread_atexit_impl, even if the program is
>> built and run using that toolchain on a (later) platform that offers
>> __cxa_thread_atexit_impl.
>>
>> This patch adds runtime testing for __cxa_thread_atexit_impl on
>> platforms that support weak symbols.
>>
>> Regstrapped on x86_64-linux-gnu, also tested with gcc-13 on i686- and
>> x86_64-, and with ac_cv_func___cxa_thread_atexit_impl=no, that, on a
>> distro that lacks __cxa_thread_atexit in libc, forces the newly-added
>> code to be exercised, and that enabled thread_local-order2.C to pass
>> where the runtime libc has __cxa_thread_atexit_impl. Ok to install?
> Seems fine to me. Any objections, Jason?
Jason, ping?
https://gcc.gnu.org/pipermail/gcc-patches/2023-November/635750.html
On 12/1/23 15:40, Alexandre Oliva wrote:
> On Nov 9, 2023, Jonathan Wakely <jwakely@redhat.com> wrote:
>
>> On Thu, 9 Nov 2023 at 01:56, Alexandre Oliva <oliva@adacore.com> wrote:
>
>>> g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
>>> a platform that lacks __cxa_thread_atexit_impl, even if the program is
>>> built and run using that toolchain on a (later) platform that offers
>>> __cxa_thread_atexit_impl.
>>>
>>> This patch adds runtime testing for __cxa_thread_atexit_impl on
>>> platforms that support weak symbols.
>>>
>>> Regstrapped on x86_64-linux-gnu, also tested with gcc-13 on i686- and
>>> x86_64-, and with ac_cv_func___cxa_thread_atexit_impl=no, that, on a
>>> distro that lacks __cxa_thread_atexit in libc, forces the newly-added
>>> code to be exercised, and that enabled thread_local-order2.C to pass
>>> where the runtime libc has __cxa_thread_atexit_impl. Ok to install?
>
>> Seems fine to me. Any objections, Jason?
>
> Jason, ping?
> https://gcc.gnu.org/pipermail/gcc-patches/2023-November/635750.html
OK by me.
Jason
Hi Alexandre!
On 2023-12-06T02:28:42-0300, Alexandre Oliva <oliva@adacore.com> wrote:
> libsupc++: try cxa_thread_atexit_impl at runtime
>
> g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
> a platform that lacks __cxa_thread_atexit_impl, even if the program is
> built and run using that toolchain on a (later) platform that offers
> __cxa_thread_atexit_impl.
>
> This patch adds runtime testing for __cxa_thread_atexit_impl on select
> platforms (GNU variants, for starters) that support weak symbols.
Need something like:
--- libstdc++-v3/libsupc++/atexit_thread.cc
+++ libstdc++-v3/libsupc++/atexit_thread.cc
@@ -164,2 +164,4 @@ __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
+#else
+ (void) dso_handle;
#endif
... to avoid:
[...]/source-gcc/libstdc++-v3/libsupc++/atexit_thread.cc: In function ‘int __cxxabiv1::__cxa_thread_atexit(void (*)(void*), void*, void*)’:
[...]/source-gcc/libstdc++-v3/libsupc++/atexit_thread.cc:151:51: error: unused parameter ‘dso_handle’ [-Werror=unused-parameter]
151 | void *obj, void *dso_handle)
| ~~~~~~^~~~~~~~~~
cc1plus: all warnings being treated as errors
make[4]: *** [atexit_thread.lo] Error 1
With that, GCC/nvptx then is back to:
UNSUPPORTED: g++.dg/tls/thread_local6.C -std=c++98
PASS: g++.dg/tls/thread_local6.C -std=c++14 (test for excess errors)
PASS: g++.dg/tls/thread_local6.C -std=c++14 execution test
PASS: g++.dg/tls/thread_local6.C -std=c++17 (test for excess errors)
PASS: g++.dg/tls/thread_local6.C -std=c++17 execution test
PASS: g++.dg/tls/thread_local6.C -std=c++20 (test for excess errors)
PASS: g++.dg/tls/thread_local6.C -std=c++20 execution test
Grüße
Thomas
> for libstdc++-v3/ChangeLog
>
> * config/os/gnu-linux/os_defines.h
> (_GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL): Define.
> * libsupc++/atexit_thread.cc [__GXX_WEAK__ &&
> _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL]
> (__cxa_thread_atexit): Add dynamic detection of
> __cxa_thread_atexit_impl.
> ---
> libstdc++-v3/config/os/gnu-linux/os_defines.h | 5 +++++
> libstdc++-v3/libsupc++/atexit_thread.cc | 23 ++++++++++++++++++++++-
> 2 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> index 87317031fcd71..a2e4baec069d5 100644
> --- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
> +++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> @@ -60,6 +60,11 @@
> # define _GLIBCXX_HAVE_FLOAT128_MATH 1
> #endif
>
> +// Enable __cxa_thread_atexit to rely on a (presumably libc-provided)
> +// __cxa_thread_atexit_impl, if it happens to be defined, even if
> +// configure couldn't find it during the build.
> +#define _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL 1
> +
> #ifdef __linux__
> // The following libpthread properties only apply to Linux, not GNU/Hurd.
>
> diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
> index 9346d50f5dafe..aa4ed5312bfe3 100644
> --- a/libstdc++-v3/libsupc++/atexit_thread.cc
> +++ b/libstdc++-v3/libsupc++/atexit_thread.cc
> @@ -138,11 +138,32 @@ namespace {
> }
> }
>
> +#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> +extern "C"
> +int __attribute__ ((__weak__))
> +__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
> + void *arg, void *d);
> +#endif
> +
> +// ??? We can't make it an ifunc, can we?
> extern "C" int
> __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> - void *obj, void */*dso_handle*/)
> + void *obj, void *dso_handle)
> _GLIBCXX_NOTHROW
> {
> +#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> + if (__cxa_thread_atexit_impl)
> + // Rely on a (presumably libc-provided) __cxa_thread_atexit_impl,
> + // if it happens to be defined, even if configure couldn't find it
> + // during the build. _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> + // may be defined e.g. in os_defines.h on platforms where some
> + // versions of libc have a __cxa_thread_atexit_impl definition,
> + // but whose earlier versions didn't. This enables programs build
> + // by toolchains compatible with earlier libc versions to still
> + // benefit from a libc-provided __cxa_thread_atexit_impl.
> + return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
> +#endif
> +
> // Do this initialization once.
> if (__gthread_active_p ())
> {
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
On Wed, 6 Dec 2023 at 12:30, Thomas Schwinge <thomas@codesourcery.com> wrote:
>
> Hi Alexandre!
>
> On 2023-12-06T02:28:42-0300, Alexandre Oliva <oliva@adacore.com> wrote:
> > libsupc++: try cxa_thread_atexit_impl at runtime
> >
> > g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
> > a platform that lacks __cxa_thread_atexit_impl, even if the program is
> > built and run using that toolchain on a (later) platform that offers
> > __cxa_thread_atexit_impl.
> >
> > This patch adds runtime testing for __cxa_thread_atexit_impl on select
> > platforms (GNU variants, for starters) that support weak symbols.
>
> Need something like:
>
> --- libstdc++-v3/libsupc++/atexit_thread.cc
> +++ libstdc++-v3/libsupc++/atexit_thread.cc
> @@ -164,2 +164,4 @@ __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
> +#else
> + (void) dso_handle;
> #endif
I would prefer:
--- a/libstdc++-v3/libsupc++/atexit_thread.cc
+++ b/libstdc++-v3/libsupc++/atexit_thread.cc
@@ -148,7 +148,7 @@ __cxa_thread_atexit_impl (void
(_GLIBCXX_CDTOR_CALLABI *func) (void *),
// ??? We can't make it an ifunc, can we?
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
- void *obj, void *dso_handle)
+ void *obj, [[maybe_unused]] void *dso_handle)
_GLIBCXX_NOTHROW
{
#if __GXX_WEAK__
>
> ... to avoid:
>
> [...]/source-gcc/libstdc++-v3/libsupc++/atexit_thread.cc: In function ‘int __cxxabiv1::__cxa_thread_atexit(void (*)(void*), void*, void*)’:
> [...]/source-gcc/libstdc++-v3/libsupc++/atexit_thread.cc:151:51: error: unused parameter ‘dso_handle’ [-Werror=unused-parameter]
> 151 | void *obj, void *dso_handle)
> | ~~~~~~^~~~~~~~~~
> cc1plus: all warnings being treated as errors
> make[4]: *** [atexit_thread.lo] Error 1
>
> With that, GCC/nvptx then is back to:
>
> UNSUPPORTED: g++.dg/tls/thread_local6.C -std=c++98
> PASS: g++.dg/tls/thread_local6.C -std=c++14 (test for excess errors)
> PASS: g++.dg/tls/thread_local6.C -std=c++14 execution test
> PASS: g++.dg/tls/thread_local6.C -std=c++17 (test for excess errors)
> PASS: g++.dg/tls/thread_local6.C -std=c++17 execution test
> PASS: g++.dg/tls/thread_local6.C -std=c++20 (test for excess errors)
> PASS: g++.dg/tls/thread_local6.C -std=c++20 execution test
>
>
> Grüße
> Thomas
>
>
> > for libstdc++-v3/ChangeLog
> >
> > * config/os/gnu-linux/os_defines.h
> > (_GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL): Define.
> > * libsupc++/atexit_thread.cc [__GXX_WEAK__ &&
> > _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL]
> > (__cxa_thread_atexit): Add dynamic detection of
> > __cxa_thread_atexit_impl.
> > ---
> > libstdc++-v3/config/os/gnu-linux/os_defines.h | 5 +++++
> > libstdc++-v3/libsupc++/atexit_thread.cc | 23 ++++++++++++++++++++++-
> > 2 files changed, 27 insertions(+), 1 deletion(-)
> >
> > diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> > index 87317031fcd71..a2e4baec069d5 100644
> > --- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
> > +++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> > @@ -60,6 +60,11 @@
> > # define _GLIBCXX_HAVE_FLOAT128_MATH 1
> > #endif
> >
> > +// Enable __cxa_thread_atexit to rely on a (presumably libc-provided)
> > +// __cxa_thread_atexit_impl, if it happens to be defined, even if
> > +// configure couldn't find it during the build.
> > +#define _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL 1
> > +
> > #ifdef __linux__
> > // The following libpthread properties only apply to Linux, not GNU/Hurd.
> >
> > diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
> > index 9346d50f5dafe..aa4ed5312bfe3 100644
> > --- a/libstdc++-v3/libsupc++/atexit_thread.cc
> > +++ b/libstdc++-v3/libsupc++/atexit_thread.cc
> > @@ -138,11 +138,32 @@ namespace {
> > }
> > }
> >
> > +#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> > +extern "C"
> > +int __attribute__ ((__weak__))
> > +__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
> > + void *arg, void *d);
> > +#endif
> > +
> > +// ??? We can't make it an ifunc, can we?
> > extern "C" int
> > __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> > - void *obj, void */*dso_handle*/)
> > + void *obj, void *dso_handle)
> > _GLIBCXX_NOTHROW
> > {
> > +#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> > + if (__cxa_thread_atexit_impl)
> > + // Rely on a (presumably libc-provided) __cxa_thread_atexit_impl,
> > + // if it happens to be defined, even if configure couldn't find it
> > + // during the build. _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> > + // may be defined e.g. in os_defines.h on platforms where some
> > + // versions of libc have a __cxa_thread_atexit_impl definition,
> > + // but whose earlier versions didn't. This enables programs build
> > + // by toolchains compatible with earlier libc versions to still
> > + // benefit from a libc-provided __cxa_thread_atexit_impl.
> > + return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
> > +#endif
> > +
> > // Do this initialization once.
> > if (__gthread_active_p ())
> > {
> -----------------
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
>
On Wed, 6 Dec 2023 at 13:53, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On Wed, 6 Dec 2023 at 12:30, Thomas Schwinge <thomas@codesourcery.com> wrote:
> >
> > Hi Alexandre!
> >
> > On 2023-12-06T02:28:42-0300, Alexandre Oliva <oliva@adacore.com> wrote:
> > > libsupc++: try cxa_thread_atexit_impl at runtime
> > >
> > > g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
> > > a platform that lacks __cxa_thread_atexit_impl, even if the program is
> > > built and run using that toolchain on a (later) platform that offers
> > > __cxa_thread_atexit_impl.
> > >
> > > This patch adds runtime testing for __cxa_thread_atexit_impl on select
> > > platforms (GNU variants, for starters) that support weak symbols.
> >
> > Need something like:
> >
> > --- libstdc++-v3/libsupc++/atexit_thread.cc
> > +++ libstdc++-v3/libsupc++/atexit_thread.cc
> > @@ -164,2 +164,4 @@ __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> > return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
> > +#else
> > + (void) dso_handle;
> > #endif
>
> I would prefer:
>
> --- a/libstdc++-v3/libsupc++/atexit_thread.cc
> +++ b/libstdc++-v3/libsupc++/atexit_thread.cc
> @@ -148,7 +148,7 @@ __cxa_thread_atexit_impl (void
> (_GLIBCXX_CDTOR_CALLABI *func) (void *),
> // ??? We can't make it an ifunc, can we?
> extern "C" int
> __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> - void *obj, void *dso_handle)
> + void *obj, [[maybe_unused]] void *dso_handle)
> _GLIBCXX_NOTHROW
> {
> #if __GXX_WEAK__
The patch is OK with that change.
>
>
>
>
> >
> > ... to avoid:
> >
> > [...]/source-gcc/libstdc++-v3/libsupc++/atexit_thread.cc: In function ‘int __cxxabiv1::__cxa_thread_atexit(void (*)(void*), void*, void*)’:
> > [...]/source-gcc/libstdc++-v3/libsupc++/atexit_thread.cc:151:51: error: unused parameter ‘dso_handle’ [-Werror=unused-parameter]
> > 151 | void *obj, void *dso_handle)
> > | ~~~~~~^~~~~~~~~~
> > cc1plus: all warnings being treated as errors
> > make[4]: *** [atexit_thread.lo] Error 1
> >
> > With that, GCC/nvptx then is back to:
> >
> > UNSUPPORTED: g++.dg/tls/thread_local6.C -std=c++98
> > PASS: g++.dg/tls/thread_local6.C -std=c++14 (test for excess errors)
> > PASS: g++.dg/tls/thread_local6.C -std=c++14 execution test
> > PASS: g++.dg/tls/thread_local6.C -std=c++17 (test for excess errors)
> > PASS: g++.dg/tls/thread_local6.C -std=c++17 execution test
> > PASS: g++.dg/tls/thread_local6.C -std=c++20 (test for excess errors)
> > PASS: g++.dg/tls/thread_local6.C -std=c++20 execution test
> >
> >
> > Grüße
> > Thomas
> >
> >
> > > for libstdc++-v3/ChangeLog
> > >
> > > * config/os/gnu-linux/os_defines.h
> > > (_GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL): Define.
> > > * libsupc++/atexit_thread.cc [__GXX_WEAK__ &&
> > > _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL]
> > > (__cxa_thread_atexit): Add dynamic detection of
> > > __cxa_thread_atexit_impl.
> > > ---
> > > libstdc++-v3/config/os/gnu-linux/os_defines.h | 5 +++++
> > > libstdc++-v3/libsupc++/atexit_thread.cc | 23 ++++++++++++++++++++++-
> > > 2 files changed, 27 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> > > index 87317031fcd71..a2e4baec069d5 100644
> > > --- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
> > > +++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
> > > @@ -60,6 +60,11 @@
> > > # define _GLIBCXX_HAVE_FLOAT128_MATH 1
> > > #endif
> > >
> > > +// Enable __cxa_thread_atexit to rely on a (presumably libc-provided)
> > > +// __cxa_thread_atexit_impl, if it happens to be defined, even if
> > > +// configure couldn't find it during the build.
> > > +#define _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL 1
> > > +
> > > #ifdef __linux__
> > > // The following libpthread properties only apply to Linux, not GNU/Hurd.
> > >
> > > diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
> > > index 9346d50f5dafe..aa4ed5312bfe3 100644
> > > --- a/libstdc++-v3/libsupc++/atexit_thread.cc
> > > +++ b/libstdc++-v3/libsupc++/atexit_thread.cc
> > > @@ -138,11 +138,32 @@ namespace {
> > > }
> > > }
> > >
> > > +#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> > > +extern "C"
> > > +int __attribute__ ((__weak__))
> > > +__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
> > > + void *arg, void *d);
> > > +#endif
> > > +
> > > +// ??? We can't make it an ifunc, can we?
> > > extern "C" int
> > > __cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
> > > - void *obj, void */*dso_handle*/)
> > > + void *obj, void *dso_handle)
> > > _GLIBCXX_NOTHROW
> > > {
> > > +#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> > > + if (__cxa_thread_atexit_impl)
> > > + // Rely on a (presumably libc-provided) __cxa_thread_atexit_impl,
> > > + // if it happens to be defined, even if configure couldn't find it
> > > + // during the build. _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
> > > + // may be defined e.g. in os_defines.h on platforms where some
> > > + // versions of libc have a __cxa_thread_atexit_impl definition,
> > > + // but whose earlier versions didn't. This enables programs build
> > > + // by toolchains compatible with earlier libc versions to still
> > > + // benefit from a libc-provided __cxa_thread_atexit_impl.
> > > + return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
> > > +#endif
> > > +
> > > // Do this initialization once.
> > > if (__gthread_active_p ())
> > > {
> > -----------------
> > Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
> >
>
On Dec 6, 2023, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> - void *obj, void *dso_handle)
>> + void *obj, [[maybe_unused]] void *dso_handle)
> The patch is OK with that change.
Thanks, here's what I'm going to install. Regstrapped on
x86_64-linux-gnu, with and without
ac_cv_func___cxa_thread_atexit_impl=no, on a machine that has
__cxa_thread_atexit_impl (but not __cxa_thread_atexit) in libc.
libsupc++: try cxa_thread_atexit_impl at runtime
g++.dg/tls/thread_local-order2.C fails when the toolchain is built for
a platform that lacks __cxa_thread_atexit_impl, even if the program is
built and run using that toolchain on a (later) platform that offers
__cxa_thread_atexit_impl.
This patch adds runtime testing for __cxa_thread_atexit_impl on select
platforms (GNU variants, for starters) that support weak symbols.
for libstdc++-v3/ChangeLog
PR libstdc++/112858
* config/os/gnu-linux/os_defines.h
(_GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL): Define.
* libsupc++/atexit_thread.cc [__GXX_WEAK__ &&
_GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL]
(__cxa_thread_atexit): Add dynamic detection of
__cxa_thread_atexit_impl.
---
libstdc++-v3/config/os/gnu-linux/os_defines.h | 5 +++++
libstdc++-v3/libsupc++/atexit_thread.cc | 23 ++++++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
index 87317031fcd71..a2e4baec069d5 100644
--- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
+++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
@@ -60,6 +60,11 @@
# define _GLIBCXX_HAVE_FLOAT128_MATH 1
#endif
+// Enable __cxa_thread_atexit to rely on a (presumably libc-provided)
+// __cxa_thread_atexit_impl, if it happens to be defined, even if
+// configure couldn't find it during the build.
+#define _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL 1
+
#ifdef __linux__
// The following libpthread properties only apply to Linux, not GNU/Hurd.
diff --git a/libstdc++-v3/libsupc++/atexit_thread.cc b/libstdc++-v3/libsupc++/atexit_thread.cc
index 9346d50f5dafe..28423344a0f34 100644
--- a/libstdc++-v3/libsupc++/atexit_thread.cc
+++ b/libstdc++-v3/libsupc++/atexit_thread.cc
@@ -138,11 +138,32 @@ namespace {
}
}
+#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
+extern "C"
+int __attribute__ ((__weak__))
+__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
+ void *arg, void *d);
+#endif
+
+// ??? We can't make it an ifunc, can we?
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
- void *obj, void */*dso_handle*/)
+ void *obj, [[maybe_unused]] void *dso_handle)
_GLIBCXX_NOTHROW
{
+#if __GXX_WEAK__ && _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
+ if (__cxa_thread_atexit_impl)
+ // Rely on a (presumably libc-provided) __cxa_thread_atexit_impl,
+ // if it happens to be defined, even if configure couldn't find it
+ // during the build. _GLIBCXX_MAY_HAVE___CXA_THREAD_ATEXIT_IMPL
+ // may be defined e.g. in os_defines.h on platforms where some
+ // versions of libc have a __cxa_thread_atexit_impl definition,
+ // but whose earlier versions didn't. This enables programs build
+ // by toolchains compatible with earlier libc versions to still
+ // benefit from a libc-provided __cxa_thread_atexit_impl.
+ return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
+#endif
+
// Do this initialization once.
if (__gthread_active_p ())
{
@@ -138,11 +138,24 @@ namespace {
}
}
+#if __GXX_WEAK__
+extern "C"
+int __attribute__ ((__weak__))
+__cxa_thread_atexit_impl (void (_GLIBCXX_CDTOR_CALLABI *func) (void *),
+ void *arg, void *d);
+#endif
+
+// ??? We can't make it an ifunc, can we?
extern "C" int
__cxxabiv1::__cxa_thread_atexit (void (_GLIBCXX_CDTOR_CALLABI *dtor)(void *),
- void *obj, void */*dso_handle*/)
+ void *obj, void *dso_handle)
_GLIBCXX_NOTHROW
{
+#if __GXX_WEAK__
+ if (__cxa_thread_atexit_impl)
+ return __cxa_thread_atexit_impl (dtor, obj, dso_handle);
+#endif
+
// Do this initialization once.
if (__gthread_active_p ())
{