Alexandre Julliard : ntdll: Store exception jump buffer in the per-thread data.
Alexandre Julliard
julliard at winehq.org
Tue Jun 1 16:04:32 CDT 2021
Module: wine
Branch: master
Commit: 1cc0649755c8817004901f0e0d9a970367a43b3c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1cc0649755c8817004901f0e0d9a970367a43b3c
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Jun 1 15:16:23 2021 +0200
ntdll: Store exception jump buffer in the per-thread data.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/signal_arm.c | 6 +++---
dlls/ntdll/unix/signal_arm64.c | 6 +++---
dlls/ntdll/unix/signal_i386.c | 6 +++---
dlls/ntdll/unix/signal_x86_64.c | 6 +++---
dlls/ntdll/unix/unix_private.h | 1 +
dlls/ntdll/unix/virtual.c | 33 ++++++++++++++++++++++++++++++---
6 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 8ecdaa3995b..ccd01e16f16 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -536,7 +536,6 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
static BOOL handle_syscall_fault( ucontext_t *context, EXCEPTION_RECORD *rec )
{
struct syscall_frame *frame = arm_thread_data()->syscall_frame;
- __WINE_FRAME *wine_frame = (__WINE_FRAME *)NtCurrentTeb()->Tib.ExceptionList;
DWORD i;
if (!frame) return FALSE;
@@ -557,12 +556,13 @@ static BOOL handle_syscall_fault( ucontext_t *context, EXCEPTION_RECORD *rec )
(DWORD)IP_sig(context), (DWORD)SP_sig(context), (DWORD)LR_sig(context),
(DWORD)PC_sig(context), (DWORD)CPSR_sig(context) );
- if ((char *)wine_frame < (char *)frame)
+ if (ntdll_get_thread_data()->jmp_buf)
{
TRACE( "returning to handler\n" );
- REGn_sig(0, context) = (DWORD)&wine_frame->jmp;
+ REGn_sig(0, context) = (DWORD)ntdll_get_thread_data()->jmp_buf;
REGn_sig(1, context) = 1;
PC_sig(context) = (DWORD)__wine_longjmp;
+ ntdll_get_thread_data()->jmp_buf = NULL;
}
else
{
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index e696ba41a66..248097ce80a 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -676,7 +676,6 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
static BOOL handle_syscall_fault( ucontext_t *context, EXCEPTION_RECORD *rec )
{
struct syscall_frame *frame = arm64_thread_data()->syscall_frame;
- __WINE_FRAME *wine_frame = (__WINE_FRAME *)NtCurrentTeb()->Tib.ExceptionList;
DWORD i;
if (!frame) return FALSE;
@@ -712,12 +711,13 @@ static BOOL handle_syscall_fault( ucontext_t *context, EXCEPTION_RECORD *rec )
(DWORD64)REGn_sig(28, context), (DWORD64)FP_sig(context),
(DWORD64)LR_sig(context), (DWORD64)SP_sig(context) );
- if ((char *)wine_frame < (char *)frame)
+ if (ntdll_get_thread_data()->jmp_buf)
{
TRACE( "returning to handler\n" );
- REGn_sig(0, context) = (ULONG_PTR)&wine_frame->jmp;
+ REGn_sig(0, context) = (ULONG_PTR)ntdll_get_thread_data()->jmp_buf;
REGn_sig(1, context) = 1;
PC_sig(context) = (ULONG_PTR)__wine_longjmp;
+ ntdll_get_thread_data()->jmp_buf = NULL;
}
else
{
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 707e965d8b3..db93d3f6ed0 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1779,7 +1779,6 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
EXCEPTION_RECORD *rec, CONTEXT *context )
{
struct syscall_frame *frame = x86_thread_data()->syscall_frame;
- __WINE_FRAME *wine_frame = (__WINE_FRAME *)NtCurrentTeb()->Tib.ExceptionList;
DWORD i;
if (!frame) return FALSE;
@@ -1796,7 +1795,7 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
context->Ebp, context->Esp, context->SegCs, context->SegDs,
context->SegEs, context->SegFs, context->SegGs, context->EFlags );
- if ((char *)wine_frame < (char *)frame)
+ if (ntdll_get_thread_data()->jmp_buf)
{
/* stack frame for calling __wine_longjmp */
struct
@@ -1809,10 +1808,11 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
TRACE( "returning to handler\n" );
stack = virtual_setup_exception( stack_ptr, sizeof(*stack), rec );
stack->retval = 1;
- stack->jmp = &wine_frame->jmp;
+ stack->jmp = ntdll_get_thread_data()->jmp_buf;
stack->retaddr = (void *)0xdeadbabe;
ESP_sig(sigcontext) = (DWORD)stack;
EIP_sig(sigcontext) = (DWORD)__wine_longjmp;
+ ntdll_get_thread_data()->jmp_buf = NULL;
}
else
{
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 1ab991d3cb5..4f28d498cc2 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2253,7 +2253,6 @@ static inline BOOL handle_interrupt( ucontext_t *sigcontext, EXCEPTION_RECORD *r
static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec, CONTEXT *context )
{
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
- __WINE_FRAME *wine_frame = (__WINE_FRAME *)NtCurrentTeb()->Tib.ExceptionList;
DWORD i;
if (!frame) return FALSE;
@@ -2272,12 +2271,13 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec,
TRACE(" r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n",
context->R12, context->R13, context->R14, context->R15 );
- if ((char *)wine_frame < (char *)frame)
+ if (ntdll_get_thread_data()->jmp_buf)
{
TRACE( "returning to handler\n" );
- RCX_sig(sigcontext) = (ULONG_PTR)&wine_frame->jmp;
+ RCX_sig(sigcontext) = (ULONG_PTR)ntdll_get_thread_data()->jmp_buf;
RDX_sig(sigcontext) = 1;
RIP_sig(sigcontext) = (ULONG_PTR)__wine_longjmp;
+ ntdll_get_thread_data()->jmp_buf = NULL;
}
else
{
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 5b9af322a68..cf3b8280200 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -68,6 +68,7 @@ struct ntdll_thread_data
struct list entry; /* entry in TEB list */
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
void *param; /* thread entry point parameter */
+ void *jmp_buf; /* setjmp buffer for exception handling */
};
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 2ef72220a45..9796451f58f 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -104,7 +104,34 @@ struct file_view
unsigned int protect; /* protection for all pages at allocation time and SEC_* flags */
};
-#define __EXCEPT_SYSCALL __EXCEPT_HANDLER(0)
+#undef __TRY
+#undef __EXCEPT
+#undef __ENDTRY
+
+#define __TRY \
+ do { __wine_jmp_buf __jmp; \
+ int __first = 1; \
+ assert( !ntdll_get_thread_data()->jmp_buf ); \
+ for (;;) if (!__first) \
+ { \
+ do {
+
+#define __EXCEPT \
+ } while(0); \
+ ntdll_get_thread_data()->jmp_buf = NULL; \
+ break; \
+ } else { \
+ if (__wine_setjmpex( &__jmp, NULL )) { \
+ do {
+
+#define __ENDTRY \
+ } while (0); \
+ break; \
+ } \
+ ntdll_get_thread_data()->jmp_buf = &__jmp; \
+ __first = 0; \
+ } \
+ } while (0);
/* per-page protection flags */
#define VPROT_READ 0x01
@@ -3428,7 +3455,7 @@ BOOL virtual_check_buffer_for_read( const void *ptr, SIZE_T size )
dummy = p[0];
dummy = p[count - 1];
}
- __EXCEPT_SYSCALL
+ __EXCEPT
{
return FALSE;
}
@@ -3461,7 +3488,7 @@ BOOL virtual_check_buffer_for_write( void *ptr, SIZE_T size )
p[0] |= 0;
p[count - 1] |= 0;
}
- __EXCEPT_SYSCALL
+ __EXCEPT
{
return FALSE;
}
More information about the wine-cvs
mailing list