These changes are enough to allow building the entirety of the native (ELF) side with `-flto`.
-- v3: loader: Mark thread_ldt, thread_data, wld_start "used". ntdll: Mark call_init_thunk and abort_thread "used".
From: William Horvath william@horvath.blog
They're called from inline assembly, so this ensures that the functions exist with the proper signature until the linking stage when LTO compilation is used. --- dlls/ntdll/unix/signal_arm.c | 4 ++-- dlls/ntdll/unix/signal_arm64.c | 4 ++-- dlls/ntdll/unix/signal_i386.c | 4 ++-- dlls/ntdll/unix/signal_x86_64.c | 4 ++-- dlls/ntdll/unix/unix_private.h | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index c9ae492597d..12389fa8f00 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -1121,8 +1121,8 @@ void signal_init_process(void) /*********************************************************************** * call_init_thunk */ -void call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, - struct syscall_frame *frame, void *syscall_cfa ) +void __attribute__((used)) call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, + struct syscall_frame *frame, void *syscall_cfa ) { struct arm_thread_data *thread_data = (struct arm_thread_data *)&teb->GdiTebBatch; CONTEXT *ctx, context = { CONTEXT_ALL }; diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 57d9c375076..6d3efaed31c 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -1447,8 +1447,8 @@ void syscall_dispatcher_return_slowpath(void) /*********************************************************************** * call_init_thunk */ -void call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, - struct syscall_frame *frame, void *syscall_cfa ) +void __attribute__((used)) call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, + struct syscall_frame *frame, void *syscall_cfa ) { struct arm64_thread_data *thread_data = (struct arm64_thread_data *)&teb->GdiTebBatch; CONTEXT *ctx, context = { CONTEXT_ALL }; diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index bdcb6bfed09..dca1cc33f2c 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2496,8 +2496,8 @@ void signal_init_process(void) /*********************************************************************** * call_init_thunk */ -void call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, - struct syscall_frame *frame, void *syscall_cfa ) +void __attribute__((used)) call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, + struct syscall_frame *frame, void *syscall_cfa ) { struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; CONTEXT *ctx, context = { CONTEXT_ALL }; diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 52c907f1a32..0ca55c7da27 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2575,8 +2575,8 @@ void signal_init_process(void) /*********************************************************************** * call_init_thunk */ -void call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, - struct syscall_frame *frame, void *syscall_cfa ) +void __attribute__((used)) call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb, + struct syscall_frame *frame, void *syscall_cfa ) { struct amd64_thread_data *thread_data = (struct amd64_thread_data *)&teb->GdiTebBatch; CONTEXT *ctx, context = { 0 }; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index f840045f841..134a5d93f32 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -253,7 +253,7 @@ extern void set_process_instrumentation_callback( void *callback ); extern void *get_cpu_area( USHORT machine ); extern void set_thread_id( TEB *teb, DWORD pid, DWORD tid ); extern NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE_T commit_size ); -extern void DECLSPEC_NORETURN abort_thread( int status ); +extern void __attribute__((used)) DECLSPEC_NORETURN abort_thread( int status ); extern void DECLSPEC_NORETURN abort_process( int status ); extern void DECLSPEC_NORETURN exit_process( int status ); extern void wait_suspend( CONTEXT *context );
From: William Horvath william@horvath.blog
--- loader/preloader.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/loader/preloader.c b/loader/preloader.c index d0551bae63a..3df0884d611 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -181,6 +181,7 @@ void __bb_init_func(void) { return; }
static int thread_data[256];
+__attribute__((used)) struct { /* this is the kernel modify_ldt struct */ @@ -333,7 +334,7 @@ static inline int wld_prctl( int code, long arg )
#elif defined(__x86_64__)
-void *thread_data[256]; +void __attribute__((used)) *thread_data[256];
/* * The _start function is the entry and exit point of this program @@ -422,7 +423,7 @@ SYSCALL_NOERR( wld_getegid, 108 /* SYS_getegid */ );
#elif defined(__aarch64__)
-void *thread_data[256]; +void __attribute__((used)) *thread_data[256];
/* * The _start function is the entry and exit point of this program @@ -529,7 +530,7 @@ SYSCALL_NOERR( wld_getegid, 177 /* SYS_getegid */ );
#elif defined(__arm__)
-void *thread_data[256]; +void __attribute__((used)) *thread_data[256];
/* * The _start function is the entry and exit point of this program @@ -1395,7 +1396,7 @@ static void set_process_name( int argc, char *argv[] ) * Load the binary and then its ELF interpreter. * Note, we assume that the binary is a dynamically linked ELF shared object. */ -void* wld_start( void **stack ) +void* __attribute__((used)) wld_start( void **stack ) { long i, *pargc; char **argv, **p;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151036
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0000000001DB00E4, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
On Fri Jan 24 19:46:51 2025 +0000, Gabriel Ivăncescu wrote:
There's no better way. You simply have to let the compiler know. And like I said, you don't have to do the others if you don't want to, in fact I very much prefer to keep this MR short and only focused on minimal amount of components (or unix side as you did), so we can get the macro and "infrastructure" in first. For your concern about doing it for everything: there's not that many ASM_GLOBAL_FUNCs that call other functions around in general, it's not like the PE conversion that touched every single module. But I could even take up that task if you want, as long as we get this one in first so I know how to proceed.
I've added the attribute to `abort_thread`.