ntdll: Unwind the syscall frame when calling KiUserExceptionDispatcher().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-08-11 14:49:34 +02:00
parent 13abe9e2bd
commit 1e7e21534e
5 changed files with 62 additions and 23 deletions

View File

@ -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" )
/**********************************************************************

View File

@ -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

View File

@ -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

View File

@ -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 );
}

View File

@ -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)