ntdll: Pass the result status to call_user_apc_dispatcher().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-05-25 13:04:24 +02:00
parent e1716530d9
commit 1364b11fd4
6 changed files with 52 additions and 46 deletions

View File

@ -354,10 +354,10 @@ static int wait_select_reply( void *cookie )
/***********************************************************************
* invoke_user_apc
*/
static void invoke_user_apc( CONTEXT *context, const user_apc_t *apc )
static void invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTATUS status )
{
call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2],
wine_server_get_ptr( apc->func ), pKiUserApcDispatcher );
wine_server_get_ptr( apc->func ), pKiUserApcDispatcher, status );
}
@ -690,7 +690,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
}
ret = server_select( select_op, size, flags, abs_timeout, NULL, NULL, &apc );
if (ret == STATUS_USER_APC) invoke_user_apc( NULL, &apc );
if (ret == STATUS_USER_APC) invoke_user_apc( NULL, &apc, ret );
/* A test on Windows 2000 shows that Windows always yields during
a wait, but a wait that is hit by an event gets a priority
@ -711,7 +711,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
if (alertable)
{
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, NULL, &apc );
if (status == STATUS_USER_APC) invoke_user_apc( context, &apc );
if (status == STATUS_USER_APC) invoke_user_apc( context, &apc, status );
}
status = NtSetContextThread( GetCurrentThread(), context );
if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)

View File

@ -476,21 +476,22 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
* call_user_apc_dispatcher
*/
__ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"mov r5, r1\n\t" /* ctx */
"mov r6, r2\n\t" /* arg1 */
"mov r7, r3\n\t" /* arg2 */
"mov r5, r1\n\t" /* arg1 */
"mov r6, r2\n\t" /* arg2 */
"mov r7, r3\n\t" /* arg3 */
"ldr r8, [sp]\n\t" /* func */
"ldr r9, [sp, #4]\n\t" /* dispatcher */
"mrc p15, 0, r10, c13, c0, 2\n\t" /* NtCurrentTeb() */
"ldr r10, [sp, #8]\n\t" /* status */
"mrc p15, 0, r11, c13, c0, 2\n\t" /* NtCurrentTeb() */
"cmp r0, #0\n\t" /* context_ptr */
"beq 1f\n\t"
"ldr r0, [r0, #0x38]\n\t" /* context_ptr->Sp */
"sub r0, r0, #0x1c8\n\t" /* sizeof(CONTEXT) + offsetof(frame,r4) */
"mov ip, #0\n\t"
"str ip, [r10, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"str ip, [r11, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"mov sp, r0\n\t"
"b 2f\n"
"1:\tldr r0, [r10, #0x1d8]\n\t"
"1:\tldr r0, [r11, #0x1d8]\n\t"
"sub r0, #0x1a0\n\t"
"mov sp, r0\n\t"
"mov r0, #3\n\t"
@ -499,14 +500,13 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"mov r1, sp\n\t"
"mov r0, #~1\n\t"
"bl " __ASM_NAME("NtGetContextThread") "\n\t"
"mov r0, #0xc0\n\t"
"str r0, [sp, #4]\n\t" /* context.R0 = STATUS_USER_APC */
"str r10, [sp, #4]\n\t" /* context.R0 = status */
"mov r0, sp\n\t"
"mov ip, #0\n\t"
"str ip, [r10, #0x1d8]\n\t"
"2:\tmov r1, r5\n\t" /* ctx */
"mov r2, r6\n\t" /* arg1 */
"mov r3, r7\n\t" /* arg2 */
"str ip, [r11, #0x1d8]\n\t"
"2:\tmov r1, r5\n\t" /* arg1 */
"mov r2, r6\n\t" /* arg2 */
"mov r3, r7\n\t" /* arg3 */
"push {r8, r9}\n\t" /* func */
"ldr lr, [r0, #0x3c]\n\t" /* context.Lr */
"bx r9" )

View File

@ -613,20 +613,21 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
*/
__ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"mov x19, x0\n\t" /* context */
"mov x20, x1\n\t" /* ctx */
"mov x21, x2\n\t" /* arg1 */
"mov x22, x3\n\t" /* arg2 */
"mov x20, x1\n\t" /* arg1 */
"mov x21, x2\n\t" /* arg2 */
"mov x22, x3\n\t" /* arg3 */
"mov x23, x4\n\t" /* func */
"mov x24, x5\n\t" /* dispatcher */
"mov x25, x6\n\t" /* status */
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
"add x25, x0, #0x2f8\n\t" /* arm64_thread_data()->syscall_frame */
"add x26, x0, #0x2f8\n\t" /* arm64_thread_data()->syscall_frame */
"cbz x19, 1f\n\t"
"ldr x0, [x19, #0x100]\n\t" /* context.Sp */
"sub x0, x0, #0x430\n\t" /* sizeof(CONTEXT) + offsetof(frame,thunk_x29) */
"str xzr, [x25]\n\t"
"str xzr, [x26]\n\t"
"mov sp, x0\n\t"
"b 2f\n"
"1:\tldr x0, [x25]\n\t"
"1:\tldr x0, [x26]\n\t"
"sub sp, x0, #0x390\n\t"
"mov w2, #0x400000\n\t" /* context.ContextFlags = CONTEXT_FULL */
"movk w2, #7\n\t"
@ -634,14 +635,13 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"mov x1, sp\n\t"
"mov x0, #~1\n\t"
"bl " __ASM_NAME("NtGetContextThread") "\n\t"
"mov w2, #0xc0\n\t" /* context.X0 = STATUS_USER_APC */
"str x2, [sp, #8]\n\t"
"str xzr, [x25]\n\t"
"str x25, [sp, #8]\n\t" /* context.X0 = status */
"str xzr, [x26]\n\t"
"mov x0, sp\n" /* context */
"2:\tldr lr, [x0, #0xf8]\n\t" /* context.Lr */
"mov x1, x20\n\t" /* ctx */
"mov x2, x21\n\t" /* arg1 */
"mov x3, x22\n\t" /* arg2 */
"mov x1, x20\n\t" /* arg1 */
"mov x2, x21\n\t" /* arg2 */
"mov x3, x22\n\t" /* arg3 */
"mov x4, x23\n\t" /* func */
"br x24" )

View File

@ -1615,15 +1615,16 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
struct apc_stack_layout
{
void *context_ptr;
void *ctx;
void *arg1;
void *arg2;
void *arg3;
void *func;
CONTEXT context;
};
struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *context, struct apc_stack_layout *stack,
void *ctx, void *arg1, void *arg2, void *func )
void *arg1, void *arg2, void *arg3,
void *func, NTSTATUS status )
{
CONTEXT c;
@ -1631,14 +1632,14 @@ struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *conte
{
c.ContextFlags = CONTEXT_FULL;
NtGetContextThread( GetCurrentThread(), &c );
c.Eax = STATUS_USER_APC;
c.Eax = status;
context = &c;
}
memmove( &stack->context, context, sizeof(stack->context) );
stack->context_ptr = &stack->context;
stack->ctx = ctx;
stack->arg1 = arg1;
stack->arg2 = arg2;
stack->arg3 = arg3;
stack->func = func;
return stack;
}
@ -1663,10 +1664,11 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movl %ebp,%esp\n\t" /* pop return address */
"cmpl %esp,%eax\n\t"
"cmovbl %eax,%esp\n\t"
"pushl 24(%ebp)\n\t" /* status */
"pushl 16(%ebp)\n\t" /* func */
"pushl 12(%ebp)\n\t" /* arg2 */
"pushl 8(%ebp)\n\t" /* arg1 */
"pushl 4(%ebp)\n\t" /* ctx */
"pushl 12(%ebp)\n\t" /* arg3 */
"pushl 8(%ebp)\n\t" /* arg2 */
"pushl 4(%ebp)\n\t" /* arg1 */
"pushl %eax\n\t"
"pushl %esi\n\t"
"call " __ASM_STDCALL("setup_user_apc_dispatcher_stack",24) "\n\t"

View File

@ -1971,7 +1971,9 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
/***********************************************************************
* call_user_apc_dispatcher
*/
struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *context, struct apc_stack_layout *stack )
struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *context,
struct apc_stack_layout *stack,
NSTATUS status )
{
CONTEXT c;
@ -1979,7 +1981,7 @@ struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *conte
{
c.ContextFlags = CONTEXT_FULL;
NtGetContextThread( GetCurrentThread(), &c );
c.Rax = STATUS_USER_APC;
c.Rax = status;
context = &c;
}
memmove( &stack->context, context, sizeof(stack->context) );
@ -1990,9 +1992,10 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq 0x28(%rsp),%rsi\n\t" /* func */
"movq 0x30(%rsp),%rdi\n\t" /* dispatcher */
"movq %gs:0x30,%rbx\n\t"
"movq %rdx,%r12\n\t" /* ctx */
"movq %r8,%r13\n\t" /* arg1 */
"movq %r9,%r14\n\t" /* arg2 */
"movq %rdx,%r12\n\t" /* arg1 */
"movq %r8,%r13\n\t" /* arg2 */
"movq %r9,%r14\n\t" /* arg3 */
"movq 0x38(%rsp),%r8\n\t" /* status */
"jrcxz 1f\n\t"
"movq 0x98(%rcx),%rdx\n\t" /* context->Rsp */
"jmp 2f\n\t"
@ -2007,9 +2010,9 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"call " __ASM_NAME("setup_user_apc_dispatcher_stack") "\n\t"
"movq %rax,%rsp\n\t"
"leaq 0x30(%rsp),%rcx\n\t" /* context */
"movq %r12,%rdx\n\t" /* ctx */
"movq %r13,%r8\n\t" /* arg1 */
"movq %r14,%r9\n" /* arg2 */
"movq %r12,%rdx\n\t" /* arg1 */
"movq %r13,%r8\n\t" /* arg2 */
"movq %r14,%r9\n" /* arg3 */
"movq $0,0x328(%rbx)\n\t" /* amd64_thread_data()->syscall_frame */
"movq %rsi,0x20(%rsp)\n\t" /* func */
"movq %rdi,%r10\n\t"

View File

@ -278,10 +278,11 @@ extern void init_cpu_info(void) DECLSPEC_HIDDEN;
extern void dbg_init(void) DECLSPEC_HIDDEN;
extern void WINAPI DECLSPEC_NORETURN call_user_apc_dispatcher( CONTEXT *context_ptr, ULONG_PTR ctx,
ULONG_PTR arg1, ULONG_PTR arg2,
extern void WINAPI DECLSPEC_NORETURN 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) ) DECLSPEC_HIDDEN;
void (WINAPI *dispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC),
NTSTATUS status ) 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 call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) DECLSPEC_HIDDEN;