Module Name:    src
Committed By:   joerg
Date:           Tue Jul 11 15:21:36 UTC 2017

Modified Files:
        src/distrib/sets/lists/debug: mi shl.mi
        src/distrib/sets/lists/tests: mi shl.mi
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax: c++config.h
        src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64: c++config.h
        src/include: dlfcn.h
        src/lib/libc/dlfcn: dlfcn_elf.c
        src/lib/libc/stdlib: Makefile.inc exit.c
        src/lib/libpthread: pthread.c
        src/libexec/ld.elf_so: rtld.c rtld.h symbols.map
        src/tests/lib/libpthread: Makefile
        src/tests/libexec/ld.elf_so: Makefile
Added Files:
        src/lib/libc/include: atexit.h
        src/lib/libc/stdlib: cxa_thread_atexit.c
        src/tests/lib/libpthread: h_thread_local_dtor.cpp
            t_thread_local_dtor.sh
        src/tests/libexec/ld.elf_so: h_thread_local_dtor.c
            t_thread_local_dtor.sh
        src/tests/libexec/ld.elf_so/helper_dso3: Makefile h_helper_dso3.cpp
Removed Files:
        src/lib/libc/stdlib: atexit.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.218 -r1.219 src/distrib/sets/lists/debug/mi
cvs rdiff -u -r1.177 -r1.178 src/distrib/sets/lists/debug/shl.mi
cvs rdiff -u -r1.754 -r1.755 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.10 -r1.11 src/distrib/sets/lists/tests/shl.mi
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha/c++config.h
cvs rdiff -u -r1.20 -r1.21 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/c++config.h
cvs rdiff -u -r1.20 -r1.21 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb/c++config.h
cvs rdiff -u -r1.11 -r1.12 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm/c++config.h
cvs rdiff -u -r1.16 -r1.17 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb/c++config.h
cvs rdiff -u -r1.16 -r1.17 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf/c++config.h
cvs rdiff -u -r1.14 -r1.15 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf/c++config.h
cvs rdiff -u -r1.13 -r1.14 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa/c++config.h
cvs rdiff -u -r1.19 -r1.20 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386/c++config.h
cvs rdiff -u -r1.4 -r1.5 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64/c++config.h
cvs rdiff -u -r1.14 -r1.15 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb/c++config.h
cvs rdiff -u -r1.17 -r1.18 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el/c++config.h
cvs rdiff -u -r1.20 -r1.21 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel/c++config.h
cvs rdiff -u -r1.5 -r1.6 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k/c++config.h
cvs rdiff -u -r1.19 -r1.20 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc/c++config.h
cvs rdiff -u -r1.7 -r1.8 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64/c++config.h
cvs rdiff -u -r1.4 -r1.5 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32/c++config.h
cvs rdiff -u -r1.4 -r1.5 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb/c++config.h
cvs rdiff -u -r1.20 -r1.21 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el/c++config.h
cvs rdiff -u -r1.19 -r1.20 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc/c++config.h
cvs rdiff -u -r1.18 -r1.19 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64/c++config.h
cvs rdiff -u -r1.20 -r1.21 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/c++config.h
cvs rdiff -u -r1.22 -r1.23 \
    src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64/c++config.h
cvs rdiff -u -r1.24 -r1.25 src/include/dlfcn.h
cvs rdiff -u -r1.13 -r1.14 src/lib/libc/dlfcn/dlfcn_elf.c
cvs rdiff -u -r0 -r1.1 src/lib/libc/include/atexit.h
cvs rdiff -u -r1.92 -r1.93 src/lib/libc/stdlib/Makefile.inc
cvs rdiff -u -r1.11 -r0 src/lib/libc/stdlib/atexit.h
cvs rdiff -u -r0 -r1.1 src/lib/libc/stdlib/cxa_thread_atexit.c
cvs rdiff -u -r1.15 -r1.16 src/lib/libc/stdlib/exit.c
cvs rdiff -u -r1.149 -r1.150 src/lib/libpthread/pthread.c
cvs rdiff -u -r1.184 -r1.185 src/libexec/ld.elf_so/rtld.c
cvs rdiff -u -r1.128 -r1.129 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.1 -r1.2 src/libexec/ld.elf_so/symbols.map
cvs rdiff -u -r1.12 -r1.13 src/tests/lib/libpthread/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/lib/libpthread/h_thread_local_dtor.cpp \
    src/tests/lib/libpthread/t_thread_local_dtor.sh
cvs rdiff -u -r1.8 -r1.9 src/tests/libexec/ld.elf_so/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/libexec/ld.elf_so/h_thread_local_dtor.c \
    src/tests/libexec/ld.elf_so/t_thread_local_dtor.sh
cvs rdiff -u -r0 -r1.1 src/tests/libexec/ld.elf_so/helper_dso3/Makefile \
    src/tests/libexec/ld.elf_so/helper_dso3/h_helper_dso3.cpp

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/debug/mi
diff -u src/distrib/sets/lists/debug/mi:1.218 src/distrib/sets/lists/debug/mi:1.219
--- src/distrib/sets/lists/debug/mi:1.218	Fri Jun  9 06:09:01 2017
+++ src/distrib/sets/lists/debug/mi	Tue Jul 11 15:21:31 2017
@@ -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

Index: src/distrib/sets/lists/debug/shl.mi
diff -u src/distrib/sets/lists/debug/shl.mi:1.177 src/distrib/sets/lists/debug/shl.mi:1.178
--- src/distrib/sets/lists/debug/shl.mi:1.177	Thu Jun 15 16:00:57 2017
+++ src/distrib/sets/lists/debug/shl.mi	Tue Jul 11 15:21:31 2017
@@ -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

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.754 src/distrib/sets/lists/tests/mi:1.755
--- src/distrib/sets/lists/tests/mi:1.754	Mon Jul  3 06:01:16 2017
+++ src/distrib/sets/lists/tests/mi	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/distrib/sets/lists/tests/shl.mi
diff -u src/distrib/sets/lists/tests/shl.mi:1.10 src/distrib/sets/lists/tests/shl.mi:1.11
--- src/distrib/sets/lists/tests/shl.mi:1.10	Mon Jun 22 06:02:02 2015
+++ src/distrib/sets/lists/tests/shl.mi	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha/c++config.h:1.18	Tue Oct 18 01:32:56 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/alpha/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/c++config.h:1.20 src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/c++config.h:1.21
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/c++config.h:1.20	Tue Oct 18 01:32:56 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/arm/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb/c++config.h:1.20 src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb/c++config.h:1.21
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb/c++config.h:1.20	Tue Oct 18 01:32:56 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/armeb/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire/c++config.h:1.11 src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire/c++config.h:1.12
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire/c++config.h:1.11	Tue Oct 18 01:32:56 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/coldfire/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm/c++config.h:1.18	Tue Oct 18 01:32:56 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earm/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb/c++config.h:1.16 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb/c++config.h:1.17
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb/c++config.h:1.16	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmeb/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf/c++config.h:1.16 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf/c++config.h:1.17
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf/c++config.h:1.16	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhf/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb/c++config.h:1.14 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb/c++config.h:1.15
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb/c++config.h:1.14	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmhfeb/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv4eb/c++config.h	Tue Jul 11 15:21:32 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6eb/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hf/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv6hfeb/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb/c++config.h:1.13	Tue Oct 18 01:32:57 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7eb/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf/c++config.h:1.13	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hf/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb/c++config.h:1.13 src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb/c++config.h:1.14
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb/c++config.h:1.13	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/earmv7hfeb/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa/c++config.h:1.18	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/hppa/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386/c++config.h:1.19 src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386/c++config.h:1.20
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386/c++config.h:1.19	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/i386/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64/c++config.h:1.4 src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64/c++config.h:1.5
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64/c++config.h:1.4	Thu Jun 30 01:44:49 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/ia64/c++config.h	Tue Jul 11 15:21:33 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000/c++config.h:1.14 src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000/c++config.h:1.15
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000/c++config.h:1.14	Sat Jun 17 17:12:03 2017
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68000/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k/c++config.h:1.18	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/m68k/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb/c++config.h:1.18	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64eb/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el/c++config.h:1.17 src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el/c++config.h:1.18
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el/c++config.h:1.17	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/mips64el/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb/c++config.h:1.20 src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb/c++config.h:1.21
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb/c++config.h:1.20	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipseb/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel/c++config.h:1.18	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/mipsel/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k/c++config.h:1.5 src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k/c++config.h:1.6
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k/c++config.h:1.5	Sat Jan 10 22:59:40 2015
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/or1k/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc/c++config.h:1.19 src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc/c++config.h:1.20
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc/c++config.h:1.19	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64/c++config.h:1.7 src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64/c++config.h:1.8
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64/c++config.h:1.7	Tue Oct 18 01:32:58 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/powerpc64/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32/c++config.h:1.4 src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32/c++config.h:1.5
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32/c++config.h:1.4	Sat Jan 10 22:59:40 2015
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv32/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64/c++config.h:1.4 src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64/c++config.h:1.5
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64/c++config.h:1.4	Sat Jan 10 22:59:40 2015
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/riscv64/c++config.h	Tue Jul 11 15:21:34 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb/c++config.h:1.18	Tue Oct 18 01:32:59 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3eb/c++config.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el/c++config.h:1.20 src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el/c++config.h:1.21
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el/c++config.h:1.20	Tue Oct 18 01:32:59 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/sh3el/c++config.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc/c++config.h:1.19 src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc/c++config.h:1.20
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc/c++config.h:1.19	Tue Oct 18 01:32:59 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc/c++config.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64/c++config.h:1.18 src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64/c++config.h:1.19
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64/c++config.h:1.18	Tue Oct 18 01:32:59 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/sparc64/c++config.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/c++config.h:1.20 src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/c++config.h:1.21
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/c++config.h:1.20	Tue Oct 18 01:32:59 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/vax/c++config.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64/c++config.h
diff -u src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64/c++config.h:1.22 src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64/c++config.h:1.23
--- src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64/c++config.h:1.22	Tue Oct 18 01:32:59 2016
+++ src/external/gpl3/gcc/lib/libstdc++-v3/arch/x86_64/c++config.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/include/dlfcn.h
diff -u src/include/dlfcn.h:1.24 src/include/dlfcn.h:1.25
--- src/include/dlfcn.h:1.24	Thu Feb 16 23:00:39 2012
+++ src/include/dlfcn.h	Tue Jul 11 15:21:35 2017
@@ -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

Index: src/lib/libc/dlfcn/dlfcn_elf.c
diff -u src/lib/libc/dlfcn/dlfcn_elf.c:1.13 src/lib/libc/dlfcn/dlfcn_elf.c:1.14
--- src/lib/libc/dlfcn/dlfcn_elf.c:1.13	Sun Jun 24 15:26:03 2012
+++ src/lib/libc/dlfcn/dlfcn_elf.c	Tue Jul 11 15:21:35 2017
@@ -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 d
 
 	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)
+{
+}

Index: src/lib/libc/stdlib/Makefile.inc
diff -u src/lib/libc/stdlib/Makefile.inc:1.92 src/lib/libc/stdlib/Makefile.inc:1.93
--- src/lib/libc/stdlib/Makefile.inc:1.92	Fri Apr  1 12:37:48 2016
+++ src/lib/libc/stdlib/Makefile.inc	Tue Jul 11 15:21:35 2017
@@ -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 \

Index: src/lib/libc/stdlib/exit.c
diff -u src/lib/libc/stdlib/exit.c:1.15 src/lib/libc/stdlib/exit.c:1.16
--- src/lib/libc/stdlib/exit.c:1.15	Wed May 18 19:36:36 2011
+++ src/lib/libc/stdlib/exit.c	Tue Jul 11 15:21:35 2017
@@ -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)

Index: src/lib/libpthread/pthread.c
diff -u src/lib/libpthread/pthread.c:1.149 src/lib/libpthread/pthread.c:1.150
--- src/lib/libpthread/pthread.c:1.149	Sun Jul  2 17:13:07 2017
+++ src/lib/libpthread/pthread.c	Tue Jul 11 15:21:35 2017
@@ -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
 #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);
 

Index: src/libexec/ld.elf_so/rtld.c
diff -u src/libexec/ld.elf_so/rtld.c:1.184 src/libexec/ld.elf_so/rtld.c:1.185
--- src/libexec/ld.elf_so/rtld.c:1.184	Thu Jun  8 18:24:39 2017
+++ src/libexec/ld.elf_so/rtld.c	Tue Jul 11 15:21:35 2017
@@ -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 d
 	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()

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.128 src/libexec/ld.elf_so/rtld.h:1.129
--- src/libexec/ld.elf_so/rtld.h:1.128	Sun Jul  9 17:57:59 2017
+++ src/libexec/ld.elf_so/rtld.h	Tue Jul 11 15:21:35 2017
@@ -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 (*)
     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__)
 /*

Index: src/libexec/ld.elf_so/symbols.map
diff -u src/libexec/ld.elf_so/symbols.map:1.1 src/libexec/ld.elf_so/symbols.map:1.2
--- src/libexec/ld.elf_so/symbols.map:1.1	Thu Dec  1 14:29:15 2016
+++ src/libexec/ld.elf_so/symbols.map	Tue Jul 11 15:21:35 2017
@@ -22,5 +22,6 @@
     __tls_get_addr;
     ___tls_get_addr;
     __gnu_Unwind_Find_exidx;
+    __dl_cxa_refcount;
   local: *;
 };

Index: src/tests/lib/libpthread/Makefile
diff -u src/tests/lib/libpthread/Makefile:1.12 src/tests/lib/libpthread/Makefile:1.13
--- src/tests/lib/libpthread/Makefile:1.12	Sun Oct 30 16:17:16 2016
+++ src/tests/lib/libpthread/Makefile	Tue Jul 11 15:21:36 2017
@@ -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

Index: src/tests/libexec/ld.elf_so/Makefile
diff -u src/tests/libexec/ld.elf_so/Makefile:1.8 src/tests/libexec/ld.elf_so/Makefile:1.9
--- src/tests/libexec/ld.elf_so/Makefile:1.8	Mon Aug 25 20:40:53 2014
+++ src/tests/libexec/ld.elf_so/Makefile	Tue Jul 11 15:21:36 2017
@@ -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}/
 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}

Added files:

Index: src/lib/libc/include/atexit.h
diff -u /dev/null src/lib/libc/include/atexit.h:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/lib/libc/include/atexit.h	Tue Jul 11 15:21:35 2017
@@ -0,0 +1,41 @@
+/*	$NetBSD: atexit.h,v 1.1 2017/07/11 15:21:35 joerg Exp $	*/
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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 <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

Index: src/lib/libc/stdlib/cxa_thread_atexit.c
diff -u /dev/null src/lib/libc/stdlib/cxa_thread_atexit.c:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/lib/libc/stdlib/cxa_thread_atexit.c	Tue Jul 11 15:21:35 2017
@@ -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 <jo...@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;
+}

Index: src/tests/lib/libpthread/h_thread_local_dtor.cpp
diff -u /dev/null src/tests/lib/libpthread/h_thread_local_dtor.cpp:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/tests/lib/libpthread/h_thread_local_dtor.cpp	Tue Jul 11 15:21:36 2017
@@ -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;
+}
Index: src/tests/lib/libpthread/t_thread_local_dtor.sh
diff -u /dev/null src/tests/lib/libpthread/t_thread_local_dtor.sh:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/tests/lib/libpthread/t_thread_local_dtor.sh	Tue Jul 11 15:21:36 2017
@@ -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
+}

Index: src/tests/libexec/ld.elf_so/h_thread_local_dtor.c
diff -u /dev/null src/tests/libexec/ld.elf_so/h_thread_local_dtor.c:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/tests/libexec/ld.elf_so/h_thread_local_dtor.c	Tue Jul 11 15:21:36 2017
@@ -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;
+}
Index: src/tests/libexec/ld.elf_so/t_thread_local_dtor.sh
diff -u /dev/null src/tests/libexec/ld.elf_so/t_thread_local_dtor.sh:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/tests/libexec/ld.elf_so/t_thread_local_dtor.sh	Tue Jul 11 15:21:36 2017
@@ -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
+}

Index: src/tests/libexec/ld.elf_so/helper_dso3/Makefile
diff -u /dev/null src/tests/libexec/ld.elf_so/helper_dso3/Makefile:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/tests/libexec/ld.elf_so/helper_dso3/Makefile	Tue Jul 11 15:21:36 2017
@@ -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>
Index: src/tests/libexec/ld.elf_so/helper_dso3/h_helper_dso3.cpp
diff -u /dev/null src/tests/libexec/ld.elf_so/helper_dso3/h_helper_dso3.cpp:1.1
--- /dev/null	Tue Jul 11 15:21:37 2017
+++ src/tests/libexec/ld.elf_so/helper_dso3/h_helper_dso3.cpp	Tue Jul 11 15:21:36 2017
@@ -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");
+}

Reply via email to