server: Store a machine ID instead of a CPU in the context structure.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-04-27 10:40:53 +02:00
parent 94d19eff22
commit 308bd35746
10 changed files with 53 additions and 46 deletions

View File

@ -370,7 +370,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
DWORD i, flags = from->ContextFlags & ~CONTEXT_ARM; /* get rid of CPU id */
memset( to, 0, sizeof(*to) );
to->cpu = CPU_ARM;
to->machine = IMAGE_FILE_MACHINE_ARMNT;
if (flags & CONTEXT_CONTROL)
{
@ -424,7 +424,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
DWORD i;
if (from->cpu != CPU_ARM) return STATUS_INVALID_PARAMETER;
if (from->machine != IMAGE_FILE_MACHINE_ARMNT) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_ARM;
if (from->flags & SERVER_CTX_CONTROL)

View File

@ -444,7 +444,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
DWORD i, flags = from->ContextFlags & ~CONTEXT_ARM64; /* get rid of CPU id */
memset( to, 0, sizeof(*to) );
to->cpu = CPU_ARM64;
to->machine = IMAGE_FILE_MACHINE_ARM64;
if (flags & CONTEXT_CONTROL)
{
@ -492,7 +492,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
DWORD i;
if (from->cpu != CPU_ARM64) return STATUS_INVALID_PARAMETER;
if (from->machine != IMAGE_FILE_MACHINE_ARM64) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_ARM64;
if (from->flags & SERVER_CTX_CONTROL)

View File

@ -1022,7 +1022,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
DWORD flags = from->ContextFlags & ~CONTEXT_i386; /* get rid of CPU id */
memset( to, 0, sizeof(*to) );
to->cpu = CPU_x86;
to->machine = IMAGE_FILE_MACHINE_I386;
if (flags & CONTEXT_CONTROL)
{
@ -1092,7 +1092,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
if (from->cpu != CPU_x86) return STATUS_INVALID_PARAMETER;
if (from->machine != IMAGE_FILE_MACHINE_I386) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_i386 | (to->ContextFlags & 0x40);
if (from->flags & SERVER_CTX_CONTROL)

View File

@ -1642,7 +1642,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
DWORD flags = from->ContextFlags & ~CONTEXT_AMD64; /* get rid of CPU id */
memset( to, 0, sizeof(*to) );
to->cpu = CPU_x86_64;
to->machine = IMAGE_FILE_MACHINE_AMD64;
if (flags & CONTEXT_CONTROL)
{
@ -1707,7 +1707,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
if (from->cpu == CPU_x86)
if (from->machine == IMAGE_FILE_MACHINE_I386)
{
/* convert the WoW64 context */
to->ContextFlags = CONTEXT_AMD64;
@ -1766,7 +1766,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
return STATUS_SUCCESS;
}
if (from->cpu != CPU_x86_64) return STATUS_INVALID_PARAMETER;
if (from->machine != IMAGE_FILE_MACHINE_AMD64) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_AMD64 | (to->ContextFlags & 0x40);
if (from->flags & SERVER_CTX_CONTROL)

View File

@ -666,7 +666,7 @@ static unsigned int wow64_get_server_context_flags( DWORD flags )
*/
static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *from )
{
if (from->cpu != CPU_x86) return STATUS_INVALID_PARAMETER;
if (from->machine != IMAGE_FILE_MACHINE_I386) return STATUS_INVALID_PARAMETER;
to->ContextFlags = WOW64_CONTEXT_i386 | (to->ContextFlags & 0x40);
if (from->flags & SERVER_CTX_CONTROL)
@ -742,7 +742,7 @@ static void wow64_context_to_server( context_t *to, const WOW64_CONTEXT *from )
DWORD flags = from->ContextFlags & ~WOW64_CONTEXT_i386; /* get rid of CPU id */
memset( to, 0, sizeof(*to) );
to->cpu = CPU_x86;
to->machine = IMAGE_FILE_MACHINE_I386;
if (flags & WOW64_CONTEXT_CONTROL)
{

View File

@ -119,7 +119,7 @@ typedef int client_cpu_t;
typedef struct
{
client_cpu_t cpu;
unsigned int machine;
unsigned int flags;
union
{
@ -6219,7 +6219,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 694
#define SERVER_PROTOCOL_VERSION 695
/* ### protocol_version end ### */

View File

@ -135,7 +135,7 @@ typedef int client_cpu_t;
/* context data */
typedef struct
{
client_cpu_t cpu; /* cpu type */
unsigned int machine; /* machine type */
unsigned int flags; /* SERVER_CTX_* flags */
union
{

View File

@ -591,9 +591,9 @@ void get_thread_context( struct thread *thread, context_t *context, unsigned int
goto done;
}
}
switch (context->cpu)
switch (context->machine)
{
case CPU_x86:
case IMAGE_FILE_MACHINE_I386:
context->debug.i386_regs.dr0 = data[0];
context->debug.i386_regs.dr1 = data[1];
context->debug.i386_regs.dr2 = data[2];
@ -601,7 +601,7 @@ void get_thread_context( struct thread *thread, context_t *context, unsigned int
context->debug.i386_regs.dr6 = data[6];
context->debug.i386_regs.dr7 = data[7];
break;
case CPU_x86_64:
case IMAGE_FILE_MACHINE_AMD64:
context->debug.x86_64_regs.dr0 = data[0];
context->debug.x86_64_regs.dr1 = data[1];
context->debug.x86_64_regs.dr2 = data[2];
@ -631,9 +631,9 @@ void set_thread_context( struct thread *thread, const context_t *context, unsign
/* force all breakpoint lengths to 1, workaround for kernel bug 200965 */
ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), 0x11110055 );
switch (context->cpu)
switch (context->machine)
{
case CPU_x86:
case IMAGE_FILE_MACHINE_I386:
/* Linux 2.6.33+ does DR0-DR3 alignment validation, so it has to know LEN bits first */
if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), context->debug.i386_regs.dr7 & 0xffff0000 ) == -1) goto error;
if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(0), context->debug.i386_regs.dr0 ) == -1) goto error;
@ -646,7 +646,7 @@ void set_thread_context( struct thread *thread, const context_t *context, unsign
if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), context->debug.i386_regs.dr7 ) == -1) goto error;
thread->system_regs |= SERVER_CTX_DEBUG_REGISTERS;
break;
case CPU_x86_64:
case IMAGE_FILE_MACHINE_AMD64:
if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), context->debug.x86_64_regs.dr7 & 0xffff0000 ) == -1) goto error;
if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(0), context->debug.x86_64_regs.dr0 ) == -1) goto error;
if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(1), context->debug.x86_64_regs.dr1 ) == -1) goto error;

View File

@ -296,7 +296,7 @@ static struct context *create_thread_context( struct thread *thread )
if (!(context = alloc_object( &context_ops ))) return NULL;
context->status = STATUS_PENDING;
memset( &context->regs, 0, sizeof(context->regs) );
context->regs.cpu = thread->process->cpu;
context->regs.machine = thread->process->machine;
return context;
}
@ -1293,7 +1293,7 @@ void kill_thread( struct thread *thread, int violent_death )
/* copy parts of a context structure */
static void copy_context( context_t *to, const context_t *from, unsigned int flags )
{
assert( to->cpu == from->cpu );
assert( to->machine == from->machine );
if (flags & SERVER_CTX_CONTROL) to->ctl = from->ctl;
if (flags & SERVER_CTX_INTEGER) to->integer = from->integer;
if (flags & SERVER_CTX_SEGMENTS) to->seg = from->seg;
@ -1305,14 +1305,14 @@ static void copy_context( context_t *to, const context_t *from, unsigned int fla
/* return the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
static unsigned int get_context_system_regs( enum cpu_type cpu )
static unsigned int get_context_system_regs( unsigned short machine )
{
switch (cpu)
switch (machine)
{
case CPU_x86: return SERVER_CTX_DEBUG_REGISTERS;
case CPU_x86_64: return SERVER_CTX_DEBUG_REGISTERS;
case CPU_ARM: return SERVER_CTX_DEBUG_REGISTERS;
case CPU_ARM64: return SERVER_CTX_DEBUG_REGISTERS;
case IMAGE_FILE_MACHINE_I386: return SERVER_CTX_DEBUG_REGISTERS;
case IMAGE_FILE_MACHINE_AMD64: return SERVER_CTX_DEBUG_REGISTERS;
case IMAGE_FILE_MACHINE_ARMNT: return SERVER_CTX_DEBUG_REGISTERS;
case IMAGE_FILE_MACHINE_ARM64: return SERVER_CTX_DEBUG_REGISTERS;
}
return 0;
}
@ -1619,7 +1619,8 @@ DECL_HANDLER(select)
if (get_req_data_size() - sizeof(*result) - req->size == sizeof(context_t))
{
const context_t *context = (const context_t *)((const char *)(result + 1) + req->size);
if ((current->context && current->context->status != STATUS_PENDING) || context->cpu != current->process->cpu)
if ((current->context && current->context->status != STATUS_PENDING) ||
context->machine != current->process->machine)
{
set_error( STATUS_INVALID_PARAMETER );
return;
@ -1627,7 +1628,7 @@ DECL_HANDLER(select)
if (!current->context && !(current->context = create_thread_context( current ))) return;
copy_context( &current->context->regs, context,
context->flags & ~(current->context->regs.flags | get_context_system_regs(current->process->cpu)) );
context->flags & ~(current->context->regs.flags | get_context_system_regs(current->process->machine)) );
current->context->status = STATUS_SUCCESS;
current->suspend_cookie = req->cookie;
wake_up( &current->context->obj, 0 );
@ -1701,7 +1702,7 @@ DECL_HANDLER(select)
{
if (current->context->regs.flags)
{
unsigned int system_flags = get_context_system_regs(current->process->cpu) &
unsigned int system_flags = get_context_system_regs(current->process->machine) &
current->context->regs.flags;
if (system_flags) set_thread_context( current, &current->context->regs, system_flags );
set_reply_data( &current->context->regs, sizeof(context_t) );
@ -1841,12 +1842,12 @@ DECL_HANDLER(get_thread_context)
if ((thread_context = (struct context *)get_handle_obj( current->process, req->handle, 0, &context_ops )))
{
close_handle( current->process, req->handle ); /* avoid extra server call */
system_flags = get_context_system_regs( thread_context->regs.cpu );
system_flags = get_context_system_regs( thread_context->regs.machine );
}
else if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
{
clear_error();
system_flags = get_context_system_regs( thread->process->cpu );
system_flags = get_context_system_regs( thread->process->machine );
if (thread->state == RUNNING)
{
reply->self = (thread == current);
@ -1862,7 +1863,7 @@ DECL_HANDLER(get_thread_context)
{
assert( reply->self );
memset( context, 0, sizeof(context_t) );
context->cpu = thread->process->cpu;
context->machine = thread->process->machine;
if (req->flags & system_flags)
{
get_thread_context( thread, context, req->flags & system_flags );
@ -1879,7 +1880,7 @@ DECL_HANDLER(get_thread_context)
if (!thread_context->status && (context = set_reply_data_size( sizeof(context_t) )))
{
memset( context, 0, sizeof(context_t) );
context->cpu = thread_context->regs.cpu;
context->machine = thread_context->regs.machine;
copy_context( context, &thread_context->regs, req->flags );
context->flags = req->flags;
}
@ -1906,9 +1907,9 @@ DECL_HANDLER(set_thread_context)
reply->self = (thread == current);
if (thread->state == TERMINATED) set_error( STATUS_UNSUCCESSFUL );
else if (context->cpu == thread->process->cpu)
else if (context->machine == thread->process->machine)
{
unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
unsigned int system_flags = get_context_system_regs( context->machine ) & context->flags;
if (thread != current) stop_thread( thread );
else if (system_flags) set_thread_context( thread, context, system_flags );
@ -1918,10 +1919,11 @@ DECL_HANDLER(set_thread_context)
thread->context->regs.flags |= context->flags;
}
}
else if (context->cpu == CPU_x86_64 && thread->process->cpu == CPU_x86)
else if (context->machine == IMAGE_FILE_MACHINE_AMD64 &&
thread->process->machine == IMAGE_FILE_MACHINE_I386)
{
/* convert the WoW64 context */
unsigned int system_flags = get_context_system_regs( context->cpu ) & context->flags;
unsigned int system_flags = get_context_system_regs( context->machine ) & context->flags;
if (system_flags)
{
set_thread_context( thread, context, system_flags );

View File

@ -616,11 +616,10 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
memset( &ctx, 0, sizeof(ctx) );
memcpy( &ctx, context, size );
fprintf( stderr,"%s{", prefix );
dump_client_cpu( "cpu=", &ctx.cpu );
switch (ctx.cpu)
switch (ctx.machine)
{
case CPU_x86:
case IMAGE_FILE_MACHINE_I386:
fprintf( stderr, "%s{machine=i386", prefix );
if (ctx.flags & SERVER_CTX_CONTROL)
fprintf( stderr, ",eip=%08x,esp=%08x,ebp=%08x,eflags=%08x,cs=%04x,ss=%04x",
ctx.ctl.i386_regs.eip, ctx.ctl.i386_regs.esp, ctx.ctl.i386_regs.ebp,
@ -658,7 +657,8 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
dump_uints( ",ymm_high=", (const unsigned int *)ctx.ymm.ymm_high_regs.ymm_high,
sizeof(ctx.ymm.ymm_high_regs) / sizeof(int) );
break;
case CPU_x86_64:
case IMAGE_FILE_MACHINE_AMD64:
fprintf( stderr, "%s{machine=x86_64", prefix );
if (ctx.flags & SERVER_CTX_CONTROL)
{
dump_uint64( ",rip=", &ctx.ctl.x86_64_regs.rip );
@ -710,7 +710,8 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
dump_uints( ",ymm_high=", (const unsigned int *)ctx.ymm.ymm_high_regs.ymm_high,
sizeof(ctx.ymm.ymm_high_regs) / sizeof(int) );
break;
case CPU_ARM:
case IMAGE_FILE_MACHINE_ARMNT:
fprintf( stderr, "%s{machine=arm", prefix );
if (ctx.flags & SERVER_CTX_CONTROL)
fprintf( stderr, ",sp=%08x,lr=%08x,pc=%08x,cpsr=%08x",
ctx.ctl.arm_regs.sp, ctx.ctl.arm_regs.lr,
@ -735,7 +736,8 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
fprintf( stderr, ",fpscr=%08x", ctx.fp.arm_regs.fpscr );
}
break;
case CPU_ARM64:
case IMAGE_FILE_MACHINE_ARM64:
fprintf( stderr, "%s{machine=arm64", prefix );
if (ctx.flags & SERVER_CTX_CONTROL)
{
dump_uint64( ",sp=", &ctx.ctl.arm64_regs.sp );
@ -774,6 +776,9 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
fprintf( stderr, ",fpcr=%08x,fpsr=%08x", ctx.fp.arm64_regs.fpcr, ctx.fp.arm64_regs.fpsr );
}
break;
default:
fprintf( stderr, "%s{machine=%04x", prefix, ctx.machine );
break;
}
fputc( '}', stderr );
remove_data( size );