[PATCH 0/2] MR10121: winecrt0, ucrtbase: Add support for atexit and GCC constructors/destructors.
From: Jacek Caban <jacek@codeweavers.com> --- dlls/winecrt0/Makefile.in | 1 + dlls/winecrt0/gcc_constr.c | 47 ++++++++++++++++++++++++++++++++++++++ include/wine/asm.h | 15 +++++++----- tools/winegcc/winegcc.c | 2 ++ 4 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 dlls/winecrt0/gcc_constr.c diff --git a/dlls/winecrt0/Makefile.in b/dlls/winecrt0/Makefile.in index 29cd88f8637..e33b940d606 100644 --- a/dlls/winecrt0/Makefile.in +++ b/dlls/winecrt0/Makefile.in @@ -18,6 +18,7 @@ SOURCES = \ exe_main.c \ exe_wentry.c \ exe_wmain.c \ + gcc_constr.c \ register.c \ setjmp.c \ stub.c \ diff --git a/dlls/winecrt0/gcc_constr.c b/dlls/winecrt0/gcc_constr.c new file mode 100644 index 00000000000..21b7778d38c --- /dev/null +++ b/dlls/winecrt0/gcc_constr.c @@ -0,0 +1,47 @@ +/* + * Copyright 2026 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 + */ + +#ifdef __WINE_PE_BUILD + +#include <stdarg.h> +#include <process.h> +#include "windef.h" +#include "winbase.h" +#include "wine/asm.h" + +extern _PVFV __CTOR_LIST__[]; +extern _PVFV __DTOR_LIST__[]; + +void __cdecl __wine_call_gcc_ctors(void) +{ + ULONG_PTR n = (ULONG_PTR)__CTOR_LIST__[0], i; + if (n == (ULONG_PTR)-1) for (n = 0; __CTOR_LIST__[n + 1]; n++); + for (i = n; i >= 1; i--) __CTOR_LIST__[i](); +} + +__ASM_SECTION_POINTER( ".section .CRT$XCB", __wine_call_gcc_ctors ) + +void __cdecl __wine_call_gcc_dtors(void) +{ + size_t i; + for (i = 1; __DTOR_LIST__[i]; i++) __DTOR_LIST__[i](); +} + +__ASM_SECTION_POINTER( ".section .CRT$XTB", __wine_call_gcc_dtors ) + +#endif diff --git a/include/wine/asm.h b/include/wine/asm.h index 172d7c8aa6e..03f99f10209 100644 --- a/include/wine/asm.h +++ b/include/wine/asm.h @@ -109,25 +109,28 @@ #define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(__ASM_NAME(#name),code) #ifdef _WIN64 -#define __ASM_GLOBAL_POINTER(name,value) \ +#define __ASM_DEFINE_POINTER(sec,decl,value) \ __ASM_BLOCK_BEGIN(__LINE__) \ - asm( ".data\n\t" \ + asm( sec "\n\t" \ ".balign 8\n\t" \ - __ASM_GLOBL(name) "\n\t" \ + decl \ ".quad " value "\n\t" \ ".text" ); __ASM_BLOCK_END #else -#define __ASM_GLOBAL_POINTER(name,value) \ +#define __ASM_DEFINE_POINTER(sec,decl,value) \ __ASM_BLOCK_BEGIN(__LINE__) \ - asm( ".data\n\t" \ + asm( sec "\n\t" \ ".balign 4\n\t" \ - __ASM_GLOBL(name) "\n\t" \ + decl \ ".long " value "\n\t" \ ".text" ); __ASM_BLOCK_END #endif +#define __ASM_GLOBAL_POINTER(name,value) __ASM_DEFINE_POINTER(".data",__ASM_GLOBL(name) "\n\t",value) +#define __ASM_SECTION_POINTER(sec,value) __ASM_DEFINE_POINTER(sec,"",__ASM_NAME(#value)) + /* import variables */ #ifdef __WINE_PE_BUILD diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index 3ce6ed1ee4f..c988be497a1 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -588,6 +588,8 @@ static struct strarray get_link_args( const char *output_name ) else if (!try_link( link_args, "-Wl,--file-alignment,0x1000,--section-alignment,0x1000" )) strarray_add( &link_args, strmake( "-Wl,--file-alignment,%s,--section-alignment,%s", file_align, section_align )); + strarray_add( &link_args, target.cpu == CPU_i386 ? + "-Wl,--undefined,___wine_call_gcc_ctors" : "-Wl,--undefined,__wine_call_gcc_ctors" ); strarray_addall( &link_args, flags ); return link_args; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10121
From: Jacek Caban <jacek@codeweavers.com> --- dlls/ucrtbase/Makefile.in | 1 + dlls/ucrtbase/atexit.c | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 dlls/ucrtbase/atexit.c diff --git a/dlls/ucrtbase/Makefile.in b/dlls/ucrtbase/Makefile.in index c9e5c3a31f7..768844fb1c6 100644 --- a/dlls/ucrtbase/Makefile.in +++ b/dlls/ucrtbase/Makefile.in @@ -9,6 +9,7 @@ VER_FILEDESCRIPTION_STR = "Wine runtime library" VER_PRODUCTVERSION = 10,0,14393,2247 SOURCES = \ + atexit.c \ console.c \ cpp.c \ crt_gccmain.c \ diff --git a/dlls/ucrtbase/atexit.c b/dlls/ucrtbase/atexit.c new file mode 100644 index 00000000000..7951be58231 --- /dev/null +++ b/dlls/ucrtbase/atexit.c @@ -0,0 +1,48 @@ +/* + * atexit implementation + * + * Copyright 2026 Jacek Caban 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 + */ + +/* this function is part of the import lib to provide floating */ +#if 0 +#pragma makedep implib +#endif + +#ifdef __WINE_PE_BUILD + +#include <process.h> +#include <stdarg.h> +#include <windef.h> +#include <winbase.h> +#include <wine/asm.h> + +static _onexit_table_t atexit_table = { 0 }; + +int __cdecl atexit(_PVFV func) +{ + return _register_onexit_function(&atexit_table, (_onexit_t)func); +} + +void __wine_exec_atexit(void) +{ + _execute_onexit_table(&atexit_table); +} + +__ASM_SECTION_POINTER( ".section .CRT$XTB", __wine_exec_atexit ) + +#endif -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10121
Piotr Caban (@piotr) commented about dlls/ucrtbase/atexit.c:
+ * 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 + */ + +/* this function is part of the import lib to provide floating */ Please remove the comment.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10121#note_129897
This merge request was approved by Piotr Caban. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10121
participants (3)
-
Jacek Caban -
Jacek Caban (@jacek) -
Piotr Caban (@piotr)