[PATCH 4/4] ntdll: Implement arm64 sigcontext access for macOS

Martin Storsjo martin at martin.st
Fri Aug 14 06:54:17 CDT 2020


Signed-off-by: Martin Storsjo <martin at 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
 }
 
 
-- 
2.17.1




More information about the wine-devel mailing list