[PATCH v9 0/4] MR9265: crt: Run MSVC constructors and destructors
There are several motivations to enable ctor/dtor support: 1. ASan. This is not just about my wine-asan work, this is important for @bernhardu's PE asan work as well. The compiler generates ctors that poisons memory around global variables so misuses of them can be caught. This is the same both of our implementations of ASan. 2. Building third-party codebases against wine's CRT. This is not necessary for mingw-gcc or llvm-mingw, but the MSVC frontend of clang is another option for cross-compiling to Windows. However right now that requires Windows SDK. Bringing wine CRT to the point of being functional enough will give us another option. Could be useful for things like Proton. 3. (Controversial) Many dlls perform init/deinit tasks in `DllMain`. Some of them might benefit from a conversion to ctor/dtor. Since nothing in wine uses ctor/dtor right now, this change shouldn't have any impact by itself. -- v9: crt: Run MSVC constructors and destructors. winecrtend: New staticlib hosting fallbacks of initterm and initterm_e. https://gitlab.winehq.org/wine/wine/-/merge_requests/9265
From: Yuxuan Shui <yshui@codeweavers.com> --- tools/winebuild/build.h | 1 + tools/winebuild/spec16.c | 1 + tools/winebuild/spec32.c | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 3acf987aab2..0cabc4648db 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -301,6 +301,7 @@ extern void output_imports( DLLSPEC *spec ); extern void output_import_lib( DLLSPEC *spec, struct strarray files ); extern void output_static_lib( const char *output_name, struct strarray files, int create ); extern void output_exports( DLLSPEC *spec ); +extern void output_crt_sections(void); extern int load_res32_file( const char *name, DLLSPEC *spec ); extern void output_resources( DLLSPEC *spec ); extern void output_bin_resources( DLLSPEC *spec, unsigned int start_rva ); diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index face1c551d9..d16e97eabe6 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -790,6 +790,7 @@ void output_spec16_file( DLLSPEC *spec16 ) output_stubs( spec16 ); output_exports( spec32 ); output_imports( spec16 ); + output_crt_sections(); if (!strcmp( spec16->dll_name, "kernel" )) output_asm_relays16(); if (needs_get_pc_thunk) output_get_pc_thunk(); if (spec16->main_module) diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 7099e82e0f6..ef280b7f51e 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -703,6 +703,32 @@ static void output_load_config(void) } +void output_crt_sections(void) +{ + /* Generate the start/end symbols for .CRT$X?? sections. The start symbol is put into + * .CRT$X?A, the end .CRT$X?Z. Since the linker sort .CRT$X?? sections by name, these symbols + * will end up at the right location.*/ + static const char sections[] = "ict"; + int i; + for (i = 0; sections[i]; i++) + { + char *symbol_name = strmake( "__x%c_a", sections[i] ); + output( "\t.section .CRT$X%cA\n", toupper( sections[i] ) ); + output( "\t.globl %s\n", asm_name( symbol_name ) ); + output( "\t.balign %u\n", get_ptr_size() ); + output( "%s:\n", asm_name( symbol_name ) ); + output( "\t%s 0\n", get_asm_ptr_keyword() ); + + symbol_name = strmake( "__x%c_z", sections[i] ); + output( "\t.section .CRT$X%cZ\n", toupper( sections[i] ) ); + output( "\t.globl %s\n", asm_name( symbol_name ) ); + output( "\t.balign %u\n", get_ptr_size() ); + output( "%s:\n", asm_name( symbol_name ) ); + output( "\t%s 0\n", get_asm_ptr_keyword() ); + } +} + + /******************************************************************* * output_module * @@ -841,6 +867,7 @@ void output_spec32_file( DLLSPEC *spec ) output_imports( spec ); if (needs_get_pc_thunk) output_get_pc_thunk(); output_load_config(); + output_crt_sections(); output_resources( spec ); output_gnu_stack_note(); close_output_file(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9265
From: Yuxuan Shui <yshui@codeweavers.com> On mingw targets this is already done by ld's linker script. --- tools/winegcc/winegcc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 7458fb08773..724bb9208d5 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -628,6 +628,9 @@ static struct strarray get_link_args( const char *output_name ) strarray_add( &link_args, strmake( "-Wl,-filealign:%s,-align:%s,-driver", file_align, section_align )); + /* Merge .CRT sections into .rdata */ + strarray_add( &link_args, "-Wl,-merge:.CRT=.rdata" ); + strarray_addall( &link_args, flags ); return link_args; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9265
From: Yuxuan Shui <yshui@codeweavers.com> --- configure | 2 ++ configure.ac | 1 + dlls/winecrtend/Makefile.in | 4 ++++ dlls/winecrtend/initterm.c | 18 ++++++++++++++++++ dlls/winecrtend/initterm_e.c | 17 +++++++++++++++++ tools/makedep.c | 2 ++ tools/winegcc/winegcc.c | 1 + 7 files changed, 45 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 21afe885c1b..a0338594543 100755 --- a/configure +++ b/configure @@ -1541,6 +1541,7 @@ enable_winebth_sys enable_winebus_sys enable_winecoreaudio_drv enable_winecrt0 +enable_winecrtend enable_wined3d enable_winedmo enable_winegstreamer @@ -23216,6 +23217,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 1d3165dff84..1c24832a86b 100644 --- a/configure.ac +++ b/configure.ac @@ -3358,6 +3358,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..d0f04e50baa --- /dev/null +++ b/dlls/winecrtend/Makefile.in @@ -0,0 +1,4 @@ +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..448456e0f9f --- /dev/null +++ b/dlls/winecrtend/initterm.c @@ -0,0 +1,18 @@ +#include <process.h> +#include "minwindef.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++; + } +} + diff --git a/dlls/winecrtend/initterm_e.c b/dlls/winecrtend/initterm_e.c new file mode 100644 index 00000000000..ff0c7da65ba --- /dev/null +++ b/dlls/winecrtend/initterm_e.c @@ -0,0 +1,17 @@ +#include <process.h> +#include "minwindef.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; +} diff --git a/tools/makedep.c b/tools/makedep.c index efc7517f0c8..f491ecf1930 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -2279,6 +2279,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; } @@ -2293,6 +2294,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 724bb9208d5..a43153b0d7f 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -1336,6 +1336,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
From: Yuxuan Shui <yshui@codeweavers.com> --- dlls/msvcr100/Makefile.in | 1 + dlls/msvcr110/Makefile.in | 1 + dlls/msvcr120/Makefile.in | 1 + dlls/msvcr70/Makefile.in | 1 + dlls/msvcr71/Makefile.in | 1 + dlls/msvcr80/Makefile.in | 1 + dlls/msvcr90/Makefile.in | 1 + dlls/msvcrt/Makefile.in | 1 + dlls/msvcrt/crt_init.c | 36 ++++++++++++++++++++++++++++++++++++ dlls/msvcrt/crt_main.c | 2 ++ dlls/msvcrt/crt_wmain.c | 2 ++ dlls/ucrtbase/Makefile.in | 1 + dlls/winecrt0/crt_dllmain.c | 28 +++++++++++++++++++++++++++- 13 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 dlls/msvcrt/crt_init.c diff --git a/dlls/msvcr100/Makefile.in b/dlls/msvcr100/Makefile.in index a0a3f64d6bf..34182e69f19 100644 --- a/dlls/msvcr100/Makefile.in +++ b/dlls/msvcr100/Makefile.in @@ -10,6 +10,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcr110/Makefile.in b/dlls/msvcr110/Makefile.in index e6798427795..fdbcba054d4 100644 --- a/dlls/msvcr110/Makefile.in +++ b/dlls/msvcr110/Makefile.in @@ -10,6 +10,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcr120/Makefile.in b/dlls/msvcr120/Makefile.in index b233753fa2e..3465d77a31e 100644 --- a/dlls/msvcr120/Makefile.in +++ b/dlls/msvcr120/Makefile.in @@ -10,6 +10,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcr70/Makefile.in b/dlls/msvcr70/Makefile.in index 9413738ae1f..be93d88764b 100644 --- a/dlls/msvcr70/Makefile.in +++ b/dlls/msvcr70/Makefile.in @@ -9,6 +9,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcr71/Makefile.in b/dlls/msvcr71/Makefile.in index 6e0b855cac3..c59ce97e8e4 100644 --- a/dlls/msvcr71/Makefile.in +++ b/dlls/msvcr71/Makefile.in @@ -9,6 +9,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcr80/Makefile.in b/dlls/msvcr80/Makefile.in index 2a84383f79d..78accf161e9 100644 --- a/dlls/msvcr80/Makefile.in +++ b/dlls/msvcr80/Makefile.in @@ -9,6 +9,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcr90/Makefile.in b/dlls/msvcr90/Makefile.in index d476d2e3080..3dfc080e554 100644 --- a/dlls/msvcr90/Makefile.in +++ b/dlls/msvcr90/Makefile.in @@ -9,6 +9,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcrt/Makefile.in b/dlls/msvcrt/Makefile.in index aa068b62e51..a4023568d71 100644 --- a/dlls/msvcrt/Makefile.in +++ b/dlls/msvcrt/Makefile.in @@ -9,6 +9,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/msvcrt/crt_init.c b/dlls/msvcrt/crt_init.c new file mode 100644 index 00000000000..fed6d821a68 --- /dev/null +++ b/dlls/msvcrt/crt_init.c @@ -0,0 +1,36 @@ +/* Utility functions for calling MSVC/MingW ctors & dtors from mainCRTStartup. */ + +#if 0 +#pragma makedep implib +#endif + +#include <process.h> +#include <stdlib.h> +#include "minwindef.h" + +extern _PIFV __xi_a[]; +extern _PIFV __xi_z[]; +extern _PVFV __xc_a[]; +extern _PVFV __xc_z[]; +extern _PVFV __xt_a[]; +extern _PVFV __xt_z[]; + +int CDECL _initterm_e(_PIFV *table, _PIFV *end); +void CDECL _initterm(_PVFV *,_PVFV *); + +static __cdecl void do_global_dtors(void) +{ + _initterm(__xt_a, __xt_z); +} + +void do_global_ctors(void) +{ + if (_initterm_e(__xi_a, __xi_z) != 0) return; + _initterm(__xc_a, __xc_z); + +#ifdef _UCRT + _crt_atexit(do_global_dtors); +#else + _onexit((_onexit_t)do_global_dtors); +#endif +} diff --git a/dlls/msvcrt/crt_main.c b/dlls/msvcrt/crt_main.c index eb785e30bb0..5eb9e5032a0 100644 --- a/dlls/msvcrt/crt_main.c +++ b/dlls/msvcrt/crt_main.c @@ -31,6 +31,7 @@ #include "winternl.h" int __cdecl main(int argc, char **argv, char **env); +void do_global_ctors( void ); static const IMAGE_NT_HEADERS *get_nt_header( void ) { @@ -54,6 +55,7 @@ int __cdecl mainCRTStartup(void) __getmainargs(&argc, &argv, &env, 0, &new_mode); #endif _set_app_type(get_nt_header()->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ? _crt_gui_app : _crt_console_app); + do_global_ctors(); ret = main(argc, argv, env); diff --git a/dlls/msvcrt/crt_wmain.c b/dlls/msvcrt/crt_wmain.c index 79755d1a6e9..71cc0e48ec7 100644 --- a/dlls/msvcrt/crt_wmain.c +++ b/dlls/msvcrt/crt_wmain.c @@ -31,6 +31,7 @@ #include "winternl.h" int __cdecl wmain(int argc, WCHAR **argv, WCHAR **env); +void do_global_ctors(void); static const IMAGE_NT_HEADERS *get_nt_header( void ) { @@ -54,6 +55,7 @@ int __cdecl wmainCRTStartup(void) __wgetmainargs(&argc, &argv, &env, 0, &new_mode); #endif _set_app_type(get_nt_header()->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI ? _crt_gui_app : _crt_console_app); + do_global_ctors(); ret = wmain(argc, argv, env); diff --git a/dlls/ucrtbase/Makefile.in b/dlls/ucrtbase/Makefile.in index a3bb54750af..1bd1073dcf1 100644 --- a/dlls/ucrtbase/Makefile.in +++ b/dlls/ucrtbase/Makefile.in @@ -9,6 +9,7 @@ SOURCES = \ console.c \ cpp.c \ crt_gccmain.c \ + crt_init.c \ crt_main.c \ crt_winmain.c \ crt_wmain.c \ diff --git a/dlls/winecrt0/crt_dllmain.c b/dlls/winecrt0/crt_dllmain.c index 181760c884a..030e5c8345c 100644 --- a/dlls/winecrt0/crt_dllmain.c +++ b/dlls/winecrt0/crt_dllmain.c @@ -22,12 +22,38 @@ #include <stdarg.h> #include <stdio.h> +#include <process.h> #include "windef.h" #include "winbase.h" +extern _PIFV __xi_a[]; +extern _PIFV __xi_z[]; +extern _PVFV __xc_a[]; +extern _PVFV __xc_z[]; +extern _PVFV __xt_a[]; +extern _PVFV __xt_z[]; + +void CDECL _initterm( _PVFV *start,_PVFV *end ); +int CDECL _initterm_e( _PIFV *table, _PIFV *end ); + +static void do_global_ctors(void) +{ + if (_initterm_e( __xi_a, __xi_z ) != 0) return; + _initterm( __xc_a, __xc_z ); +} + +static void do_global_dtors(void) +{ + _initterm( __xt_a, __xt_z ); +} + 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
On Fri Dec 12 03:07:57 2025 +0000, Yuxuan Shui wrote:
changed this line in [version 9 of the diff](/wine/wine/-/merge_requests/9265/diffs?diff_id=231922&start_sha=6e30709e30d98da3e94be98da972a8e890d75c9c#0719c2159befb363c9a867ff09219d50ac8dc799_36_36) ok, i am going with the `libwinecrtend.a` approach again.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9265#note_125516
Bernhard Übelacker (@bernhardu) commented about dlls/winecrt0/crt_dllmain.c:
#include <stdarg.h> #include <stdio.h> +#include <process.h> #include "windef.h" #include "winbase.h"
+extern _PIFV __xi_a[]; +extern _PIFV __xi_z[]; +extern _PVFV __xc_a[]; +extern _PVFV __xc_z[]; +extern _PVFV __xt_a[]; +extern _PVFV __xt_z[]; + +void CDECL _initterm( _PVFV *start,_PVFV *end );
Hello @yshui, I am using your patches from this MR when I notice a new version. And I have a CI job running which tries to stay near the regular CI job and uses "--enable-werror". Unfortunately I received now [this error](https://gitlab.winehq.org/bernhardu/wine/-/jobs/217171#L80) : ``` + make -s ../dlls/winecrt0/crt_dllmain.c:37:11: error: '_initterm_e' redeclared without 'dllimport' attribute: previous 'dllimport' ignored [-Werror,-Winconsistent-dllimport] 37 | int CDECL _initterm_e( _PIFV *table, _PIFV *end ); ``` Do you get this first "warning", too? <details> <summary> Unfortunately simply adding the `_ACRTIMP` like used in the declaration makes it fail later with: </summary> ``` tools/winegcc/winegcc -o dlls/kernel32/x86_64-windows/kernel32.dll --wine-objdir . -b x86_64-windows -Wl,--wine-builtin -shared \ /home/bernhard/data/entwicklung/2025/wine/wine/dlls/kernel32/kernel32.spec -nodefaultlibs \ -Wb,-F,KERNEL32.dll -Wl,--image-base,0x178000000 dlls/kernel32/x86_64-windows/atom.o \ dlls/kernel32/x86_64-windows/comm.o dlls/kernel32/x86_64-windows/computername.o \ dlls/kernel32/x86_64-windows/console.o dlls/kernel32/x86_64-windows/debugger.o \ dlls/kernel32/x86_64-windows/file.o dlls/kernel32/x86_64-windows/heap.o \ dlls/kernel32/x86_64-windows/kernel_main.o dlls/kernel32/x86_64-windows/locale.o \ dlls/kernel32/x86_64-windows/lzexpand.o dlls/kernel32/x86_64-windows/module.o \ dlls/kernel32/x86_64-windows/path.o dlls/kernel32/x86_64-windows/powermgnt.o \ dlls/kernel32/x86_64-windows/process.o dlls/kernel32/x86_64-windows/profile.o \ dlls/kernel32/x86_64-windows/resource.o dlls/kernel32/x86_64-windows/sync.o \ dlls/kernel32/x86_64-windows/tape.o dlls/kernel32/x86_64-windows/thread.o \ dlls/kernel32/x86_64-windows/toolhelp.o dlls/kernel32/x86_64-windows/version.o \ dlls/kernel32/x86_64-windows/virtual.o dlls/kernel32/x86_64-windows/volume.o \ dlls/kernel32/version.res -Wl,--debug-file,dlls/kernel32/x86_64-windows/kernel32.pdb \ dlls/kernelbase/x86_64-windows/libkernelbase.a dlls/ntdll/x86_64-windows/libntdll.a \ dlls/winecrt0/x86_64-windows/libwinecrt0.a libs/compiler-rt/x86_64-windows/libcompiler-rt.a \ dlls/winecrtend/x86_64-windows/libwinecrtend.a --no-default-config -fms-hotpatch -Wl,-debug:dwarf lld-link: error: undefined symbol: __declspec(dllimport) _initterm_e
referenced by /home/bernhard/data/entwicklung/2025/wine/wine/dlls/winecrt0/crt_dllmain.c:41 libwinecrt0.a(crt_dllmain.o):(do_global_ctors) NOTE: a relevant symbol '_initterm_e' is available in dlls/winecrtend/x86_64-windows/libwinecrtend.a but cannot be used because it is not an import library.
</summary>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/9265#note_125557
On Sat Dec 13 00:01:26 2025 +0000, Bernhard Übelacker wrote:
Hello @yshui, I am using your patches from this MR when I notice a new version. And I have a CI job running which tries to stay near the regular CI job and uses "--enable-werror". Unfortunately I received now [this error](https://gitlab.winehq.org/bernhardu/wine/-/jobs/217171#L80) : ``` + make -s ../dlls/winecrt0/crt_dllmain.c:37:11: error: '_initterm_e' redeclared without 'dllimport' attribute: previous 'dllimport' ignored [-Werror,-Winconsistent-dllimport] 37 | int CDECL _initterm_e( _PIFV *table, _PIFV *end ); ``` Do you get this first "warning", too? <details> <summary> Unfortunately simply adding the `_ACRTIMP` like used in the declaration makes it fail later with: </summary> ``` tools/winegcc/winegcc -o dlls/kernel32/x86_64-windows/kernel32.dll --wine-objdir . -b x86_64-windows -Wl,--wine-builtin -shared \
/home/bernhard/data/entwicklung/2025/wine/wine/dlls/kernel32/kernel32.spec -nodefaultlibs \ -Wb,-F,KERNEL32.dll -Wl,--image-base,0x178000000 dlls/kernel32/x86_64-windows/atom.o \ dlls/kernel32/x86_64-windows/comm.o dlls/kernel32/x86_64-windows/computername.o \ dlls/kernel32/x86_64-windows/console.o dlls/kernel32/x86_64-windows/debugger.o \ dlls/kernel32/x86_64-windows/file.o dlls/kernel32/x86_64-windows/heap.o \ dlls/kernel32/x86_64-windows/kernel_main.o dlls/kernel32/x86_64-windows/locale.o \ dlls/kernel32/x86_64-windows/lzexpand.o dlls/kernel32/x86_64-windows/module.o \ dlls/kernel32/x86_64-windows/path.o dlls/kernel32/x86_64-windows/powermgnt.o \ dlls/kernel32/x86_64-windows/process.o dlls/kernel32/x86_64-windows/profile.o \ dlls/kernel32/x86_64-windows/resource.o dlls/kernel32/x86_64-windows/sync.o \ dlls/kernel32/x86_64-windows/tape.o dlls/kernel32/x86_64-windows/thread.o \ dlls/kernel32/x86_64-windows/toolhelp.o dlls/kernel32/x86_64-windows/version.o \ dlls/kernel32/x86_64-windows/virtual.o dlls/kernel32/x86_64-windows/volume.o \ dlls/kernel32/version.res -Wl,--debug-file,dlls/kernel32/x86_64-windows/kernel32.pdb \ dlls/kernelbase/x86_64-windows/libkernelbase.a dlls/ntdll/x86_64-windows/libntdll.a \ dlls/winecrt0/x86_64-windows/libwinecrt0.a libs/compiler-rt/x86_64-windows/libcompiler-rt.a \ dlls/winecrtend/x86_64-windows/libwinecrtend.a --no-default-config -fms-hotpatch -Wl,-debug:dwarf lld-link: error: undefined symbol: __declspec(dllimport) _initterm_e
referenced by /home/bernhard/data/entwicklung/2025/wine/wine/dlls/winecrt0/crt_dllmain.c:41 libwinecrt0.a(crt_dllmain.o):(do_global_ctors) NOTE: a relevant symbol '_initterm_e' is available in dlls/winecrtend/x86_64-windows/libwinecrtend.a but cannot be used because it is not an import library.
</summary> I have removed the "--enable-werror" in [this job](https://gitlab.winehq.org/bernhardu/wine/-/jobs/217175#L159), but there I see now also such lines `lld-link: warning: literal .edata sections override exports`, which did not appear with the previous version of this MR.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9265#note_125560
participants (3)
-
Bernhard Übelacker (@bernhardu) -
Yuxuan Shui -
Yuxuan Shui (@yshui)