ntdll: Store FPU and XMM contexts in x86 syscall frame.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bbae70bf1e
commit
ce5f17c892
|
@ -918,6 +918,7 @@ void signal_init_threading(void)
|
|||
*/
|
||||
NTSTATUS signal_alloc_thread( TEB *teb )
|
||||
{
|
||||
teb->WOW32Reserved = __wine_syscall_dispatcher;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -461,6 +461,17 @@ enum i386_trap_code
|
|||
#endif
|
||||
};
|
||||
|
||||
struct syscall_xsave
|
||||
{
|
||||
union
|
||||
{
|
||||
XSAVE_FORMAT xsave;
|
||||
FLOATING_SAVE_AREA fsave;
|
||||
} u;
|
||||
};
|
||||
|
||||
C_ASSERT( sizeof(struct syscall_xsave) == 0x200 );
|
||||
|
||||
struct syscall_frame
|
||||
{
|
||||
DWORD eflags; /* 00 */
|
||||
|
@ -502,6 +513,8 @@ C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, gs )
|
|||
C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, exit_frame ) == 0x1f4 );
|
||||
C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, syscall_frame ) == 0x1f8 );
|
||||
|
||||
static void *syscall_dispatcher;
|
||||
|
||||
static inline struct x86_thread_data *x86_thread_data(void)
|
||||
{
|
||||
return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data;
|
||||
|
@ -2424,6 +2437,7 @@ NTSTATUS signal_alloc_thread( TEB *teb )
|
|||
}
|
||||
else thread_data->fs = gdt_fs_sel;
|
||||
|
||||
teb->WOW32Reserved = syscall_dispatcher;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2501,7 +2515,14 @@ void signal_init_process(void)
|
|||
*/
|
||||
void *signal_init_syscalls(void)
|
||||
{
|
||||
return __wine_syscall_dispatcher;
|
||||
extern void __wine_syscall_dispatcher_fxsave(void) DECLSPEC_HIDDEN;
|
||||
|
||||
if (cpu_info.FeatureSet & CPU_FEATURE_FXSR)
|
||||
syscall_dispatcher = __wine_syscall_dispatcher_fxsave;
|
||||
else
|
||||
syscall_dispatcher = __wine_syscall_dispatcher;
|
||||
|
||||
return NtCurrentTeb()->WOW32Reserved = syscall_dispatcher;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2556,7 +2556,6 @@ static void init_teb( TEB *teb, PEB *peb )
|
|||
PtrToUlong( &teb64->ActivationContextStack.FrameListCache );
|
||||
teb64->StaticUnicodeString.Buffer = PtrToUlong( teb64->StaticUnicodeBuffer );
|
||||
teb64->StaticUnicodeString.MaximumLength = sizeof( teb64->StaticUnicodeBuffer );
|
||||
teb->WOW32Reserved = __wine_syscall_dispatcher;
|
||||
#endif
|
||||
teb->Peb = peb;
|
||||
teb->Tib.Self = &teb->Tib;
|
||||
|
|
|
@ -1456,7 +1456,19 @@ static void output_syscall_dispatcher( int count, const char *variant )
|
|||
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( "\tsubl $0x200,%%esp\n") ;
|
||||
output( "\tandl $~63,%%esp\n" );
|
||||
if (!*variant)
|
||||
{
|
||||
output( "\tfnsave (%%esp)\n" );
|
||||
output( "\tfwait\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
output( "\tfxsave (%%esp)\n" );
|
||||
}
|
||||
output( "\tleal -0x30(%%ebp),%%ecx\n" );
|
||||
output( "\tmovl %%ecx,%%fs:0x1f8\n" ); /* x86_thread_data()->syscall_frame */
|
||||
output( "\tcmpl $%u,%%eax\n", count );
|
||||
output( "\tjae 4f\n" );
|
||||
if (UsePIC)
|
||||
|
@ -1479,6 +1491,17 @@ static void output_syscall_dispatcher( int count, const char *variant )
|
|||
else
|
||||
output( "\tcall *.Lsyscall_table(,%%eax,4)\n" );
|
||||
output( "2:\tmovl $0,%%fs:0x1f8\n" );
|
||||
output( "\tleal -0x230(%%ebp),%%ebx\n") ;
|
||||
output( "\tandl $~63,%%ebx\n" );
|
||||
if (!*variant)
|
||||
{
|
||||
output( "\tfrstor (%%ebx)\n" );
|
||||
output( "\tfwait\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
output( "\tfxrstor (%%ebx)\n" );
|
||||
}
|
||||
output( "\tleal -0x30(%%ebp),%%ebx\n" );
|
||||
output_cfi( ".cfi_def_cfa_register %%ebx" );
|
||||
output_cfi( ".cfi_adjust_cfa_offset 0x30\n" );
|
||||
|
@ -1792,6 +1815,9 @@ void output_syscalls( DLLSPEC *spec )
|
|||
|
||||
switch( target_cpu )
|
||||
{
|
||||
case CPU_x86:
|
||||
output_syscall_dispatcher( count, "_fxsave" );
|
||||
break;
|
||||
case CPU_x86_64:
|
||||
output_syscall_dispatcher( count, "_xsave" );
|
||||
output_syscall_dispatcher( count, "_xsavec" );
|
||||
|
|
Loading…
Reference in New Issue