Module: wine Branch: master Commit: fa47ea740020dd5bffa94b3cd835559393b2f752 URL: https://gitlab.winehq.org/wine/wine/-/commit/fa47ea740020dd5bffa94b3cd835559...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Mar 8 12:24:49 2023 +0100
server: Determine the native thread context flags on the client side.
---
dlls/ntdll/unix/thread.c | 15 +++++++++++++++ include/wine/server_protocol.h | 7 +++++-- server/protocol.def | 2 ++ server/request.h | 6 ++++-- server/thread.c | 8 +++----- server/trace.c | 2 ++ 6 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index d56962e1721..79943ebabc2 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -207,6 +207,18 @@ static unsigned int get_server_context_flags( const void *context, USHORT machin }
+/*********************************************************************** + * get_native_context_flags + * + * Get flags for registers that are set from the native context in WoW mode. + */ +static unsigned int get_native_context_flags( USHORT native_machine, USHORT wow_machine ) +{ + if (native_machine == wow_machine) return 0; + return SERVER_CTX_DEBUG_REGISTERS | SERVER_CTX_FLOATING_POINT | SERVER_CTX_YMM_REGISTERS; +} + + /*********************************************************************** * context_to_server * @@ -1691,6 +1703,7 @@ NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USH SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); + req->native_flags = server_contexts[0].flags & get_native_context_flags( native_machine, machine ); wine_server_add_data( req, server_contexts, count * sizeof(server_contexts[0]) ); ret = wine_server_call( req ); *self = reply->self; @@ -1717,6 +1730,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma req->handle = wine_server_obj_handle( handle ); req->flags = flags; req->machine = machine; + req->native_flags = flags & get_native_context_flags( native_machine, machine ); wine_server_set_reply( req, server_contexts, sizeof(server_contexts) ); ret = wine_server_call( req ); *self = reply->self; @@ -1734,6 +1748,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma req->context = wine_server_obj_handle( context_handle ); req->flags = flags; req->machine = machine; + req->native_flags = flags & get_native_context_flags( native_machine, machine ); wine_server_set_reply( req, server_contexts, sizeof(server_contexts) ); ret = wine_server_call( req ); count = wine_server_reply_size( reply ) / sizeof(server_contexts[0]); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index ffef499df20..f61918271ff 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2531,8 +2531,9 @@ struct get_thread_context_request obj_handle_t handle; obj_handle_t context; unsigned int flags; + unsigned int native_flags; unsigned short machine; - char __pad_26[6]; + char __pad_30[2]; }; struct get_thread_context_reply { @@ -2548,7 +2549,9 @@ struct set_thread_context_request { struct request_header __header; obj_handle_t handle; + unsigned int native_flags; /* VARARG(contexts,contexts); */ + char __pad_20[4]; }; struct set_thread_context_reply { @@ -6355,7 +6358,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 761 +#define SERVER_PROTOCOL_VERSION 762
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index 57957efdae3..c857f72ce68 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1931,6 +1931,7 @@ struct process_info obj_handle_t handle; /* thread handle */ obj_handle_t context; /* context handle */ unsigned int flags; /* context flags */ + unsigned int native_flags; /* flags for native context if WoW present */ unsigned short machine; /* context architecture */ @REPLY int self; /* was it a handle to the current thread? */ @@ -1942,6 +1943,7 @@ struct process_info /* Set the current context of a thread */ @REQ(set_thread_context) obj_handle_t handle; /* thread handle */ + unsigned int native_flags; /* flags for native context if WoW present */ VARARG(contexts,contexts); /* thread context(s) */ @REPLY int self; /* was it a handle to the current thread? */ diff --git a/server/request.h b/server/request.h index 10b877b1deb..b8d4f6a6d5e 100644 --- a/server/request.h +++ b/server/request.h @@ -1278,13 +1278,15 @@ C_ASSERT( sizeof(struct get_timer_info_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, context) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, flags) == 20 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, machine) == 24 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, native_flags) == 24 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, machine) == 28 ); C_ASSERT( sizeof(struct get_thread_context_request) == 32 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 ); C_ASSERT( sizeof(struct get_thread_context_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, handle) == 12 ); -C_ASSERT( sizeof(struct set_thread_context_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, native_flags) == 16 ); +C_ASSERT( sizeof(struct set_thread_context_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct set_thread_context_reply, self) == 8 ); C_ASSERT( sizeof(struct set_thread_context_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_selector_entry_request, handle) == 12 ); diff --git a/server/thread.c b/server/thread.c index 5f8493dd309..c9adccfef66 100644 --- a/server/thread.c +++ b/server/thread.c @@ -127,8 +127,6 @@ struct context
/* flags for registers that always need to be set from the server side */ static const unsigned int system_flags = SERVER_CTX_DEBUG_REGISTERS; -/* flags for registers that are set from the native context even in WoW mode */ -static const unsigned int always_native_flags = SERVER_CTX_DEBUG_REGISTERS | SERVER_CTX_FLOATING_POINT | SERVER_CTX_YMM_REGISTERS;
static void dump_context( struct object *obj, int verbose ); static int context_signaled( struct object *obj, struct wait_queue_entry *entry ); @@ -1866,8 +1864,8 @@ DECL_HANDLER(get_thread_context)
if (req->machine == thread_context->regs[CTX_WOW].machine) { - native_flags = req->flags & always_native_flags; - wow_flags = req->flags & ~always_native_flags; + native_flags = req->native_flags; + wow_flags = req->flags & ~native_flags; } if ((context = set_reply_data_size( (!!native_flags + !!wow_flags) * sizeof(context_t) ))) { @@ -1922,7 +1920,7 @@ DECL_HANDLER(set_thread_context) unsigned int ctx = CTX_NATIVE; const context_t *context = &contexts[CTX_NATIVE]; unsigned int flags = system_flags & context->flags; - unsigned int native_flags = always_native_flags & context->flags; + unsigned int native_flags = context->flags & req->native_flags;
if (thread != current) stop_thread( thread ); else if (flags) set_thread_context( thread, context, flags ); diff --git a/server/trace.c b/server/trace.c index 91bc3ae7af9..fb006f605b5 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2509,6 +2509,7 @@ static void dump_get_thread_context_request( const struct get_thread_context_req fprintf( stderr, " handle=%04x", req->handle ); fprintf( stderr, ", context=%04x", req->context ); fprintf( stderr, ", flags=%08x", req->flags ); + fprintf( stderr, ", native_flags=%08x", req->native_flags ); fprintf( stderr, ", machine=%04x", req->machine ); }
@@ -2522,6 +2523,7 @@ static void dump_get_thread_context_reply( const struct get_thread_context_reply static void dump_set_thread_context_request( const struct set_thread_context_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); + fprintf( stderr, ", native_flags=%08x", req->native_flags ); dump_varargs_contexts( ", contexts=", cur_size ); }