ntdll: Handle interrupt exceptions in signal handler on x86_64.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-09-04 12:46:23 +02:00 committed by Alexandre Julliard
parent b76df7fa6d
commit 2fff34493f
1 changed files with 16 additions and 15 deletions

View File

@ -2664,16 +2664,6 @@ static void raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
set_cpu_context( context ); set_cpu_context( context );
} }
break; break;
case EXCEPTION_BREAKPOINT:
switch (rec->ExceptionInformation[0])
{
case 1: /* BREAKPOINT_PRINT */
case 3: /* BREAKPOINT_LOAD_SYMBOLS */
case 4: /* BREAKPOINT_UNLOAD_SYMBOLS */
case 5: /* BREAKPOINT_COMMAND_STRING (>= Win2003) */
set_cpu_context( context );
}
break;
} }
status = NtRaiseException( rec, context, TRUE ); status = NtRaiseException( rec, context, TRUE );
raise_status( status, rec ); raise_status( status, rec );
@ -2919,23 +2909,34 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
* *
* Handle an interrupt. * Handle an interrupt.
*/ */
static inline BOOL handle_interrupt( unsigned int interrupt, EXCEPTION_RECORD *rec, CONTEXT *context ) static inline BOOL handle_interrupt( ucontext_t *sigcontext, EXCEPTION_RECORD *rec, CONTEXT *context )
{ {
switch(interrupt) switch (ERROR_sig(sigcontext) >> 3)
{ {
case 0x2c: case 0x2c:
rec->ExceptionCode = STATUS_ASSERTION_FAILURE; rec->ExceptionCode = STATUS_ASSERTION_FAILURE;
return TRUE; break;
case 0x2d: case 0x2d:
switch (context->Rax)
{
case 1: /* BREAKPOINT_PRINT */
case 3: /* BREAKPOINT_LOAD_SYMBOLS */
case 4: /* BREAKPOINT_UNLOAD_SYMBOLS */
case 5: /* BREAKPOINT_COMMAND_STRING (>= Win2003) */
RIP_sig(sigcontext) += 3;
return TRUE;
}
context->Rip += 3; context->Rip += 3;
rec->ExceptionCode = EXCEPTION_BREAKPOINT; rec->ExceptionCode = EXCEPTION_BREAKPOINT;
rec->ExceptionAddress = (void *)context->Rip; rec->ExceptionAddress = (void *)context->Rip;
rec->NumberParameters = 1; rec->NumberParameters = 1;
rec->ExceptionInformation[0] = context->Rax; rec->ExceptionInformation[0] = context->Rax;
return TRUE; break;
default: default:
return FALSE; return FALSE;
} }
setup_raise_exception( sigcontext, rec, raise_generic_exception );
return TRUE;
} }
@ -2992,7 +2993,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
CONTEXT *win_context = get_exception_context( rec ); CONTEXT *win_context = get_exception_context( rec );
WORD err = ERROR_sig(ucontext); WORD err = ERROR_sig(ucontext);
if (!err && (rec->ExceptionCode = is_privileged_instr( win_context ))) break; if (!err && (rec->ExceptionCode = is_privileged_instr( win_context ))) break;
if ((err & 7) == 2 && handle_interrupt( err >> 3, rec, win_context )) break; if ((err & 7) == 2 && handle_interrupt( ucontext, rec, win_context )) return;
rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION; rec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
rec->NumberParameters = 2; rec->NumberParameters = 2;
rec->ExceptionInformation[0] = 0; rec->ExceptionInformation[0] = 0;