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:
Jacek Caban 2021-03-01 16:51:32 +01:00 committed by Alexandre Julliard
parent bbae70bf1e
commit ce5f17c892
4 changed files with 50 additions and 3 deletions

View File

@ -918,6 +918,7 @@ void signal_init_threading(void)
*/
NTSTATUS signal_alloc_thread( TEB *teb )
{
teb->WOW32Reserved = __wine_syscall_dispatcher;
return STATUS_SUCCESS;
}

View File

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

View File

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

View File

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