crt: tls: Call __dyn_tls_dtor also from the thread_local_exe_atexit_callback msvc/UCRT calls the __dyn_tls_dtor function two times, once during the exit() call via thread_local_exe_atexit_callback and second time from the PE TLS callback. So do the same thing in mingw-w64. Stores the __dyn_tls_dtor pointer into the tentative __dyn_tls_dtor_callback variable, so it can be referenced and called on demand. msvc also provides the __dyn_tls_dtor_callback symbol. Note that __dyn_tls_dtor has already guard which prevents duplicate execution of individual callbacks. This change fixes execution order of atexit and __dyn_tls_dtor callbacks by executing all __dyn_tls_dtor callbacks before atexit callbacks. This matches the msvc behavior. Signed-off-by: LIU Hao <lh_mouse@126.com>
diff --git a/mingw-w64-crt/crt/tls_exe_atexit_callback.c b/mingw-w64-crt/crt/tls_exe_atexit_callback.c index fa9d270..9db49ac 100644 --- a/mingw-w64-crt/crt/tls_exe_atexit_callback.c +++ b/mingw-w64-crt/crt/tls_exe_atexit_callback.c
@@ -6,6 +6,7 @@ #include <process.h> +const _tls_callback_type __dyn_tls_dtor_callback __attribute__((common)); /* tentative */ const _tls_callback_type __mingw_cxa_atexit_callback_ptr __attribute__((common)); /* tentative */ #if defined(__i386__) @@ -14,6 +15,8 @@ #endif static void __stdcall tls_exe_atexit_callback(void *handle, unsigned long reason, void *reserved) { + if (__dyn_tls_dtor_callback) + __dyn_tls_dtor_callback(handle, reason, reserved); if (__mingw_cxa_atexit_callback_ptr) __mingw_cxa_atexit_callback_ptr(handle, reason, reserved); }
diff --git a/mingw-w64-crt/crt/tlsdtor.c b/mingw-w64-crt/crt/tlsdtor.c index 22880ce..2441590 100644 --- a/mingw-w64-crt/crt/tlsdtor.c +++ b/mingw-w64-crt/crt/tlsdtor.c
@@ -13,6 +13,7 @@ #include <sect_attribs.h> #include <memory.h> #include <malloc.h> +#include <process.h> #include <corecrt_startup.h> #include <thread_local.h> @@ -97,8 +98,13 @@ } } +const _tls_callback_type __dyn_tls_dtor_callback = __dyn_tls_dtor; static _CRTALLOC(".CRT$XLD") const PIMAGE_TLS_CALLBACK __xl_d = __dyn_tls_dtor; +/* Force inclusion of code which registers __dyn_tls_dtor_callback for EXE builds */ +extern const uintptr_t __mingw_register_thread_local_exe_atexit_callback_provider; +static __attribute__((used)) const void *const _include_dyn_tls_dtor_callback_caller = &__mingw_register_thread_local_exe_atexit_callback_provider; + /* Force tlssup.c (_tls_used symbol for .tls linker section) to be linked. */ extern const IMAGE_TLS_DIRECTORY _tls_used; static __attribute__((destructor)) void _include_tls_used(void) { asm volatile ("" :: "r" (&_tls_used)); }