From fa5759b9efad3b00e8ce349889e411792748f87f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 11 Jun 2021 12:40:08 +0200 Subject: [PATCH] ntdll: Simplify the platform-specific dispatcher interface. Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/server.c | 9 +++------ dlls/ntdll/unix/signal_arm.c | 29 ++++++++++++++--------------- dlls/ntdll/unix/signal_arm64.c | 28 +++++++++++++--------------- dlls/ntdll/unix/signal_i386.c | 29 ++++++++++++++--------------- dlls/ntdll/unix/signal_x86_64.c | 29 ++++++++++++++--------------- dlls/ntdll/unix/thread.c | 2 +- dlls/ntdll/unix/unix_private.h | 14 +++++--------- 7 files changed, 64 insertions(+), 76 deletions(-) diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 19e9d603d52..57d552a3c9a 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -357,7 +357,7 @@ static int wait_select_reply( void *cookie ) static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTATUS status ) { return call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2], - wine_server_get_ptr( apc->func ), pKiUserApcDispatcher, status ); + wine_server_get_ptr( apc->func ), status ); } @@ -698,10 +698,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable ) status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, NULL, &apc ); if (status == STATUS_USER_APC) return invoke_user_apc( context, &apc, status ); } - status = NtSetContextThread( GetCurrentThread(), context ); - if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) - signal_restore_full_cpu_context(); - return status; + return signal_set_full_context( context ); } @@ -1745,7 +1742,7 @@ NTSTATUS WINAPI NtClose( HANDLE handle ) if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &port, sizeof(port), NULL) && port) { NtCurrentTeb()->ExceptionCode = ret; - call_raise_user_exception_dispatcher( pKiRaiseUserExceptionDispatcher ); + call_raise_user_exception_dispatcher(); } return ret; } diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index aaa527af6aa..8a45d0ba086 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -319,13 +319,15 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext ) /*********************************************************************** - * signal_restore_full_cpu_context - * - * Restore full context from syscall frame + * signal_set_full_context */ -void signal_restore_full_cpu_context(void) +NTSTATUS signal_set_full_context( CONTEXT *context ) { - arm_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); + + if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) + arm_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + return status; } @@ -496,10 +498,8 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, - PNTAPCFUNC func, - void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC), - NTSTATUS status ) +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, + PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = arm_thread_data()->syscall_frame; ULONG sp = context ? context->Sp : frame->sp; @@ -524,7 +524,7 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON stack->context.R0 = status; } frame->sp = (DWORD)stack; - frame->pc = (DWORD)dispatcher; + frame->pc = (DWORD)pKiUserApcDispatcher; frame->r0 = (DWORD)&stack->context; frame->r1 = arg1; frame->r2 = arg2; @@ -538,17 +538,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON /*********************************************************************** * call_raise_user_exception_dispatcher */ -void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) +void call_raise_user_exception_dispatcher(void) { - arm_thread_data()->syscall_frame->pc = (DWORD)dispatcher; + arm_thread_data()->syscall_frame->pc = (DWORD)pKiRaiseUserExceptionDispatcher; } /*********************************************************************** * call_user_exception_dispatcher */ -NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, - NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) +NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ) { struct syscall_frame *frame = arm_thread_data()->syscall_frame; NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); @@ -556,7 +555,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT * if (status) return status; frame->r0 = (DWORD)rec; frame->r1 = (DWORD)context; - frame->pc = (DWORD)dispatcher; + frame->pc = (DWORD)pKiUserExceptionDispatcher; frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL; return status; } diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index ce118384fcf..0cb1bde1d55 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -409,13 +409,14 @@ static void restore_fpu( struct syscall_frame *frame, ucontext_t *sigcontext ) /*********************************************************************** - * signal_restore_full_cpu_context - * - * Restore full context from syscall frame + * signal_set_full_context */ -void signal_restore_full_cpu_context(void) +NTSTATUS signal_set_full_context( CONTEXT *context ) { - raise( SIGUSR2 ); + NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); + + if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) raise( SIGUSR2 ); + return status; } @@ -643,10 +644,8 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, - PNTAPCFUNC func, - void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC), - NTSTATUS status ) +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, + PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = arm64_thread_data()->syscall_frame; ULONG64 sp = context ? context->Sp : frame->sp; @@ -666,7 +665,7 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON stack->context.u.s.X0 = status; } frame->sp = (ULONG64)stack; - frame->pc = (ULONG64)dispatcher; + frame->pc = (ULONG64)pKiUserApcDispatcher; frame->x[0] = (ULONG64)&stack->context; frame->x[1] = arg1; frame->x[2] = arg2; @@ -680,17 +679,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON /*********************************************************************** * call_raise_user_exception_dispatcher */ -void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) +void call_raise_user_exception_dispatcher(void) { - arm64_thread_data()->syscall_frame->pc = (UINT64)dispatcher; + arm64_thread_data()->syscall_frame->pc = (UINT64)pKiRaiseUserExceptionDispatcher; } /*********************************************************************** * call_user_exception_dispatcher */ -NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, - NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) +NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ) { struct syscall_frame *frame = arm64_thread_data()->syscall_frame; NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); @@ -698,7 +696,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT * if (status) return status; frame->x[0] = (ULONG64)rec; frame->x[1] = (ULONG64)context; - frame->pc = (ULONG64)dispatcher; + frame->pc = (ULONG64)pKiUserExceptionDispatcher; frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL; return status; } diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index bb7b711fa5d..0b2b269505f 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -921,13 +921,15 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t /*********************************************************************** - * signal_restore_full_cpu_context - * - * Restore full context from syscall frame + * signal_set_full_context */ -void signal_restore_full_cpu_context(void) +NTSTATUS signal_set_full_context( CONTEXT *context ) { - x86_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); + + if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) + x86_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + return status; } @@ -1566,10 +1568,8 @@ struct apc_stack_layout /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, - ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, - void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC), - NTSTATUS status ) +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, + PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = x86_thread_data()->syscall_frame; ULONG esp = context ? context->Esp : frame->esp; @@ -1590,7 +1590,7 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, stack->func = func; frame->ebp = stack->context.Ebp; frame->esp = (ULONG)stack - 4; - frame->eip = (ULONG)dispatcher; + frame->eip = (ULONG)pKiUserApcDispatcher; return status; } @@ -1598,17 +1598,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, /*********************************************************************** * call_raise_user_exception_dispatcher */ -void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) +void call_raise_user_exception_dispatcher(void) { - x86_thread_data()->syscall_frame->eip = (DWORD)dispatcher; + x86_thread_data()->syscall_frame->eip = (DWORD)pKiRaiseUserExceptionDispatcher; } /*********************************************************************** * call_user_exception_dispatcher */ -NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, - NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) +NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ) { struct syscall_frame *frame = x86_thread_data()->syscall_frame; void **stack = (void **)frame->esp; @@ -1617,7 +1616,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT * *(--stack) = context; *(--stack) = rec; frame->esp = (ULONG)stack; - frame->eip = (ULONG)dispatcher; + frame->eip = (ULONG)pKiUserExceptionDispatcher; return STATUS_SUCCESS; } diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 3cd57211f94..4845d3dd5f4 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1551,13 +1551,15 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon /*********************************************************************** - * signal_restore_full_cpu_context - * - * Restore full context from syscall frame + * signal_set_full_context */ -void signal_restore_full_cpu_context(void) +NTSTATUS signal_set_full_context( CONTEXT *context ) { - amd64_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); + + if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) + amd64_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER; + return status; } @@ -1915,10 +1917,8 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) /*********************************************************************** * call_user_apc_dispatcher */ -NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, - PNTAPCFUNC func, - void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC), - NTSTATUS status ) +NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, + PNTAPCFUNC func, NTSTATUS status ) { struct syscall_frame *frame = amd64_thread_data()->syscall_frame; ULONG64 rsp = context ? context->Rsp : frame->rsp; @@ -1939,7 +1939,7 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON } frame->rbp = stack->context.Rbp; frame->rsp = (ULONG64)stack - 8; - frame->rip = (ULONG64)dispatcher; + frame->rip = (ULONG64)pKiUserApcDispatcher; frame->rcx = (ULONG64)&stack->context; frame->rdx = arg1; frame->r8 = arg2; @@ -1953,17 +1953,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON /*********************************************************************** * call_raise_user_exception_dispatcher */ -void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) +void call_raise_user_exception_dispatcher(void) { - amd64_thread_data()->syscall_frame->rip = (UINT64)dispatcher; + amd64_thread_data()->syscall_frame->rip = (UINT64)pKiRaiseUserExceptionDispatcher; } /*********************************************************************** * call_user_exception_dispatcher */ -NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, - NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) +NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ) { struct syscall_frame *frame = amd64_thread_data()->syscall_frame; struct stack_layout *stack; @@ -1989,7 +1988,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT * if (stack->rec.ExceptionCode == EXCEPTION_BREAKPOINT) stack->context.Rip--; frame->rbp = context->Rbp; frame->rsp = (ULONG64)stack; - frame->rip = (ULONG64)dispatcher; + frame->rip = (ULONG64)pKiUserExceptionDispatcher; frame->restore_flags |= CONTEXT_CONTROL; return status; } diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 9859301c8ac..ce72cc8b6cb 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1152,7 +1152,7 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) return NtContinue( context, FALSE ); - if (first_chance) return call_user_exception_dispatcher( rec, context, pKiUserExceptionDispatcher ); + if (first_chance) return call_user_exception_dispatcher( rec, context ); if (rec->ExceptionFlags & EH_STACK_INVALID) ERR_(seh)("Exception frame is not in stack limits => unable to dispatch exception.\n"); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index d67b39e8c52..f6934ae9e91 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -249,7 +249,7 @@ extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE ent extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int) ) DECLSPEC_HIDDEN; extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN; extern unsigned int __wine_syscall_flags DECLSPEC_HIDDEN; -extern void signal_restore_full_cpu_context(void) DECLSPEC_HIDDEN; +extern NTSTATUS signal_set_full_context( CONTEXT *context ) DECLSPEC_HIDDEN; extern NTSTATUS get_thread_wow64_context( HANDLE handle, void *ctx, ULONG size ) DECLSPEC_HIDDEN; extern NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size ) DECLSPEC_HIDDEN; extern void fill_vm_counters( VM_COUNTERS_EX *pvmi, int unix_pid ) DECLSPEC_HIDDEN; @@ -284,14 +284,10 @@ extern void add_completion( HANDLE handle, ULONG_PTR value, NTSTATUS status, ULO extern void dbg_init(void) DECLSPEC_HIDDEN; -extern NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR arg1, - ULONG_PTR arg2, ULONG_PTR arg3, - PNTAPCFUNC func, - void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC), - NTSTATUS status ) DECLSPEC_HIDDEN; -extern NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, - NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN; -extern void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) DECLSPEC_HIDDEN; +extern NTSTATUS call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, + PNTAPCFUNC func, NTSTATUS status ) DECLSPEC_HIDDEN; +extern NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN; +extern void call_raise_user_exception_dispatcher(void) DECLSPEC_HIDDEN; #define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */