Alexandre Julliard : ntdll: Handle signals on the signal stack also on ARM.

Alexandre Julliard julliard at winehq.org
Wed Jul 15 16:44:45 CDT 2020


Module: wine
Branch: master
Commit: 1e4865ffcfa4933ff27b1e66405e1498dd9d1781
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1e4865ffcfa4933ff27b1e66405e1498dd9d1781

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul 15 10:34:18 2020 +0200

ntdll: Handle signals on the signal stack also on ARM.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/signal_arm.c | 117 ++++++++++++-------------------------------
 1 file changed, 32 insertions(+), 85 deletions(-)

diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index eaa58fe00b..1e8abb494c 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -172,8 +172,6 @@ enum arm_trap_code
     TRAP_ARM_ALIGNFLT   = 17,  /* Alignment check exception */
 };
 
-typedef void (WINAPI *raise_func)( EXCEPTION_RECORD *rec, CONTEXT *context );
-
 
 /***********************************************************************
  *           unwind_builtin_dll
@@ -507,29 +505,29 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
 }
 
 
-extern void raise_func_trampoline_thumb( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
+extern void raise_func_trampoline_thumb( EXCEPTION_RECORD *rec, CONTEXT *context, void *func );
 __ASM_GLOBAL_FUNC( raise_func_trampoline_thumb,
                    ".thumb\n\t"
-                   "blx r2\n\t"
+                   "bx r2\n\t"
                    "bkpt")
 
-extern void raise_func_trampoline_arm( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
+extern void raise_func_trampoline_arm( EXCEPTION_RECORD *rec, CONTEXT *context, void *func );
 __ASM_GLOBAL_FUNC( raise_func_trampoline_arm,
                    ".arm\n\t"
-                   "blx r2\n\t"
+                   "bx r2\n\t"
                    "bkpt")
 
 /***********************************************************************
- *           setup_exception_record
+ *           setup_exception
  *
- * Setup the exception record and context on the thread stack.
+ * Modify the signal context to call the exception raise function.
  */
-static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func func, EXCEPTION_RECORD *rec )
+static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
 {
-    struct stack_layout
+    struct
     {
-        CONTEXT           context;
-        EXCEPTION_RECORD  rec;
+        CONTEXT          context;
+        EXCEPTION_RECORD rec;
     } *stack;
     void *stack_ptr = (void *)(SP_sig(sigcontext) & ~3);
 
@@ -544,39 +542,29 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun
         PC_sig(sigcontext) = (DWORD)raise_func_trampoline_thumb;
     else
         PC_sig(sigcontext) = (DWORD)raise_func_trampoline_arm;
-    REGn_sig(0, sigcontext) = (DWORD)&stack->rec;  /* first arg for raise_func */
-    REGn_sig(1, sigcontext) = (DWORD)&stack->context; /* second arg for raise_func */
-    REGn_sig(2, sigcontext) = (DWORD)func; /* the raise_func as third arg for the trampoline */
-    return &stack->rec;
+    REGn_sig(0, sigcontext) = (DWORD)&stack->rec;  /* first arg for KiUserExceptionDispatcher */
+    REGn_sig(1, sigcontext) = (DWORD)&stack->context; /* second arg for KiUserExceptionDispatcher */
+    REGn_sig(2, sigcontext) = (DWORD)pKiUserExceptionDispatcher;
 }
 
-extern void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
-                                                   NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
+void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
+                                            NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
 {
     dispatcher( rec, context );
 }
 
-/**********************************************************************
- *		raise_segv_exception
- */
-static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
-{
-    NTSTATUS status = NtRaiseException( rec, context, TRUE );
-    if (status) RtlRaiseStatus( status );
-}
-
 
 /**********************************************************************
  *		segv_handler
  *
  * Handler for SIGSEGV and related errors.
  */
-static void segv_handler( int signal, siginfo_t *info, void *ucontext )
+static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 {
     EXCEPTION_RECORD rec = { 0 };
-    ucontext_t *context = ucontext;
+    ucontext_t *context = sigcontext;
 
-    switch(get_trap_code(signal, context))
+    switch (get_trap_code(signal, context))
     {
     case TRAP_ARM_PRIVINFLT:   /* Invalid opcode exception */
         rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
@@ -584,8 +572,8 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
     case TRAP_ARM_PAGEFLT:  /* Page fault */
         rec.NumberParameters = 2;
         rec.ExceptionInformation[0] = (get_error_code(context) & 0x800) != 0;
-        rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
-        rec.ExceptionCode = virtual_handle_fault( info->si_addr, rec.ExceptionInformation[0],
+        rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
+        rec.ExceptionCode = virtual_handle_fault( siginfo->si_addr, rec.ExceptionInformation[0],
                                                   (void *)SP_sig(context) );
         if (!rec.ExceptionCode) return;
         break;
@@ -603,7 +591,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
         rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
         break;
     }
-    setup_exception( context, raise_segv_exception, &rec );
+    setup_exception( context, &rec );
 }
 
 
@@ -612,13 +600,11 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
  *
  * Handler for SIGTRAP.
  */
-static void trap_handler( int signal, siginfo_t *info, void *ucontext )
+static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 {
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-    NTSTATUS status;
+    EXCEPTION_RECORD rec = { 0 };
 
-    switch ( info->si_code )
+    switch (siginfo->si_code)
     {
     case TRAP_TRACE:
         rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
@@ -628,15 +614,7 @@ static void trap_handler( int signal, siginfo_t *info, void *ucontext )
         rec.ExceptionCode = EXCEPTION_BREAKPOINT;
         break;
     }
-
-    save_context( &context, ucontext );
-    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = (LPVOID)context.Pc;
-    rec.NumberParameters = 0;
-    status = NtRaiseException( &rec, &context, TRUE );
-    if (status) RtlRaiseStatus( status );
-    restore_context( &context, ucontext );
+    setup_exception( sigcontext, &rec );
 }
 
 
@@ -647,11 +625,7 @@ static void trap_handler( int signal, siginfo_t *info, void *ucontext )
  */
 static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 {
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-    NTSTATUS status;
-
-    save_context( &context, sigcontext );
+    EXCEPTION_RECORD rec = { 0 };
 
     switch (siginfo->si_code & 0xffff )
     {
@@ -697,14 +671,7 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
         rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
         break;
     }
-    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = (LPVOID)context.Pc;
-    rec.NumberParameters = 0;
-    status = NtRaiseException( &rec, &context, TRUE );
-    if (status) RtlRaiseStatus( status );
-
-    restore_context( &context, sigcontext );
+    setup_exception( sigcontext, &rec );
 }
 
 
@@ -715,19 +682,9 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
  */
 static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 {
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-    NTSTATUS status;
+    EXCEPTION_RECORD rec = { CONTROL_C_EXIT };
 
-    save_context( &context, sigcontext );
-    rec.ExceptionCode    = CONTROL_C_EXIT;
-    rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = (LPVOID)context.Pc;
-    rec.NumberParameters = 0;
-    status = NtRaiseException( &rec, &context, TRUE );
-    if (status) RtlRaiseStatus( status );
-    restore_context( &context, sigcontext );
+    setup_exception( sigcontext, &rec );
 }
 
 
@@ -738,19 +695,9 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
  */
 static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 {
-    EXCEPTION_RECORD rec;
-    CONTEXT context;
-    NTSTATUS status;
+    EXCEPTION_RECORD rec = { EXCEPTION_WINE_ASSERTION, EH_NONCONTINUABLE };
 
-    save_context( &context, sigcontext );
-    rec.ExceptionCode    = EXCEPTION_WINE_ASSERTION;
-    rec.ExceptionFlags   = EH_NONCONTINUABLE;
-    rec.ExceptionRecord  = NULL;
-    rec.ExceptionAddress = (LPVOID)context.Pc;
-    rec.NumberParameters = 0;
-    status = NtRaiseException( &rec, &context, TRUE );
-    if (status) RtlRaiseStatus( status );
-    restore_context( &context, sigcontext );
+    setup_exception( sigcontext, &rec );
 }
 
 
@@ -846,7 +793,7 @@ void signal_init_process(void)
     struct sigaction sig_act;
 
     sig_act.sa_mask = server_block_set;
-    sig_act.sa_flags = SA_RESTART | SA_SIGINFO;
+    sig_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
 
     sig_act.sa_sigaction = int_handler;
     if (sigaction( SIGINT, &sig_act, NULL ) == -1) goto error;




More information about the wine-cvs mailing list