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