Alexandre Julliard : ntdll: Support Thumb mode in signal handling.

Alexandre Julliard julliard at winehq.org
Tue Jan 19 15:44:00 CST 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jan 18 11:43:55 2021 +0100

ntdll: Support Thumb mode in signal handling.

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

---

 dlls/ntdll/unix/signal_arm.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 6fa37b81415..231f23e354a 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -283,6 +283,7 @@ static void save_context( CONTEXT *context, const ucontext_t *sigcontext )
     context->Cpsr = CPSR_sig(sigcontext); /* Current State Register */
     context->R11  = FP_sig(sigcontext);   /* Frame pointer */
     context->R12  = IP_sig(sigcontext);   /* Intra-Procedure-call scratch register */
+    if (CPSR_sig(sigcontext) & 0x20) context->Pc |= 1;  /* Thumb mode */
     save_fpu( context, sigcontext );
 }
 
@@ -305,6 +306,8 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext )
     CPSR_sig(sigcontext) = context->Cpsr; /* Current State Register */
     FP_sig(sigcontext)   = context->R11;  /* Frame pointer */
     IP_sig(sigcontext)   = context->R12;  /* Intra-Procedure-call scratch register */
+    if (PC_sig(sigcontext) & 1) CPSR_sig(sigcontext) |= 0x20;
+    else CPSR_sig(sigcontext) &= ~0x20;
     restore_fpu( context, sigcontext );
 }
 
@@ -534,19 +537,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
 }
 
 
-extern void raise_func_trampoline_thumb( EXCEPTION_RECORD *rec, CONTEXT *context, void *func );
-__ASM_GLOBAL_FUNC( raise_func_trampoline_thumb,
-                   ".thumb\n\t"
-                   "bx r2\n\t"
-                   "bkpt\n\t"
-                   ".arm")
-
-extern void raise_func_trampoline_arm( EXCEPTION_RECORD *rec, CONTEXT *context, void *func );
-__ASM_GLOBAL_FUNC( raise_func_trampoline_arm,
-                   ".arm\n\t"
-                   "bx r2\n\t"
-                   "bkpt")
-
 /***********************************************************************
  *           setup_exception
  *
@@ -566,7 +556,8 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
 
     rec->ExceptionAddress = (void *)PC_sig(sigcontext);
     save_context( &context, sigcontext );
-    if (rec->ExceptionCode == EXCEPTION_BREAKPOINT) context.Pc += 4;
+    if (rec->ExceptionCode == EXCEPTION_BREAKPOINT)
+        context.Pc += CPSR_sig(sigcontext) & 0x20 ? 2 : 4;
 
     status = send_debug_event( rec, &context, TRUE );
     if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
@@ -581,13 +572,11 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
 
     /* now modify the sigcontext to return to the raise function */
     SP_sig(sigcontext) = (DWORD)stack;
-    if (CPSR_sig(sigcontext) & 0x20)
-        PC_sig(sigcontext) = (DWORD)raise_func_trampoline_thumb;
-    else
-        PC_sig(sigcontext) = (DWORD)raise_func_trampoline_arm;
+    PC_sig(sigcontext) = (DWORD)pKiUserExceptionDispatcher;
+    if (PC_sig(sigcontext) & 1) CPSR_sig(sigcontext) |= 0x20;
+    else CPSR_sig(sigcontext) &= ~0x20;
     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;
 }
 
 
@@ -999,6 +988,7 @@ static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry,
     context->R1 = (DWORD)arg;
     context->Sp = (DWORD)teb->Tib.StackBase;
     context->Pc = (DWORD)pRtlUserThreadStart;
+    if (context->Pc & 1) context->Cpsr |= 0x20; /* thumb mode */
 }
 
 




More information about the wine-cvs mailing list