Commit fa47ea74 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Determine the native thread context flags on the client side.

parent eccf9299
...@@ -208,6 +208,18 @@ static unsigned int get_server_context_flags( const void *context, USHORT machin ...@@ -208,6 +208,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 * context_to_server
* *
* Convert a register context to the server format. * Convert a register context to the server format.
...@@ -1691,6 +1703,7 @@ NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USH ...@@ -1691,6 +1703,7 @@ NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USH
SERVER_START_REQ( set_thread_context ) SERVER_START_REQ( set_thread_context )
{ {
req->handle = wine_server_obj_handle( handle ); 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]) ); wine_server_add_data( req, server_contexts, count * sizeof(server_contexts[0]) );
ret = wine_server_call( req ); ret = wine_server_call( req );
*self = reply->self; *self = reply->self;
...@@ -1717,6 +1730,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma ...@@ -1717,6 +1730,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma
req->handle = wine_server_obj_handle( handle ); req->handle = wine_server_obj_handle( handle );
req->flags = flags; req->flags = flags;
req->machine = machine; req->machine = machine;
req->native_flags = flags & get_native_context_flags( native_machine, machine );
wine_server_set_reply( req, server_contexts, sizeof(server_contexts) ); wine_server_set_reply( req, server_contexts, sizeof(server_contexts) );
ret = wine_server_call( req ); ret = wine_server_call( req );
*self = reply->self; *self = reply->self;
...@@ -1734,6 +1748,7 @@ NTSTATUS get_thread_context( HANDLE handle, void *context, BOOL *self, USHORT ma ...@@ -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->context = wine_server_obj_handle( context_handle );
req->flags = flags; req->flags = flags;
req->machine = machine; req->machine = machine;
req->native_flags = flags & get_native_context_flags( native_machine, machine );
wine_server_set_reply( req, server_contexts, sizeof(server_contexts) ); wine_server_set_reply( req, server_contexts, sizeof(server_contexts) );
ret = wine_server_call( req ); ret = wine_server_call( req );
count = wine_server_reply_size( reply ) / sizeof(server_contexts[0]); count = wine_server_reply_size( reply ) / sizeof(server_contexts[0]);
......
...@@ -2531,8 +2531,9 @@ struct get_thread_context_request ...@@ -2531,8 +2531,9 @@ struct get_thread_context_request
obj_handle_t handle; obj_handle_t handle;
obj_handle_t context; obj_handle_t context;
unsigned int flags; unsigned int flags;
unsigned int native_flags;
unsigned short machine; unsigned short machine;
char __pad_26[6]; char __pad_30[2];
}; };
struct get_thread_context_reply struct get_thread_context_reply
{ {
...@@ -2548,7 +2549,9 @@ struct set_thread_context_request ...@@ -2548,7 +2549,9 @@ struct set_thread_context_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t handle;
unsigned int native_flags;
/* VARARG(contexts,contexts); */ /* VARARG(contexts,contexts); */
char __pad_20[4];
}; };
struct set_thread_context_reply struct set_thread_context_reply
{ {
...@@ -6355,7 +6358,7 @@ union generic_reply ...@@ -6355,7 +6358,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 761 #define SERVER_PROTOCOL_VERSION 762
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -1931,6 +1931,7 @@ struct process_info ...@@ -1931,6 +1931,7 @@ struct process_info
obj_handle_t handle; /* thread handle */ obj_handle_t handle; /* thread handle */
obj_handle_t context; /* context handle */ obj_handle_t context; /* context handle */
unsigned int flags; /* context flags */ unsigned int flags; /* context flags */
unsigned int native_flags; /* flags for native context if WoW present */
unsigned short machine; /* context architecture */ unsigned short machine; /* context architecture */
@REPLY @REPLY
int self; /* was it a handle to the current thread? */ int self; /* was it a handle to the current thread? */
...@@ -1942,6 +1943,7 @@ struct process_info ...@@ -1942,6 +1943,7 @@ struct process_info
/* Set the current context of a thread */ /* Set the current context of a thread */
@REQ(set_thread_context) @REQ(set_thread_context)
obj_handle_t handle; /* thread handle */ obj_handle_t handle; /* thread handle */
unsigned int native_flags; /* flags for native context if WoW present */
VARARG(contexts,contexts); /* thread context(s) */ VARARG(contexts,contexts); /* thread context(s) */
@REPLY @REPLY
int self; /* was it a handle to the current thread? */ int self; /* was it a handle to the current thread? */
......
...@@ -1278,13 +1278,15 @@ C_ASSERT( sizeof(struct get_timer_info_reply) == 24 ); ...@@ -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, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, context) == 16 ); 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, 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( 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, self) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, handle) == 12 );
C_ASSERT( sizeof(struct get_thread_context_reply) == 16 ); C_ASSERT( sizeof(struct get_thread_context_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, handle) == 12 ); 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( FIELD_OFFSET(struct set_thread_context_reply, self) == 8 );
C_ASSERT( sizeof(struct set_thread_context_reply) == 16 ); C_ASSERT( sizeof(struct set_thread_context_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_selector_entry_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_selector_entry_request, handle) == 12 );
......
...@@ -127,8 +127,6 @@ struct context ...@@ -127,8 +127,6 @@ struct context
/* flags for registers that always need to be set from the server side */ /* flags for registers that always need to be set from the server side */
static const unsigned int system_flags = SERVER_CTX_DEBUG_REGISTERS; 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 void dump_context( struct object *obj, int verbose );
static int context_signaled( struct object *obj, struct wait_queue_entry *entry ); static int context_signaled( struct object *obj, struct wait_queue_entry *entry );
...@@ -1866,8 +1864,8 @@ DECL_HANDLER(get_thread_context) ...@@ -1866,8 +1864,8 @@ DECL_HANDLER(get_thread_context)
if (req->machine == thread_context->regs[CTX_WOW].machine) if (req->machine == thread_context->regs[CTX_WOW].machine)
{ {
native_flags = req->flags & always_native_flags; native_flags = req->native_flags;
wow_flags = req->flags & ~always_native_flags; wow_flags = req->flags & ~native_flags;
} }
if ((context = set_reply_data_size( (!!native_flags + !!wow_flags) * sizeof(context_t) ))) if ((context = set_reply_data_size( (!!native_flags + !!wow_flags) * sizeof(context_t) )))
{ {
...@@ -1922,7 +1920,7 @@ DECL_HANDLER(set_thread_context) ...@@ -1922,7 +1920,7 @@ DECL_HANDLER(set_thread_context)
unsigned int ctx = CTX_NATIVE; unsigned int ctx = CTX_NATIVE;
const context_t *context = &contexts[CTX_NATIVE]; const context_t *context = &contexts[CTX_NATIVE];
unsigned int flags = system_flags & context->flags; 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 ); if (thread != current) stop_thread( thread );
else if (flags) set_thread_context( thread, context, flags ); else if (flags) set_thread_context( thread, context, flags );
......
...@@ -2509,6 +2509,7 @@ static void dump_get_thread_context_request( const struct get_thread_context_req ...@@ -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, " handle=%04x", req->handle );
fprintf( stderr, ", context=%04x", req->context ); fprintf( stderr, ", context=%04x", req->context );
fprintf( stderr, ", flags=%08x", req->flags ); fprintf( stderr, ", flags=%08x", req->flags );
fprintf( stderr, ", native_flags=%08x", req->native_flags );
fprintf( stderr, ", machine=%04x", req->machine ); fprintf( stderr, ", machine=%04x", req->machine );
} }
...@@ -2522,6 +2523,7 @@ static void dump_get_thread_context_reply( const struct get_thread_context_reply ...@@ -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 ) static void dump_set_thread_context_request( const struct set_thread_context_request *req )
{ {
fprintf( stderr, " handle=%04x", req->handle ); fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", native_flags=%08x", req->native_flags );
dump_varargs_contexts( ", contexts=", cur_size ); dump_varargs_contexts( ", contexts=", cur_size );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment