ntdll: Send first chance debug event while on signal stack on ARM64.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
afe8467110
commit
82c753a273
|
@ -483,52 +483,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* setup_exception
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* raise_generic_exception
|
|
||||||
*/
|
|
||||||
static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
|
||||||
{
|
|
||||||
NTSTATUS status = NtRaiseException( rec, context, TRUE );
|
|
||||||
raise_status( status, rec );
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* setup_raise_exception
|
|
||||||
*
|
|
||||||
* Modify the signal context to call the exception raise function.
|
|
||||||
*/
|
|
||||||
static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
|
|
||||||
{
|
|
||||||
SP_sig(sigcontext) = (ULONG_PTR)stack;
|
|
||||||
PC_sig(sigcontext) = (ULONG_PTR)raise_generic_exception;
|
|
||||||
REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec; /* first arg for raise_generic_exception */
|
|
||||||
REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for raise_generic_exception */
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* libunwind_virtual_unwind
|
* libunwind_virtual_unwind
|
||||||
*
|
*
|
||||||
|
@ -852,6 +806,7 @@ static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_con
|
||||||
dispatch.TargetPc = 0;
|
dispatch.TargetPc = 0;
|
||||||
dispatch.ContextRecord = &context;
|
dispatch.ContextRecord = &context;
|
||||||
dispatch.HistoryTable = &table;
|
dispatch.HistoryTable = &table;
|
||||||
|
dispatch.NonVolatileRegisters = (BYTE *)&context.u.s.X19;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
|
status = virtual_unwind( UNW_FLAG_EHANDLER, &dispatch, &context );
|
||||||
|
@ -979,19 +934,12 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
|
||||||
context->u.s.X24, context->u.s.X25, context->u.s.X26, context->u.s.X27 );
|
context->u.s.X24, context->u.s.X25, context->u.s.X26, context->u.s.X27 );
|
||||||
TRACE(" x28=%016lx fp=%016lx lr=%016lx sp=%016lx\n",
|
TRACE(" x28=%016lx fp=%016lx lr=%016lx sp=%016lx\n",
|
||||||
context->u.s.X28, context->u.s.Fp, context->u.s.Lr, context->Sp );
|
context->u.s.X28, context->u.s.Fp, context->u.s.Lr, context->Sp );
|
||||||
TRACE(" pc=%016lx\n",
|
|
||||||
context->Pc );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status = send_debug_event( rec, TRUE, context );
|
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) goto done;
|
||||||
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
|
if ((status = call_function_handlers( rec, context )) == STATUS_SUCCESS) goto done;
|
||||||
return STATUS_SUCCESS;
|
if (status != STATUS_UNHANDLED_EXCEPTION) return status;
|
||||||
|
|
||||||
if ((status = call_function_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION)
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* last chance exception */
|
/* last chance exception */
|
||||||
|
@ -1008,7 +956,62 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
|
||||||
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
|
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
|
||||||
NtTerminateProcess( NtCurrentProcess(), rec->ExceptionCode );
|
NtTerminateProcess( NtCurrentProcess(), rec->ExceptionCode );
|
||||||
}
|
}
|
||||||
return STATUS_SUCCESS;
|
done:
|
||||||
|
return NtSetContextThread( GetCurrentThread(), context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* setup_exception
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* raise_generic_exception
|
||||||
|
*/
|
||||||
|
static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
|
{
|
||||||
|
NTSTATUS status = raise_exception( rec, context, TRUE );
|
||||||
|
raise_status( status, rec );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* setup_raise_exception
|
||||||
|
*
|
||||||
|
* Modify the signal context to call the exception raise function.
|
||||||
|
*/
|
||||||
|
static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *stack )
|
||||||
|
{
|
||||||
|
NTSTATUS status = send_debug_event( &stack->rec, TRUE, &stack->context );
|
||||||
|
|
||||||
|
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
|
||||||
|
{
|
||||||
|
restore_context( &stack->context, sigcontext );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SP_sig(sigcontext) = (ULONG_PTR)stack;
|
||||||
|
PC_sig(sigcontext) = (ULONG_PTR)raise_generic_exception;
|
||||||
|
REGn_sig(0, sigcontext) = (ULONG_PTR)&stack->rec; /* first arg for raise_generic_exception */
|
||||||
|
REGn_sig(1, sigcontext) = (ULONG_PTR)&stack->context; /* second arg for raise_generic_exception */
|
||||||
|
REGn_sig(18, sigcontext) = (ULONG_PTR)NtCurrentTeb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
@ -1790,10 +1793,10 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec
|
||||||
TRACE(" x28=%016lx fp=%016lx lr=%016lx sp=%016lx\n",
|
TRACE(" x28=%016lx fp=%016lx lr=%016lx sp=%016lx\n",
|
||||||
context->u.s.X28, context->u.s.Fp, context->u.s.Lr, context->Sp );
|
context->u.s.X28, context->u.s.Fp, context->u.s.Lr, context->Sp );
|
||||||
|
|
||||||
dispatch.EstablisherFrame = context->Sp;
|
|
||||||
dispatch.TargetPc = (ULONG64)target_ip;
|
dispatch.TargetPc = (ULONG64)target_ip;
|
||||||
dispatch.ContextRecord = context;
|
dispatch.ContextRecord = context;
|
||||||
dispatch.HistoryTable = table;
|
dispatch.HistoryTable = table;
|
||||||
|
dispatch.NonVolatileRegisters = (BYTE *)&context->u.s.X19;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -1891,9 +1894,13 @@ void WINAPI RtlUnwind( void *frame, void *target_ip, EXCEPTION_RECORD *rec, void
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
|
NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
|
||||||
{
|
{
|
||||||
NTSTATUS status = raise_exception( rec, context, first_chance );
|
if (first_chance)
|
||||||
if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context );
|
{
|
||||||
return status;
|
NTSTATUS status = send_debug_event( rec, TRUE, context );
|
||||||
|
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
|
||||||
|
NtSetContextThread( GetCurrentThread(), context );
|
||||||
|
}
|
||||||
|
return raise_exception( rec, context, first_chance );
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1902,12 +1909,10 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
|
||||||
void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec )
|
void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec )
|
||||||
{
|
{
|
||||||
CONTEXT context;
|
CONTEXT context;
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
RtlCaptureContext( &context );
|
RtlCaptureContext( &context );
|
||||||
rec->ExceptionAddress = (LPVOID)context.Pc;
|
rec->ExceptionAddress = (LPVOID)context.Pc;
|
||||||
status = raise_exception( rec, &context, TRUE );
|
RtlRaiseStatus( NtRaiseException( rec, &context, TRUE ));
|
||||||
if (status) raise_status( status, rec );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
Loading…
Reference in New Issue