ntdll: Generate syscall entry points from the C code with asm macros.
This commit is contained in:
parent
5148911b81
commit
48a5459827
6 changed files with 149 additions and 2 deletions
|
@ -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];
|
||||
|
|
Loading…
Add table
Reference in a new issue