From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/loader.c | 2 ++ dlls/ntdll/unix/unix_private.h | 2 ++ tools/winebuild/build.h | 1 + tools/winebuild/import.c | 9 ++++++++- tools/winebuild/parser.c | 6 ++++++ tools/winebuild/winebuild.man.in | 4 ++++ 6 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index cbfd1dacc90..72727d3d789 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1338,6 +1338,7 @@ NTSTATUS ntdll_init_syscalls( ULONG id, SYSTEM_SERVICE_TABLE *table, void **disp struct syscall_info { BYTE syscall_args; + BYTE syscall_nofpu; }; struct syscall_table_info { @@ -1358,6 +1359,7 @@ NTSTATUS ntdll_init_syscalls( ULONG id, SYSTEM_SERVICE_TABLE *table, void **disp for (i = 0; i < table_info->limit; ++i) { table->ArgumentTable[i] = table_info->info[i].syscall_args; + if (table_info->info[i].syscall_nofpu) table->CounterTable[i] |= SYSCALL_FLAG_NOFPU; }
KeServiceDescriptorTable[id] = *table; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index a7fae7ab7ab..c34ce872930 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -96,6 +96,8 @@ static const LONG teb_offset = 0x2000; #define FILE_WRITE_TO_END_OF_FILE ((LONGLONG)-1) #define FILE_USE_FILE_POINTER_POSITION ((LONGLONG)-2)
+#define SYSCALL_FLAG_NOFPU 0x80000000 + /* callbacks to PE ntdll from the Unix side */ extern void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) DECLSPEC_HIDDEN; diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 576304cd2b8..216f6859fe7 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -189,6 +189,7 @@ static inline int is_pe(void) #define FLAG_FASTCALL 0x0100 /* function uses fastcall calling convention */ #define FLAG_SYSCALL 0x0200 /* function is a system call */ #define FLAG_IMPORT 0x0400 /* export is imported from another module */ +#define FLAG_NOFPU 0x0800 /* function skips default syscall FPU save / restore */
#define FLAG_FORWARD 0x1000 /* function is a forwarded name */ #define FLAG_EXT_LINK 0x2000 /* function links to an external symbol */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 9f87adcf593..905e6262650 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1495,12 +1495,19 @@ void output_syscalls( DLLSPEC *spec ) default: break; } + + /* struct syscall_table_info */ output( "\t.data\n" ); output( "\t.align %d\n", get_alignment( get_ptr_size() ) ); output( "%s\n", asm_globl("__wine_syscall_dispatcher") ); output( "\t%s 0\n", get_asm_ptr_keyword() ); output( "\t.short %u\n", count ); - for (i = 0; i < count; i++) output( "\t.byte %u\n", get_args_size( syscalls[i] )); + + for (i = 0; i < count; i++) /* struct syscall_info */ + { + output( "\t.byte %u\n", get_args_size( syscalls[i] )); /* syscall_args */ + output( "\t.byte %u\n", !!(syscalls[i]->flags & FLAG_NOFPU) ); /* syscall_nofpu */ + } }
diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 11b422bd435..0a1fbe52e62 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -71,6 +71,7 @@ static const char * const FlagNames[] = "fastcall", /* FLAG_FASTCALL */ "syscall", /* FLAG_SYSCALL */ "import", /* FLAG_IMPORT */ + "nofpu", /* FLAG_NOFPU */ NULL };
@@ -328,6 +329,11 @@ static int parse_spec_arguments( ORDDEF *odp, DLLSPEC *spec, int optional ) return 0; } } + else if (odp->flags & FLAG_NOFPU) + { + error( "The nofpu flag can only be used on a syscall function\n" ); + return 0; + } return 1; }
diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index 23ef3495744..ce016b542fb 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -324,6 +324,10 @@ only). The entry point will be exported by ordinal instead of by name. The name is still available for importing. .TP +.B -nofpu +The entry point is a NT syscall which does not save or restore the +FPU state and assumes it will not be modified by the call. +.TP .B -ret16 The function returns a 16-bit value (Win16 only). .TP