ntdll: Store all non-volatile i386 registers in syscall dispatcher.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-02-25 18:53:56 +01:00 committed by Alexandre Julliard
parent c6d303ca23
commit b04f2689a2
2 changed files with 26 additions and 16 deletions

View File

@ -479,10 +479,10 @@ struct syscall_frame
DWORD edi; /* 28 */
DWORD esi; /* 2c */
DWORD ebp; /* 30 */
DWORD thunk_addr;
DWORD ret_addr;
};
C_ASSERT( sizeof(struct syscall_frame) == 0x34 );
struct x86_thread_data
{
DWORD fs; /* 1d4 TEB selector */
@ -1314,20 +1314,20 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
if (needed_flags & CONTEXT_CONTROL)
{
context->Esp = (DWORD)&frame->ret_addr;
context->Esp = frame->esp;
context->Ebp = frame->ebp;
context->Eip = frame->thunk_addr;
context->EFlags = 0x202;
context->SegCs = get_cs();
context->SegSs = get_ds();
context->Eip = frame->eip;
context->EFlags = frame->eflags;
context->SegCs = frame->cs;
context->SegSs = frame->ds;
context->ContextFlags |= CONTEXT_CONTROL;
}
if (needed_flags & CONTEXT_SEGMENTS)
{
context->SegDs = get_ds();
context->SegEs = get_ds();
context->SegFs = get_fs();
context->SegGs = get_gs();
context->SegDs = frame->ds;
context->SegEs = frame->es;
context->SegFs = frame->fs;
context->SegGs = frame->gs;
context->ContextFlags |= CONTEXT_SEGMENTS;
}
if (needed_flags & CONTEXT_FLOATING_POINT) save_fpu( context );
@ -1732,7 +1732,6 @@ struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *conte
}
C_ASSERT( sizeof(struct apc_stack_layout) == 0x2e0 );
C_ASSERT( offsetof(struct syscall_frame, ret_addr) == 0x38 );
C_ASSERT( offsetof(struct apc_stack_layout, context) == 20 );
/***********************************************************************
@ -1916,14 +1915,14 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
}
else
{
TRACE( "returning to user mode ip=%08x ret=%08x\n", frame->ret_addr, rec->ExceptionCode );
TRACE( "returning to user mode ip=%08x ret=%08x\n", frame->eip, rec->ExceptionCode );
EAX_sig(sigcontext) = rec->ExceptionCode;
EBX_sig(sigcontext) = frame->ebx;
ESI_sig(sigcontext) = frame->esi;
EDI_sig(sigcontext) = frame->edi;
EBP_sig(sigcontext) = frame->ebp;
ESP_sig(sigcontext) = (DWORD)&frame->ret_addr;
EIP_sig(sigcontext) = frame->thunk_addr;
ESP_sig(sigcontext) = frame->esp;
EIP_sig(sigcontext) = frame->eip;
x86_thread_data()->syscall_frame = NULL;
}
return TRUE;

View File

@ -1438,13 +1438,24 @@ static void output_syscall_dispatcher( int count, const char *variant )
output_cfi( ".cfi_rel_offset %%ebp,0\n" );
output( "\tmovl %%esp,%%ebp\n" );
output_cfi( ".cfi_def_cfa_register %%ebp\n" );
output( "\tsubl $0x30,%%esp\n" );
output( "\tleal -0x2c(%%esp),%%esp\n" );
output( "\tmovl %%ebx,-0x14(%%ebp)\n" );
output_cfi( ".cfi_rel_offset %%ebx,-0x14\n" );
output( "\tmovl %%edi,-0x08(%%ebp)\n" );
output_cfi( ".cfi_rel_offset %%edi,-0x08\n" );
output( "\tmovl %%esi,-0x04(%%ebp)\n" );
output_cfi( ".cfi_rel_offset %%esi,-0x04\n" );
output( "\tpushfl\n" );
output( "\tmovw %%gs,-0x1a(%%ebp)\n" );
output( "\tmovw %%fs,-0x1c(%%ebp)\n" );
output( "\tmovw %%es,-0x1e(%%ebp)\n" );
output( "\tmovw %%ds,-0x20(%%ebp)\n" );
output( "\tmovw %%ss,-0x22(%%ebp)\n" );
output( "\tmovw %%cs,-0x24(%%ebp)\n" );
output( "\tleal 8(%%ebp),%%ecx\n" );
output( "\tmovl %%ecx,-0x28(%%ebp)\n" ); /* frame->esp */
output( "\tmovl 4(%%ebp),%%ecx\n" );
output( "\tmovl %%ecx,-0x2c(%%ebp)\n" ); /* frame->eip */
output( "\tmovl %%esp,%%fs:0x1f8\n" ); /* x86_thread_data()->syscall_frame */
output( "\tcmpl $%u,%%eax\n", count );
output( "\tjae 3f\n" );