diff --git a/sdk/lib/vcruntime/CMakeLists.txt b/sdk/lib/vcruntime/CMakeLists.txt index 633a1b7a466..405dc705bd9 100644 --- a/sdk/lib/vcruntime/CMakeLists.txt +++ b/sdk/lib/vcruntime/CMakeLists.txt @@ -20,7 +20,6 @@ list(APPEND VCRT_COMMON_SOURCES __report_gsfailure.c __report_rangecheckfailure.c __security_init_cookie.c - __vcrt_init.c _fltused.c initializers.cpp isa_available.cpp @@ -29,11 +28,13 @@ list(APPEND VCRT_COMMON_SOURCES list(APPEND VCRT_RUNTIME_SOURCES __std_terminate.c + __vcrt_init.c ) list(APPEND VCRT_STARTUP_SOURCES __acrt_initialize_stub.cpp __scrt_uninitialize_crt.cpp + __vcrt_init_stubs.c mainCRTStartup.cpp wmainCRTStartup.cpp ) diff --git a/sdk/lib/vcruntime/__vcrt_init.c b/sdk/lib/vcruntime/__vcrt_init.c index 45cce866e92..839c24de7e8 100644 --- a/sdk/lib/vcruntime/__vcrt_init.c +++ b/sdk/lib/vcruntime/__vcrt_init.c @@ -8,29 +8,64 @@ // SPDX-License-Identifier: MIT // -#include +#include + +void msvcrt_init_exception(HINSTANCE hinstDLL); +BOOL msvcrt_init_tls(void); +void msvcrt_free_tls_mem(void); +BOOL msvcrt_free_tls(void); __vcrt_bool __cdecl __vcrt_initialize(void) { - return 1; + msvcrt_init_exception(GetModuleHandle(NULL)); + + if (!msvcrt_init_tls()) + return FALSE; + + return TRUE; } __vcrt_bool __cdecl __vcrt_uninitialize(_In_ __vcrt_bool _Terminating) { - return 1; + if (!msvcrt_free_tls()) + return FALSE; + + return TRUE; } __vcrt_bool __cdecl __vcrt_uninitialize_critical(void) { - return 1; + return TRUE; } __vcrt_bool __cdecl __vcrt_thread_attach(void) { - return 1; + // Not called by UCRT + return TRUE; } __vcrt_bool __cdecl __vcrt_thread_detach(void) { - return 1; + // Not called by UCRT + return TRUE; } + +// UCRT doesn't have a thread detach callback for the vcruntime TLS, because +// the native vcruntime uses FlsAlloc and provides a cleanup callback there. +// Since we don't have that, we use TLS callbacks. +const IMAGE_TLS_DIRECTORY* __p_tls_used = &_tls_used; + +static +VOID +WINAPI +wine_tls_cleanup_callback(PVOID hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + // For the last thread, only DLL_PROCESS_DETACH is called + if ((fdwReason == DLL_THREAD_DETACH) || + (fdwReason == DLL_PROCESS_DETACH)) + { + msvcrt_free_tls_mem(); + } +} + +_CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK wine_tls_cleanup_ptr = wine_tls_cleanup_callback; diff --git a/sdk/lib/vcruntime/__vcrt_init_stubs.c b/sdk/lib/vcruntime/__vcrt_init_stubs.c new file mode 100644 index 00000000000..3b01a3f119b --- /dev/null +++ b/sdk/lib/vcruntime/__vcrt_init_stubs.c @@ -0,0 +1,36 @@ +// +// __vcrt_init_stubs.c +// +// Copyright (c) 2024 Timo Kreuzer +// +// Stubs for vcruntime initialization and termination in vcstartup. +// +// SPDX-License-Identifier: MIT +// + +#include + +__vcrt_bool __cdecl __vcrt_initialize(void) +{ + return 1; +} + +__vcrt_bool __cdecl __vcrt_uninitialize(_In_ __vcrt_bool _Terminating) +{ + return 1; +} + +__vcrt_bool __cdecl __vcrt_uninitialize_critical(void) +{ + return 1; +} + +__vcrt_bool __cdecl __vcrt_thread_attach(void) +{ + return 1; +} + +__vcrt_bool __cdecl __vcrt_thread_detach(void) +{ + return 1; +}