diff --git a/build-scripts/build-step-arm64ec.sh b/build-scripts/build-step-arm64ec.sh index b4d8c8def23f..21c0ef50ae7b 100644 --- a/build-scripts/build-step-arm64ec.sh +++ b/build-scripts/build-step-arm64ec.sh @@ -247,7 +247,7 @@ do rm -rf $OUTPUT_DIR/lib rm -rf $OUTPUT_DIR/share rm -rf $install_dir - make -j$(nproc) + make -j$(nproc) || exit $? fi if [ "$arg" == "--install" ] @@ -257,7 +257,7 @@ do mkdir -p $OUTPUT_DIR/lib mkdir -p $OUTPUT_DIR/share mkdir -p $install_dir - make install -j$(nproc) + make install -j$(nproc) || exit $? echo "Copying files..." cp -r $install_dir/bin/wine* $OUTPUT_DIR/bin cp -r $install_dir/bin/reg* $OUTPUT_DIR/bin diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index 8be6c7e785be..8f8b3d2a86d5 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -615,6 +615,7 @@ static const WCHAR *hack_append_command_line( const WCHAR *cmd ) {L"EverQuest 2\\LaunchPad.exe", L" --use-gl=swiftshader"}, {L"Everquest F2P\\LaunchPad.exe", L" --use-gl=swiftshader"}, {L"Red Tie Runner.exe", L" --use-angle=gl"}, + {L"SocialClubHelper.exe", L" --disable-gpu --disable-gpu-compositing --disable-gpu-rasterization", "1174180"}, {L"UnrealCEFSubProcess.exe", L" --use-gl=swiftshader", "2316580"}, {L"UnrealCEFSubProcess.exe", L" --use-angle=d3d9", "2684500"}, }; diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index 3a8576d3e1bf..850af09c6b3d 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -1281,8 +1281,40 @@ __ASM_GLOBAL_FUNC( "#KiUserEmulationDispatcher", /******************************************************************* * dispatch_syscall */ +static ULONG translate_rdr2_syscall( ULONG syscall, ULONG_PTR pc ) +{ + static int is_rdr2 = -1; + WCHAR appid[8]; + SIZE_T len; + + if (syscall != 0xf2 || pc < 0x140000000ull || pc >= 0x150000000ull) return syscall; + + /* RDR2's protection code bypasses ntdll and issues NtGetContextThread + * using the Windows 10 2009 service number 0xf2. FEX reports it through + * STATUS_EMULATION_SYSCALL, but Wine 11 assigns NtGetContextThread the + * generated service number 0x97. The other direct syscalls used by RDR2 + * have explicit Windows-compatible IDs in ntdll.spec. */ + if (is_rdr2 == -1) + { + is_rdr2 = (!RtlQueryEnvironmentVariable( NULL, L"SteamGameId", 11, appid, + ARRAY_SIZE(appid), &len ) && len == 7 && + (!wcsncmp( appid, L"1174180", 7 ) || !wcsncmp( appid, L"1404210", 7 ))) || + (!RtlQueryEnvironmentVariable( NULL, L"SteamAppId", 10, appid, + ARRAY_SIZE(appid), &len ) && len == 7 && + (!wcsncmp( appid, L"1174180", 7 ) || !wcsncmp( appid, L"1404210", 7 ))); + if (is_rdr2) WARN( "RDR2 direct syscall at %p: 0xf2 -> %#x (NtGetContextThread).\n", + (void *)pc, __id_NtGetContextThread ); + } + + /* Only translate direct calls made by the game/launcher image. Calls + * through Wine's ntdll already carry Wine's own generated service IDs. */ + return is_rdr2 ? __id_NtGetContextThread : syscall; +} + static void dispatch_syscall( ARM64_NT_CONTEXT *context ) { + context->X8 = translate_rdr2_syscall( context->X8, context->Pc ); + if (context->X8 < __nb_syscalls) /* syscall number in rax */ { context->X0 = context->X4; /* get first param from r10 */ diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 6e1697720f08..a954b6190fc0 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -837,6 +837,40 @@ static void reserve_area( void *addr, void *end ) } +/* + * CEF's V8 sandbox normally reserves a 1 TB placeholder. On 39-bit ARM64 + * hosts V8 falls back to a 128 GB partial reservation, but by the time the + * renderer initializes, native mappings have fragmented every suitably + * aligned range. Keep one range intact from process startup. Adding it to + * Wine's reserved-area list lets VirtualAlloc2 replace the PROT_NONE mapping + * when V8 creates its placeholder. + */ +static void reserve_rdr2_v8_sandbox(void) +{ +#if defined(__aarch64__) && defined(_WIN64) + static const char app_id[] = "1174180"; + const char *steam_game_id = getenv( "SteamGameId" ); + const char *steam_app_id = getenv( "SteamAppId" ); + void *base = (void *)0x2000000000; + size_t size = 0x2000000000; + + if ((!steam_game_id || strcmp( steam_game_id, app_id )) && + (!steam_app_id || strcmp( steam_app_id, app_id ))) return; + if (is_beyond_limit( base, size, host_addr_space_limit )) return; + if (mmap_is_in_reserved_area( base, size ) == 1) return; + + if (anon_mmap_tryfixed( base, size, PROT_NONE, MAP_NORESERVE ) == base) + { + mmap_add_reserved_area( base, size ); + FIXME( "HACK: reserved RDR2 V8 sandbox address space %p-%p.\n", + base, (char *)base + size ); + } + else WARN( "failed to reserve RDR2 V8 sandbox address space %p-%p.\n", + base, (char *)base + size ); +#endif +} + + static void mmap_init( const struct preload_info *preload_info ) { #ifndef _WIN64 @@ -3957,6 +3991,9 @@ void virtual_init(void) size = (char *)address_space_start - (char *)0x10000; if (size && mmap_is_in_reserved_area( (void*)0x10000, size ) == 1) anon_mmap_fixed( (void *)0x10000, size, PROT_READ | PROT_WRITE, 0 ); + + /* Keep alloc_virtual_heap() from carving its bookkeeping data out of this area. */ + reserve_rdr2_v8_sandbox(); }