From: Yuxuan Shui <yshui(a)codeweavers.com> --- dlls/winecrt0/crt_dllmain.c | 79 ++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/dlls/winecrt0/crt_dllmain.c b/dlls/winecrt0/crt_dllmain.c index 181760c884a..7cdd24c4516 100644 --- a/dlls/winecrt0/crt_dllmain.c +++ b/dlls/winecrt0/crt_dllmain.c @@ -22,12 +22,89 @@ #include <stdarg.h> #include <stdio.h> +#include <process.h> #include "windef.h" #include "winbase.h" +#if defined(__GNUC__) +/* Reference: mingw-w64-crt: crt/gccmain.c */ +typedef void (*fnptr)(void); +extern fnptr __CTOR_LIST__[]; +extern fnptr __DTOR_LIST__[]; +#elif defined(_MSC_VER) +/* Sections named .CRT$??? in objects files are automatically merged into .CRT in the + * final binary during linking, sorted by the section names alphabetically. The names + * don't have significance to the linker but conventions do apply. */ +#pragma section(".CRT$XIA", read, write) +#pragma section(".CRT$XIZ", read, write) +#pragma section(".CRT$XCA", read, write) +#pragma section(".CRT$XCZ", read, write) +#pragma section(".CRT$XTA", read, write) +#pragma section(".CRT$XTZ", read, write) +#pragma comment(linker, "/merge:.CRT=.rdata") +__declspec(allocate(".CRT$XIA")) _PIFV __xi_a[] = { NULL }; +__declspec(allocate(".CRT$XIZ")) _PIFV __xi_z[] = { NULL }; +__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[] = { NULL }; +__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[] = { NULL }; +__declspec(allocate(".CRT$XTA")) _PVFV __xt_a[] = { NULL }; +__declspec(allocate(".CRT$XTZ")) _PVFV __xt_z[] = { NULL }; +#endif + +static inline void initterm( _PVFV *start,_PVFV *end ) +{ + _PVFV* current = start; + + while (current<end) + { + if (*current) + (**current)(); + current++; + } +} + +static inline int initterm_e( _PIFV *table, _PIFV *end ) +{ + int res = 0; + + while (!res && table < end) { + if (*table) + res = (**table)(); + table++; + } + return res; +} + +static void do_global_ctors(void) +{ +#if defined(__GNUC__) + ULONG_PTR nfns = (ULONG_PTR)__CTOR_LIST__[0], i; + if (nfns == (ULONG_PTR)-1) + for (nfns = 0; __CTOR_LIST__[nfns + 1]; nfns++); + for (i = nfns; i >= 1; i--) __CTOR_LIST__[i](); +#elif defined(_MSC_VER) + if (initterm_e( __xi_a, __xi_z ) != 0) return; + initterm( __xc_a, __xc_z ); +#endif +} + + +static void do_global_dtors(void) +{ +#if defined(__GNUC__) + SIZE_T i; + for (i = 1; __DTOR_LIST__[i]; i++) __DTOR_LIST__[i](); +#elif defined(_MSC_VER) + initterm( __xt_a, __xt_z ); +#endif +} + BOOL WINAPI DllMainCRTStartup( HINSTANCE inst, DWORD reason, void *reserved ) { - return DllMain( inst, reason, reserved ); + BOOL ret; + if (reason == DLL_PROCESS_ATTACH) do_global_ctors(); + ret = DllMain( inst, reason, reserved ); + if (reason == DLL_PROCESS_DETACH) do_global_dtors(); + return ret; } #endif -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9265