Alexandre Julliard : ntdll: Send first chance debug event while on signal stack on ARM64.

Alexandre Julliard julliard at winehq.org
Thu Sep 19 16:35:18 CDT 2019


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Sep 19 19:41:42 2019 +0200

ntdll: Send first chance debug event while on signal stack on ARM64.

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

---

 dlls/ntdll/signal_arm64.c | 133 ++++++++++++++++++++++++----------------------
 1 file changed, 69 insertions(+), 64 deletions(-)

diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 7abf389bbd..43e5969229 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -483,52 +483,6 @@ 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 )
-{
-    struct stack_layout *stack;
-    DWORD exception_code = 0;
-
-    /* push the stack_layout structure */
-    stack = (struct stack_layout *)((SP_sig(sigcontext) - sizeof(*stack)) & ~15);
-
-    stack->rec.ExceptionRecord  = NULL;
-    stack->rec.ExceptionCode    = exception_code;
-    stack->rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
-    stack->rec.ExceptionAddress = (LPVOID)PC_sig(sigcontext);
-    stack->rec.NumberParameters = 0;
-
-    save_context( &stack->context, sigcontext );
-    save_fpu( &stack->context, sigcontext );
-    return stack;
-}
-
-/**********************************************************************
- *		raise_generic_exception
- */
-static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
-{
-    NTSTATUS status = NtRaiseException( rec, context, TRUE );
-    raise_status( status, rec );
-}
-
-/***********************************************************************
- *           setup_raise_exception
- *
- * Modify the signal context to call the exception raise function.
- */
-static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
-{
-    SP_sig(sigcontext) = (ULONG_PTR)stack;
-    PC_sig(sigcontext) = (ULONG_PTR)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 */
-}
-
 /***********************************************************************
  *           libunwind_virtual_unwind
  *
@@ -852,6 +806,7 @@ static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_con
     dispatch.TargetPc      = 0;
     dispatch.ContextRecord = &context;
     dispatch.HistoryTable  = &table;
+    dispatch.NonVolatileRegisters = (BYTE *)&context.u.s.X19;
     for (;;)
     {
         status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
@@ -979,19 +934,12 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
                   context->u.s.X24, context->u.s.X25, context->u.s.X26, context->u.s.X27 );
             TRACE(" x28=%016lx  fp=%016lx  lr=%016lx  sp=%016lx\n",
                   context->u.s.X28, context->u.s.Fp, context->u.s.Lr, context->Sp );
-            TRACE("  pc=%016lx\n",
-                  context->Pc );
         }
 
-        status = send_debug_event( rec, TRUE, context );
-        if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
-            return STATUS_SUCCESS;
+        if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) goto done;
 
-        if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
-            return STATUS_SUCCESS;
-
-        if ((status = call_function_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION)
-            return status;
+        if ((status = call_function_handlers( rec, context )) == STATUS_SUCCESS) goto done;
+        if (status != STATUS_UNHANDLED_EXCEPTION) return status;
     }
 
     /* last chance exception */
@@ -1008,7 +956,62 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
                 rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
         NtTerminateProcess( NtCurrentProcess(), rec->ExceptionCode );
     }
-    return STATUS_SUCCESS;
+done:
+    return NtSetContextThread( GetCurrentThread(), context );
+}
+
+/***********************************************************************
+ *           setup_exception
+ *
+ * Setup the exception record and context on the thread stack.
+ */
+static struct stack_layout *setup_exception( ucontext_t *sigcontext )
+{
+    struct stack_layout *stack;
+    DWORD exception_code = 0;
+
+    /* push the stack_layout structure */
+    stack = (struct stack_layout *)((SP_sig(sigcontext) - sizeof(*stack)) & ~15);
+
+    stack->rec.ExceptionRecord  = NULL;
+    stack->rec.ExceptionCode    = exception_code;
+    stack->rec.ExceptionFlags   = EXCEPTION_CONTINUABLE;
+    stack->rec.ExceptionAddress = (LPVOID)PC_sig(sigcontext);
+    stack->rec.NumberParameters = 0;
+
+    save_context( &stack->context, sigcontext );
+    save_fpu( &stack->context, sigcontext );
+    return stack;
+}
+
+/**********************************************************************
+ *		raise_generic_exception
+ */
+static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
+{
+    NTSTATUS status = raise_exception( rec, context, TRUE );
+    raise_status( status, rec );
+}
+
+/***********************************************************************
+ *           setup_raise_exception
+ *
+ * Modify the signal context to call the exception raise function.
+ */
+static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
+{
+    NTSTATUS status = send_debug_event( &stack->rec, TRUE, &stack->context );
+
+    if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
+    {
+        restore_context( &stack->context, sigcontext );
+        return;
+    }
+    SP_sig(sigcontext) = (ULONG_PTR)stack;
+    PC_sig(sigcontext) = (ULONG_PTR)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(18, sigcontext) = (ULONG_PTR)NtCurrentTeb();
 }
 
 /**********************************************************************
@@ -1790,10 +1793,10 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
     TRACE(" x28=%016lx  fp=%016lx  lr=%016lx  sp=%016lx\n",
           context->u.s.X28, context->u.s.Fp, context->u.s.Lr, context->Sp );
 
-    dispatch.EstablisherFrame = context->Sp;
     dispatch.TargetPc         = (ULONG64)target_ip;
     dispatch.ContextRecord    = context;
     dispatch.HistoryTable     = table;
+    dispatch.NonVolatileRegisters = (BYTE *)&context->u.s.X19;
 
     for (;;)
     {
@@ -1891,9 +1894,13 @@ void WINAPI RtlUnwind( void *frame, void *target_ip, EXCEPTION_RECORD *rec, void
  */
 NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
 {
-    NTSTATUS status = raise_exception( rec, context, first_chance );
-    if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context );
-    return status;
+    if (first_chance)
+    {
+        NTSTATUS status = send_debug_event( rec, TRUE, context );
+        if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
+            NtSetContextThread( GetCurrentThread(), context );
+    }
+    return raise_exception( rec, context, first_chance );
 }
 
 /***********************************************************************
@@ -1902,12 +1909,10 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
 void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec )
 {
     CONTEXT context;
-    NTSTATUS status;
 
     RtlCaptureContext( &context );
     rec->ExceptionAddress = (LPVOID)context.Pc;
-    status = raise_exception( rec, &context, TRUE );
-    if (status) raise_status( status, rec );
+    RtlRaiseStatus( NtRaiseException( rec, &context, TRUE ));
 }
 
 /*************************************************************************




More information about the wine-cvs mailing list