Commit 48a54598 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Generate syscall entry points from the C code with asm macros.

parent 5148911b
......@@ -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.@)
*
......
......@@ -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.@)
*
......
......@@ -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
*/
......
......@@ -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
*/
......
......@@ -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 */
......@@ -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];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment