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)); }