ntdll: Use a stack_layout structure to build exception data on ARM64.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d9ec920fd9
commit
7736f3837e
|
@ -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 );
|
||||
|
||||
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);
|
||||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
@ -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.
|
||||
*/
|
||||
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
|
||||
{
|
||||
CONTEXT context;
|
||||
EXCEPTION_RECORD rec;
|
||||
void *redzone[2];
|
||||
} *stack;
|
||||
struct stack_layout *stack;
|
||||
DWORD exception_code = 0;
|
||||
|
||||
/* push the stack_layout structure */
|
||||
|
@ -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(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
|
|||
*/
|
||||
static void segv_handler( int signal, siginfo_t *info, void *ucontext )
|
||||
{
|
||||
EXCEPTION_RECORD *rec;
|
||||
struct stack_layout *stack;
|
||||
ucontext_t *context = ucontext;
|
||||
|
||||
/* check for page fault inside the thread stack */
|
||||
|
@ -1050,32 +1054,32 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
|
|||
case 1: /* handled */
|
||||
return;
|
||||
case -1: /* overflow */
|
||||
rec = setup_exception( context, raise_segv_exception );
|
||||
rec->ExceptionCode = EXCEPTION_STACK_OVERFLOW;
|
||||
stack = setup_exception( context, raise_segv_exception );
|
||||
stack->rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rec = setup_exception( context, raise_segv_exception );
|
||||
if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
|
||||
stack = setup_exception( context, raise_segv_exception );
|
||||
if (stack->rec.ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
|
||||
|
||||
switch(signal)
|
||||
{
|
||||
case SIGILL: /* Invalid opcode exception */
|
||||
rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
|
||||
stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
|
||||
break;
|
||||
case SIGSEGV: /* Segmentation fault */
|
||||
rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
|
||||
rec->NumberParameters = 2;
|
||||
rec->ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
|
||||
rec->ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
|
||||
stack->rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
|
||||
stack->rec.NumberParameters = 2;
|
||||
stack->rec.ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
|
||||
stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
|
||||
break;
|
||||
case SIGBUS: /* Alignment check exception */
|
||||
rec->ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
|
||||
stack->rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
|
||||
break;
|
||||
default:
|
||||
ERR("Got unexpected signal %i\n", signal);
|
||||
rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
|
||||
stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
{
|
||||
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)
|
||||
{
|
||||
case TRAP_TRACE:
|
||||
rec->ExceptionCode = EXCEPTION_SINGLE_STEP;
|
||||
stack->rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
|
||||
break;
|
||||
case TRAP_BRKPT:
|
||||
default:
|
||||
rec->ExceptionCode = EXCEPTION_BREAKPOINT;
|
||||
stack->rec.ExceptionCode = EXCEPTION_BREAKPOINT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
{
|
||||
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception );
|
||||
struct stack_layout *stack = setup_exception( sigcontext, raise_generic_exception );
|
||||
|
||||
switch (siginfo->si_code & 0xffff )
|
||||
{
|
||||
#ifdef FPE_FLTSUB
|
||||
case FPE_FLTSUB:
|
||||
rec->ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
|
||||
stack->rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_INTDIV
|
||||
case FPE_INTDIV:
|
||||
rec->ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
|
||||
stack->rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_INTOVF
|
||||
case FPE_INTOVF:
|
||||
rec->ExceptionCode = EXCEPTION_INT_OVERFLOW;
|
||||
stack->rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_FLTDIV
|
||||
case FPE_FLTDIV:
|
||||
rec->ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
|
||||
stack->rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_FLTOVF
|
||||
case FPE_FLTOVF:
|
||||
rec->ExceptionCode = EXCEPTION_FLT_OVERFLOW;
|
||||
stack->rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_FLTUND
|
||||
case FPE_FLTUND:
|
||||
rec->ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
|
||||
stack->rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_FLTRES
|
||||
case FPE_FLTRES:
|
||||
rec->ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
|
||||
stack->rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FPE_FLTINV
|
||||
case FPE_FLTINV:
|
||||
#endif
|
||||
default:
|
||||
rec->ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
|
||||
stack->rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1166,9 +1170,9 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
|||
{
|
||||
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 )
|
|||
*/
|
||||
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;
|
||||
rec->ExceptionFlags = EH_NONCONTINUABLE;
|
||||
stack->rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
|
||||
stack->rec.ExceptionFlags = EH_NONCONTINUABLE;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue