ntdll: Handle single step exception in setup_raise_exception 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:45:56 +02:00 committed by Alexandre Julliard
parent be7a8d6b7a
commit b76df7fa6d
1 changed files with 19 additions and 31 deletions

View File

@ -2680,36 +2680,6 @@ static void raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
}
/**********************************************************************
* raise_trap_exception
*/
static void raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
{
NTSTATUS status;
if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
/* when single stepping can't tell whether this is a hw bp or a
* single step interrupt. try to avoid as much overhead as possible
* and only do a server call if there is any hw bp enabled. */
if( !(context->EFlags & 0x100) || (amd64_thread_data()->dr7 & 0xff) )
{
/* (possible) hardware breakpoint, fetch the debug registers */
DWORD saved_flags = context->ContextFlags;
context->ContextFlags = CONTEXT_DEBUG_REGISTERS;
NtGetContextThread(GetCurrentThread(), context);
context->ContextFlags |= saved_flags; /* restore flags */
}
context->EFlags &= ~0x100; /* clear single-step flag */
}
status = NtRaiseException( rec, context, TRUE );
raise_status( status, rec );
}
/**********************************************************************
* raise_generic_exception
*
@ -2827,6 +2797,24 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
struct stack_layout *stack = CONTAINING_RECORD( rec, struct stack_layout, rec );
ULONG64 *rsp_ptr;
if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
/* when single stepping can't tell whether this is a hw bp or a
* single step interrupt. try to avoid as much overhead as possible
* and only do a server call if there is any hw bp enabled. */
if( !(stack->context.EFlags & 0x100) || (amd64_thread_data()->dr7 & 0xff) )
{
/* (possible) hardware breakpoint, fetch the debug registers */
DWORD saved_flags = stack->context.ContextFlags;
stack->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
NtGetContextThread(GetCurrentThread(), &stack->context);
stack->context.ContextFlags |= saved_flags; /* restore flags */
}
stack->context.EFlags &= ~0x100; /* clear single-step flag */
}
/* store return address and %rbp without aligning, so that the offset is fixed */
rsp_ptr = (ULONG64 *)RSP_sig(sigcontext) - 16;
*(--rsp_ptr) = RIP_sig(sigcontext);
@ -3070,7 +3058,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
break;
}
setup_raise_exception( sigcontext, rec, raise_trap_exception );
setup_raise_exception( sigcontext, rec, raise_generic_exception );
}
/**********************************************************************