Commit 1cc06497 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Store exception jump buffer in the per-thread data.

parent 10eba9b2
......@@ -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
{
......
......@@ -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
{
......
......@@ -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
{
......
......@@ -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
{
......
......@@ -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) );
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment