"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "dlls/ntdll/unix/signal_arm64.c" between
wine-5.12.tar.xz and wine-5.13.tar.xz

About: Wine is an Open Source implementation of the MS Windows API on top of X, OpenGL, and Unix. Think of Wine as a compatibility layer for running Windows programs. Development release.

signal_arm64.c  (wine-5.12.tar.xz):signal_arm64.c  (wine-5.13.tar.xz)
skipping to change at line 72 skipping to change at line 72
#include "ntstatus.h" #include "ntstatus.h"
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include "windef.h" #include "windef.h"
#include "winnt.h" #include "winnt.h"
#include "winternl.h" #include "winternl.h"
#include "wine/exception.h" #include "wine/exception.h"
#include "wine/asm.h" #include "wine/asm.h"
#include "unix_private.h" #include "unix_private.h"
#include "wine/debug.h" #include "wine/debug.h"
#ifdef HAVE_LIBUNWIND
WINE_DEFAULT_DEBUG_CHANNEL(seh); WINE_DEFAULT_DEBUG_CHANNEL(seh);
#endif
/*********************************************************************** /***********************************************************************
* signal context platform-specific definitions * signal context platform-specific definitions
*/ */
#ifdef linux #ifdef linux
/* All Registers access - only for local access */ /* All Registers access - only for local access */
# define REG_sig(reg_name, context) ((context)->uc_mcontext.reg_name) # define REG_sig(reg_name, context) ((context)->uc_mcontext.reg_name)
# define REGn_sig(reg_num, context) ((context)->uc_mcontext.regs[reg_num]) # define REGn_sig(reg_num, context) ((context)->uc_mcontext.regs[reg_num])
skipping to change at line 117 skipping to change at line 119
{ {
struct esr_context *esr = (struct esr_context *)get_extended_sigcontext( sig context, ESR_MAGIC ); struct esr_context *esr = (struct esr_context *)get_extended_sigcontext( sig context, ESR_MAGIC );
if (esr) return esr->esr; if (esr) return esr->esr;
return 0; return 0;
} }
#endif /* linux */ #endif /* linux */
static pthread_key_t teb_key; static pthread_key_t teb_key;
static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
typedef void (*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];
};
struct arm64_thread_data struct arm64_thread_data
{ {
void *exit_frame; /* exit frame pointer */ void *exit_frame; /* exit frame pointer */
CONTEXT *context; /* context to set with SIGUSR2 */ CONTEXT *context; /* context to set with SIGUSR2 */
}; };
C_ASSERT( sizeof(struct arm64_thread_data) <= sizeof(((TEB *)0)->SystemReserved2 ) ); C_ASSERT( sizeof(struct arm64_thread_data) <= sizeof(((TEB *)0)->SystemReserved2 ) );
C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct arm64_thread_data, exit_frame ) == 0x300 ); C_ASSERT( offsetof( TEB, SystemReserved2 ) + offsetof( struct arm64_thread_data, exit_frame ) == 0x300 );
static inline struct arm64_thread_data *arm64_thread_data(void) static inline struct arm64_thread_data *arm64_thread_data(void)
skipping to change at line 526 skipping to change at line 516
if (self && needed_flags) if (self && needed_flags)
{ {
CONTEXT ctx; CONTEXT ctx;
RtlCaptureContext( &ctx ); RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags ); copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags; context->ContextFlags |= ctx.ContextFlags & needed_flags;
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/*********************************************************************** extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, void
* setup_exception *dispatcher, void *sp );
*
* Setup the exception record and context on the thread stack.
*/
static struct stack_layout *setup_exception( ucontext_t *sigcontext )
{
struct stack_layout *stack;
DWORD exception_code = 0;
/* push the stack_layout structure */
stack = (struct stack_layout *)((SP_sig(sigcontext) - sizeof(*stack)) & ~15)
;
stack->rec.ExceptionRecord = NULL;
stack->rec.ExceptionCode = exception_code;
stack->rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
stack->rec.ExceptionAddress = (LPVOID)PC_sig(sigcontext);
stack->rec.NumberParameters = 0;
save_context( &stack->context, sigcontext );
save_fpu( &stack->context, sigcontext );
return stack;
}
extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, rais
e_func func, void *sp );
__ASM_GLOBAL_FUNC( raise_func_trampoline, __ASM_GLOBAL_FUNC( raise_func_trampoline,
__ASM_CFI(".cfi_signal_frame\n\t") __ASM_CFI(".cfi_signal_frame\n\t")
"stp x29, x30, [sp, #-0x20]!\n\t" "stp x29, x30, [sp, #-0x20]!\n\t"
__ASM_CFI(".cfi_def_cfa_offset 32\n\t") __ASM_CFI(".cfi_def_cfa_offset 32\n\t")
__ASM_CFI(".cfi_offset 29, -32\n\t") __ASM_CFI(".cfi_offset 29, -32\n\t")
__ASM_CFI(".cfi_offset 30, -24\n\t") __ASM_CFI(".cfi_offset 30, -24\n\t")
"mov x29, sp\n\t" "mov x29, sp\n\t"
__ASM_CFI(".cfi_def_cfa_register 29\n\t") __ASM_CFI(".cfi_def_cfa_register 29\n\t")
"str x3, [sp, 0x10]\n\t" "str x3, [sp, 0x10]\n\t"
__ASM_CFI(".cfi_remember_state\n\t") __ASM_CFI(".cfi_remember_state\n\t")
__ASM_CFI(".cfi_escape 0x0f,0x03,0x8d,0x10,0x06\n\t") /* CFA */ __ASM_CFI(".cfi_escape 0x0f,0x03,0x8d,0x10,0x06\n\t") /* CFA */
__ASM_CFI(".cfi_escape 0x10,0x1d,0x02,0x8d,0x00\n\t") /* x29 */ __ASM_CFI(".cfi_escape 0x10,0x1d,0x02,0x8d,0x00\n\t") /* x29 */
__ASM_CFI(".cfi_escape 0x10,0x1e,0x02,0x8d,0x08\n\t") /* x30 */ __ASM_CFI(".cfi_escape 0x10,0x1e,0x02,0x8d,0x08\n\t") /* x30 */
"blr x2\n\t" "blr x2\n\t"
__ASM_CFI(".cfi_restore_state\n\t") __ASM_CFI(".cfi_restore_state\n\t")
"brk #1") "brk #1")
/*********************************************************************** /***********************************************************************
* setup_raise_exception * setup_exception
* *
* Modify the signal context to call the exception raise function. * Modify the signal context to call the exception raise function.
*/ */
static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout * stack ) static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
{ {
NTSTATUS status = send_debug_event( &stack->rec, &stack->context, TRUE ); struct
{
CONTEXT context;
EXCEPTION_RECORD rec;
void *redzone[3];
} *stack;
void *stack_ptr = (void *)(SP_sig(sigcontext) & ~15);
CONTEXT context;
NTSTATUS status;
rec->ExceptionAddress = (void *)PC_sig(sigcontext);
save_context( &context, sigcontext );
save_fpu( &context, sigcontext );
status = send_debug_event( rec, &context, TRUE );
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
{ {
restore_context( &stack->context, sigcontext ); restore_context( &context, sigcontext );
return; return;
} }
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if (rec->ExceptionCode == EXCEPTION_BREAKPOINT) context.Pc += 4;
stack = virtual_setup_exception( stack_ptr, (sizeof(*stack) + 15) & ~15, rec
);
stack->rec = *rec;
stack->context = context;
REGn_sig(3, sigcontext) = SP_sig(sigcontext); /* original stack pointer, fou rth arg for raise_func_trampoline */ REGn_sig(3, sigcontext) = SP_sig(sigcontext); /* original stack pointer, fou rth arg for raise_func_trampoline */
SP_sig(sigcontext) = (ULONG_PTR)stack; SP_sig(sigcontext) = (ULONG_PTR)stack;
LR_sig(sigcontext) = PC_sig(sigcontext); LR_sig(sigcontext) = PC_sig(sigcontext);
PC_sig(sigcontext) = (ULONG_PTR)raise_func_trampoline; /* raise_generic_exce PC_sig(sigcontext) = (ULONG_PTR)raise_func_trampoline;
ption; */ REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec; /* first arg for KiUserEx
REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec; /* first arg for raise_ge ceptionDispatcher */
neric_exception */ REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for KiUs
REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for rais erExceptionDispatcher */
e_generic_exception */ REGn_sig(2, sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher; /* dispatch
REGn_sig(2, sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher; /* third ar er arg for raise_func_trampoline */
g for raise_func_trampoline */
REGn_sig(18, sigcontext) = (ULONG_PTR)NtCurrentTeb(); REGn_sig(18, sigcontext) = (ULONG_PTR)NtCurrentTeb();
} }
void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *cont void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *cont
ext ) ext,
NTSTATUS (WINAPI *dispatcher)(EXCEPT
ION_RECORD*,CONTEXT*) )
{ {
pKiUserExceptionDispatcher( rec, context ); dispatcher( rec, context );
} }
/********************************************************************** /**********************************************************************
* segv_handler * segv_handler
* *
* Handler for SIGSEGV and related errors. * Handler for SIGSEGV.
*/ */
static void segv_handler( int signal, siginfo_t *info, void *ucontext ) static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
struct stack_layout *stack; EXCEPTION_RECORD rec = { 0 };
ucontext_t *context = ucontext; ucontext_t *context = sigcontext;
/* check for page fault inside the thread stack */ rec.NumberParameters = 2;
if (signal == SIGSEGV) rec.ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
{ rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
switch (virtual_handle_stack_fault( info->si_addr )) rec.ExceptionCode = virtual_handle_fault( siginfo->si_addr, rec.ExceptionInf
{ ormation[0],
case 1: /* handled */ (void *)SP_sig(context) );
return; if (!rec.ExceptionCode) return;
case -1: /* overflow */ setup_exception( context, &rec );
stack = setup_exception( context ); }
stack->rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
goto done;
}
}
stack = setup_exception( context ); /**********************************************************************
if (stack->rec.ExceptionCode == EXCEPTION_STACK_OVERFLOW) goto done; * ill_handler
*
* Handler for SIGILL.
*/
static void ill_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
EXCEPTION_RECORD rec = { EXCEPTION_ILLEGAL_INSTRUCTION };
switch(signal) setup_exception( sigcontext, &rec );
{ }
case SIGILL: /* Invalid opcode exception */
stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; /**********************************************************************
break; * bus_handler
case SIGSEGV: /* Segmentation fault */ *
stack->rec.NumberParameters = 2; * Handler for SIGBUS.
stack->rec.ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) ! */
= 0; static void bus_handler( int signal, siginfo_t *siginfo, void *sigcontext )
stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr; {
if (!(stack->rec.ExceptionCode = virtual_handle_fault( (void *)stack->re EXCEPTION_RECORD rec = { EXCEPTION_DATATYPE_MISALIGNMENT };
c.ExceptionInformation[1],
stack->rec.ExceptionInf setup_exception( sigcontext, &rec );
ormation[0], FALSE )))
return;
break;
case SIGBUS: /* Alignment check exception */
stack->rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
break;
default:
ERR("Got unexpected signal %i\n", signal);
stack->rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break;
}
done:
setup_raise_exception( context, stack );
} }
/********************************************************************** /**********************************************************************
* trap_handler * trap_handler
* *
* Handler for SIGTRAP. * 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 )
{ {
ucontext_t *context = ucontext; EXCEPTION_RECORD rec = { 0 };
struct stack_layout *stack = setup_exception( context );
switch (info->si_code) switch (siginfo->si_code)
{ {
case TRAP_TRACE: case TRAP_TRACE:
stack->rec.ExceptionCode = EXCEPTION_SINGLE_STEP; rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
break; break;
case TRAP_BRKPT: case TRAP_BRKPT:
default: default:
stack->rec.ExceptionCode = EXCEPTION_BREAKPOINT; rec.ExceptionCode = EXCEPTION_BREAKPOINT;
stack->context.Pc += 4;
break; break;
} }
setup_raise_exception( context, stack ); setup_exception( sigcontext, &rec );
} }
/********************************************************************** /**********************************************************************
* fpe_handler * fpe_handler
* *
* Handler for SIGFPE. * Handler for SIGFPE.
*/ */
static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
struct stack_layout *stack = setup_exception( sigcontext ); EXCEPTION_RECORD rec = { 0 };
switch (siginfo->si_code & 0xffff ) switch (siginfo->si_code & 0xffff )
{ {
#ifdef FPE_FLTSUB #ifdef FPE_FLTSUB
case FPE_FLTSUB: case FPE_FLTSUB:
stack->rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
break; break;
#endif #endif
#ifdef FPE_INTDIV #ifdef FPE_INTDIV
case FPE_INTDIV: case FPE_INTDIV:
stack->rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
break; break;
#endif #endif
#ifdef FPE_INTOVF #ifdef FPE_INTOVF
case FPE_INTOVF: case FPE_INTOVF:
stack->rec.ExceptionCode = EXCEPTION_INT_OVERFLOW; rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
break; break;
#endif #endif
#ifdef FPE_FLTDIV #ifdef FPE_FLTDIV
case FPE_FLTDIV: case FPE_FLTDIV:
stack->rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO; rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
break; break;
#endif #endif
#ifdef FPE_FLTOVF #ifdef FPE_FLTOVF
case FPE_FLTOVF: case FPE_FLTOVF:
stack->rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW; rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
break; break;
#endif #endif
#ifdef FPE_FLTUND #ifdef FPE_FLTUND
case FPE_FLTUND: case FPE_FLTUND:
stack->rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW; rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
break; break;
#endif #endif
#ifdef FPE_FLTRES #ifdef FPE_FLTRES
case FPE_FLTRES: case FPE_FLTRES:
stack->rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT; 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:
stack->rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION; rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
break; break;
} }
setup_raise_exception( sigcontext, stack ); setup_exception( sigcontext, &rec );
} }
/********************************************************************** /**********************************************************************
* int_handler * int_handler
* *
* Handler for SIGINT. * Handler for SIGINT.
*/ */
static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext ) static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
struct stack_layout *stack = setup_exception( sigcontext ); EXCEPTION_RECORD rec = { CONTROL_C_EXIT };
stack->rec.ExceptionCode = CONTROL_C_EXIT; setup_exception( sigcontext, &rec );
setup_raise_exception( sigcontext, stack );
} }
/********************************************************************** /**********************************************************************
* abrt_handler * abrt_handler
* *
* Handler for SIGABRT. * Handler for SIGABRT.
*/ */
static void abrt_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 ); EXCEPTION_RECORD rec = { EXCEPTION_WINE_ASSERTION, EH_NONCONTINUABLE };
stack->rec.ExceptionCode = EXCEPTION_WINE_ASSERTION; setup_exception( sigcontext, &rec );
stack->rec.ExceptionFlags = EH_NONCONTINUABLE;
setup_raise_exception( sigcontext, stack );
} }
/********************************************************************** /**********************************************************************
* quit_handler * quit_handler
* *
* Handler for SIGQUIT. * Handler for SIGQUIT.
*/ */
static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext ) static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{ {
abort_thread(0); abort_thread(0);
skipping to change at line 839 skipping to change at line 814
*/ */
void signal_free_thread( TEB *teb ) void signal_free_thread( TEB *teb )
{ {
} }
/********************************************************************** /**********************************************************************
* signal_init_thread * signal_init_thread
*/ */
void signal_init_thread( TEB *teb ) void signal_init_thread( TEB *teb )
{ {
stack_t ss;
ss.ss_sp = (char *)teb + teb_size;
ss.ss_size = signal_stack_size;
ss.ss_flags = 0;
if (sigaltstack( &ss, NULL ) == -1) perror( "sigaltstack" );
/* Win64/ARM applications expect the TEB pointer to be in the x18 platform r egister. */ /* Win64/ARM applications expect the TEB pointer to be in the x18 platform r egister. */
__asm__ __volatile__( "mov x18, %0" : : "r" (teb) ); __asm__ __volatile__( "mov x18, %0" : : "r" (teb) );
pthread_setspecific( teb_key, teb ); pthread_setspecific( teb_key, teb );
} }
/********************************************************************** /**********************************************************************
* signal_init_process * signal_init_process
*/ */
void signal_init_process(void) void signal_init_process(void)
skipping to change at line 878 skipping to change at line 846
sig_act.sa_sigaction = quit_handler; sig_act.sa_sigaction = quit_handler;
if (sigaction( SIGQUIT, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGQUIT, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = usr1_handler; sig_act.sa_sigaction = usr1_handler;
if (sigaction( SIGUSR1, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGUSR1, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = usr2_handler; sig_act.sa_sigaction = usr2_handler;
if (sigaction( SIGUSR2, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGUSR2, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = trap_handler; sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = segv_handler; sig_act.sa_sigaction = segv_handler;
if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = ill_handler;
if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
sig_act.sa_sigaction = bus_handler;
if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error; if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
return; return;
error: error:
perror("sigaction"); perror("sigaction");
exit(1); exit(1);
} }
/*********************************************************************** /***********************************************************************
* init_thread_context * init_thread_context
 End of changes. 42 change blocks. 
131 lines changed or deleted 99 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)