ntdll: Translate signal to trap when trap code is 0 on ARM.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46187
Signed-off-by: André Hentschel <nerv@dawncrow.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit 4bfc2c32ff)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
oldstable
André Hentschel 2019-04-09 21:55:59 +02:00 committed by Michael Stefaniuc
parent ce799d6b15
commit 89046193dc
1 changed files with 19 additions and 5 deletions

View File

@ -142,10 +142,24 @@ struct UNWIND_INFO
* *
* Get the trap code for a signal. * Get the trap code for a signal.
*/ */
static inline enum arm_trap_code get_trap_code( const ucontext_t *sigcontext ) static inline enum arm_trap_code get_trap_code( int signal, const ucontext_t *sigcontext )
{ {
#ifdef TRAP_sig #ifdef TRAP_sig
return TRAP_sig(sigcontext); enum arm_trap_code trap = TRAP_sig(sigcontext);
if (trap)
return trap;
/* trap is 0 on arm64 kernel */
switch (signal)
{
case SIGILL:
return TRAP_ARM_PRIVINFLT;
case SIGSEGV:
return TRAP_ARM_PAGEFLT;
case SIGBUS:
return TRAP_ARM_ALIGNFLT;
default:
return trap;
}
#else #else
return TRAP_ARM_UNKNOWN; /* unknown trap code */ return TRAP_ARM_UNKNOWN; /* unknown trap code */
#endif #endif
@ -718,7 +732,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
ucontext_t *context = ucontext; ucontext_t *context = ucontext;
/* check for page fault inside the thread stack */ /* check for page fault inside the thread stack */
if (get_trap_code(context) == TRAP_ARM_PAGEFLT && if (get_trap_code(signal, context) == TRAP_ARM_PAGEFLT &&
(char *)info->si_addr >= (char *)NtCurrentTeb()->DeallocationStack && (char *)info->si_addr >= (char *)NtCurrentTeb()->DeallocationStack &&
(char *)info->si_addr < (char *)NtCurrentTeb()->Tib.StackBase && (char *)info->si_addr < (char *)NtCurrentTeb()->Tib.StackBase &&
virtual_handle_stack_fault( info->si_addr )) virtual_handle_stack_fault( info->si_addr ))
@ -735,7 +749,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
rec = setup_exception( context, raise_segv_exception ); rec = setup_exception( context, raise_segv_exception );
if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return; if (rec->ExceptionCode == EXCEPTION_STACK_OVERFLOW) return;
switch(get_trap_code(context)) switch(get_trap_code(signal, context))
{ {
case TRAP_ARM_PRIVINFLT: /* Invalid opcode exception */ case TRAP_ARM_PRIVINFLT: /* Invalid opcode exception */
rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
@ -756,7 +770,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
rec->ExceptionInformation[1] = 0xffffffff; rec->ExceptionInformation[1] = 0xffffffff;
break; break;
default: default:
ERR("Got unexpected trap %d\n", get_trap_code(context)); ERR("Got unexpected trap %d\n", get_trap_code(signal, context));
rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; rec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break; break;
} }