Signed-off-by: Martin Storsjo martin@martin.st --- dlls/ntdll/unix/signal_arm64.c | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index cc34690f96..f1c6cdc5fa 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -110,6 +110,20 @@ static DWORD64 get_fault_esr( ucontext_t *sigcontext ) return 0; }
+#elif defined(__APPLE__) + +/* Special Registers access */ +# define SP_sig(context) ((context)->uc_mcontext->__ss.__sp) /* Stack pointer */ +# define PC_sig(context) ((context)->uc_mcontext->__ss.__pc) /* Program counter */ +# define PSTATE_sig(context) ((context)->uc_mcontext->__ss.__cpsr) /* Current State Register */ +# define FP_sig(context) ((context)->uc_mcontext->__ss.__fp) /* Frame pointer */ +# define LR_sig(context) ((context)->uc_mcontext->__ss.__lr) /* Link Register */ + +static DWORD64 get_fault_esr( ucontext_t *sigcontext ) +{ + return sigcontext->uc_mcontext->__es.__esr; +} + #endif /* linux */
static pthread_key_t teb_key; @@ -299,7 +313,11 @@ static void save_context( CONTEXT *context, const ucontext_t *sigcontext ) context->Sp = SP_sig(sigcontext); /* Stack pointer */ context->Pc = PC_sig(sigcontext); /* Program Counter */ context->Cpsr = PSTATE_sig(sigcontext); /* Current State Register */ +#ifdef linux for (i = 0; i <= 28; i++) context->u.X[i] = REGn_sig( i, sigcontext ); +#elif defined(__APPLE__) + for (i = 0; i <= 28; i++) context->u.X[i] = sigcontext->uc_mcontext->__ss.__x[i]; +#endif }
@@ -317,7 +335,11 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext ) SP_sig(sigcontext) = context->Sp; /* Stack pointer */ PC_sig(sigcontext) = context->Pc; /* Program Counter */ PSTATE_sig(sigcontext) = context->Cpsr; /* Current State Register */ +#ifdef linux for (i = 0; i <= 28; i++) REGn_sig( i, sigcontext ) = context->u.X[i]; +#elif defined(__APPLE__) + for (i = 0; i <= 28; i++) sigcontext->uc_mcontext->__ss.__x[i] = context->u.X[i]; +#endif }
@@ -328,6 +350,7 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext ) */ static void save_fpu( CONTEXT *context, ucontext_t *sigcontext ) { +#ifdef linux struct fpsimd_context *fp = get_fpsimd_context( sigcontext );
if (!fp) return; @@ -335,6 +358,12 @@ static void save_fpu( CONTEXT *context, ucontext_t *sigcontext ) context->Fpcr = fp->fpcr; context->Fpsr = fp->fpsr; memcpy( context->V, fp->vregs, sizeof(context->V) ); +#elif defined(__APPLE__) + context->ContextFlags |= CONTEXT_FLOATING_POINT; + context->Fpcr = sigcontext->uc_mcontext->__ns.__fpcr; + context->Fpsr = sigcontext->uc_mcontext->__ns.__fpsr; + memcpy( context->V, sigcontext->uc_mcontext->__ns.__v, sizeof(context->V) ); +#endif }
@@ -345,12 +374,18 @@ static void save_fpu( CONTEXT *context, ucontext_t *sigcontext ) */ static void restore_fpu( CONTEXT *context, ucontext_t *sigcontext ) { +#ifdef linux struct fpsimd_context *fp = get_fpsimd_context( sigcontext );
if (!fp) return; fp->fpcr = context->Fpcr; fp->fpsr = context->Fpsr; memcpy( fp->vregs, context->V, sizeof(fp->vregs) ); +#elif defined(__APPLE__) + sigcontext->uc_mcontext->__ns.__fpcr = context->Fpcr; + sigcontext->uc_mcontext->__ns.__fpsr = context->Fpsr; + memcpy( sigcontext->uc_mcontext->__ns.__v, context->V, sizeof(context->V) ); +#endif }
@@ -594,6 +629,7 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) stack->rec = *rec; stack->context = context;
+#ifdef linux REGn_sig(3, sigcontext) = SP_sig(sigcontext); /* original stack pointer, fourth arg for raise_func_trampoline */ SP_sig(sigcontext) = (ULONG_PTR)stack; LR_sig(sigcontext) = PC_sig(sigcontext); @@ -602,6 +638,16 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for KiUserExceptionDispatcher */ REGn_sig(2, sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher; /* dispatcher arg for raise_func_trampoline */ REGn_sig(18, sigcontext) = (ULONG_PTR)NtCurrentTeb(); +#elif defined(__APPLE__) + sigcontext->uc_mcontext->__ss.__x[3] = sigcontext->uc_mcontext->__ss.__sp; /* original stack pointer, fourth arg for raise_func_trampoline */ + sigcontext->uc_mcontext->__ss.__sp = (ULONG_PTR)stack; + sigcontext->uc_mcontext->__ss.__lr = sigcontext->uc_mcontext->__ss.__pc; + sigcontext->uc_mcontext->__ss.__pc = (ULONG_PTR)raise_func_trampoline; + sigcontext->uc_mcontext->__ss.__x[0] = (ULONG_PTR)&stack->rec; /* first arg for KiUserExceptionDispatcher */ + sigcontext->uc_mcontext->__ss.__x[1] = (ULONG_PTR)&stack->context; /* second arg for KiUserExceptionDispatcher */ + sigcontext->uc_mcontext->__ss.__x[2] = (ULONG_PTR)pKiUserExceptionDispatcher; /* dispatcher arg for raise_func_trampoline */ + sigcontext->uc_mcontext->__ss.__x[18] = (ULONG_PTR)NtCurrentTeb(); +#endif }