improve windows static library initialization to account for thread local destructors (issue #944)

This commit is contained in:
Daan 2024-10-23 01:10:00 -07:00
parent d951b4dd23
commit 925efaeac9

View File

@ -641,26 +641,47 @@ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
#elif !defined(MI_WIN_USE_FLS) #elif !defined(MI_WIN_USE_FLS)
#define MI_PRIM_HAS_PROCESS_ATTACH 1 #define MI_PRIM_HAS_PROCESS_ATTACH 1
static void NTAPI mi_win_main_attach(PVOID module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {
mi_win_main(module, reason, reserved);
}
}
static void NTAPI mi_win_main_detach(PVOID module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {
mi_win_main(module, reason, reserved);
}
}
// Set up TLS callbacks in a statically linked library by using special data sections. // Set up TLS callbacks in a statically linked library by using special data sections.
// See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows> // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>
// We may use ".CRT$XLY" instead of "B" -- see also issue #869. // We use 2 entries to ensure we call attach events before constructors
// are called, and detach events after destructors are called.
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
#if defined(_WIN64) #if defined(_WIN64)
#pragma comment(linker, "/INCLUDE:_tls_used") #pragma comment(linker, "/INCLUDE:_tls_used")
#pragma comment(linker, "/INCLUDE:_mi_tls_callback") #pragma comment(linker, "/INCLUDE:_mi_tls_callback_pre")
#pragma const_seg(".CRT$XLB") #pragma comment(linker, "/INCLUDE:_mi_tls_callback_post")
extern const PIMAGE_TLS_CALLBACK _mi_tls_callback[]; #pragma const_seg(".CRT$XLB")
const PIMAGE_TLS_CALLBACK _mi_tls_callback[] = { &mi_win_main }; extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];
#pragma const_seg() const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };
#pragma const_seg()
#pragma const_seg(".CRT$XLY")
extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];
const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };
#pragma const_seg()
#else #else
#pragma comment(linker, "/INCLUDE:__tls_used") #pragma comment(linker, "/INCLUDE:__tls_used")
#pragma comment(linker, "/INCLUDE:__mi_tls_callback") #pragma comment(linker, "/INCLUDE:__mi_tls_callback_pre")
#pragma data_seg(".CRT$XLB") #pragma comment(linker, "/INCLUDE:__mi_tls_callback_post")
PIMAGE_TLS_CALLBACK _mi_tls_callback[] = { &mi_win_main }; #pragma data_seg(".CRT$XLB")
#pragma data_seg() PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };
#pragma data_seg()
#pragma data_seg(".CRT$XLY")
PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };
#pragma data_seg()
#endif #endif
#if defined(__cplusplus) #if defined(__cplusplus)