[PATCH 1/2] ntdll: Explicitly clobber X16/X17 registers on ARM64 syscall return.
Jinoh Kang
jinoh.kang.kr at gmail.com
Mon Nov 8 09:41:17 CST 2021
Synchronize syscall_frame to match the actual state on syscall return.
This is required for a follow-up patch that addresses incorrect
behaviour of __wine_syscall_dispatcher, specifically unconditional
clobbering of X16 and X17 registers, while minimizing the performance
impact. (Hence the "fastpath")
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
dlls/ntdll/unix/signal_arm64.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index fa402a7a83e..da5739b6f1c 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -324,6 +324,17 @@ NTSTATUS CDECL unwind_builtin_dll( ULONG type, DISPATCHER_CONTEXT *dispatch, CON
}
+/***********************************************************************
+ * syscall_frame_fixup_for_fastpath
+ *
+ * Clobbers the frame's X16 and X17 register values.
+ */
+static void syscall_frame_fixup_for_fastpath( struct syscall_frame *frame )
+{
+ frame->x[16] = frame->pc;
+ frame->x[17] = frame->sp;
+}
+
/***********************************************************************
* save_context
*
@@ -686,6 +697,7 @@ NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR a
frame->x[3] = arg3;
frame->x[4] = (ULONG64)func;
frame->restore_flags |= CONTEXT_CONTROL | CONTEXT_INTEGER;
+ syscall_frame_fixup_for_fastpath( frame );
return status;
}
@@ -718,6 +730,7 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
frame->lr = lr;
frame->sp = sp;
frame->restore_flags |= CONTEXT_INTEGER | CONTEXT_CONTROL;
+ syscall_frame_fixup_for_fastpath( frame );
return status;
}
@@ -757,6 +770,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
callback_frame.frame.restore_flags = CONTEXT_INTEGER;
callback_frame.frame.syscall_table = frame->syscall_table;
callback_frame.frame.prev_frame = frame;
+ syscall_frame_fixup_for_fastpath( &callback_frame.frame );
arm64_thread_data()->syscall_frame = &callback_frame.frame;
__wine_syscall_dispatcher_return( &callback_frame.frame, 0 );
@@ -1187,6 +1201,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame->prev_frame = NULL;
frame->restore_flags |= CONTEXT_INTEGER;
frame->syscall_table = KeServiceDescriptorTable;
+ syscall_frame_fixup_for_fastpath( frame );
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
__wine_syscall_dispatcher_return( frame, 0 );
--
2.33.1
More information about the wine-devel
mailing list