Alexandre Julliard : ntdll: Use a stack_layout structure to build exception data on ARM64.

Alexandre Julliard julliard at winehq.org
Thu Sep 12 16:28:57 CDT 2019


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Sep 12 21:07:14 2019 +0200

ntdll: Use a stack_layout structure to build exception data on ARM64.

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

---

 dlls/ntdll/signal_arm64.c | 80 +++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 38 deletions(-)

diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index ebba8e9cae..3194cc82b6 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -114,6 +114,15 @@ static const size_t teb_size = 0x2000;  /* we reserve two pages for the TEB */
 static const size_t signal_stack_size = max( MINSIGSTKSZ, 8192 );
 
 typedef void (WINAPI *raise_func)( EXCEPTION_RECORD *rec, CONTEXT *context );
+
+/* stack layout when calling an exception raise function */
+struct stack_layout
+{
+    CONTEXT           context;
+    EXCEPTION_RECORD  rec;
+    void             *redzone[2];
+};
+
 typedef int (*wine_signal_handler)(unsigned int sig);
 
 static wine_signal_handler handlers[256];
@@ -471,18 +480,13 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
 
 
 /***********************************************************************
- *           setup_exception_record
+ *           setup_exception
  *
  * Setup the exception record and context on the thread stack.
  */
-static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func func )
+static struct stack_layout *setup_exception( ucontext_t *sigcontext, raise_func func )
 {
-    struct stack_layout
-    {
-        CONTEXT           context;
-        EXCEPTION_RECORD  rec;
-        void             *redzone[2];
-    } *stack;
+    struct stack_layout *stack;
     DWORD exception_code = 0;
 
     /* push the stack_layout structure */
@@ -503,7 +507,7 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun
     REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec;  /* first arg for raise_func */
     REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for raise_func */
 
-    return &stack->rec;
+    return stack;
 }
 
 /**********************************************************************
@@ -1039,7 +1043,7 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
  */
 static void segv_handler( int signal, siginfo_t *info, void *ucontext )
 {
-    EXCEPTION_RECORD *rec;
+    struct stack_layout *stack;
     ucontext_t *context = ucontext;
 
     /* check for page fault inside the thread stack */
@@ -1050,32 +1054,32 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
         case 1:  /* handled */
             return;
         case -1:  /* overflow */
-            rec = setup_exception( context, raise_segv_exception );
-            rec->ExceptionCode = EXCEPTION_STACK_OVERFLOW;
+            stack = setup_exception( context, raise_segv_exception );
+            stack->rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
             return;
         }
     }
 
-    rec = setup_exception( context, raise_segv_exception );
-    if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
+    stack = setup_exception( context, raise_segv_exception );
+    if (stack->rec.ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
 
     switch(signal)
     {
     case SIGILL:   /* Invalid opcode exception */
-        rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+        stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
         break;
     case SIGSEGV:  /* Segmentation fault */
-        rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
-        rec->NumberParameters = 2;
-        rec->ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
-        rec->ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
+        stack->rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+        stack->rec.NumberParameters = 2;
+        stack->rec.ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
+        stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
         break;
     case SIGBUS:  /* Alignment check exception */
-        rec->ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
+        stack->rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
         break;
     default:
         ERR("Got unexpected signal %i\n", signal);
-        rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+        stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
         break;
     }
 }
@@ -1088,16 +1092,16 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
 static void trap_handler( int signal, siginfo_t *info, void *ucontext )
 {
     ucontext_t *context = ucontext;
-    EXCEPTION_RECORD *rec = setup_exception( context, raise_trap_exception );
+    struct stack_layout *stack = setup_exception( context, raise_trap_exception );
 
     switch (info->si_code)
     {
     case TRAP_TRACE:
-        rec->ExceptionCode = EXCEPTION_SINGLE_STEP;
+        stack->rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
         break;
     case TRAP_BRKPT:
     default:
-        rec->ExceptionCode = EXCEPTION_BREAKPOINT;
+        stack->rec.ExceptionCode = EXCEPTION_BREAKPOINT;
         break;
     }
 }
@@ -1109,50 +1113,50 @@ 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 = setup_exception( sigcontext, raise_generic_exception );
+    struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
 
     switch (siginfo->si_code & 0xffff )
     {
 #ifdef FPE_FLTSUB
     case FPE_FLTSUB:
-        rec->ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
+        stack->rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
         break;
 #endif
 #ifdef FPE_INTDIV
     case FPE_INTDIV:
-        rec->ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
+        stack->rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
         break;
 #endif
 #ifdef FPE_INTOVF
     case FPE_INTOVF:
-        rec->ExceptionCode = EXCEPTION_INT_OVERFLOW;
+        stack->rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
         break;
 #endif
 #ifdef FPE_FLTDIV
     case FPE_FLTDIV:
-        rec->ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
+        stack->rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
         break;
 #endif
 #ifdef FPE_FLTOVF
     case FPE_FLTOVF:
-        rec->ExceptionCode = EXCEPTION_FLT_OVERFLOW;
+        stack->rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
         break;
 #endif
 #ifdef FPE_FLTUND
     case FPE_FLTUND:
-        rec->ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
+        stack->rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
         break;
 #endif
 #ifdef FPE_FLTRES
     case FPE_FLTRES:
-        rec->ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
+        stack->rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
         break;
 #endif
 #ifdef FPE_FLTINV
     case FPE_FLTINV:
 #endif
     default:
-        rec->ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+        stack->rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
         break;
     }
 }
@@ -1166,9 +1170,9 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 {
     if (!dispatch_signal(SIGINT))
     {
-        EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception );
+        struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
 
-        rec->ExceptionCode = CONTROL_C_EXIT;
+        stack->rec.ExceptionCode = CONTROL_C_EXIT;
     }
 }
 
@@ -1180,10 +1184,10 @@ 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 = setup_exception( sigcontext, raise_generic_exception );
+    struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
 
-    rec->ExceptionCode  = EXCEPTION_WINE_ASSERTION;
-    rec->ExceptionFlags = EH_NONCONTINUABLE;
+    stack->rec.ExceptionCode  = EXCEPTION_WINE_ASSERTION;
+    stack->rec.ExceptionFlags = EH_NONCONTINUABLE;
 }
 
 




More information about the wine-cvs mailing list