diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index b32665611f1..f8aca6dfb7f 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -179,10 +179,12 @@ void WINAPI RtlRaiseStatus( NTSTATUS status ) /******************************************************************* * KiRaiseUserExceptionDispatcher (NTDLL.@) */ -void WINAPI KiRaiseUserExceptionDispatcher(void) +NTSTATUS WINAPI KiRaiseUserExceptionDispatcher(void) { - EXCEPTION_RECORD rec = { NtCurrentTeb()->ExceptionCode }; + DWORD code = NtCurrentTeb()->ExceptionCode; + EXCEPTION_RECORD rec = { code }; RtlRaiseException( &rec ); + return code; } diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 776a22321a0..d621d4ef8e8 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -95,7 +95,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(module); extern IMAGE_NT_HEADERS __wine_spec_nt_header; void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) = NULL; -void (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL; +NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL; void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) = NULL; NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) = NULL; void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) = NULL; diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 3f68e87acbe..d867a7fb462 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1650,7 +1650,7 @@ NTSTATUS WINAPI NtClose( HANDLE handle ) if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &port, sizeof(port), NULL) && port) { NtCurrentTeb()->ExceptionCode = ret; - pKiRaiseUserExceptionDispatcher(); + call_raise_user_exception_dispatcher( pKiRaiseUserExceptionDispatcher ); } return ret; } diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 30a1f619695..e619dbd9755 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -596,6 +596,14 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1, } +/*********************************************************************** + * call_raise_user_exception_dispatcher + */ +__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher, + "mov r2, r0\n\t" /* dispatcher */ + "b " __ASM_NAME("call_user_exception_dispatcher") ) + + /*********************************************************************** * call_user_exception_dispatcher */ diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index b36b75972c9..d5ced2172a2 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -597,6 +597,14 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1, } +/*********************************************************************** + * call_raise_user_exception_dispatcher + */ +__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher, + "mov x2, x0\n\t" /* dispatcher */ + "b " __ASM_NAME("call_user_exception_dispatcher") ) + + /*********************************************************************** * call_user_exception_dispatcher */ diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 00bb422c44e..39c154ebbc1 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1555,6 +1555,22 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1, } +/*********************************************************************** + * call_raise_user_exception_dispatcher + */ +__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher, + "movl %fs:0x1f8,%eax\n\t" /* x86_thread_data()->syscall_frame */ + "pushl (%eax)\n\t" /* frame->prev_frame */ + "popl %fs:0x1f8\n\t" + "movl 4(%eax),%edi\n\t" /* frame->edi */ + "movl 8(%eax),%esi\n\t" /* frame->esi */ + "movl 12(%eax),%ebx\n\t" /* frame->ebx */ + "movl 16(%eax),%ebp\n\t" /* frame->ebp */ + "movl 4(%esp),%edx\n\t" /* dispatcher */ + "leal 24(%eax),%esp\n\t" + "jmp *%edx" ) + + /*********************************************************************** * call_user_exception_dispatcher */ diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index a1de8818458..a1918908fc5 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1907,6 +1907,37 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1, } +/*********************************************************************** + * call_raise_user_exception_dispatcher + */ +__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher, + "movq %gs:0x30,%rdx\n\t" + "movq 0x328(%rdx),%rax\n\t" /* amd64_thread_data()->syscall_frame */ + "pushq (%rax)\n\t" /* frame->prev_frame */ + "popq 0x328(%rdx)\n\t" + "movdqu 0x10(%rax),%xmm6\n\t" /* frame->xmm[0..19 */ + "movdqu 0x20(%rax),%xmm7\n\t" + "movdqu 0x30(%rax),%xmm8\n\t" + "movdqu 0x40(%rax),%xmm9\n\t" + "movdqu 0x50(%rax),%xmm10\n\t" + "movdqu 0x60(%rax),%xmm11\n\t" + "movdqu 0x70(%rax),%xmm12\n\t" + "movdqu 0x80(%rax),%xmm13\n\t" + "movdqu 0x90(%rax),%xmm14\n\t" + "movdqu 0xa0(%rax),%xmm15\n\t" + "ldmxcsr 0xb0(%rax)\n\t" /* frame->mxcsr */ + "movq 0xb8(%rax),%r12\n\t" /* frame->r12 */ + "movq 0xc0(%rax),%r13\n\t" /* frame->r13 */ + "movq 0xc8(%rax),%r14\n\t" /* frame->r14 */ + "movq 0xd0(%rax),%r15\n\t" /* frame->r15 */ + "movq 0xd8(%rax),%rdi\n\t" /* frame->rdi */ + "movq 0xe0(%rax),%rsi\n\t" /* frame->rsi */ + "movq 0xe8(%rax),%rbx\n\t" /* frame->rbx */ + "movq 0xf0(%rax),%rbp\n\t" /* frame->rbp */ + "leaq 0x100(%rax),%rsp\n\t" + "jmpq *%rcx" ) + + /*********************************************************************** * call_user_exception_dispatcher */ diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 7a6bb3c64a1..397211957bd 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -84,7 +84,7 @@ static const SIZE_T signal_stack_size = 0x10000 - 0x3000; /* callbacks to PE ntdll from the Unix side */ extern void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) DECLSPEC_HIDDEN; -extern void (WINAPI *pKiRaiseUserExceptionDispatcher)(void) DECLSPEC_HIDDEN; +extern NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) DECLSPEC_HIDDEN; extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) DECLSPEC_HIDDEN; extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN; extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) DECLSPEC_HIDDEN; @@ -262,6 +262,7 @@ extern void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR ULONG_PTR arg2, PNTAPCFUNC func ) DECLSPEC_HIDDEN; extern void WINAPI DECLSPEC_NORETURN call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN; +extern void WINAPI DECLSPEC_NORETURN call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) DECLSPEC_HIDDEN; #define TICKSPERSEC 10000000 #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)