ntdll: Simplify the platform-specific dispatcher interface.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-06-11 12:40:08 +02:00
parent 7954b86f6b
commit fa5759b9ef
7 changed files with 64 additions and 76 deletions

View File

@ -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 ) 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], 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 ); 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 ); if (status == STATUS_USER_APC) return invoke_user_apc( context, &apc, status );
} }
status = NtSetContextThread( GetCurrentThread(), context ); return signal_set_full_context( context );
if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
signal_restore_full_cpu_context();
return status;
} }
@ -1745,7 +1742,7 @@ NTSTATUS WINAPI NtClose( HANDLE handle )
if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &port, sizeof(port), NULL) && port) if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &port, sizeof(port), NULL) && port)
{ {
NtCurrentTeb()->ExceptionCode = ret; NtCurrentTeb()->ExceptionCode = ret;
call_raise_user_exception_dispatcher( pKiRaiseUserExceptionDispatcher ); call_raise_user_exception_dispatcher();
} }
return ret; return ret;
} }

View File

@ -319,13 +319,15 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext )
/*********************************************************************** /***********************************************************************
* signal_restore_full_cpu_context * signal_set_full_context
*
* Restore full context from syscall frame
*/ */
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 * call_user_apc_dispatcher
*/ */
NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
PNTAPCFUNC func, PNTAPCFUNC func, NTSTATUS status )
void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC),
NTSTATUS status )
{ {
struct syscall_frame *frame = arm_thread_data()->syscall_frame; struct syscall_frame *frame = arm_thread_data()->syscall_frame;
ULONG sp = context ? context->Sp : frame->sp; 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; stack->context.R0 = status;
} }
frame->sp = (DWORD)stack; frame->sp = (DWORD)stack;
frame->pc = (DWORD)dispatcher; frame->pc = (DWORD)pKiUserApcDispatcher;
frame->r0 = (DWORD)&stack->context; frame->r0 = (DWORD)&stack->context;
frame->r1 = arg1; frame->r1 = arg1;
frame->r2 = arg2; frame->r2 = arg2;
@ -538,17 +538,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON
/*********************************************************************** /***********************************************************************
* call_raise_user_exception_dispatcher * 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 * call_user_exception_dispatcher
*/ */
NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context )
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
{ {
struct syscall_frame *frame = arm_thread_data()->syscall_frame; struct syscall_frame *frame = arm_thread_data()->syscall_frame;
NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); NTSTATUS status = NtSetContextThread( GetCurrentThread(), context );
@ -556,7 +555,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *
if (status) return status; if (status) return status;
frame->r0 = (DWORD)rec; frame->r0 = (DWORD)rec;
frame->r1 = (DWORD)context; frame->r1 = (DWORD)context;
frame->pc = (DWORD)dispatcher; frame->pc = (DWORD)pKiUserExceptionDispatcher;
frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL; frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL;
return status; return status;
} }

View File

@ -409,13 +409,14 @@ static void restore_fpu( struct syscall_frame *frame, ucontext_t *sigcontext )
/*********************************************************************** /***********************************************************************
* signal_restore_full_cpu_context * signal_set_full_context
*
* Restore full context from syscall frame
*/ */
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 * call_user_apc_dispatcher
*/ */
NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
PNTAPCFUNC func, PNTAPCFUNC func, NTSTATUS status )
void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC),
NTSTATUS status )
{ {
struct syscall_frame *frame = arm64_thread_data()->syscall_frame; struct syscall_frame *frame = arm64_thread_data()->syscall_frame;
ULONG64 sp = context ? context->Sp : frame->sp; 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; stack->context.u.s.X0 = status;
} }
frame->sp = (ULONG64)stack; frame->sp = (ULONG64)stack;
frame->pc = (ULONG64)dispatcher; frame->pc = (ULONG64)pKiUserApcDispatcher;
frame->x[0] = (ULONG64)&stack->context; frame->x[0] = (ULONG64)&stack->context;
frame->x[1] = arg1; frame->x[1] = arg1;
frame->x[2] = arg2; 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 * 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 * call_user_exception_dispatcher
*/ */
NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context )
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
{ {
struct syscall_frame *frame = arm64_thread_data()->syscall_frame; struct syscall_frame *frame = arm64_thread_data()->syscall_frame;
NTSTATUS status = NtSetContextThread( GetCurrentThread(), context ); NTSTATUS status = NtSetContextThread( GetCurrentThread(), context );
@ -698,7 +696,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *
if (status) return status; if (status) return status;
frame->x[0] = (ULONG64)rec; frame->x[0] = (ULONG64)rec;
frame->x[1] = (ULONG64)context; frame->x[1] = (ULONG64)context;
frame->pc = (ULONG64)dispatcher; frame->pc = (ULONG64)pKiUserExceptionDispatcher;
frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL; frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL;
return status; return status;
} }

View File

@ -921,13 +921,15 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
/*********************************************************************** /***********************************************************************
* signal_restore_full_cpu_context * signal_set_full_context
*
* Restore full context from syscall frame
*/ */
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 * call_user_apc_dispatcher
*/ */
NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, PNTAPCFUNC func, NTSTATUS status )
void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC),
NTSTATUS status )
{ {
struct syscall_frame *frame = x86_thread_data()->syscall_frame; struct syscall_frame *frame = x86_thread_data()->syscall_frame;
ULONG esp = context ? context->Esp : frame->esp; 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; stack->func = func;
frame->ebp = stack->context.Ebp; frame->ebp = stack->context.Ebp;
frame->esp = (ULONG)stack - 4; frame->esp = (ULONG)stack - 4;
frame->eip = (ULONG)dispatcher; frame->eip = (ULONG)pKiUserApcDispatcher;
return status; return status;
} }
@ -1598,17 +1598,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1,
/*********************************************************************** /***********************************************************************
* call_raise_user_exception_dispatcher * 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 * call_user_exception_dispatcher
*/ */
NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context )
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
{ {
struct syscall_frame *frame = x86_thread_data()->syscall_frame; struct syscall_frame *frame = x86_thread_data()->syscall_frame;
void **stack = (void **)frame->esp; void **stack = (void **)frame->esp;
@ -1617,7 +1616,7 @@ NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *
*(--stack) = context; *(--stack) = context;
*(--stack) = rec; *(--stack) = rec;
frame->esp = (ULONG)stack; frame->esp = (ULONG)stack;
frame->eip = (ULONG)dispatcher; frame->eip = (ULONG)pKiUserExceptionDispatcher;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View File

@ -1551,13 +1551,15 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon
/*********************************************************************** /***********************************************************************
* signal_restore_full_cpu_context * signal_set_full_context
*
* Restore full context from syscall frame
*/ */
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 * call_user_apc_dispatcher
*/ */
NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
PNTAPCFUNC func, PNTAPCFUNC func, NTSTATUS status )
void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC),
NTSTATUS status )
{ {
struct syscall_frame *frame = amd64_thread_data()->syscall_frame; struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
ULONG64 rsp = context ? context->Rsp : frame->rsp; 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->rbp = stack->context.Rbp;
frame->rsp = (ULONG64)stack - 8; frame->rsp = (ULONG64)stack - 8;
frame->rip = (ULONG64)dispatcher; frame->rip = (ULONG64)pKiUserApcDispatcher;
frame->rcx = (ULONG64)&stack->context; frame->rcx = (ULONG64)&stack->context;
frame->rdx = arg1; frame->rdx = arg1;
frame->r8 = arg2; frame->r8 = arg2;
@ -1953,17 +1953,16 @@ NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULON
/*********************************************************************** /***********************************************************************
* call_raise_user_exception_dispatcher * 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 * call_user_exception_dispatcher
*/ */
NTSTATUS WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context, NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context )
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
{ {
struct syscall_frame *frame = amd64_thread_data()->syscall_frame; struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
struct stack_layout *stack; 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--; if (stack->rec.ExceptionCode == EXCEPTION_BREAKPOINT) stack->context.Rip--;
frame->rbp = context->Rbp; frame->rbp = context->Rbp;
frame->rsp = (ULONG64)stack; frame->rsp = (ULONG64)stack;
frame->rip = (ULONG64)dispatcher; frame->rip = (ULONG64)pKiUserExceptionDispatcher;
frame->restore_flags |= CONTEXT_CONTROL; frame->restore_flags |= CONTEXT_CONTROL;
return status; return status;
} }

View File

@ -1152,7 +1152,7 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
return NtContinue( context, FALSE ); 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) if (rec->ExceptionFlags & EH_STACK_INVALID)
ERR_(seh)("Exception frame is not in stack limits => unable to dispatch exception.\n"); ERR_(seh)("Exception frame is not in stack limits => unable to dispatch exception.\n");

View File

@ -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 DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int) ) DECLSPEC_HIDDEN;
extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN; extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
extern unsigned int __wine_syscall_flags 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 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 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; 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 void dbg_init(void) DECLSPEC_HIDDEN;
extern NTSTATUS WINAPI call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR arg1, extern NTSTATUS call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3,
ULONG_PTR arg2, ULONG_PTR arg3, PNTAPCFUNC func, NTSTATUS status ) DECLSPEC_HIDDEN;
PNTAPCFUNC func, extern NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN;
void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC), extern void call_raise_user_exception_dispatcher(void) DECLSPEC_HIDDEN;
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;
#define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */ #define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */