ntdll: Don't pass arguments on the stack for user callbacks on ARM.

This commit is contained in:
Alexandre Julliard 2023-06-01 13:26:19 +02:00
parent d8c39b3d5a
commit 091513ffaa

View file

@ -1152,13 +1152,14 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
/***********************************************************************
* call_user_mode_callback
*/
extern NTSTATUS CDECL call_user_mode_callback( void *func, void *stack, void **ret_ptr,
ULONG *ret_len, TEB *teb ) DECLSPEC_HIDDEN;
extern NTSTATUS call_user_mode_callback( ULONG id, void *args, ULONG len, void **ret_ptr,
ULONG *ret_len, void *func, TEB *teb ) DECLSPEC_HIDDEN;
__ASM_GLOBAL_FUNC( call_user_mode_callback,
"push {r2-r12,lr}\n\t"
"push {r4-r12,lr}\n\t"
"ldr ip, [sp, #0x2c]\n\t" /* func */
"ldr r4, [sp, #0x30]\n\t" /* teb */
"ldr r5, [r4]\n\t" /* teb->Tib.ExceptionList */
"str r5, [sp, #0x28]\n\t"
"push {r3, r5}\n\t"
#ifndef __SOFTFP__
"sub sp, sp, #0x90\n\t"
"mov r5, sp\n\t"
@ -1172,17 +1173,15 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback,
"str sp, [r4, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"ldr r6, [r5, #0x50]\n\t" /* prev_frame->syscall_table */
"str r6, [sp, #0x50]\n\t" /* frame->syscall_table */
"mov ip, r0\n\t"
"mov sp, r1\n\t"
"pop {r0-r3}\n\t"
"bx ip" )
/***********************************************************************
* user_mode_callback_return
*/
extern void CDECL DECLSPEC_NORETURN user_mode_callback_return( void *ret_ptr, ULONG ret_len,
NTSTATUS status, TEB *teb ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN user_mode_callback_return( void *ret_ptr, ULONG ret_len,
NTSTATUS status, TEB *teb ) DECLSPEC_HIDDEN;
__ASM_GLOBAL_FUNC( user_mode_callback_return,
"ldr r4, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"ldr r5, [r4, #0x4c]\n\t" /* frame->prev_frame */
@ -1195,9 +1194,9 @@ __ASM_GLOBAL_FUNC( user_mode_callback_return,
"add r5, r5, #0x90\n\t"
#endif
"mov sp, r5\n\t"
"ldr r5, [sp, #0x28]\n\t"
"str r5, [r3]\n\t" /* teb->Tib.ExceptionList */
"pop {r5, r6}\n\t" /* ret_ptr, ret_len */
"pop {r5, r7}\n\t"
"ldr r6, [sp, #0x28]\n\t" /* ret_len */
"str r7, [r3]\n\t" /* teb->Tib.ExceptionList */
"str r0, [r5]\n\t" /* ret_ptr */
"str r1, [r6]\n\t" /* ret_len */
"mov r0, r2\n\t" /* status */
@ -1211,18 +1210,13 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
{
struct syscall_frame *frame = arm_thread_data()->syscall_frame;
void *args_data = (void *)((frame->sp - len) & ~15);
ULONG_PTR *stack = args_data;
if ((char *)ntdll_get_thread_data()->kernel_stack + min_kernel_stack > (char *)&frame)
return STATUS_STACK_OVERFLOW;
memcpy( args_data, args, len );
*(--stack) = 0;
*(--stack) = len;
*(--stack) = (ULONG_PTR)args_data;
*(--stack) = id;
return call_user_mode_callback( pKiUserCallbackDispatcher, stack, ret_ptr, ret_len, NtCurrentTeb() );
return call_user_mode_callback( id, args_data, len, ret_ptr, ret_len,
pKiUserCallbackDispatcher, NtCurrentTeb() );
}