ntdll: Unwind the syscall frame when calling KiUserExceptionDispatcher().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
13abe9e2bd
commit
1e7e21534e
|
@ -599,11 +599,24 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
|
|||
/***********************************************************************
|
||||
* call_user_exception_dispatcher
|
||||
*/
|
||||
void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
|
||||
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
|
||||
{
|
||||
dispatcher( rec, context );
|
||||
}
|
||||
__ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
|
||||
"mov r4, r0\n\t"
|
||||
"mov r5, r1\n\t"
|
||||
"mov r6, r2\n\t"
|
||||
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
|
||||
"add r7, r0, #0x1d8\n\t" /* arm_thread_data()->syscall_frame */
|
||||
"mov r0, r4\n\t"
|
||||
"mov r1, r5\n\t"
|
||||
"mov r2, r6\n\t"
|
||||
"ldr r3, [r7]\n\t"
|
||||
"ldr r4, [r3]\n\t" /* frame->prev_frame */
|
||||
"str r4, [r7]\n\t"
|
||||
"add r3, r3, #8\n\t"
|
||||
"ldm r3, {r5-r11}\n\t"
|
||||
"ldr r4, [r3, #32]\n\t"
|
||||
"ldr lr, [r3, #36]\n\t"
|
||||
"add sp, r3, #40\n\t"
|
||||
"bx r2" )
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
|
|
@ -600,11 +600,27 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
|
|||
/***********************************************************************
|
||||
* call_user_exception_dispatcher
|
||||
*/
|
||||
void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
|
||||
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) )
|
||||
{
|
||||
dispatcher( rec, context );
|
||||
}
|
||||
__ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
|
||||
"mov x19, x0\n\t"
|
||||
"mov x20, x1\n\t"
|
||||
"mov x21, x2\n\t"
|
||||
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
|
||||
"add x4, x0, #0x2f8\n\t" /* arm64_thread_data()->syscall_frame */
|
||||
"ldr x5, [x4]\n\t"
|
||||
"ldr x6, [x5, #88]\n\t" /* frame->prev_frame */
|
||||
"str x6, [x4]\n\t"
|
||||
"mov x0, x19\n\t"
|
||||
"mov x1, x20\n\t"
|
||||
"mov x2, x21\n\t"
|
||||
"ldp x19, x20, [x5, #96]\n\t" /* frame->x19,x20 */
|
||||
"ldp x21, x22, [x5, #112]\n\t" /* frame->x21,x22 */
|
||||
"ldp x23, x24, [x5, #128]\n\t" /* frame->x23,x24 */
|
||||
"ldp x25, x26, [x5, #144]\n\t" /* frame->x25,x26 */
|
||||
"ldp x27, x28, [x5, #160]\n\t" /* frame->x27,x28 */
|
||||
"ldp x29, x30, [x5, #176]\n\t" /* frame->thunk_x29,ret_addr */
|
||||
"add sp, x5, #192\n\t"
|
||||
"br x2" )
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* segv_handler
|
||||
|
|
|
@ -1559,13 +1559,23 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
|
|||
* call_user_exception_dispatcher
|
||||
*/
|
||||
__ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
|
||||
"add $4,%esp\n\t"
|
||||
"movl (%esp),%eax\n\t" /* rec */
|
||||
"cmpl $0x80000003,(%eax)\n\t" /* ExceptionCode */
|
||||
"movl 4(%esp),%edx\n\t" /* rec */
|
||||
"movl 8(%esp),%ecx\n\t" /* context */
|
||||
"cmpl $0x80000003,(%edx)\n\t" /* rec->ExceptionCode */
|
||||
"jne 1f\n\t"
|
||||
"movl 4(%esp),%eax\n\t" /* context */
|
||||
"decl 0xb8(%eax)\n\t" /* Eip */
|
||||
"1:\tjmp *8(%esp)")
|
||||
"decl 0xb8(%ecx)\n" /* context->Eip */
|
||||
"1:\tmovl %fs:0x1f8,%eax\n\t" /* x86_thread_data()->syscall_frame */
|
||||
"pushl (%eax)\n\t" /* frame->prev_frame */
|
||||
"popl %fs:0x1f8\n\t"
|
||||
"movl 4(%eax),%edi\n\t" /* frame->edi */
|
||||
"movl 8(%eax),%esi\n\t" /* frame->esi */
|
||||
"movl 12(%eax),%ebx\n\t" /* frame->ebx */
|
||||
"movl 16(%eax),%ebp\n\t" /* frame->ebp */
|
||||
"movl %edx,16(%eax)\n\t"
|
||||
"movl %ecx,20(%eax)\n\t"
|
||||
"movl 12(%esp),%edx\n\t" /* dispatcher */
|
||||
"leal 16(%eax),%esp\n\t"
|
||||
"jmp *%edx" )
|
||||
|
||||
/**********************************************************************
|
||||
* get_fpu_code
|
||||
|
|
|
@ -1926,15 +1926,15 @@ void WINAPI do_call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *c
|
|||
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*),
|
||||
struct stack_layout *stack )
|
||||
{
|
||||
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
|
||||
|
||||
memmove(&stack->context, context, sizeof(*context));
|
||||
memcpy(&stack->rec, rec, sizeof(*rec));
|
||||
|
||||
if (stack->rec.ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||
{
|
||||
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
|
||||
stack->context.Rip--;
|
||||
}
|
||||
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
|
||||
if (stack->rec.ExceptionCode == EXCEPTION_BREAKPOINT) stack->context.Rip--;
|
||||
|
||||
amd64_thread_data()->syscall_frame = frame->prev_frame;
|
||||
user_exception_dispatcher_trampoline( stack, dispatcher );
|
||||
}
|
||||
|
||||
|
|
|
@ -260,8 +260,8 @@ extern void dbg_init(void) DECLSPEC_HIDDEN;
|
|||
|
||||
extern void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
|
||||
ULONG_PTR arg2, PNTAPCFUNC func ) DECLSPEC_HIDDEN;
|
||||
extern void WINAPI call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
|
||||
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN;
|
||||
extern void WINAPI DECLSPEC_NORETURN call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
|
||||
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN;
|
||||
|
||||
#define TICKSPERSEC 10000000
|
||||
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
|
||||
|
|
Loading…
Reference in New Issue