Commit 7736f383 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Use a stack_layout structure to build exception data on ARM64.

parent d9ec920f
...@@ -114,6 +114,15 @@ static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */ ...@@ -114,6 +114,15 @@ static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
static const size_t signal_stack_size = max( MINSIGSTKSZ, 8192 ); static const size_t signal_stack_size = max( MINSIGSTKSZ, 8192 );
typedef void (WINAPI *raise_func)( EXCEPTION_RECORD *rec, CONTEXT *context ); typedef void (WINAPI *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[2];
};
typedef int (*wine_signal_handler)(unsigned int sig); typedef int (*wine_signal_handler)(unsigned int sig);
static wine_signal_handler handlers[256]; static wine_signal_handler handlers[256];
...@@ -471,18 +480,13 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) ...@@ -471,18 +480,13 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
/*********************************************************************** /***********************************************************************
* setup_exception_record * setup_exception
* *
* Setup the exception record and context on the thread stack. * Setup the exception record and context on the thread stack.
*/ */
static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func func ) static struct stack_layout *setup_exception( ucontext_t *sigcontext, raise_func func )
{ {
struct stack_layout struct stack_layout *stack;
{
CONTEXT context;
EXCEPTION_RECORD rec;
void *redzone[2];
} *stack;
DWORD exception_code = 0; DWORD exception_code = 0;
/* push the stack_layout structure */ /* push the stack_layout structure */
...@@ -503,7 +507,7 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun ...@@ -503,7 +507,7 @@ static EXCEPTION_RECORD *setup_exception( ucontext_t *sigcontext, raise_func fun
REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec; /* first arg for raise_func */ REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec; /* first arg for raise_func */
REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for raise_func */ REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for raise_func */
return &stack->rec; return stack;
} }
/********************************************************************** /**********************************************************************
...@@ -1039,7 +1043,7 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f ...@@ -1039,7 +1043,7 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
*/ */
static void segv_handler( int signal, siginfo_t *info, void *ucontext ) static void segv_handler( int signal, siginfo_t *info, void *ucontext )
{ {
EXCEPTION_RECORD *rec; struct stack_layout *stack;
ucontext_t *context = ucontext; ucontext_t *context = ucontext;
/* check for page fault inside the thread stack */ /* check for page fault inside the thread stack */
...@@ -1050,32 +1054,32 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext ) ...@@ -1050,32 +1054,32 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
case 1: /* handled */ case 1: /* handled */
return; return;
case -1: /* overflow */ case -1: /* overflow */
rec = setup_exception( context, raise_segv_exception ); stack = setup_exception( context, raise_segv_exception );
rec->ExceptionCode = EXCEPTION_STACK_OVERFLOW; stack->rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
return; return;
} }
} }
rec = setup_exception( context, raise_segv_exception ); stack = setup_exception( context, raise_segv_exception );
if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return; if (stack->rec.ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
switch(signal) switch(signal)
{ {
case SIGILL: /* Invalid opcode exception */ case SIGILL: /* Invalid opcode exception */
rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break; break;
case SIGSEGV: /* Segmentation fault */ case SIGSEGV: /* Segmentation fault */
rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION; stack->rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
rec->NumberParameters = 2; stack->rec.NumberParameters = 2;
rec->ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0; stack->rec.ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
rec->ExceptionInformation[1] = (ULONG_PTR)info->si_addr; stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
break; break;
case SIGBUS: /* Alignment check exception */ case SIGBUS: /* Alignment check exception */
rec->ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT; stack->rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
break; break;
default: default:
ERR("Got unexpected signal %i\n", signal); ERR("Got unexpected signal %i\n", signal);
rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break; break;
} }
} }
...@@ -1088,16 +1092,16 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext ) ...@@ -1088,16 +1092,16 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
static void trap_handler( int signal, siginfo_t *info, void *ucontext ) static void trap_handler( int signal, siginfo_t *info, void *ucontext )
{ {
ucontext_t *context = ucontext; ucontext_t *context = ucontext;
EXCEPTION_RECORD *rec = setup_exception( context, raise_trap_exception ); struct stack_layout *stack = setup_exception( context, raise_trap_exception );
switch (info->si_code) switch (info->si_code)
{ {
case TRAP_TRACE: case TRAP_TRACE:
rec->ExceptionCode = EXCEPTION_SINGLE_STEP; stack->rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
break; break;
case TRAP_BRKPT: case TRAP_BRKPT:
default: default:
rec->ExceptionCode = EXCEPTION_BREAKPOINT; stack->rec.ExceptionCode = EXCEPTION_BREAKPOINT;
break; break;
} }
} }
...@@ -1109,50 +1113,50 @@ static void trap_handler( int signal, siginfo_t *info, void *ucontext ) ...@@ -1109,50 +1113,50 @@ static void trap_handler( int signal, siginfo_t *info, void *ucontext )
*/ */
static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception ); struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
switch (siginfo->si_code & 0xffff ) switch (siginfo->si_code & 0xffff )
{ {
#ifdef FPE_FLTSUB #ifdef FPE_FLTSUB
case FPE_FLTSUB: case FPE_FLTSUB:
rec->ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; stack->rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
break; break;
#endif #endif
#ifdef FPE_INTDIV #ifdef FPE_INTDIV
case FPE_INTDIV: case FPE_INTDIV:
rec->ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; stack->rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
break; break;
#endif #endif
#ifdef FPE_INTOVF #ifdef FPE_INTOVF
case FPE_INTOVF: case FPE_INTOVF:
rec->ExceptionCode = EXCEPTION_INT_OVERFLOW; stack->rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
break; break;
#endif #endif
#ifdef FPE_FLTDIV #ifdef FPE_FLTDIV
case FPE_FLTDIV: case FPE_FLTDIV:
rec->ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO; stack->rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
break; break;
#endif #endif
#ifdef FPE_FLTOVF #ifdef FPE_FLTOVF
case FPE_FLTOVF: case FPE_FLTOVF:
rec->ExceptionCode = EXCEPTION_FLT_OVERFLOW; stack->rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
break; break;
#endif #endif
#ifdef FPE_FLTUND #ifdef FPE_FLTUND
case FPE_FLTUND: case FPE_FLTUND:
rec->ExceptionCode = EXCEPTION_FLT_UNDERFLOW; stack->rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
break; break;
#endif #endif
#ifdef FPE_FLTRES #ifdef FPE_FLTRES
case FPE_FLTRES: case FPE_FLTRES:
rec->ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT; stack->rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
break; break;
#endif #endif
#ifdef FPE_FLTINV #ifdef FPE_FLTINV
case FPE_FLTINV: case FPE_FLTINV:
#endif #endif
default: default:
rec->ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION; stack->rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
break; break;
} }
} }
...@@ -1166,9 +1170,9 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -1166,9 +1170,9 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
if (!dispatch_signal(SIGINT)) if (!dispatch_signal(SIGINT))
{ {
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception ); struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
rec->ExceptionCode = CONTROL_C_EXIT; stack->rec.ExceptionCode = CONTROL_C_EXIT;
} }
} }
...@@ -1180,10 +1184,10 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -1180,10 +1184,10 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*/ */
static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception ); struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
rec->ExceptionCode = EXCEPTION_WINE_ASSERTION; stack->rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
rec->ExceptionFlags = EH_NONCONTINUABLE; stack->rec.ExceptionFlags = EH_NONCONTINUABLE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment