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 "wine/exception.h"
|
||||||
#include "ntdll_misc.h"
|
#include "ntdll_misc.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "winnt.h"
|
#include "ntsyscalls.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
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.@)
|
* __chkstk (NTDLL.@)
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
#include "ntdll_misc.h"
|
#include "ntdll_misc.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "winnt.h"
|
#include "ntsyscalls.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
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.@)
|
* __chkstk (NTDLL.@)
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "ntdll_misc.h"
|
#include "ntdll_misc.h"
|
||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "ntsyscalls.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
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,
|
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher,
|
||||||
PEXCEPTION_HANDLER handler, PEXCEPTION_HANDLER nested_handler );
|
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
|
* is_valid_frame
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
#include "ntdll_misc.h"
|
#include "ntdll_misc.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "ntsyscalls.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(unwind);
|
WINE_DEFAULT_DEBUG_CHANNEL(unwind);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(seh);
|
WINE_DECLARE_DEBUG_CHANNEL(seh);
|
||||||
|
@ -79,6 +80,15 @@ struct MSVCRT_JUMP_BUFFER
|
||||||
M128A Xmm15;
|
M128A Xmm15;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* syscalls
|
||||||
|
*/
|
||||||
|
#define SYSCALL_ENTRY(id,name,args) __ASM_SYSCALL_FUNC( id, name )
|
||||||
|
ALL_SYSCALLS64
|
||||||
|
#undef SYSCALL_ENTRY
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Definitions for Win32 unwind tables
|
* Definitions for Win32 unwind tables
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -192,4 +192,111 @@
|
||||||
|
|
||||||
#endif /* __i386__ */
|
#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 */
|
#endif /* __WINE_WINE_ASM_H */
|
||||||
|
|
|
@ -1399,6 +1399,8 @@ void output_syscalls( DLLSPEC *spec )
|
||||||
int i, count;
|
int i, count;
|
||||||
ORDDEF **syscalls = NULL;
|
ORDDEF **syscalls = NULL;
|
||||||
|
|
||||||
|
if (!spec->syscall_table) return;
|
||||||
|
|
||||||
for (i = count = 0; i < spec->nb_entry_points; i++)
|
for (i = count = 0; i < spec->nb_entry_points; i++)
|
||||||
{
|
{
|
||||||
ORDDEF *odp = &spec->entry_points[i];
|
ORDDEF *odp = &spec->entry_points[i];
|
||||||
|
|
Loading…
Add table
Reference in a new issue