mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
ntdll-WRITECOPY: Install existing signal handlers earlier instead of using a special early signal handler.
This commit is contained in:
parent
5eeb4b76d6
commit
ae46f56f2c
@ -0,0 +1,63 @@
|
||||
From 96831bd0bda656192510397cd18cb2c4bff5d8f4 Mon Sep 17 00:00:00 2001
|
||||
From: Elizabeth Figura <zfigura@codeweavers.com>
|
||||
Date: Thu, 22 Aug 2024 18:42:33 -0500
|
||||
Subject: [PATCH 03/10] ntdll: Install signal handlers a bit earlier.
|
||||
|
||||
The wine-staging WRITECOPY implementation needs to be able to handle write faults while relocating builtin modules loaded during process initialization.
|
||||
|
||||
Note that the comment about debug events isn't relevant anymore because these exceptions all happen on the Unix stack anyway.
|
||||
|
||||
Probably there's a better solution involving simply not write-protecting these pages until we get to PE code, but that's not worth writing when this whole patch set is moribund anyway.
|
||||
---
|
||||
dlls/ntdll/unix/loader.c | 1 +
|
||||
dlls/ntdll/unix/server.c | 5 -----
|
||||
dlls/ntdll/unix/signal_i386.c | 5 ++++-
|
||||
3 files changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index 92f2e2eb3a3..a6ea16bb7bb 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1866,6 +1866,7 @@ static void start_main_thread(void)
|
||||
set_load_order_app_name( main_wargv[0] );
|
||||
init_thread_stack( teb, 0, 0, 0 );
|
||||
NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );
|
||||
+ signal_init_process();
|
||||
load_ntdll();
|
||||
load_wow64_ntdll( main_image_info.Machine );
|
||||
load_apiset_dll();
|
||||
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
|
||||
index 27dbf1331aa..80504e3459c 100644
|
||||
--- a/dlls/ntdll/unix/server.c
|
||||
+++ b/dlls/ntdll/unix/server.c
|
||||
@@ -1674,11 +1674,6 @@ void server_init_process_done(void)
|
||||
send_server_task_port();
|
||||
#endif
|
||||
|
||||
- /* Install signal handlers; this cannot be done earlier, since we cannot
|
||||
- * send exceptions to the debugger before the create process event that
|
||||
- * is sent by init_process_done */
|
||||
- signal_init_process();
|
||||
-
|
||||
/* always send the native TEB */
|
||||
if (!(teb = NtCurrentTeb64())) teb = NtCurrentTeb();
|
||||
|
||||
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
|
||||
index 61d41ec3589..b838a7a8669 100644
|
||||
--- a/dlls/ntdll/unix/signal_i386.c
|
||||
+++ b/dlls/ntdll/unix/signal_i386.c
|
||||
@@ -719,7 +719,10 @@ static inline void *init_handler( const ucontext_t *sigcontext )
|
||||
{
|
||||
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
|
||||
set_fs( thread_data->fs );
|
||||
- set_gs( thread_data->gs );
|
||||
+ /* FIXME ZF: This is a bit of a hack, but it doesn't matter,
|
||||
+ * since this patch set goes in the wrong direction anyway. */
|
||||
+ if (thread_data->gs)
|
||||
+ set_gs( thread_data->gs );
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,178 +0,0 @@
|
||||
From c9d4a9c3a65b1ff1a0c4b4042394f2fab3b2019a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 4 Oct 2014 02:53:22 +0200
|
||||
Subject: [PATCH] ntdll: Setup a temporary signal handler during process
|
||||
startup to handle page faults. (v2)
|
||||
|
||||
---
|
||||
dlls/ntdll/unix/loader.c | 2 ++
|
||||
dlls/ntdll/unix/signal_arm.c | 6 ++++
|
||||
dlls/ntdll/unix/signal_arm64.c | 6 ++++
|
||||
dlls/ntdll/unix/signal_i386.c | 52 +++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/signal_x86_64.c | 6 ++++
|
||||
dlls/ntdll/unix/unix_private.h | 1 +
|
||||
dlls/ntdll/unix/virtual.c | 2 +-
|
||||
7 files changed, 74 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index fa1a943fd51..5a8b0f57e42 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -2142,6 +2142,8 @@ DECLSPEC_EXPORT void __wine_main( int argc, char *argv[], char *envp[] )
|
||||
#endif
|
||||
|
||||
virtual_init();
|
||||
+ signal_init_early();
|
||||
+
|
||||
init_environment();
|
||||
|
||||
#ifdef __APPLE__
|
||||
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
|
||||
index 5115fa7ec3a..8e23007e936 100644
|
||||
--- a/dlls/ntdll/unix/signal_arm.c
|
||||
+++ b/dlls/ntdll/unix/signal_arm.c
|
||||
@@ -1615,6 +1615,12 @@ void signal_init_process(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+/**********************************************************************
|
||||
+ * signal_init_early
|
||||
+ */
|
||||
+void signal_init_early(void)
|
||||
+{
|
||||
+}
|
||||
|
||||
/***********************************************************************
|
||||
* call_init_thunk
|
||||
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
|
||||
index f96ec330796..eaecf988c54 100644
|
||||
--- a/dlls/ntdll/unix/signal_arm64.c
|
||||
+++ b/dlls/ntdll/unix/signal_arm64.c
|
||||
@@ -1623,6 +1623,12 @@ void signal_init_process(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+/**********************************************************************
|
||||
+ * signal_init_early
|
||||
+ */
|
||||
+void signal_init_early(void)
|
||||
+{
|
||||
+}
|
||||
|
||||
/***********************************************************************
|
||||
* syscall_dispatcher_return_slowpath
|
||||
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
|
||||
index c64a8b1efe2..cc1eff1f40b 100644
|
||||
--- a/dlls/ntdll/unix/signal_i386.c
|
||||
+++ b/dlls/ntdll/unix/signal_i386.c
|
||||
@@ -1895,6 +1895,30 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext )
|
||||
}
|
||||
|
||||
|
||||
+/**********************************************************************
|
||||
+ * segv_handler_early
|
||||
+ *
|
||||
+ * Handler for SIGSEGV and related errors. Used only during the initialization
|
||||
+ * of the process to handle virtual faults.
|
||||
+ */
|
||||
+static void segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||
+{
|
||||
+ ucontext_t *ucontext = sigcontext;
|
||||
+
|
||||
+ switch (TRAP_sig(ucontext))
|
||||
+ {
|
||||
+ case TRAP_x86_PAGEFLT: /* Page fault */
|
||||
+ if (!virtual_handle_fault( siginfo->si_addr, (ERROR_sig(ucontext) >> 1) & 0x09,
|
||||
+ NULL))
|
||||
+ return;
|
||||
+ /* fall-through */
|
||||
+ default:
|
||||
+ WINE_ERR( "Got unexpected trap %d during process initialization\n", TRAP_sig(ucontext) );
|
||||
+ abort_thread(1);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* segv_handler
|
||||
*
|
||||
@@ -2465,6 +2489,34 @@ void signal_init_process(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+/**********************************************************************
|
||||
+ * signal_init_early
|
||||
+ */
|
||||
+void signal_init_early(void)
|
||||
+{
|
||||
+ struct sigaction sig_act;
|
||||
+
|
||||
+ sig_act.sa_mask = server_block_set;
|
||||
+ sig_act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||
+#ifdef SA_ONSTACK
|
||||
+ sig_act.sa_flags |= SA_ONSTACK;
|
||||
+#endif
|
||||
+#ifdef __ANDROID__
|
||||
+ sig_act.sa_flags |= SA_RESTORER;
|
||||
+ sig_act.sa_restorer = rt_sigreturn;
|
||||
+#endif
|
||||
+ sig_act.sa_sigaction = segv_handler_early;
|
||||
+ if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
|
||||
+ if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
|
||||
+#ifdef SIGBUS
|
||||
+ if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
|
||||
+#endif
|
||||
+ return;
|
||||
+
|
||||
+error:
|
||||
+ perror("sigaction");
|
||||
+ exit(1);
|
||||
+}
|
||||
|
||||
/***********************************************************************
|
||||
* call_init_thunk
|
||||
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
|
||||
index a28762915be..d22515ab921 100644
|
||||
--- a/dlls/ntdll/unix/signal_x86_64.c
|
||||
+++ b/dlls/ntdll/unix/signal_x86_64.c
|
||||
@@ -2659,6 +2659,12 @@ void signal_init_process(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+/**********************************************************************
|
||||
+ * signal_init_early
|
||||
+ */
|
||||
+void signal_init_early(void)
|
||||
+{
|
||||
+}
|
||||
|
||||
/***********************************************************************
|
||||
* call_init_thunk
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index fadad6ae824..d8eaabef781 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -277,6 +277,7 @@ extern void signal_init_threading(void);
|
||||
extern NTSTATUS signal_alloc_thread( TEB *teb );
|
||||
extern void signal_free_thread( TEB *teb );
|
||||
extern void signal_init_process(void);
|
||||
+extern void signal_init_early(void);
|
||||
extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE entry, void *arg,
|
||||
BOOL suspend, TEB *teb );
|
||||
extern SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4];
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index e0099f1a5c2..fd0b382b368 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -3961,7 +3961,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (!is_inside_signal_stack( stack ) && (vprot & VPROT_GUARD))
|
||||
+ if (stack && !is_inside_signal_stack( stack ) && (vprot & VPROT_GUARD))
|
||||
{
|
||||
struct thread_stack_info stack_info;
|
||||
if (!is_inside_thread_stack( page, &stack_info ))
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,86 +0,0 @@
|
||||
From 153825fbb1dfc7e8624808681fd44f244b5c7c0e Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Wesie <awesie@gmail.com>
|
||||
Date: Fri, 24 Apr 2020 14:55:15 -0500
|
||||
Subject: [PATCH] ntdll: Support WRITECOPY on x64.
|
||||
|
||||
Signed-off-by: Andrew Wesie <awesie@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/signal_x86_64.c | 41 +++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/virtual.c | 2 +-
|
||||
2 files changed, 42 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
|
||||
index db608b358ea..741d0ebed5f 100644
|
||||
--- a/dlls/ntdll/unix/signal_x86_64.c
|
||||
+++ b/dlls/ntdll/unix/signal_x86_64.c
|
||||
@@ -2266,6 +2266,30 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec,
|
||||
}
|
||||
|
||||
|
||||
+/**********************************************************************
|
||||
+ * segv_handler_early
|
||||
+ *
|
||||
+ * Handler for SIGSEGV and related errors. Used only during the initialization
|
||||
+ * of the process to handle virtual faults.
|
||||
+ */
|
||||
+static void segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||
+{
|
||||
+ ucontext_t *ucontext = sigcontext;
|
||||
+
|
||||
+ switch(TRAP_sig(ucontext))
|
||||
+ {
|
||||
+ case TRAP_x86_PAGEFLT: /* Page fault */
|
||||
+ if (!virtual_handle_fault( siginfo->si_addr, (ERROR_sig(ucontext) >> 1) & 0x09,
|
||||
+ NULL ))
|
||||
+ return;
|
||||
+ /* fall-through */
|
||||
+ default:
|
||||
+ WINE_ERR( "Got unexpected trap %lld during process initialization\n", TRAP_sig(ucontext) );
|
||||
+ abort_thread(1);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* segv_handler
|
||||
*
|
||||
@@ -2641,6 +2665,23 @@ void signal_init_process(void)
|
||||
*/
|
||||
void signal_init_early(void)
|
||||
{
|
||||
+ struct sigaction sig_act;
|
||||
+
|
||||
+ sig_act.sa_mask = server_block_set;
|
||||
+ sig_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
|
||||
+
|
||||
+ sig_act.sa_sigaction = segv_handler_early;
|
||||
+ if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
|
||||
+ if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
|
||||
+#ifdef SIGBUS
|
||||
+ if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
|
||||
+#endif
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+ error:
|
||||
+ perror("sigaction");
|
||||
+ exit(1);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index 21760152115..534f99a7064 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -820,7 +820,7 @@ static int get_unix_prot( BYTE vprot )
|
||||
if (vprot & VPROT_READ) prot |= PROT_READ;
|
||||
if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ;
|
||||
if (vprot & VPROT_EXEC) prot |= PROT_EXEC | PROT_READ;
|
||||
-#if defined(__i386__)
|
||||
+#if defined(__i386__) || defined(__x86_64__)
|
||||
if (vprot & VPROT_WRITECOPY)
|
||||
{
|
||||
if (experimental_WRITECOPY() && !(vprot & VPROT_WRITTEN))
|
||||
--
|
||||
2.28.0
|
||||
|
Loading…
Reference in New Issue
Block a user