From: Yuxuan Shui <yshui@codeweavers.com> --- configure | 2 ++ configure.ac | 1 + dlls/winecrtend/Makefile.in | 6 +++++ dlls/winecrtend/initterm.c | 42 +++++++++++++++++++++++++++++++ dlls/winecrtend/initterm_e.c | 43 ++++++++++++++++++++++++++++++++ include/msvcrt/corecrt_startup.h | 1 + tools/makedep.c | 2 ++ tools/winegcc/winegcc.c | 1 + 8 files changed, 98 insertions(+) create mode 100644 dlls/winecrtend/Makefile.in create mode 100644 dlls/winecrtend/initterm.c create mode 100644 dlls/winecrtend/initterm_e.c diff --git a/configure b/configure index 2aaea971a4d..9cc65a877fd 100755 --- a/configure +++ b/configure @@ -1542,6 +1542,7 @@ enable_winebth_sys enable_winebus_sys enable_winecoreaudio_drv enable_winecrt0 +enable_winecrtend enable_wined3d enable_winedmo enable_winegstreamer @@ -23219,6 +23220,7 @@ wine_fn_config_makefile dlls/winebth.sys enable_winebth_sys wine_fn_config_makefile dlls/winebus.sys enable_winebus_sys wine_fn_config_makefile dlls/winecoreaudio.drv enable_winecoreaudio_drv wine_fn_config_makefile dlls/winecrt0 enable_winecrt0 +wine_fn_config_makefile dlls/winecrtend enable_winecrtend wine_fn_config_makefile dlls/wined3d enable_wined3d wine_fn_config_makefile dlls/winedmo enable_winedmo wine_fn_config_makefile dlls/winegstreamer enable_winegstreamer diff --git a/configure.ac b/configure.ac index da4a0af4a60..8c94f3d33bd 100644 --- a/configure.ac +++ b/configure.ac @@ -3360,6 +3360,7 @@ WINE_CONFIG_MAKEFILE(dlls/winebth.sys) WINE_CONFIG_MAKEFILE(dlls/winebus.sys) WINE_CONFIG_MAKEFILE(dlls/winecoreaudio.drv) WINE_CONFIG_MAKEFILE(dlls/winecrt0) +WINE_CONFIG_MAKEFILE(dlls/winecrtend) WINE_CONFIG_MAKEFILE(dlls/wined3d) WINE_CONFIG_MAKEFILE(dlls/winedmo) WINE_CONFIG_MAKEFILE(dlls/winegstreamer) diff --git a/dlls/winecrtend/Makefile.in b/dlls/winecrtend/Makefile.in new file mode 100644 index 00000000000..dddc41e4531 --- /dev/null +++ b/dlls/winecrtend/Makefile.in @@ -0,0 +1,6 @@ +STATICLIB = libwinecrtend.a + +SOURCES = \ + initterm.c \ + initterm_e.c + diff --git a/dlls/winecrtend/initterm.c b/dlls/winecrtend/initterm.c new file mode 100644 index 00000000000..5fabba2e7db --- /dev/null +++ b/dlls/winecrtend/initterm.c @@ -0,0 +1,42 @@ +/* + * _initterm fallback implementation + * + * Copyright 2025 Yuxuan Shui for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _ACRTIMP + +#include <process.h> +#include "minwindef.h" + +#include "wine/asm.h" + +/* This is a fallback version of msvcrt's _initterm. Since _initterm is used in winecrt0, + * if the final object is linked with a version of msvcrt without the _initterm function, this + * version will be used. */ +void CDECL _initterm( _PVFV *start,_PVFV *end ) +{ + _PVFV *current = start; + + while (current < end) + { + if (*current) (**current)(); + current++; + } +} + +__ASM_GLOBAL_IMPORT(_initterm) diff --git a/dlls/winecrtend/initterm_e.c b/dlls/winecrtend/initterm_e.c new file mode 100644 index 00000000000..bb4d3d2ef02 --- /dev/null +++ b/dlls/winecrtend/initterm_e.c @@ -0,0 +1,43 @@ +/* + * _initterm_e fallback implementation + * + * Copyright 2025 Yuxuan Shui for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _ACRTIMP + +#include <process.h> +#include "minwindef.h" + +#include "wine/asm.h" + +/* This is a fallback version of msvcrt's _initterm_e. Since _initterm_e is used in winecrt0, + * if the final object is linked with a version of msvcrt without the _initterm_e function, this + * version will be used. */ +int CDECL _initterm_e( _PIFV *table, _PIFV *end ) +{ + int res = 0; + + while (!res && table < end) + { + if (*table) res = (**table)(); + table++; + } + return res; +} + +__ASM_GLOBAL_IMPORT(_initterm_e) diff --git a/include/msvcrt/corecrt_startup.h b/include/msvcrt/corecrt_startup.h index c1c519da618..4094cb16150 100644 --- a/include/msvcrt/corecrt_startup.h +++ b/include/msvcrt/corecrt_startup.h @@ -26,6 +26,7 @@ typedef void (__cdecl *_PVFV)(void); typedef int (__cdecl *_PIFV)(void); typedef void (__cdecl *_PVFI)(int); +_ACRTIMP void __cdecl _initterm(_PVFV *, _PVFV *); _ACRTIMP int __cdecl _initterm_e(_PIFV *, _PIFV *); typedef struct _onexit_table_t { diff --git a/tools/makedep.c b/tools/makedep.c index acd6bb85225..e8be349c4c6 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -2277,6 +2277,7 @@ static struct strarray get_default_imports( const struct makefile *make, struct STRARRAY_FOR_EACH( imp, &imports ) if (!strcmp( imp, "winecrt0" )) return ret; strarray_add( &ret, "winecrt0" ); if (compiler_rt) strarray_add( &ret, compiler_rt ); + strarray_add( &ret, "winecrtend" ); return ret; } @@ -2291,6 +2292,7 @@ static struct strarray get_default_imports( const struct makefile *make, struct strarray_add( &ret, "kernel32" ); strarray_add( &ret, "ntdll" ); + strarray_add( &ret, "winecrtend" ); return ret; } diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index f5eb2a81d83..b1f36a29a67 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -1337,6 +1337,7 @@ static void build(struct strarray input_files, const char *output) if (is_win16_app) add_library(lib_dirs, &files, "kernel"); add_library(lib_dirs, &files, "kernel32"); add_library(lib_dirs, &files, "ntdll"); + add_library(lib_dirs, &files, "winecrtend"); } /* set default entry point, if needed */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9265