diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index 941b127a2f6..a1beb9a4997 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -275,7 +275,6 @@ static void test_process_machine( HANDLE process, HANDLE thread, win32_entry is the redirected x86-64 -> ARM64EC one */ ok( image.TransferAddress != entry_point, "wrong entry %p\n", image.TransferAddress ); ok( image.TransferAddress != win32_entry, "wrong entry %p\n", image.TransferAddress ); - todo_wine ok( win32_entry != entry_point, "wrong win32 entry %p\n", win32_entry ); } } diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 05284115b67..88b24420ec1 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1585,24 +1585,23 @@ static void load_ntdll_wow64_functions( HMODULE module ) /*********************************************************************** - * redirect_arm64ec_ptr + * redirect_arm64ec_rva * - * Redirect a function pointer through the arm64ec redirection table. + * Redirect an address through the arm64ec redirection table. */ -static void *redirect_arm64ec_ptr( void *module, void *ptr, - const IMAGE_ARM64EC_REDIRECTION_ENTRY *map, ULONG map_count ) +ULONG_PTR redirect_arm64ec_rva( void *base, ULONG_PTR rva, const IMAGE_ARM64EC_METADATA *metadata ) { - int min = 0, max = map_count - 1; - ULONG_PTR rva = (char *)ptr - (char *)module; + const IMAGE_ARM64EC_REDIRECTION_ENTRY *map = get_rva( base, metadata->RedirectionMetadata ); + int min = 0, max = metadata->RedirectionMetadataCount - 1; 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) return map[pos].Destination; if (map[pos].Source < rva) min = pos + 1; else max = pos - 1; } - return ptr; + return rva; } @@ -1615,13 +1614,11 @@ static void redirect_ntdll_functions( HMODULE module ) { const IMAGE_LOAD_CONFIG_DIRECTORY *loadcfg; const IMAGE_ARM64EC_METADATA *metadata; - const IMAGE_ARM64EC_REDIRECTION_ENTRY *map; if (!(loadcfg = get_module_data_dir( module, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, NULL ))) return; if (!(metadata = (void *)loadcfg->CHPEMetadataPointer)) return; - if (!(map = get_rva( module, metadata->RedirectionMetadata ))) return; #define REDIRECT(name) \ - p##name = redirect_arm64ec_ptr( module, p##name, map, metadata->RedirectionMetadataCount ) + p##name = get_rva( module, redirect_arm64ec_rva( module, (char *)p##name - (char *)module, metadata )) REDIRECT( DbgUiRemoteBreakin ); REDIRECT( KiRaiseUserExceptionDispatcher ); REDIRECT( KiUserExceptionDispatcher ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index af746b220e8..cbf72651a9a 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -191,6 +191,7 @@ extern BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ); extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *curdir, USHORT load_machine, WCHAR **image, void **module ); extern NTSTATUS load_start_exe( WCHAR **image, void **module ); +extern ULONG_PTR redirect_arm64ec_rva( void *module, ULONG_PTR rva, const IMAGE_ARM64EC_METADATA *metadata ); extern void start_server( BOOL debug ); extern unsigned int server_call_unlocked( void *req_ptr ); diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index cfe19eae89d..02c0bebe879 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2488,7 +2488,7 @@ static void alloc_arm64ec_map(void) * update_arm64ec_ranges */ static void update_arm64ec_ranges( struct file_view *view, IMAGE_NT_HEADERS *nt, - const IMAGE_DATA_DIRECTORY *dir ) + const IMAGE_DATA_DIRECTORY *dir, UINT *entry_point ) { const IMAGE_ARM64EC_METADATA *metadata; const IMAGE_CHPE_RANGE_ENTRY *map; @@ -2501,6 +2501,7 @@ static void update_arm64ec_ranges( struct file_view *view, IMAGE_NT_HEADERS *nt, if (!arm64ec_view) alloc_arm64ec_map(); commit_arm64ec_map( view ); metadata = (void *)(base + (cfg->CHPEMetadataPointer - nt->OptionalHeader.ImageBase)); + *entry_point = redirect_arm64ec_rva( base, nt->OptionalHeader.AddressOfEntryPoint, metadata ); if (!metadata->CodeMap) return; map = (void *)(base + metadata->CodeMap); @@ -2865,11 +2866,11 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena (!machine && main_image_info.Machine == IMAGE_FILE_MACHINE_AMD64))) { update_arm64x_mapping( view, nt, dir, sections ); - /* reload changed data from NT header */ - image_info->machine = nt->FileHeader.Machine; - image_info->entry_point = nt->OptionalHeader.AddressOfEntryPoint; + /* reload changed machine from NT header */ + image_info->machine = nt->FileHeader.Machine; } - if (image_info->machine == IMAGE_FILE_MACHINE_AMD64) update_arm64ec_ranges( view, nt, dir ); + if (image_info->machine == IMAGE_FILE_MACHINE_AMD64) + update_arm64ec_ranges( view, nt, dir, &image_info->entry_point ); } #endif if (machine && machine != nt->FileHeader.Machine) return STATUS_NOT_SUPPORTED;