Module: wine Branch: master Commit: 3cf8d501f8d9975cd9d88c6cd01578271a0b4447 URL: https://gitlab.winehq.org/wine/wine/-/commit/3cf8d501f8d9975cd9d88c6cd015782...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jul 8 13:14:21 2024 +0200
ntdll: Load xtajit64.dll on ARM64EC.
---
dlls/ntdll/loader.c | 53 ++++++++++++++++++++++++++++++++++++++++++--- dlls/ntdll/ntdll_misc.h | 3 +++ dlls/ntdll/signal_arm64ec.c | 38 ++++++++++++++++++++++++++++++++ loader/wine.inf.in | 1 + 4 files changed, 92 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index e7b724471e7..bad1492e138 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -4144,6 +4144,44 @@ static void elevate_token(void) NtClose( linked.LinkedToken ); }
+#ifdef __arm64ec__ + +static void load_arm64ec_module(void) +{ + ULONG buffer[16]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + UNICODE_STRING nameW = RTL_CONSTANT_STRING( L"\Registry\Machine\Software\Microsoft\Wow64\amd64" ); + WCHAR module[64] = L"C:\windows\system32\xtajit64.dll"; + OBJECT_ATTRIBUTES attr; + WINE_MODREF *wm; + NTSTATUS status; + HANDLE key; + + InitializeObjectAttributes( &attr, &nameW, OBJ_CASE_INSENSITIVE, 0, NULL ); + if (!NtOpenKey( &key, KEY_READ | KEY_WOW64_64KEY, &attr )) + { + UNICODE_STRING valueW = RTL_CONSTANT_STRING( L"" ); + ULONG dirlen = wcslen( L"C:\windows\system32\" ); + ULONG size = sizeof(buffer); + + if (!NtQueryValueKey( key, &valueW, KeyValuePartialInformation, buffer, size, &size ) && info->Type == REG_SZ) + { + size = sizeof(module) - (dirlen + 1) * sizeof(WCHAR); + memcpy( module + dirlen, info->Data, min( info->DataLength, size )); + } + NtClose( key ); + } + + if ((status = load_dll( NULL, module, 0, &wm, FALSE )) || + (status = arm64ec_process_init( wm->ldr.DllBase ))) + { + ERR( "could not load %s, status %lx\n", debugstr_w(module), status ); + NtTerminateProcess( GetCurrentProcess(), status ); + } +} + +#endif + #ifdef _WIN64
static void build_wow64_main_module(void) @@ -4316,6 +4354,10 @@ void loader_init( CONTEXT *context, void **entry )
wm = build_main_module(); build_ntdll_module(); +#ifdef __arm64ec__ + load_arm64ec_module(); + update_load_config( wm->ldr.DllBase ); +#endif
if ((status = load_dll( NULL, L"kernel32.dll", 0, &kernel32, FALSE )) != STATUS_SUCCESS) { @@ -4344,11 +4386,16 @@ void loader_init( CONTEXT *context, void **entry ) } imports_fixup_done = TRUE; } - else wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress ); - + else + { #ifdef _WIN64 - if (NtCurrentTeb()->WowTebOffset) init_wow64( context ); + if (NtCurrentTeb()->WowTebOffset) init_wow64( context ); #endif +#ifdef __arm64ec__ + arm64ec_thread_init(); +#endif + wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress ); + }
RtlAcquirePebLock(); InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks ); diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index cc467d44966..bda4dd61d25 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -162,6 +162,9 @@ extern void heap_thread_detach(void);
#ifdef __arm64ec__
+extern NTSTATUS arm64ec_process_init( HMODULE module ); +extern NTSTATUS arm64ec_thread_init(void); + extern void *__os_arm64x_check_call; extern void *__os_arm64x_check_icall; extern void *__os_arm64x_check_icall_cfg; diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index 393d5f7e697..3fbdb63cb83 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -39,6 +39,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh); WINE_DECLARE_DEBUG_CHANNEL(relay);
+/* xtajit64.dll functions */ +static NTSTATUS (WINAPI *pProcessInit)(void); +static NTSTATUS (WINAPI *pThreadInit)(void);
static inline CHPE_V2_CPU_AREA_INFO *get_arm64ec_cpu_area(void) { @@ -88,6 +91,41 @@ static BOOL send_cross_process_notification( HANDLE process, UINT id, const void }
+/******************************************************************* + * arm64ec_process_init + */ +NTSTATUS arm64ec_process_init( HMODULE module ) +{ + NTSTATUS status = STATUS_SUCCESS; + + __os_arm64x_dispatch_call_no_redirect = RtlFindExportedRoutineByName( module, "ExitToX64" ); + __os_arm64x_dispatch_fptr = RtlFindExportedRoutineByName( module, "DispatchJump" ); + __os_arm64x_dispatch_ret = RtlFindExportedRoutineByName( module, "RetToEntryThunk" ); + +#define GET_PTR(name) p ## name = RtlFindExportedRoutineByName( module, #name ) + GET_PTR( ProcessInit ); + GET_PTR( ThreadInit ); +#undef GET_PTR + + if (pProcessInit) status = pProcessInit(); + + if (!status) status = arm64ec_thread_init(); + return status; +} + + +/******************************************************************* + * arm64ec_thread_init + */ +NTSTATUS arm64ec_thread_init(void) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (pThreadInit) status = pThreadInit(); + return status; +} + + /******************************************************************* * syscalls */ diff --git a/loader/wine.inf.in b/loader/wine.inf.in index f952ef84f43..0b4fb295093 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -431,6 +431,7 @@ HKLM,%CurrentVersion%,"ProgramFilesDir (x86)",,"%16426%" HKLM,%CurrentVersion%,"CommonFilesDir (x86)",,"%16428%" HKLM,%CurrentVersion%,"ProgramFilesDir (Arm)",,"C:\Program Files (Arm)" HKLM,%CurrentVersion%,"CommonFilesDir (Arm)",,"C:\Program Files (Arm)\Common Files" +HKLM,Software\Microsoft\Wow64\amd64,,2,"xtajit64.dll" HKLM,Software\Microsoft\Wow64\arm,,2,"wowarmhw.dll" HKLM,Software\Microsoft\Wow64\x86,,2,"xtajit.dll"