From: Jacek Caban Subject: [PATCH 2/3] ntdll: Store all non-volatile i386 registers in syscall dispatcher. Message-Id: Date: Thu, 25 Feb 2021 18:53:56 +0100 Signed-off-by: Jacek Caban --- dlls/ntdll/unix/signal_i386.c | 29 ++++++++++++++--------------- tools/winebuild/import.c | 13 ++++++++++++- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 6c46c615f56..be3f1060e4a 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -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; diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 8620e9be479..c3b8c3e115b 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -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( "\tsubl $0x2c,%%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" );