For cases where the builtin DLLs still are built as ELF as opposed
to PE, there's a risk of x18 being clobbered anywhere, after
the point where x18 is initialized at the moment, before entering
native code, if the surrounding operating system ABI doesn't treat
x18 as reserved.
Set the register in assembly code, to avoid the risk of any compiler
generated code (potentially calling helper functions) between setting
x18 and calling the native code entry points.
Signed-off-by: Martin Storsjo <martin(a)martin.st>
---
Something similar was already done for some functions as part of
e91e6cc9bdb4846.
---
dlls/kernel32/process.c | 14 ++++++++++++++
dlls/ntdll/loader.c | 16 ++++++++++++++++
dlls/ntdll/signal_arm64.c | 9 +++++++--
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index b2bd5980fd..f32c588c26 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -118,6 +118,20 @@ __ASM_GLOBAL_FUNC( __wine_start_process,
"pushl %ebx\n\t" /* arg */
"pushl %eax\n\t" /* entry */
"call " __ASM_NAME("start_process") )
+#elif defined(__aarch64__)
+extern DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry );
+__ASM_GLOBAL_FUNC( call_process_entry,
+ "stp x0, x1, [sp, #-32]!\n\t"
+ "stp x29, x30, [sp, #16]\n\t"
+ "add x29, sp, #16\n\t"
+ __ASM_CFI(".cfi_def_cfa w29, 16\n\t")
+ __ASM_CFI(".cfi_offset w30, -8\n\t")
+ __ASM_CFI(".cfi_offset w29, -16\n\t")
+ "bl " __ASM_NAME("NtCurrentTeb") "\n\t"
+ "mov x18, x0\n\t"
+ "ldp x29, x30, [sp, #16]\n\t"
+ "ldp x0, x1, [sp], #32\n\t"
+ "br x1\n\t")
#else
static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
{
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 6290cbcb4e..1779bcb136 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -284,6 +284,22 @@ __ASM_GLOBAL_FUNC(call_dll_entry_point,
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
__ASM_CFI(".cfi_same_value %ebp\n\t")
"ret" )
+#elif defined(__aarch64__)
+extern BOOL call_dll_entry_point( DLLENTRYPROC proc, void *module, UINT reason, void *reserved );
+__ASM_GLOBAL_FUNC(call_dll_entry_point,
+ "stp x29, x30, [sp, #-48]!\n\t"
+ "stp x0, x1, [sp, #16]\n\t"
+ "stp x2, x3, [sp, #32]\n\t"
+ "mov x29, sp\n\t"
+ __ASM_CFI(".cfi_def_cfa w29, 48\n\t")
+ __ASM_CFI(".cfi_offset w30, -40\n\t")
+ __ASM_CFI(".cfi_offset w29, -48\n\t")
+ "bl " __ASM_NAME("NtCurrentTeb") "\n\t"
+ "mov x18, x0\n\t"
+ "ldp x3, x0, [sp, #16]\n\t"
+ "ldp x1, x2, [sp, #32]\n\t"
+ "ldp x29, x30, [sp], #48\n\t"
+ "br x3\n\t")
#else /* __i386__ */
static inline BOOL call_dll_entry_point( DLLENTRYPROC proc, void *module,
UINT reason, void *reserved )
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 573eaef0f6..928ff07cf6 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -198,6 +198,11 @@ static DWORD __cdecl unwind_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_
return ExceptionCollidedUnwind;
}
+extern DWORD call_language_handler_wrapper( EXCEPTION_RECORD *rec, void *frame, CONTEXT *context, DISPATCHER_CONTEXT *dispatch, PEXCEPTION_ROUTINE handler, TEB *teb );
+__ASM_GLOBAL_FUNC( call_language_handler_wrapper,
+ "mov x18, x5\n\t"
+ "br x4\n\t")
+
/**********************************************************************
* call_unwind_handler
*
@@ -214,7 +219,7 @@ static DWORD call_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT *dis
TRACE( "calling handler %p (rec=%p, frame=0x%lx context=%p, dispatch=%p)\n",
dispatch->LanguageHandler, rec, dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch );
- res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch );
+ res = call_language_handler_wrapper( rec, (void *)dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch, dispatch->LanguageHandler, NtCurrentTeb() );
TRACE( "handler %p returned %x\n", dispatch->LanguageHandler, res );
__wine_pop_frame( &frame.frame );
@@ -288,7 +293,7 @@ static DWORD call_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_C
TRACE( "calling handler %p (rec=%p, frame=0x%lx context=%p, dispatch=%p)\n",
dispatch->LanguageHandler, rec, dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch );
- res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, context, dispatch );
+ res = call_language_handler_wrapper( rec, (void *)dispatch->EstablisherFrame, context, dispatch, dispatch->LanguageHandler, NtCurrentTeb() );
TRACE( "handler at %p returned %u\n", dispatch->LanguageHandler, res );
__wine_pop_frame( &frame );
--
2.17.1