From e05c6c821104d45344fc532a15f96360a24a0174 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 8 Feb 2024 13:10:44 +0100 Subject: [PATCH] server: Don't update the entry point in the image information for ARM64EC modules. --- dlls/ntdll/tests/wow64.c | 39 +++++++++++++++++++++++++++++----- dlls/ntdll/unix/server.c | 5 ++--- include/wine/server_protocol.h | 5 ++--- server/debugger.c | 2 +- server/mapping.c | 8 +++++-- server/process.c | 13 +----------- server/protocol.def | 1 - server/request.h | 5 ++--- server/trace.c | 4 +--- 9 files changed, 49 insertions(+), 33 deletions(-) diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c index ce8ea70c5f9..941b127a2f6 100644 --- a/dlls/ntdll/tests/wow64.c +++ b/dlls/ntdll/tests/wow64.c @@ -174,6 +174,7 @@ static BOOL create_process_machine( char *cmdline, DWORD flags, USHORT machine, ret = CreateProcessA( NULL, cmdline, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT | flags, NULL, NULL, &si.StartupInfo, pi ); DeleteProcThreadAttributeList( list ); + free( list ); return ret; } @@ -226,7 +227,8 @@ static void test_process_architecture( HANDLE process, USHORT expect_machine, US } } -static void test_process_machine( HANDLE process, USHORT expect_machine, USHORT expect_image ) +static void test_process_machine( HANDLE process, HANDLE thread, + USHORT expect_machine, USHORT expect_image ) { PROCESS_BASIC_INFORMATION basic; SECTION_IMAGE_INFORMATION image; @@ -236,6 +238,8 @@ static void test_process_machine( HANDLE process, USHORT expect_machine, USHORT ULONG len; SIZE_T size; NTSTATUS status; + void *entry_point = NULL; + void *win32_entry = NULL; status = NtQueryInformationProcess( process, ProcessBasicInformation, &basic, sizeof(basic), &len ); ok( !status, "ProcessBasicInformation failed %lx\n", status ); @@ -245,11 +249,35 @@ static void test_process_machine( HANDLE process, USHORT expect_machine, USHORT { ok( nt.FileHeader.Machine == expect_machine, "wrong nt machine %x / %x\n", nt.FileHeader.Machine, expect_machine ); + entry_point = (char *)peb.ImageBaseAddress + nt.OptionalHeader.AddressOfEntryPoint; } status = NtQueryInformationProcess( process, ProcessImageInformation, &image, sizeof(image), &len ); ok( !status, "ProcessImageInformation failed %lx\n", status ); ok( image.Machine == expect_image, "wrong image info %x / %x\n", image.Machine, expect_image ); + + status = NtQueryInformationThread( thread, ThreadQuerySetWin32StartAddress, + &win32_entry, sizeof(win32_entry), &len ); + ok( !status, "ThreadQuerySetWin32StartAddress failed %lx\n", status ); + + if (!entry_point) return; + + if (image.Machine == expect_machine) + { + ok( image.TransferAddress == entry_point, "wrong entry %p / %p\n", + image.TransferAddress, entry_point ); + ok( win32_entry == entry_point, "wrong win32 entry %p / %p\n", + win32_entry, entry_point ); + } + else + { + /* image.TransferAddress is the ARM64 entry, entry_point is the x86-64 one, + 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 ); + } } static void test_query_architectures(void) @@ -302,7 +330,7 @@ static void test_query_architectures(void) winetest_push_context( "current" ); test_process_architecture( GetCurrentProcess(), is_win64 ? native_machine : current_machine, native_machine ); - test_process_machine( GetCurrentProcess(), current_machine, + test_process_machine( GetCurrentProcess(), GetCurrentThread(), current_machine, is_arm64ec ? native_machine : current_machine ); winetest_pop_context(); @@ -315,7 +343,8 @@ static void test_query_architectures(void) { winetest_push_context( "system32" ); test_process_architecture( pi.hProcess, native_machine, native_machine ); - test_process_machine( pi.hProcess, is_win64 ? current_machine : native_machine, native_machine ); + test_process_machine( pi.hProcess, pi.hThread, + is_win64 ? current_machine : native_machine, native_machine ); TerminateProcess( pi.hProcess, 0 ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); @@ -326,7 +355,7 @@ static void test_query_architectures(void) { winetest_push_context( "syswow64" ); test_process_architecture( pi.hProcess, IMAGE_FILE_MACHINE_I386, native_machine ); - test_process_machine( pi.hProcess, IMAGE_FILE_MACHINE_I386, IMAGE_FILE_MACHINE_I386 ); + test_process_machine( pi.hProcess, pi.hThread, IMAGE_FILE_MACHINE_I386, IMAGE_FILE_MACHINE_I386 ); TerminateProcess( pi.hProcess, 0 ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); @@ -340,7 +369,7 @@ static void test_query_architectures(void) { winetest_push_context( "%04x", machine ); test_process_architecture( pi.hProcess, native_machine, native_machine ); - test_process_machine( pi.hProcess, machine, native_machine ); + test_process_machine( pi.hProcess, pi.hThread, machine, native_machine ); TerminateProcess( pi.hProcess, 0 ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 69e6567c911..88ac9551060 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1673,7 +1673,7 @@ size_t server_init_process(void) */ void server_init_process_done(void) { - void *entry, *teb; + void *teb; unsigned int status; int suspend; FILE_FS_DEVICE_INFORMATION info; @@ -1704,12 +1704,11 @@ void server_init_process_done(void) #endif status = wine_server_call( req ); suspend = reply->suspend; - entry = wine_server_get_ptr( reply->entry ); } SERVER_END_REQ; assert( !status ); - signal_start_thread( entry, peb, suspend, NtCurrentTeb() ); + signal_start_thread( main_image_info.TransferAddress, peb, suspend, NtCurrentTeb() ); } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 139a7bca69e..0286ee7056e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -974,9 +974,8 @@ struct init_process_done_request struct init_process_done_reply { struct reply_header __header; - client_ptr_t entry; int suspend; - char __pad_20[4]; + char __pad_12[4]; }; @@ -6507,7 +6506,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 786 +#define SERVER_PROTOCOL_VERSION 787 /* ### protocol_version end ### */ diff --git a/server/debugger.c b/server/debugger.c index 48adb244b09..c59a0abea77 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -159,7 +159,7 @@ static void fill_create_process_event( struct debug_event *event, const void *ar const struct memory_view *view = arg; const pe_image_info_t *image_info = get_view_image_info( view, &event->data.create_process.base ); - event->data.create_process.start = event->data.create_process.base + image_info->entry_point; + event->data.create_process.start = event->sender->entry_point; event->data.create_process.dbg_offset = image_info->dbg_offset; event->data.create_process.dbg_size = image_info->dbg_size; /* the doc says write access too, but this doesn't seem a good idea */ diff --git a/server/mapping.c b/server/mapping.c index 69d8f71e23b..13604455729 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -1393,9 +1393,9 @@ DECL_HANDLER(map_image_view) view->committed = NULL; view->shared = mapping->shared ? (struct shared_map *)grab_object( mapping->shared ) : NULL; view->image = mapping->image; - view->image.entry_point = req->entry; if (add_process_view( current, view )) { + current->entry_point = view->base + req->entry; current->process->machine = (view->image.image_flags & IMAGE_FLAGS_ComPlusNativeReady) ? native_machine : req->machine; } @@ -1438,7 +1438,11 @@ DECL_HANDLER(map_builtin_view) view->image = *image; view->namelen = namelen; memcpy( view->name, image + 1, namelen ); - if (add_process_view( current, view )) current->process->machine = image->machine; + if (add_process_view( current, view )) + { + current->entry_point = view->base + image->entry_point; + current->process->machine = image->machine; + } } } diff --git a/server/process.c b/server/process.c index 39076351cea..3651696f505 100644 --- a/server/process.c +++ b/server/process.c @@ -1414,37 +1414,26 @@ DECL_HANDLER(get_startup_info) DECL_HANDLER(init_process_done) { struct process *process = current->process; - struct memory_view *view; - client_ptr_t base; - const pe_image_info_t *image_info; if (is_process_init_done(process)) { set_error( STATUS_INVALID_PARAMETER ); return; } - if (!(view = get_exe_view( process ))) - { - set_error( STATUS_DLL_NOT_FOUND ); - return; - } - if (!(image_info = get_view_image_info( view, &base ))) return; current->teb = req->teb; process->peb = req->peb; process->ldt_copy = req->ldt_copy; process->start_time = current_time; - current->entry_point = base + image_info->entry_point; init_process_tracing( process ); generate_startup_debug_events( process ); set_process_startup_state( process, STARTUP_DONE ); - if (image_info->subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI) + if (process->image_info.subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL ); if (process->debug_obj) set_process_debug_flag( process, 1 ); - reply->entry = current->entry_point; reply->suspend = (current->suspend || process->suspend); } diff --git a/server/protocol.def b/server/protocol.def index 5d60e7fcda3..ee4648350db 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -958,7 +958,6 @@ typedef struct client_ptr_t peb; /* PEB of new process (in process address space) */ client_ptr_t ldt_copy; /* address of LDT copy (in process address space) */ @REPLY - client_ptr_t entry; /* process entry point */ int suspend; /* is process suspended? */ @END diff --git a/server/request.h b/server/request.h index 89d5a621b16..79a76f02392 100644 --- a/server/request.h +++ b/server/request.h @@ -778,9 +778,8 @@ C_ASSERT( FIELD_OFFSET(struct init_process_done_request, teb) == 16 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, peb) == 24 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, ldt_copy) == 32 ); C_ASSERT( sizeof(struct init_process_done_request) == 40 ); -C_ASSERT( FIELD_OFFSET(struct init_process_done_reply, entry) == 8 ); -C_ASSERT( FIELD_OFFSET(struct init_process_done_reply, suspend) == 16 ); -C_ASSERT( sizeof(struct init_process_done_reply) == 24 ); +C_ASSERT( FIELD_OFFSET(struct init_process_done_reply, suspend) == 8 ); +C_ASSERT( sizeof(struct init_process_done_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct init_first_thread_request, unix_pid) == 12 ); C_ASSERT( FIELD_OFFSET(struct init_first_thread_request, unix_tid) == 16 ); C_ASSERT( FIELD_OFFSET(struct init_first_thread_request, debug_level) == 20 ); diff --git a/server/trace.c b/server/trace.c index 1b65d2b977e..a29041031df 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1461,8 +1461,7 @@ static void dump_init_process_done_request( const struct init_process_done_reque static void dump_init_process_done_reply( const struct init_process_done_reply *req ) { - dump_uint64( " entry=", &req->entry ); - fprintf( stderr, ", suspend=%d", req->suspend ); + fprintf( stderr, " suspend=%d", req->suspend ); } static void dump_init_first_thread_request( const struct init_first_thread_request *req ) @@ -5495,7 +5494,6 @@ static const struct { "DEVICE_NOT_READY", STATUS_DEVICE_NOT_READY }, { "DIRECTORY_NOT_EMPTY", STATUS_DIRECTORY_NOT_EMPTY }, { "DISK_FULL", STATUS_DISK_FULL }, - { "DLL_NOT_FOUND", STATUS_DLL_NOT_FOUND }, { "ERROR_CLASS_ALREADY_EXISTS", 0xc0010000 | ERROR_CLASS_ALREADY_EXISTS }, { "ERROR_CLASS_DOES_NOT_EXIST", 0xc0010000 | ERROR_CLASS_DOES_NOT_EXIST }, { "ERROR_CLASS_HAS_WINDOWS", 0xc0010000 | ERROR_CLASS_HAS_WINDOWS },