Alexandre Julliard : ntdll: Send debug event before pushing exception data on ARM64.

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


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

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

ntdll: Send debug event before pushing exception data on ARM64.

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

---

 dlls/ntdll/unix/signal_arm64.c | 91 ++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 53 deletions(-)

diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index d5df921af7..8353a70e52 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -114,17 +114,6 @@ static DWORD64 get_fault_esr( ucontext_t *sigcontext )
 
 static pthread_key_t teb_key;
 
-typedef void (*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[3];
-};
-C_ASSERT( !(sizeof(struct stack_layout) % 16) );
-
 struct arm64_thread_data
 {
     void     *exit_frame;    /* exit frame pointer */
@@ -534,26 +523,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
 }
 
 
-/***********************************************************************
- *           setup_exception
- *
- * Setup the exception record and context on the thread stack.
- */
-static struct stack_layout *setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
-{
-    void *stack_ptr = (void *)(SP_sig(sigcontext) & ~15);
-    struct stack_layout *stack;
-
-    rec->ExceptionAddress = (void *)PC_sig(sigcontext);
-    stack = virtual_setup_exception( stack_ptr, sizeof(*stack), rec );
-    stack->rec = *rec;
-    save_context( &stack->context, sigcontext );
-    save_fpu( &stack->context, sigcontext );
-    return stack;
-}
-
-
-extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func, void *sp );
+extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, void *dispatcher, void *sp );
 __ASM_GLOBAL_FUNC( raise_func_trampoline,
                    __ASM_CFI(".cfi_signal_frame\n\t")
                    "stp x29, x30, [sp, #-0x20]!\n\t"
@@ -572,26 +542,48 @@ __ASM_GLOBAL_FUNC( raise_func_trampoline,
                    "brk #1")
 
 /***********************************************************************
- *           setup_raise_exception
+ *           setup_exception
  *
  * Modify the signal context to call the exception raise function.
  */
-static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
+static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
 {
-    NTSTATUS status = send_debug_event( &stack->rec, &stack->context, TRUE );
+    struct
+    {
+        CONTEXT           context;
+        EXCEPTION_RECORD  rec;
+        void             *redzone[3];
+    } *stack;
+
+    void *stack_ptr = (void *)(SP_sig(sigcontext) & ~15);
+    CONTEXT context;
+    NTSTATUS status;
 
+    rec->ExceptionAddress = (void *)PC_sig(sigcontext);
+    save_context( &context, sigcontext );
+    save_fpu( &context, sigcontext );
+
+    status = send_debug_event( rec, &context, TRUE );
     if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
     {
-        restore_context( &stack->context, sigcontext );
+        restore_context( &context, sigcontext );
         return;
     }
+
+    /* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
+    if (rec->ExceptionCode == EXCEPTION_BREAKPOINT) context.Pc += 4;
+
+    stack = virtual_setup_exception( stack_ptr, (sizeof(*stack) + 15) & ~15, rec );
+    stack->rec = *rec;
+    stack->context = context;
+
     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);
-    PC_sig(sigcontext) = (ULONG_PTR)raise_func_trampoline; /* raise_generic_exception; */
-    REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec;  /* first arg for raise_generic_exception */
-    REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for raise_generic_exception */
-    REGn_sig(2, sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher; /* third arg for raise_func_trampoline */
+    PC_sig(sigcontext) = (ULONG_PTR)raise_func_trampoline;
+    REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec;  /* first arg for KiUserExceptionDispatcher */
+    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();
 }
 
@@ -609,7 +601,6 @@ void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *cont
 static void segv_handler( int signal, siginfo_t *info, void *ucontext )
 {
     EXCEPTION_RECORD rec = { 0 };
-    struct stack_layout *stack;
     ucontext_t *context = ucontext;
 
     switch(signal)
@@ -633,8 +624,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
         rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
         break;
     }
-    stack = setup_exception( context, &rec );
-    setup_raise_exception( context, stack );
+    setup_exception( context, &rec );
 }
 
 
@@ -647,7 +637,6 @@ static void trap_handler( int signal, siginfo_t *info, void *ucontext )
 {
     EXCEPTION_RECORD rec = { 0 };
     ucontext_t *context = ucontext;
-    struct stack_layout *stack;
 
     switch (info->si_code)
     {
@@ -657,11 +646,9 @@ static void trap_handler( int signal, siginfo_t *info, void *ucontext )
     case TRAP_BRKPT:
     default:
         rec.ExceptionCode = EXCEPTION_BREAKPOINT;
-        PC_sig(context) += 4;
         break;
     }
-    stack = setup_exception( context, &rec );
-    setup_raise_exception( context, stack );
+    setup_exception( context, &rec );
 }
 
 
@@ -673,7 +660,6 @@ 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 = { 0 };
-    struct stack_layout *stack;
 
     switch (siginfo->si_code & 0xffff )
     {
@@ -719,8 +705,7 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
         rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
         break;
     }
-    stack = setup_exception( sigcontext, &rec );
-    setup_raise_exception( sigcontext, stack );
+    setup_exception( sigcontext, &rec );
 }
 
 
@@ -732,8 +717,8 @@ 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 = { CONTROL_C_EXIT };
-    struct stack_layout *stack = setup_exception( sigcontext, &rec );
-    setup_raise_exception( sigcontext, stack );
+
+    setup_exception( sigcontext, &rec );
 }
 
 
@@ -745,8 +730,8 @@ 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 = { EXCEPTION_WINE_ASSERTION, EH_NONCONTINUABLE };
-    struct stack_layout *stack = setup_exception( sigcontext, &rec );
-    setup_raise_exception( sigcontext, stack );
+
+    setup_exception( sigcontext, &rec );
 }
 
 




More information about the wine-cvs mailing list