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:
parent
b76df7fa6d
commit
2fff34493f
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue