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:
parent
c6d303ca23
commit
b04f2689a2
|
@ -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;
|
||||
|
|
|
@ -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" );
|
||||
|
|
Loading…
Reference in New Issue