Author: kib Date: Sat Jan 7 16:05:19 2017 New Revision: 311651 URL: https://svnweb.freebsd.org/changeset/base/311651
Log: Export __cxa_thread_atexit_impl as an alias for __cxa_thread_atexit. libstdc++ before gcc r244057 expected that libc provided __cxa_thread_atexit_impl, and libstdc++ implemented __cxa_thread_atexit, by forwarding the calls to _impl. Mentioned gcc revision checks for __cxa_thread_atexit in libc and does not provide the symbol from libstdc++ if found. This change helps older gcc, in particular, all released versions which implement thread_local, by consolidating the implementation into libc. For that versions, if configured with the current libc, the __cxa_thread_atexit is exported from libstdc++ as a trivial wrapper around libc::__cxa_thread_atexit_impl. The __cxa_thread_atexit implementation is put into separate source file to allow for static linking with older libstdc++.a. gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78968 Reported by: Hannes Hauswedell <h2+fbsdpo...@fsfe.org> PR: 215709 Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Added: head/lib/libc/stdlib/cxa_thread_atexit_impl.c - copied, changed from r311650, head/lib/libc/stdlib/cxa_thread_atexit.c Modified: head/lib/libc/include/libc_private.h head/lib/libc/stdlib/Makefile.inc head/lib/libc/stdlib/Symbol.map head/lib/libc/stdlib/cxa_thread_atexit.c Modified: head/lib/libc/include/libc_private.h ============================================================================== --- head/lib/libc/include/libc_private.h Sat Jan 7 15:58:57 2017 (r311650) +++ head/lib/libc/include/libc_private.h Sat Jan 7 16:05:19 2017 (r311651) @@ -272,6 +272,8 @@ void _malloc_thread_cleanup(void); * thread is exiting, so its thread-local dtors should be called. */ void __cxa_thread_call_dtors(void); +int __cxa_thread_atexit_hidden(void (*dtor_func)(void *), void *obj, + void *dso_symbol) __hidden; /* * These functions are used by the threading libraries in order to protect Modified: head/lib/libc/stdlib/Makefile.inc ============================================================================== --- head/lib/libc/stdlib/Makefile.inc Sat Jan 7 15:58:57 2017 (r311650) +++ head/lib/libc/stdlib/Makefile.inc Sat Jan 7 16:05:19 2017 (r311651) @@ -5,7 +5,9 @@ .PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/stdlib ${LIBC_SRCTOP}/stdlib MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ - bsearch.c cxa_thread_atexit.c div.c exit.c getenv.c getopt.c getopt_long.c \ + bsearch.c \ + cxa_thread_atexit.c cxa_thread_atexit_impl.c \ + div.c exit.c getenv.c getopt.c getopt_long.c \ getsubopt.c hcreate.c hcreate_r.c hdestroy_r.c heapsort.c heapsort_b.c \ hsearch_r.c imaxabs.c imaxdiv.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ Modified: head/lib/libc/stdlib/Symbol.map ============================================================================== --- head/lib/libc/stdlib/Symbol.map Sat Jan 7 15:58:57 2017 (r311650) +++ head/lib/libc/stdlib/Symbol.map Sat Jan 7 16:05:19 2017 (r311651) @@ -118,6 +118,7 @@ FBSD_1.4 { FBSD_1.5 { __cxa_thread_atexit; + __cxa_thread_atexit_impl; }; FBSDprivate_1.0 { Modified: head/lib/libc/stdlib/cxa_thread_atexit.c ============================================================================== --- head/lib/libc/stdlib/cxa_thread_atexit.c Sat Jan 7 15:58:57 2017 (r311650) +++ head/lib/libc/stdlib/cxa_thread_atexit.c Sat Jan 7 16:05:19 2017 (r311651) @@ -1,7 +1,10 @@ /*- - * Copyright (c) 2016 Mahdi Mokhtari <mokh...@gmail.com> + * Copyright (c) 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -27,114 +30,11 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/queue.h> -#include "namespace.h" -#include <errno.h> -#include <link.h> -#include <pthread.h> -#include <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include "un-namespace.h" #include "libc_private.h" -/* - * C++11 introduces the thread_local scope (like __thread with some - * additions). As a key-feature it should support non-trivial - * destructors, registered with __cxa_thread_atexit() to be executed - * at the thread termination. - * - * The implemention keeps a _Thread_local list of destructors per each - * thread, and calls __cxa_thread_call_dtors() on each thread's exit - * to do cleanup. For a thread calling exit(3), in particular, for - * the initial thread returning from main(), we call - * __cxa_thread_call_dtors() inside exit(). - * - * It could be possible that a dynamically loaded library, use - * thread_local variable but is dlclose()'d before thread exit. The - * destructor of this variable will then try to access the address, - * for calling it but it's unloaded, so it'll crash. We're using - * __elf_phdr_match_addr() to detect and prevent such cases and so - * prevent the crash. - */ - -#define CXA_DTORS_ITERATIONS 4 - -struct cxa_thread_dtor { - void *obj; - void (*func)(void *); - void *dso; - LIST_ENTRY(cxa_thread_dtor) entry; -}; -static _Thread_local LIST_HEAD(dtor_list, cxa_thread_dtor) dtors = - LIST_HEAD_INITIALIZER(dtors); - int __cxa_thread_atexit(void (*dtor_func)(void *), void *obj, void *dso_symbol) { - struct cxa_thread_dtor *new_dtor; - - new_dtor = malloc(sizeof(*new_dtor)); - if (new_dtor == NULL) { - errno = ENOMEM; /* forcibly override malloc(3) error */ - return (-1); - } - - new_dtor->obj = obj; - new_dtor->func = dtor_func; - new_dtor->dso = dso_symbol; - LIST_INSERT_HEAD(&dtors, new_dtor, entry); - return (0); -} - -static void -walk_cb_call(struct cxa_thread_dtor *dtor) -{ - struct dl_phdr_info phdr_info; - - if (_rtld_addr_phdr(dtor->dso, &phdr_info) && - __elf_phdr_match_addr(&phdr_info, dtor->func)) - dtor->func(dtor->obj); - else - fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from " - "unloaded dso, skipping\n", (void *)(dtor->func)); -} - -static void -walk_cb_nocall(struct cxa_thread_dtor *dtor __unused) -{ -} - -static void -cxa_thread_walk(void (*cb)(struct cxa_thread_dtor *)) -{ - struct cxa_thread_dtor *dtor, *tdtor; - - LIST_FOREACH_SAFE(dtor, &dtors, entry, tdtor) { - LIST_REMOVE(dtor, entry); - cb(dtor); - free(dtor); - } -} - -/* - * This is the callback function we use to call destructors, once for - * each thread. It is called in exit(3) in libc/stdlib/exit.c and - * before exit_thread() in libthr/thread/thr_exit.c. - */ -void -__cxa_thread_call_dtors(void) -{ - int i; - - for (i = 0; i < CXA_DTORS_ITERATIONS && !LIST_EMPTY(&dtors); i++) - cxa_thread_walk(walk_cb_call); - if (!LIST_EMPTY(&dtors)) { - fprintf(stderr, "Thread %p is exiting with more " - "thread-specific dtors created after %d iterations " - "of destructor calls\n", - _pthread_self(), i); - cxa_thread_walk(walk_cb_nocall); - } + return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); } Copied and modified: head/lib/libc/stdlib/cxa_thread_atexit_impl.c (from r311650, head/lib/libc/stdlib/cxa_thread_atexit.c) ============================================================================== --- head/lib/libc/stdlib/cxa_thread_atexit.c Sat Jan 7 15:58:57 2017 (r311650, copy source) +++ head/lib/libc/stdlib/cxa_thread_atexit_impl.c Sat Jan 7 16:05:19 2017 (r311651) @@ -1,7 +1,11 @@ /*- * Copyright (c) 2016 Mahdi Mokhtari <mokh...@gmail.com> + * Copyright (c) 2016, 2017 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -70,7 +74,16 @@ static _Thread_local LIST_HEAD(dtor_list LIST_HEAD_INITIALIZER(dtors); int -__cxa_thread_atexit(void (*dtor_func)(void *), void *obj, void *dso_symbol) +__cxa_thread_atexit_impl(void (*dtor_func)(void *), void *obj, + void *dso_symbol) +{ + + return (__cxa_thread_atexit_hidden(dtor_func, obj, dso_symbol)); +} + +int +__cxa_thread_atexit_hidden(void (*dtor_func)(void *), void *obj, + void *dso_symbol) { struct cxa_thread_dtor *new_dtor; _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"