[PATCH v3 0/2] MR6877: ntdll: Force redirect all ARM64EC indirect calls until the JIT is ready.
Tested by running chrome without no-sandbox successfully. -- v3: ntdll: Force redirect all ARM64EC indirect calls until the JIT is ready. ntdll: Add arm64ec_get_module_metadata helper. https://gitlab.winehq.org/wine/wine/-/merge_requests/6877
From: Billy Laws <blaws05(a)gmail.com> --- dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/signal_arm64ec.c | 18 ++++++++++++++++++ dlls/ntdll/unwind.c | 12 ++---------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 22a3a6ced60..fb5fb311646 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -169,6 +169,7 @@ extern void heap_thread_detach(void); extern NTSTATUS arm64ec_process_init( HMODULE module ); extern NTSTATUS arm64ec_thread_init(void); +extern IMAGE_ARM64EC_METADATA *arm64ec_get_module_metadata( HMODULE module ); extern void arm64ec_update_hybrid_metadata( void *module, IMAGE_NT_HEADERS *nt, const IMAGE_ARM64EC_METADATA *metadata ); extern void invoke_arm64ec_syscall(void); diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index fbd49fd26c7..3106d9f57a3 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -220,6 +220,24 @@ NTSTATUS arm64ec_thread_init(void) } +/********************************************************************** + * arm64ec_get_module_metadata + */ +IMAGE_ARM64EC_METADATA *arm64ec_get_module_metadata( HMODULE module ) +{ + IMAGE_LOAD_CONFIG_DIRECTORY *cfg; + ULONG size; + + if (!(cfg = RtlImageDirectoryEntryToData( module, TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &size ))) + return NULL; + + size = min( size, cfg->Size ); + if (size <= offsetof( IMAGE_LOAD_CONFIG_DIRECTORY, CHPEMetadataPointer )) return NULL; + return (IMAGE_ARM64EC_METADATA *)cfg->CHPEMetadataPointer; +} + + static void update_hybrid_pointer( void *module, const IMAGE_SECTION_HEADER *sec, UINT rva, void *ptr ) { if (!rva) return; diff --git a/dlls/ntdll/unwind.c b/dlls/ntdll/unwind.c index 91b07a7cc8c..c11bd9ddb9c 100644 --- a/dlls/ntdll/unwind.c +++ b/dlls/ntdll/unwind.c @@ -267,16 +267,8 @@ PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable( ULONG_PTR pc, ULONG_PTR *base, #ifdef __arm64ec__ if (RtlIsEcCode( pc )) { - IMAGE_LOAD_CONFIG_DIRECTORY *cfg; - IMAGE_ARM64EC_METADATA *metadata; - ULONG size; - - if (!(cfg = RtlImageDirectoryEntryToData( module->DllBase, TRUE, - IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &size ))) - return NULL; - size = min( size, cfg->Size ); - if (size <= offsetof( IMAGE_LOAD_CONFIG_DIRECTORY, CHPEMetadataPointer )) return NULL; - metadata = (IMAGE_ARM64EC_METADATA *)cfg->CHPEMetadataPointer; + IMAGE_ARM64EC_METADATA *metadata = arm64ec_get_module_metadata( module->DllBase ); + if (!metadata) return NULL; *len = metadata->ExtraRFETableSize; return (RUNTIME_FUNCTION *)(*base + metadata->ExtraRFETable); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6877
From: Billy Laws <blaws05(a)gmail.com> --- dlls/ntdll/signal_arm64ec.c | 48 +++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/signal_arm64ec.c b/dlls/ntdll/signal_arm64ec.c index 3106d9f57a3..4505aeacfba 100644 --- a/dlls/ntdll/signal_arm64ec.c +++ b/dlls/ntdll/signal_arm64ec.c @@ -155,6 +155,25 @@ static BOOL send_cross_process_notification( HANDLE process, UINT id, const void } +static void *arm64ec_redirect_ptr( HMODULE module, void *ptr, const IMAGE_ARM64EC_METADATA *metadata ) +{ + const IMAGE_ARM64EC_REDIRECTION_ENTRY *map = get_rva( module, metadata->RedirectionMetadata ); + int min = 0, max = metadata->RedirectionMetadataCount - 1; + ULONG_PTR rva = (ULONG_PTR)ptr - (ULONG_PTR)module; + + if (!ptr) return NULL; + while (min <= max) + { + int pos = (min + max) / 2; + if (map[pos].Source == rva) return get_rva( module, map[pos].Destination ); + if (map[pos].Source < rva) min = pos + 1; + else max = pos - 1; + } + return ptr; +} + +static void arm64x_check_call(void); + /******************************************************************* * arm64ec_process_init */ @@ -162,12 +181,14 @@ NTSTATUS arm64ec_process_init( HMODULE module ) { NTSTATUS status = STATUS_SUCCESS; CHPEV2_PROCESS_INFO *info = (CHPEV2_PROCESS_INFO *)(RtlGetCurrentPeb() + 1); + const IMAGE_ARM64EC_METADATA *metadata = arm64ec_get_module_metadata( module ); __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 ) +#define GET_PTR(name) p ## name = arm64ec_redirect_ptr( module, \ + RtlFindExportedRoutineByName( module, #name ), metadata ) GET_PTR( BTCpu64FlushInstructionCache ); GET_PTR( BTCpu64IsProcessorFeaturePresent ); GET_PTR( BTCpu64NotifyMemoryDirty ); @@ -202,6 +223,9 @@ NTSTATUS arm64ec_process_init( HMODULE module ) } if (!status && pThreadInit) status = pThreadInit(); leave_syscall_callback(); + __os_arm64x_check_call = arm64x_check_call; + __os_arm64x_check_icall = arm64x_check_call; + __os_arm64x_check_icall_cfg = arm64x_check_call; return status; } @@ -271,11 +295,11 @@ void arm64ec_update_hybrid_metadata( void *module, IMAGE_NT_HEADERS *nt, NtProtectVirtualMemory( NtCurrentProcess(), &base, &size, PAGE_READWRITE, &protect_old ); #define SET_FUNC(func,val) update_hybrid_pointer( module, sec, metadata->func, val ) - SET_FUNC( __os_arm64x_dispatch_call, __os_arm64x_check_call ); + SET_FUNC( __os_arm64x_dispatch_call, arm64x_check_call ); SET_FUNC( __os_arm64x_dispatch_call_no_redirect, __os_arm64x_dispatch_call_no_redirect ); SET_FUNC( __os_arm64x_dispatch_fptr, __os_arm64x_dispatch_fptr ); - SET_FUNC( __os_arm64x_dispatch_icall, __os_arm64x_check_icall ); - SET_FUNC( __os_arm64x_dispatch_icall_cfg, __os_arm64x_check_icall_cfg ); + SET_FUNC( __os_arm64x_dispatch_icall, arm64x_check_call ); + SET_FUNC( __os_arm64x_dispatch_icall_cfg, arm64x_check_call ); SET_FUNC( __os_arm64x_dispatch_ret, __os_arm64x_dispatch_ret ); SET_FUNC( __os_arm64x_helper3, __os_arm64x_helper3 ); SET_FUNC( __os_arm64x_helper4, __os_arm64x_helper4 ); @@ -1790,6 +1814,16 @@ NTSTATUS __attribute__((naked)) __wine_unix_call_arm64ec( unixlib_handle_t handl NTSTATUS (WINAPI *__wine_unix_call_dispatcher_arm64ec)( unixlib_handle_t, unsigned int, void * ) = __wine_unix_call_arm64ec; +static void __attribute__((naked)) arm64x_check_call_early(void) +{ + asm( "mov x11, x9\n\t" + "ret" ); +} + +static void __attribute__((naked)) arm64x_check_icall_early(void) +{ + asm( "ret" ); +} /************************************************************************** * arm64x_check_call @@ -2017,9 +2051,9 @@ void WINAPI LdrInitializeThunk( CONTEXT *arm_context, ULONG_PTR unk2, ULONG_PTR if (!__os_arm64x_check_call) { - __os_arm64x_check_call = arm64x_check_call; - __os_arm64x_check_icall = arm64x_check_call; - __os_arm64x_check_icall_cfg = arm64x_check_call; + __os_arm64x_check_call = arm64x_check_call_early; + __os_arm64x_check_icall = arm64x_check_icall_early; + __os_arm64x_check_icall_cfg = arm64x_check_icall_early; __os_arm64x_get_x64_information = LdrpGetX64Information; __os_arm64x_set_x64_information = LdrpSetX64Information; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6877
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150287 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/ntdll/ntdll_misc.h:169 error: patch failed: dlls/ntdll/signal_arm64ec.c:220 error: patch failed: dlls/ntdll/signal_arm64ec.c:271 Task: Patch failed to apply === debian11b (build log) === error: patch failed: dlls/ntdll/ntdll_misc.h:169 error: patch failed: dlls/ntdll/signal_arm64ec.c:220 error: patch failed: dlls/ntdll/signal_arm64ec.c:271 Task: Patch failed to apply
participants (3)
-
Billy Laws -
Billy Laws (@bylaws) -
Marvin