mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 04:48:36 +00:00
ntdll: Use assembly wrapper for unixlib calls on ARM64EC.
Instead of using indirect C calls, which need to go through the call dispatcher.
This commit is contained in:
parent
127650c293
commit
434702fdc9
|
@ -1723,6 +1723,7 @@
|
|||
@ stdcall __wine_ctrl_routine(ptr)
|
||||
@ extern -private __wine_syscall_dispatcher
|
||||
@ extern -private __wine_unix_call_dispatcher
|
||||
@ extern -private -arch=arm64ec __wine_unix_call_dispatcher_arm64ec
|
||||
@ extern -private __wine_unixlib_handle
|
||||
|
||||
# Debugging
|
||||
|
|
|
@ -2227,6 +2227,22 @@ ULONG WINAPI RtlWalkFrameChain( void **buffer, ULONG count, ULONG flags )
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* __wine_unix_call_arm64ec
|
||||
*/
|
||||
NTSTATUS __attribute__((naked)) __wine_unix_call_arm64ec( unixlib_handle_t handle, unsigned int code, void *args )
|
||||
{
|
||||
asm( ".seh_proc \"#__wine_unix_call_arm64ec\"\n\t"
|
||||
".seh_endprologue\n\t"
|
||||
"adrp x16, __wine_unix_call_dispatcher_arm64ec\n\t"
|
||||
"ldr x16, [x16, #:lo12:__wine_unix_call_dispatcher_arm64ec]\n\t"
|
||||
"br x16\n\t"
|
||||
".seh_endproc" );
|
||||
}
|
||||
|
||||
NTSTATUS (WINAPI *__wine_unix_call_dispatcher_arm64ec)( unixlib_handle_t, unsigned int, void * ) = __wine_unix_call_arm64ec;
|
||||
|
||||
|
||||
static int code_match( BYTE *code, const BYTE *seq, size_t len )
|
||||
{
|
||||
for ( ; len; len--, code++, seq++) if (*seq && *code != *seq) return 0;
|
||||
|
@ -2262,7 +2278,6 @@ void *check_call( void **target, void *exit_thunk, void *dest )
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (dest == __wine_unix_call_dispatcher) return dest;
|
||||
if (RtlIsEcCode( (ULONG_PTR)dest )) return dest;
|
||||
if (code_match( dest, jmp_sequence, sizeof(jmp_sequence) ))
|
||||
{
|
||||
|
|
|
@ -1517,6 +1517,7 @@ static void load_ntdll_functions( HMODULE module )
|
|||
{
|
||||
void **p__wine_syscall_dispatcher;
|
||||
void **p__wine_unix_call_dispatcher;
|
||||
void **p__wine_unix_call_dispatcher_arm64ec = NULL;
|
||||
unixlib_handle_t *p__wine_unixlib_handle;
|
||||
const IMAGE_EXPORT_DIRECTORY *exports;
|
||||
|
||||
|
@ -1539,9 +1540,19 @@ static void load_ntdll_functions( HMODULE module )
|
|||
GET_FUNC( __wine_syscall_dispatcher );
|
||||
GET_FUNC( __wine_unix_call_dispatcher );
|
||||
GET_FUNC( __wine_unixlib_handle );
|
||||
if (is_arm64ec())
|
||||
{
|
||||
GET_FUNC( __wine_unix_call_dispatcher_arm64ec );
|
||||
}
|
||||
*p__wine_syscall_dispatcher = __wine_syscall_dispatcher;
|
||||
*p__wine_unix_call_dispatcher = __wine_unix_call_dispatcher;
|
||||
*p__wine_unixlib_handle = (UINT_PTR)unix_call_funcs;
|
||||
if (p__wine_unix_call_dispatcher_arm64ec)
|
||||
{
|
||||
/* redirect __wine_unix_call_dispatcher to __wine_unix_call_dispatcher_arm64ec */
|
||||
*p__wine_unix_call_dispatcher = *p__wine_unix_call_dispatcher_arm64ec;
|
||||
*p__wine_unix_call_dispatcher_arm64ec = __wine_unix_call_dispatcher;
|
||||
}
|
||||
else *p__wine_unix_call_dispatcher = __wine_unix_call_dispatcher;
|
||||
#undef GET_FUNC
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,31 @@ static NTSTATUS WINAPI unix_call_init( unixlib_handle_t handle, unsigned int cod
|
|||
unixlib_handle_t __wine_unixlib_handle = 0;
|
||||
NTSTATUS (WINAPI *__wine_unix_call_dispatcher)( unixlib_handle_t, unsigned int, void * ) = unix_call_init;
|
||||
|
||||
#ifdef __arm64ec__
|
||||
|
||||
static NTSTATUS WINAPI unix_call_init_arm64ec( unixlib_handle_t handle, unsigned int code, void *args );
|
||||
|
||||
static __attribute__((used)) NTSTATUS (WINAPI *__wine_unix_call_dispatcher_arm64ec)( unixlib_handle_t, unsigned int, void * ) = unix_call_init_arm64ec;
|
||||
|
||||
static NTSTATUS WINAPI unix_call_init_arm64ec( unixlib_handle_t handle, unsigned int code, void *args )
|
||||
{
|
||||
InterlockedExchangePointer( (void **)&__wine_unix_call_dispatcher_arm64ec,
|
||||
get_dispatcher( "__wine_unix_call_dispatcher_arm64ec" ));
|
||||
return __wine_unix_call_arm64ec( handle, code, args );
|
||||
}
|
||||
|
||||
NTSTATUS __attribute__((naked)) __wine_unix_call_arm64ec( unixlib_handle_t handle, unsigned int code, void *args )
|
||||
{
|
||||
asm( ".seh_proc \"#__wine_unix_call_arm64ec\"\n\t"
|
||||
".seh_endprologue\n\t"
|
||||
"adrp x16, __wine_unix_call_dispatcher_arm64ec\n\t"
|
||||
"ldr x16, [x16, #:lo12:__wine_unix_call_dispatcher_arm64ec]\n\t"
|
||||
"br x16\n\t"
|
||||
".seh_endproc" );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NTSTATUS WINAPI __wine_init_unix_call(void)
|
||||
{
|
||||
return NtQueryVirtualMemory( GetCurrentProcess(), image_base(), MemoryWineUnixFuncs,
|
||||
|
|
|
@ -262,10 +262,18 @@ extern unixlib_handle_t __wine_unixlib_handle;
|
|||
extern NTSTATUS (WINAPI *__wine_unix_call_dispatcher)( unixlib_handle_t, unsigned int, void * );
|
||||
extern NTSTATUS WINAPI __wine_init_unix_call(void);
|
||||
|
||||
#ifdef __arm64ec__
|
||||
NTSTATUS __wine_unix_call_arm64ec( unixlib_handle_t handle, unsigned int code, void *args );
|
||||
static inline NTSTATUS __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args )
|
||||
{
|
||||
return __wine_unix_call_arm64ec( handle, code, args );
|
||||
}
|
||||
#else
|
||||
static inline NTSTATUS __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args )
|
||||
{
|
||||
return __wine_unix_call_dispatcher( handle, code, args );
|
||||
}
|
||||
#endif
|
||||
|
||||
#define WINE_UNIX_CALL(code,args) __wine_unix_call( __wine_unixlib_handle, (code), (args) )
|
||||
|
||||
|
|
Loading…
Reference in a new issue