Module: wine Branch: master Commit: 48a54598279c638070c890bd6a8be305b4bfda7d URL: https://gitlab.winehq.org/wine/wine/-/commit/48a54598279c638070c890bd6a8be30...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Nov 20 18:06:33 2023 +0100
ntdll: Generate syscall entry points from the C code with asm macros.
---
dlls/ntdll/signal_arm.c | 11 ++++- dlls/ntdll/signal_arm64.c | 10 ++++- dlls/ntdll/signal_i386.c | 11 +++++ dlls/ntdll/signal_x86_64.c | 10 +++++ include/wine/asm.h | 107 +++++++++++++++++++++++++++++++++++++++++++++ tools/winebuild/import.c | 2 + 6 files changed, 149 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 9a9fc6483f1..475fd6afc34 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -31,7 +31,7 @@ #include "wine/exception.h" #include "ntdll_misc.h" #include "wine/debug.h" -#include "winnt.h" +#include "ntsyscalls.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); WINE_DECLARE_DEBUG_CHANNEL(relay); @@ -93,6 +93,15 @@ static inline BOOL is_valid_frame( ULONG_PTR frame ) }
+/******************************************************************* + * syscalls + */ +#define SYSCALL_ENTRY(id,name,args) __ASM_SYSCALL_FUNC( id, name, args ) +ALL_SYSCALLS32 +DEFINE_SYSCALL_HELPER32() +#undef SYSCALL_ENTRY + + /************************************************************************** * __chkstk (NTDLL.@) * diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index cb796141871..9ceb3540a38 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -33,7 +33,7 @@ #include "wine/exception.h" #include "ntdll_misc.h" #include "wine/debug.h" -#include "winnt.h" +#include "ntsyscalls.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); WINE_DECLARE_DEBUG_CHANNEL(relay); @@ -100,6 +100,14 @@ static inline BOOL is_valid_frame( ULONG_PTR frame ) }
+/******************************************************************* + * syscalls + */ +#define SYSCALL_ENTRY(id,name,args) __ASM_SYSCALL_FUNC( id, name ) +ALL_SYSCALLS64 +#undef SYSCALL_ENTRY + + /************************************************************************** * __chkstk (NTDLL.@) * diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index c4d0f0e6898..27a65f24076 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -33,6 +33,7 @@ #include "ntdll_misc.h" #include "wine/exception.h" #include "wine/debug.h" +#include "ntsyscalls.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh); WINE_DECLARE_DEBUG_CHANNEL(relay); @@ -71,6 +72,16 @@ extern DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_R CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher, PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nested_handler );
+ +/******************************************************************* + * syscalls + */ +#define SYSCALL_ENTRY(id,name,args) __ASM_SYSCALL_FUNC( id, name, args ) +ALL_SYSCALLS32 +DEFINE_SYSCALL_HELPER32() +#undef SYSCALL_ENTRY + + /******************************************************************* * is_valid_frame */ diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 7f09ec0abea..f578d082b69 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -31,6 +31,7 @@ #include "wine/list.h" #include "ntdll_misc.h" #include "wine/debug.h" +#include "ntsyscalls.h"
WINE_DEFAULT_DEBUG_CHANNEL(unwind); WINE_DECLARE_DEBUG_CHANNEL(seh); @@ -79,6 +80,15 @@ struct MSVCRT_JUMP_BUFFER M128A Xmm15; };
+ +/******************************************************************* + * syscalls + */ +#define SYSCALL_ENTRY(id,name,args) __ASM_SYSCALL_FUNC( id, name ) +ALL_SYSCALLS64 +#undef SYSCALL_ENTRY + + /*********************************************************************** * Definitions for Win32 unwind tables */ diff --git a/include/wine/asm.h b/include/wine/asm.h index 2a21bceb55e..a1a61532f44 100644 --- a/include/wine/asm.h +++ b/include/wine/asm.h @@ -192,4 +192,111 @@
#endif /* __i386__ */
+/* syscall support */ + +#ifdef __i386__ +# ifdef __PIC__ +# define __ASM_SYSCALL_FUNC(id,name,args) \ + __ASM_STDCALL_FUNC( name, args, \ + "call 1f\n" \ + "1:\tpopl %eax\n\t" \ + "movl " __ASM_NAME("__wine_syscall_dispatcher") "-1b(%eax),%edx\n\t" \ + "movl $(" #id "),%eax\n\t" \ + "call *%edx\n\t" \ + "ret $" #args ) +# define DEFINE_SYSCALL_HELPER32() +# else +# define __ASM_SYSCALL_FUNC(id,name,args) \ + __ASM_STDCALL_FUNC( name, args, \ + "movl $(" #id "),%eax\n\t" \ + "movl $" __ASM_NAME("__wine_syscall") ",%edx\n\t" \ + "call *%edx\n\t" \ + "ret $" #args ) +# define DEFINE_SYSCALL_HELPER32() \ + __ASM_GLOBAL_FUNC( __wine_syscall, "jmp *(" __ASM_NAME("__wine_syscall_dispatcher") ")" ) +# endif +#elif defined __aarch64__ +# define __ASM_SYSCALL_FUNC(id,name) \ + __ASM_GLOBAL_FUNC( name, \ + __ASM_SEH(".seh_endprologue\n\t") \ + "mov x8, #(" #id ")\n\t" \ + "mov x9, x30\n\t" \ + "ldr x16, 1f\n\t" \ + "ldr x16, [x16]\n\t" \ + "blr x16\n\t" \ + "ret\n" \ + "1:\t.quad " __ASM_NAME("__wine_syscall_dispatcher") ) +#elif defined __x86_64__ +/* Chromium depends on syscall thunks having the same form as on + * Windows. For 64-bit systems the only viable form we can emulate is + * having an int $0x2e fallback. Since actually using an interrupt is + * expensive, and since for some reason Chromium doesn't actually + * validate that instruction, we can just put a jmp there instead. */ +# ifdef __WINE_PE_BUILD +# define __ASM_SYSCALL_FUNC(id,name) \ + __ASM_GLOBAL_FUNC( name, \ + __ASM_SEH(".seh_endprologue\n\t") \ + ".byte 0x4c,0x8b,0xd1\n\t" /* movq %rcx,%r10 */ \ + ".byte 0xb8\n\t" /* movl $i,%eax */ \ + ".long (" #id ")\n\t" \ + ".byte 0xf6,0x04,0x25,0x08,0x03,0xfe,0x7f,0x01\n\t" /* testb $1,0x7ffe0308 */ \ + ".byte 0x75,0x03\n\t" /* jne 1f */ \ + ".byte 0x0f,0x05\n\t" /* syscall */ \ + ".byte 0xc3\n\t" /* ret */ \ + "jmp 1f\n\t" \ + ".byte 0xc3\n" /* ret */ \ + "1:\t.byte 0xff,0x14,0x25\n\t" /* 1: callq *(0x7ffe1000) */ \ + ".long 0x7ffe1000\n\t" \ + "ret" ) +# else +# define __ASM_SYSCALL_FUNC(id,name) \ + __ASM_GLOBAL_FUNC( name, \ + __ASM_SEH(".seh_endprologue\n\t") \ + ".byte 0x4c,0x8b,0xd1\n\t" /* movq %rcx,%r10 */ \ + ".byte 0xb8\n\t" /* movl $i,%eax */ \ + ".long (" #id ")\n\t" \ + ".byte 0xf6,0x04,0x25,0x08,0x03,0xfe,0x7f,0x01\n\t" /* testb $1,0x7ffe0308 */ \ + ".byte 0x75,0x03\n\t" /* jne 1f */ \ + ".byte 0x0f,0x05\n\t" /* syscall */ \ + ".byte 0xc3\n\t" /* ret */ \ + "jmp 1f\n\t" \ + ".byte 0xc3\n" /* ret */ \ + "nop\n" \ + "1:\tcallq *" __ASM_NAME("__wine_syscall_dispatcher") "(%rip)\n\t" \ + "ret" ) +# endif +#elif defined __arm__ +# define __ASM_SYSCALL_FUNC(id,name,args) \ + __ASM_GLOBAL_FUNC( name, \ + "push {r0-r3}\n\t" \ + "movw ip, #(" #id ")\n\t" \ + "mov r3, lr\n\t" \ + "bl " __ASM_NAME("__wine_syscall") "\n\t" \ + "bx lr" ) +# ifndef __PIC__ +# define DEFINE_SYSCALL_HELPER32() \ + __ASM_GLOBAL_FUNC( __wine_syscall, \ + "movw r0, :lower16:" __ASM_NAME("__wine_syscall_dispatcher") "\n\t" \ + "movt r0, :upper16:" __ASM_NAME("__wine_syscall_dispatcher") "\n\t" \ + "ldr r0, [r0]\n\t" \ + "bx r0" ) +# elif defined __thumb__ +# define DEFINE_SYSCALL_HELPER32() \ + __ASM_GLOBAL_FUNC( __wine_syscall, \ + "ldr r0, 2f\n" \ + "1:\tadd r0, pc\n\t" \ + "ldr r0, [r0]\n\t" \ + "bx r0\n" \ + "2:\t.long " __ASM_NAME("__wine_syscall_dispatcher") "-1b-4" ) +# else +# define DEFINE_SYSCALL_HELPER32() \ + __ASM_GLOBAL_FUNC( __wine_syscall, \ + "ldr r0, 2f\n" \ + "1:\tadd r0, pc\n\t" \ + "ldr r0, [r0]\n\t" \ + "bx r0\n" \ + "2:\t.long " __ASM_NAME("__wine_syscall_dispatcher") "-1b-8" ) +# endif +#endif + #endif /* __WINE_WINE_ASM_H */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index e3bb8b7f3db..4a1146c8c9d 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1399,6 +1399,8 @@ void output_syscalls( DLLSPEC *spec ) int i, count; ORDDEF **syscalls = NULL;
+ if (!spec->syscall_table) return; + for (i = count = 0; i < spec->nb_entry_points; i++) { ORDDEF *odp = &spec->entry_points[i];