Implement __cxa_thread_atexit and __cxa_thread_atexit_impl. This

functions are used for destructors of thread_local objects.

If a pending destructor exists, prevent unloading of shared objects.
Introduce __dl_cxa_refcount interface for this purpose. When the last
reference is gone and the object has been dlclose'd before, the
unloading is finalized.

Ideally, __cxa_thread_atexit_impl wouldn't exist, but libstdc++ insists
on providing __cxa_thread_atexit as direct wrapper without further
patching.
This commit is contained in:
joerg 2017-07-11 15:21:31 +00:00
parent c73729d5e0
commit e5678be828
60 changed files with 576 additions and 59 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.218 2017/06/09 06:09:01 knakahara Exp $
# $NetBSD: mi,v 1.219 2017/07/11 15:21:31 joerg Exp $
./etc/mtree/set.debug comp-sys-root
./usr/lib comp-sys-usr compatdir
./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib,compatfile
@ -2197,6 +2197,7 @@
./usr/libdata/debug/usr/tests/lib/libpthread/h_cancel.debug tests-lib-tests debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libpthread/h_exit.debug tests-lib-tests debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libpthread/h_resolv.debug tests-lib-tests debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libpthread/h_thread_local_dtor.debug tests-lib-tests debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libpthread/t_barrier.debug tests-lib-tests debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libpthread/t_cond.debug tests-lib-tests debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libpthread/t_condwait.debug tests-lib-tests debug,atf,compattestfile

View File

@ -1,4 +1,4 @@
# $NetBSD: shl.mi,v 1.177 2017/06/15 16:00:57 christos Exp $
# $NetBSD: shl.mi,v 1.178 2017/07/11 15:21:31 joerg Exp $
./usr/lib/libbfd_g.a comp-c-debuglib debuglib,compatfile,binutils
./usr/libdata/debug/lib base-sys-usr debug,dynamicroot,compatdir
./usr/libdata/debug/lib/libblacklist.so.0.0.debug comp-sys-debug debug,dynamicroot
@ -307,8 +307,10 @@
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso2/libh_helper_symver_dso.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_thread_local_dtor tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/libh_helper_dso1.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/libh_helper_dso2.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/libh_helper_dso3.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/libh_helper_ifunc_dso.so.1.debug tests-libexec-debug debug,compattestfile,atf
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso_g.a comp-c-debuglib atf,debuglib,compattestfile
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso_g.a comp-c-debuglib atf,debuglib,compattestfile

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.754 2017/07/03 06:01:16 ozaki-r Exp $
# $NetBSD: mi,v 1.755 2017/07/11 15:21:32 joerg Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -3044,6 +3044,7 @@
./usr/tests/lib/libpthread/h_cancel tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/h_exit tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/h_resolv tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/h_thread_local_dtor tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/t_atexit tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/t_barrier tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/t_cancel tests-lib-tests compattestfile,atf
@ -3069,6 +3070,7 @@
./usr/tests/lib/libpthread/t_sleep tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/t_status tests-obsolete obsolete
./usr/tests/lib/libpthread/t_swapcontext tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/t_thread_local_dtor tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread/t_timedmutex tests-lib-tests compattestfile,atf
./usr/tests/lib/libpthread_dbg tests-obsolete obsolete
./usr/tests/lib/libpthread_dbg/Atffile tests-obsolete obsolete
@ -3206,6 +3208,7 @@
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso2 tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/h_ifunc tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/h_locking tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/h_thread_local_dtor tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/t_df_1_noopen tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/t_dl_symver tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/t_dlerror-cleared tests-libexec-tests compattestfile,atf,pic
@ -3213,6 +3216,7 @@
./usr/tests/libexec/ld.elf_so/t_dlinfo tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/t_dlvsym tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/t_ifunc tests-libexec-tests compattestfile,atf,pic
./usr/tests/libexec/ld.elf_so/t_thread_local_dtor tests-libexec-tests compattestfile,atf,pic
./usr/tests/modules tests-sys-tests compattestfile,atf
./usr/tests/net tests-net-tests compattestfile,atf
./usr/tests/net/Atffile tests-net-tests compattestfile,atf

View File

@ -1,4 +1,4 @@
# $NetBSD: shl.mi,v 1.10 2015/06/22 06:02:02 matt Exp $
# $NetBSD: shl.mi,v 1.11 2017/07/11 15:21:32 joerg Exp $
#
./usr/tests/lib/csu/h_initfini3_dso.so tests-lib-tests compattestfile,atf
./usr/tests/lib/csu/h_initfini3_dso.so.1 tests-lib-tests compattestfile,atf
@ -20,6 +20,8 @@
./usr/tests/libexec/ld.elf_so/libh_helper_dso1.so.1 tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/libh_helper_dso2.so tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/libh_helper_dso2.so.1 tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/libh_helper_dso3.so tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/libh_helper_dso3.so.1 tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/libh_helper_ifunc_dso.so tests-libexec-tests compattestfile,atf
./usr/tests/libexec/ld.elf_so/libh_helper_ifunc_dso.so.1 tests-libexec-tests compattestfile,atf
./usr/tests/util/id/libfake.so.0 tests-obsolete obsolete

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1132,7 +1132,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1132,7 +1132,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1132,7 +1132,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1203,7 +1203,7 @@ namespace std
/* #undef _GLIBCXX_HAVE__TANL */
/* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */
/* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL */
#define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1
/* Define as const if the declaration of iconv() needs const. */
#define _GLIBCXX_ICONV_CONST const

View File

@ -1,4 +1,4 @@
/* $NetBSD: dlfcn.h,v 1.24 2012/02/16 23:00:39 joerg Exp $ */
/* $NetBSD: dlfcn.h,v 1.25 2017/07/11 15:21:35 joerg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -34,6 +34,12 @@
#include <sys/featuretest.h>
#include <sys/cdefs.h>
#include <machine/ansi.h>
#ifdef _BSD_SSIZE_T_
typedef _BSD_SSIZE_T_ ssize_t;
#undef _BSD_SSIZE_T_
#endif
#if defined(_NETBSD_SOURCE)
typedef struct _dl_info {
@ -59,6 +65,7 @@ int dlctl(void *, int, void *);
int dlinfo(void *, int, void *);
void *dlvsym(void * __restrict, const char * __restrict,
const char * __restrict);
void __dl_cxa_refcount(void *, ssize_t);
#endif
__aconst char *dlerror(void);
__END_DECLS

View File

@ -1,4 +1,4 @@
/* $NetBSD: dlfcn_elf.c,v 1.13 2012/06/24 15:26:03 christos Exp $ */
/* $NetBSD: dlfcn_elf.c,v 1.14 2017/07/11 15:21:35 joerg Exp $ */
/*
* Copyright (c) 2000 Takuya SHIOZAKI
@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: dlfcn_elf.c,v 1.13 2012/06/24 15:26:03 christos Exp $");
__RCSID("$NetBSD: dlfcn_elf.c,v 1.14 2017/07/11 15:21:35 joerg Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -75,6 +75,7 @@ __weak_alias(__dlerror,___dlerror)
__weak_alias(__dladdr,___dladdr)
__weak_alias(__dlinfo,___dlinfo)
__weak_alias(__dl_iterate_phdr,___dl_iterate_phdr)
__weak_alias(__dl_cxa_refcount, ___dl_cxa_refcount)
#endif
/*
@ -203,3 +204,11 @@ dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
return callback(&phdr_info, sizeof(phdr_info), data);
}
void ___dl_cxa_refcount(void *, ssize_t);
/*ARGSUSED*/
void
___dl_cxa_refcount(void *dso_symbol, ssize_t delta)
{
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: atexit.h,v 1.11 2008/04/28 20:23:00 martin Exp $ */
/* $NetBSD: atexit.h,v 1.1 2017/07/11 15:21:35 joerg Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -29,5 +29,13 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdbool.h>
int __cxa_atexit(void (*)(void *), void *, void *);
void __cxa_finalize(void *);
void __cxa_thread_run_atexit(void);
int __cxa_thread_atexit(void (*)(void *), void *, void *);
#ifdef _LIBC
__dso_hidden bool __cxa_thread_atexit_used;
#endif

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.92 2016/04/01 12:37:48 msaitoh Exp $
# $NetBSD: Makefile.inc,v 1.93 2017/07/11 15:21:35 joerg Exp $
# from: @(#)Makefile.inc 8.3 (Berkeley) 2/4/95
# stdlib sources
@ -6,7 +6,7 @@
SRCS+= _env.c _rand48.c \
a64l.c abort.c aligned_alloc.c atexit.c atof.c atoi.c atol.c atoll.c \
bsearch.c drand48.c exit.c \
bsearch.c cxa_thread_atexit.c drand48.c exit.c \
getenv.c getopt.c getopt_long.c getsubopt.c \
hcreate.c heapsort.c imaxdiv.c insque.c jrand48.c l64a.c lldiv.c \
lcong48.c lrand48.c lsearch.c merge.c mi_vector_hash.c mrand48.c \

View File

@ -0,0 +1,88 @@
/* $NetBSD: cxa_thread_atexit.c,v 1.1 2017/07/11 15:21:35 joerg Exp $ */
/*-
* Copyright (c) 2017 Joerg Sonnenberger <joerg@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: cxa_thread_atexit.c,v 1.1 2017/07/11 15:21:35 joerg Exp $");
#include <sys/queue.h>
#include <dlfcn.h>
#include <stdlib.h>
#include "atexit.h"
__dso_hidden bool __cxa_thread_atexit_used;
struct cxa_dtor {
SLIST_ENTRY(cxa_dtor) link;
void *dso_symbol;
void *obj;
void (*dtor)(void *);
};
/* Assumes NULL initialization. */
static __thread SLIST_HEAD(, cxa_dtor) cxa_dtors = SLIST_HEAD_INITIALIZER(cxa_dstors);
void
__cxa_thread_run_atexit(void)
{
struct cxa_dtor *entry;
while ((entry = SLIST_FIRST(&cxa_dtors)) != NULL) {
SLIST_REMOVE_HEAD(&cxa_dtors, link);
(*entry->dtor)(entry->obj);
if (entry->dso_symbol)
__dl_cxa_refcount(entry->dso_symbol, -1);
free(entry);
}
}
/*
* This dance is necessary since libstdc++ includes
* __cxa_thread_atexit unconditionally.
*/
__weak_alias(__cxa_thread_atexit, __cxa_thread_atexit_impl)
int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);
int
__cxa_thread_atexit_impl(void (*dtor)(void *), void *obj, void *dso_symbol)
{
struct cxa_dtor *entry;
__cxa_thread_atexit_used = true;
entry = malloc(sizeof(*entry));
if (entry == NULL)
return -1;
entry->dso_symbol = dso_symbol;
if (dso_symbol)
__dl_cxa_refcount(entry->dso_symbol, 1);
entry->obj = obj;
entry->dtor = dtor;
SLIST_INSERT_HEAD(&cxa_dtors, entry, link);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: exit.c,v 1.15 2011/05/18 19:36:36 dsl Exp $ */
/* $NetBSD: exit.c,v 1.16 2017/07/11 15:21:35 joerg Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -34,10 +34,11 @@
#if 0
static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: exit.c,v 1.15 2011/05/18 19:36:36 dsl Exp $");
__RCSID("$NetBSD: exit.c,v 1.16 2017/07/11 15:21:35 joerg Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/tls.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef _LIBC
@ -55,6 +56,10 @@ exit(int status)
{
#ifdef _LIBC
# if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
if (__cxa_thread_atexit_used)
__cxa_thread_run_atexit();
# endif
__cxa_finalize(NULL);
#endif
if (__cleanup)

View File

@ -1,4 +1,4 @@
/* $NetBSD: pthread.c,v 1.149 2017/07/02 17:13:07 joerg Exp $ */
/* $NetBSD: pthread.c,v 1.150 2017/07/11 15:21:35 joerg Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: pthread.c,v 1.149 2017/07/02 17:13:07 joerg Exp $");
__RCSID("$NetBSD: pthread.c,v 1.150 2017/07/11 15:21:35 joerg Exp $");
#define __EXPOSE_STACK 1
@ -59,6 +59,7 @@ __RCSID("$NetBSD: pthread.c,v 1.149 2017/07/02 17:13:07 joerg Exp $");
#include <unistd.h>
#include <sched.h>
#include "atexit.h"
#include "pthread.h"
#include "pthread_int.h"
#include "pthread_makelwp.h"
@ -654,6 +655,10 @@ pthread_exit(void *retval)
pthread_mutex_lock(&self->pt_lock);
}
pthread_mutex_unlock(&self->pt_lock);
__cxa_thread_run_atexit();
pthread_mutex_lock(&self->pt_lock);
/* Perform cleanup of thread-specific data */
pthread__destroy_tsd(self);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.c,v 1.184 2017/06/08 18:24:39 joerg Exp $ */
/* $NetBSD: rtld.c,v 1.185 2017/07/11 15:21:35 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: rtld.c,v 1.184 2017/06/08 18:24:39 joerg Exp $");
__RCSID("$NetBSD: rtld.c,v 1.185 2017/07/11 15:21:35 joerg Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -1425,6 +1425,45 @@ dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *pa
return error;
}
void
__dl_cxa_refcount(void *addr, ssize_t delta)
{
sigset_t mask;
Obj_Entry *obj;
if (delta == 0)
return;
dbg(("__dl_cxa_refcount of %p with %zd", addr, delta));
_rtld_exclusive_enter(&mask);
obj = _rtld_obj_from_addr(addr);
if (obj == NULL) {
dbg(("__dl_cxa_refcont: address not found"));
_rtld_error("No shared object contains address");
_rtld_exclusive_exit(&mask);
return;
}
if (delta > 0 && obj->cxa_refcount > SIZE_MAX - delta)
_rtld_error("Reference count overflow");
else if (delta < 0 && obj->cxa_refcount < -1 + (size_t)-(delta + 1))
_rtld_error("Reference count underflow");
else {
if (obj->cxa_refcount == 0)
++obj->refcount;
obj->cxa_refcount += delta;
dbg(("new reference count: %zu", obj->cxa_refcount));
if (obj->cxa_refcount == 0) {
--obj->refcount;
if (obj->refcount == 0)
_rtld_unload_object(&mask, obj, true);
}
}
_rtld_exclusive_exit(&mask);
}
/*
* Error reporting function. Use it like printf. If formats the message
* into a buffer, and sets things up so that the next call to dlerror()

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.h,v 1.128 2017/07/09 17:57:59 joerg Exp $ */
/* $NetBSD: rtld.h,v 1.129 2017/07/11 15:21:35 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -298,6 +298,7 @@ typedef struct Struct_Obj_Entry {
size_t init_arraysz; /* # of entries in it */
Elf_Addr *fini_array; /* start of fini array */
size_t fini_arraysz; /* # of entries in it */
size_t cxa_refcount; /* For TLS destructors. */
#ifdef __ARM_EABI__
void *exidx_start;
size_t exidx_sz;
@ -355,6 +356,7 @@ __dso_public int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
void *);
__dso_public void *_dlauxinfo(void) __pure;
__dso_public void __dl_cxa_refcount(void *addr, ssize_t delta);
#if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
/*

View File

@ -22,5 +22,6 @@
__tls_get_addr;
___tls_get_addr;
__gnu_Unwind_Find_exidx;
__dl_cxa_refcount;
local: *;
};

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.12 2016/10/30 16:17:16 kamil Exp $
# $NetBSD: Makefile,v 1.13 2017/07/11 15:21:36 joerg Exp $
NOMAN= # defined
@ -38,6 +38,7 @@ TESTS_C+= t_sigsuspend
TESTS_C+= t_siglongjmp
TESTS_C+= t_sleep
TESTS_C+= t_swapcontext
TESTS_SH+= t_thread_local_dtor
TESTS_C+= t_timedmutex
LDADD.t_sem+= -lrt
@ -47,6 +48,11 @@ PROGS= h_atexit
PROGS+= h_cancel
PROGS+= h_exit
PROGS+= h_resolv
PROGS_CXX+= h_thread_local_dtor
COPTS.h_thread_local_dtor.cpp+= -std=c++11
# Deal with questionable warning and header quality in libstdc++.
COPTS.h_thread_local_dtor.cpp+= ${${ACTIVE_CC} == "gcc" :? -Wno-ctor-dtor-privacy -Wno-sign-compare -Wno-shadow :}
FILESDIR= ${TESTSDIR}
FILES= d_mach

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016 Tavian Barnes. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: h_thread_local_dtor.cpp,v 1.1 2017/07/11 15:21:36 joerg Exp $");
#include <cstdlib>
#include <thread>
static int seq;
class OrderChecker {
public:
explicit OrderChecker(int n) : n_{n} { }
~OrderChecker() {
if (seq != n_) {
printf("Unexpected sequence point: %d\n", 3);
_Exit(1);
}
++seq;
}
private:
int n_;
};
template <int ID>
class CreatesThreadLocalInDestructor {
public:
~CreatesThreadLocalInDestructor() {
thread_local OrderChecker checker{ID};
}
};
OrderChecker global{7};
void thread_fn() {
static OrderChecker fn_static{5};
thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
thread_local OrderChecker fn_thread_local{1};
thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
}
int main() {
static OrderChecker fn_static{6};
std::thread{thread_fn}.join();
if (seq != 3) {
printf("Unexpected sequence point: %d\n", 3);
_Exit(1);
}
thread_local OrderChecker fn_thread_local{4};
thread_local CreatesThreadLocalInDestructor<3> creates_tl;
return 0;
}

View File

@ -0,0 +1,41 @@
# $NetBSD: t_thread_local_dtor.sh,v 1.1 2017/07/11 15:21:36 joerg Exp $
#
# Copyright (c) 2008 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
atf_test_case thread_local_dtor_order
thread_local_dtor_order_head()
{
atf_set "descr" "Checks destructor order for thread_local objects"
}
thread_local_dtor_order_body()
{
atf_check -o ignore "$(atf_get_srcdir)/h_thread_local_dtor"
}
atf_init_test_cases()
{
atf_add_test_case thread_local_dtor_order
}

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.8 2014/08/25 20:40:53 joerg Exp $
# $NetBSD: Makefile,v 1.9 2017/07/11 15:21:36 joerg Exp $
#
NOMAN= # defined
@ -7,7 +7,7 @@ NOMAN= # defined
.if ${MKPIC} != "no"
SUBDIR+= helper_dso1 .WAIT helper_dso2 .WAIT \
SUBDIR+= helper_dso1 helper_dso3 .WAIT helper_dso2 .WAIT \
helper_ifunc_dso \
helper_symver_dso0 .WAIT helper_symver_dso1 .WAIT \
helper_symver_dso2 .WAIT \
@ -22,7 +22,7 @@ LDADD.t_dlvsym= -Wl,-rpath,${TESTSDIR}/h_helper_symver_dso2
LDADD.t_ifunc= -Wl,-rpath,${TESTSDIR} -lutil
DPADD.t_ifunc= ${LIBUTIL}
TESTS_SH+= t_df_1_noopen t_dl_symver
TESTS_SH+= t_df_1_noopen t_dl_symver t_thread_local_dtor
BINDIR= ${TESTSDIR}
PROGS+= h_df_1_noopen1
@ -32,6 +32,9 @@ PROGS+= h_df_1_noopen2
SRCS.h_df_1_noopen2= h_df_1_noopen.c
LDADD.h_df_1_noopen2= -lpthread
PROGS+= h_thread_local_dtor
LDADD.h_thread_local_dtor= -Wl,-rpath,${TESTSDIR} -lpthread
PROGS+= h_ifunc
SRCS.h_ifunc= h_ifunc.c
IFUNCDIR!= cd ${.CURDIR}/helper_ifunc_dso && ${PRINTOBJDIR}

View File

@ -0,0 +1,92 @@
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Joerg Sonnenberger.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <dlfcn.h>
#include <err.h>
#include <pthread.h>
#include <stdio.h>
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
static void *
thread_helper(void *arg)
{
void (*testfunc)(void) = arg;
testfunc();
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond1);
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond2, &mutex);
pthread_mutex_unlock(&mutex);
return NULL;
}
int
main(void)
{
void *dso;
void (*testfunc)(void);
pthread_t thread;
dso = dlopen("libh_helper_dso3.so", RTLD_LAZY);
if (dso == NULL)
errx(1, "%s", dlerror());
testfunc = dlsym(dso, "testfunc");
if (testfunc == NULL)
errx(1, "%s", dlerror());
pthread_mutex_lock(&mutex);
if (pthread_create(&thread, NULL, thread_helper, testfunc))
err(1, "pthread_create");
pthread_cond_wait(&cond1, &mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond2);
pthread_mutex_unlock(&mutex);
printf("before dlclose\n");
dlclose(dso);
printf("after dlclose\n");
dso = dlopen("libh_helper_dso3.so", RTLD_LAZY);
if (dso == NULL)
errx(1, "%s", dlerror());
dlclose(dso);
if (pthread_join(thread, NULL))
err(1, "pthread_join");
return 0;
}

View File

@ -0,0 +1,22 @@
# $NetBSD: Makefile,v 1.1 2017/07/11 15:21:36 joerg Exp $
.include <bsd.own.mk>
LIB= h_helper_dso3
LIBISCXX= yes
SRCS= h_helper_dso3.cpp
LIBDIR= ${TESTSBASE}/libexec/ld.elf_so
SHLIBDIR= ${TESTSBASE}/libexec/ld.elf_so
SHLIB_MAJOR= 1
MKSTATICLIB= no
MKPROFILE= no
MKPICINSTALL= no
MKLINT= no
NOMAN= # defined
CXXFLAGS+= -std=c++11
.include <bsd.lib.mk>

View File

@ -0,0 +1,46 @@
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Joerg Sonnenberger.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdio>
struct VerboseDestructor {
const char *identifier;
VerboseDestructor(const char *identifier_) : identifier(identifier_) {
printf("in ctor: %s\n", identifier);
}
~VerboseDestructor() {
printf("in dtor: %s\n", identifier);
}
};
static VerboseDestructor global_dtor("global_dtor");
extern "C" void testfunc(void) {
static thread_local VerboseDestructor tls_dtor("thread_local");
}

View File

@ -0,0 +1,54 @@
# $NetBSD: t_thread_local_dtor.sh,v 1.1 2017/07/11 15:21:36 joerg Exp $
#
# Copyright (c) 2017 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
atf_test_case thread_local_dtor
thread_local_dtor_head()
{
atf_set "descr" "Checks dlclose vs thread_local"
}
thread_local_dtor_body()
{
$(atf_get_srcdir)/h_thread_local_dtor >out \
|| atf_fail "h_thread_local_dtor failed, see output of the test for details"
cat >exp <<EOF
in ctor: global_dtor
in ctor: thread_local
before dlclose
after dlclose
in dtor: thread_local
in dtor: global_dtor
EOF
diff -Nru exp out \
|| atf_fail "h_thread_local_dtor failed, see output of the test for details"
}
atf_init_test_cases()
{
atf_add_test_case thread_local_dtor
}