Alexandre Julliard : ntdll: Factor out setup_raise_exception() on i386.
Alexandre Julliard
julliard at winehq.org
Thu Sep 12 16:28:56 CDT 2019
Module: wine
Branch: master
Commit: 41509c0d5be4172d673249e1faccaf1117d43434
URL: https://source.winehq.org/git/wine.git/?a=commit;h=41509c0d5be4172d673249e1faccaf1117d43434
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Sep 12 19:23:26 2019 +0200
ntdll: Factor out setup_raise_exception() on i386.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/signal_i386.c | 69 ++++++++++++++++++++++++++++--------------------
1 file changed, 41 insertions(+), 28 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index d58e1e5653..5699a99932 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1786,7 +1786,7 @@ static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context )
* Setup the exception record and context on the thread stack.
*/
static struct stack_layout *setup_exception_record( ucontext_t *sigcontext, void *stack_ptr,
- WORD fs, WORD gs, raise_func func )
+ WORD fs, WORD gs )
{
struct stack_layout *stack = stack_ptr;
DWORD exception_code = 0;
@@ -1848,10 +1848,6 @@ static struct stack_layout *setup_exception_record( ucontext_t *sigcontext, void
#elif defined(VALGRIND_MAKE_WRITABLE)
VALGRIND_MAKE_WRITABLE(stack, sizeof(*stack));
#endif
- stack->ret_addr = (void *)0xdeadbabe; /* raise_func must not return */
- stack->rec_ptr = &stack->rec;
- stack->context_ptr = &stack->context;
-
stack->rec.ExceptionRecord = NULL;
stack->rec.ExceptionCode = exception_code;
stack->rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
@@ -1859,19 +1855,6 @@ static struct stack_layout *setup_exception_record( ucontext_t *sigcontext, void
stack->rec.NumberParameters = 0;
save_context( &stack->context, sigcontext, fs, gs );
-
- /* now modify the sigcontext to return to the raise function */
- ESP_sig(sigcontext) = (DWORD)stack;
- EIP_sig(sigcontext) = (DWORD)func;
- /* clear single-step, direction, and align check flag */
- EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
- CS_sig(sigcontext) = wine_get_cs();
- DS_sig(sigcontext) = wine_get_ds();
- ES_sig(sigcontext) = wine_get_es();
- FS_sig(sigcontext) = wine_get_fs();
- GS_sig(sigcontext) = wine_get_gs();
- SS_sig(sigcontext) = wine_get_ss();
-
return stack;
}
@@ -1883,12 +1866,35 @@ static struct stack_layout *setup_exception_record( ucontext_t *sigcontext, void
* sigcontext so that the return from the signal handler will call
* the raise function.
*/
-static struct stack_layout *setup_exception( ucontext_t *sigcontext, raise_func func )
+static struct stack_layout *setup_exception( ucontext_t *sigcontext )
{
WORD fs, gs;
void *stack = init_handler( sigcontext, &fs, &gs );
- return setup_exception_record( sigcontext, stack, fs, gs, func );
+ return setup_exception_record( sigcontext, stack, fs, gs );
+}
+
+
+/***********************************************************************
+ * setup_raise_exception
+ *
+ * Change context to setup a call to a raise exception function.
+ */
+static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack, raise_func func )
+{
+ ESP_sig(sigcontext) = (DWORD)stack;
+ EIP_sig(sigcontext) = (DWORD)func;
+ /* clear single-step, direction, and align check flag */
+ EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
+ CS_sig(sigcontext) = wine_get_cs();
+ DS_sig(sigcontext) = wine_get_ds();
+ ES_sig(sigcontext) = wine_get_es();
+ FS_sig(sigcontext) = wine_get_fs();
+ GS_sig(sigcontext) = wine_get_gs();
+ SS_sig(sigcontext) = wine_get_ss();
+ stack->ret_addr = (void *)0xdeadbabe; /* raise_func must not return */
+ stack->rec_ptr = &stack->rec; /* arguments for raise_func */
+ stack->context_ptr = &stack->context;
}
@@ -2055,14 +2061,14 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
case 1: /* handled */
return;
case -1: /* overflow */
- stack = setup_exception_record( context, stack_ptr, fs, gs, raise_segv_exception );
+ stack = setup_exception_record( context, stack_ptr, fs, gs );
stack->rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
- return;
+ goto done;
}
}
- stack = setup_exception_record( context, stack_ptr, fs, gs, raise_segv_exception );
- if (stack->rec.ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
+ stack = setup_exception_record( context, stack_ptr, fs, gs );
+ if (stack->rec.ExceptionCode == EXCEPTION_STACK_OVERFLOW) goto done;
switch(get_trap_code(context))
{
@@ -2116,6 +2122,8 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break;
}
+done:
+ setup_raise_exception( context, stack, raise_segv_exception );
}
@@ -2127,7 +2135,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
ucontext_t *context = sigcontext;
- struct stack_layout *stack = setup_exception( context, raise_trap_exception );
+ struct stack_layout *stack = setup_exception( context );
switch(get_trap_code(context))
{
@@ -2145,6 +2153,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
stack->rec.ExceptionInformation[2] = 0; /* FIXME */
break;
}
+ setup_raise_exception( context, stack, raise_trap_exception );
}
@@ -2156,7 +2165,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
ucontext_t *context = sigcontext;
- struct stack_layout *stack = setup_exception( context, raise_generic_exception );
+ struct stack_layout *stack = setup_exception( context );
switch(get_trap_code(context))
{
@@ -2189,6 +2198,8 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
stack->rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
break;
}
+
+ setup_raise_exception( context, stack, raise_generic_exception );
}
@@ -2205,8 +2216,9 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
init_handler( sigcontext, &fs, &gs );
if (!dispatch_signal(SIGINT))
{
- struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
+ struct stack_layout *stack = setup_exception( sigcontext );
stack->rec.ExceptionCode = CONTROL_C_EXIT;
+ setup_raise_exception( sigcontext, stack, raise_generic_exception );
}
}
@@ -2217,9 +2229,10 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*/
static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
- struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
+ struct stack_layout *stack = setup_exception( sigcontext );
stack->rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
stack->rec.ExceptionFlags = EH_NONCONTINUABLE;
+ setup_raise_exception( sigcontext, stack, raise_generic_exception );
}
More information about the wine-cvs
mailing list