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.
From: Billy Laws blaws05@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); }
From: Billy Laws blaws05@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; }
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