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 )
{
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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");

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 __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 */