Commit c0319e0e authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move server wait functions to the Unix library.

parent b925dd78
......@@ -232,7 +232,7 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
time.QuadPart = timeout * (LONGLONG)-10000000;
select_op.wait.op = SELECT_WAIT;
select_op.wait.handles[0] = wine_server_obj_handle( sem );
ret = server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
ret = unix_funcs->server_wait( &select_op, offsetof( select_op_t, wait.handles[1] ), 0, &time );
}
return ret;
}
......
......@@ -114,7 +114,7 @@ void wait_suspend( CONTEXT *context )
int saved_errno = errno;
/* wait with 0 timeout, will only return once the thread is no longer suspended */
server_select( NULL, 0, SELECT_INTERRUPTIBLE, 0, context, NULL, NULL );
unix_funcs->server_select( NULL, 0, SELECT_INTERRUPTIBLE, 0, context, NULL, NULL );
errno = saved_errno;
}
......@@ -159,7 +159,7 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *con
{
select_op.wait.op = SELECT_WAIT;
select_op.wait.handles[0] = handle;
server_select( &select_op, offsetof( select_op_t, wait.handles[1] ), SELECT_INTERRUPTIBLE, TIMEOUT_INFINITE, &exception_context, NULL, NULL );
unix_funcs->server_select( &select_op, offsetof( select_op_t, wait.handles[1] ), SELECT_INTERRUPTIBLE, TIMEOUT_INFINITE, &exception_context, NULL, NULL );
SERVER_START_REQ( get_exception_status )
{
......
......@@ -1797,7 +1797,7 @@ NTSTATUS WINAPI DbgUiIssueRemoteBreakin( HANDLE process )
memset( &call, 0, sizeof(call) );
call.type = APC_BREAK_PROCESS;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status) return status;
return result.break_process.status;
}
......@@ -1101,7 +1101,7 @@ static NTSTATUS wait_objects( DWORD count, const HANDLE *handles,
if (alertable) flags |= SELECT_ALERTABLE;
select_op.wait.op = wait_any ? SELECT_WAIT : SELECT_WAIT_ALL;
for (i = 0; i < count; i++) select_op.wait.handles[i] = wine_server_obj_handle( handles[i] );
return server_wait( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout );
return unix_funcs->server_wait( &select_op, offsetof( select_op_t, wait.handles[count] ), flags, timeout );
}
......@@ -1140,7 +1140,7 @@ NTSTATUS WINAPI NtSignalAndWaitForSingleObject( HANDLE hSignalObject, HANDLE hWa
select_op.signal_and_wait.op = SELECT_SIGNAL_AND_WAIT;
select_op.signal_and_wait.wait = wine_server_obj_handle( hWaitObject );
select_op.signal_and_wait.signal = wine_server_obj_handle( hSignalObject );
return server_wait( &select_op, sizeof(select_op.signal_and_wait), flags, timeout );
return unix_funcs->server_wait( &select_op, sizeof(select_op.signal_and_wait), flags, timeout );
}
......@@ -1165,7 +1165,7 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
{
/* if alertable, we need to query the server */
if (alertable)
return server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, timeout );
return unix_funcs->server_wait( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, timeout );
if (!timeout || timeout->QuadPart == TIMEOUT_INFINITE) /* sleep forever */
{
......@@ -1264,7 +1264,7 @@ NTSTATUS WINAPI NtWaitForKeyedEvent( HANDLE handle, const void *key,
select_op.keyed_event.op = SELECT_KEYED_EVENT_WAIT;
select_op.keyed_event.handle = wine_server_obj_handle( handle );
select_op.keyed_event.key = wine_server_client_ptr( key );
return server_wait( &select_op, sizeof(select_op.keyed_event), flags, timeout );
return unix_funcs->server_wait( &select_op, sizeof(select_op.keyed_event), flags, timeout );
}
/******************************************************************************
......@@ -1282,7 +1282,7 @@ NTSTATUS WINAPI NtReleaseKeyedEvent( HANDLE handle, const void *key,
select_op.keyed_event.op = SELECT_KEYED_EVENT_RELEASE;
select_op.keyed_event.handle = wine_server_obj_handle( handle );
select_op.keyed_event.key = wine_server_client_ptr( key );
return server_wait( &select_op, sizeof(select_op.keyed_event), flags, timeout );
return unix_funcs->server_wait( &select_op, sizeof(select_op.keyed_event), flags, timeout );
}
/******************************************************************
......@@ -2579,7 +2579,7 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
select_op.keyed_event.handle = wine_server_obj_handle( keyed_event );
select_op.keyed_event.key = wine_server_client_ptr( addr );
return server_select( &select_op, sizeof(select_op.keyed_event), SELECT_INTERRUPTIBLE, abs_timeout, NULL, &addr_section, NULL );
return unix_funcs->server_select( &select_op, sizeof(select_op.keyed_event), SELECT_INTERRUPTIBLE, abs_timeout, NULL, &addr_section, NULL );
}
/***********************************************************************
......
......@@ -413,7 +413,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
call.create_thread.reserve = stack_reserve;
call.create_thread.commit = stack_commit;
call.create_thread.suspend = suspended;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.create_thread.status == STATUS_SUCCESS)
......
......@@ -1010,6 +1010,9 @@ static struct unix_funcs unix_funcs =
get_thread_ldt_entry,
server_call_unlocked,
wine_server_call,
server_select,
server_wait,
server_queue_process_apc,
server_send_fd,
server_get_unix_fd,
server_fd_to_handle,
......
......@@ -69,6 +69,116 @@
static pthread_key_t teb_key;
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
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;
if (flags & CONTEXT_CONTROL)
{
to->flags |= SERVER_CTX_CONTROL;
to->ctl.arm_regs.sp = from->Sp;
to->ctl.arm_regs.lr = from->Lr;
to->ctl.arm_regs.pc = from->Pc;
to->ctl.arm_regs.cpsr = from->Cpsr;
}
if (flags & CONTEXT_INTEGER)
{
to->flags |= SERVER_CTX_INTEGER;
to->integer.arm_regs.r[0] = from->R0;
to->integer.arm_regs.r[1] = from->R1;
to->integer.arm_regs.r[2] = from->R2;
to->integer.arm_regs.r[3] = from->R3;
to->integer.arm_regs.r[4] = from->R4;
to->integer.arm_regs.r[5] = from->R5;
to->integer.arm_regs.r[6] = from->R6;
to->integer.arm_regs.r[7] = from->R7;
to->integer.arm_regs.r[8] = from->R8;
to->integer.arm_regs.r[9] = from->R9;
to->integer.arm_regs.r[10] = from->R10;
to->integer.arm_regs.r[11] = from->R11;
to->integer.arm_regs.r[12] = from->R12;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->flags |= SERVER_CTX_FLOATING_POINT;
for (i = 0; i < 32; i++) to->fp.arm_regs.d[i] = from->u.D[i];
to->fp.arm_regs.fpscr = from->Fpscr;
}
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->flags |= SERVER_CTX_DEBUG_REGISTERS;
for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->debug.arm_regs.bvr[i] = from->Bvr[i];
for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->debug.arm_regs.bcr[i] = from->Bcr[i];
for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->debug.arm_regs.wvr[i] = from->Wvr[i];
for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->debug.arm_regs.wcr[i] = from->Wcr[i];
}
return STATUS_SUCCESS;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
DWORD i;
if (from->cpu != CPU_ARM) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_ARM;
if (from->flags & SERVER_CTX_CONTROL)
{
to->ContextFlags |= CONTEXT_CONTROL;
to->Sp = from->ctl.arm_regs.sp;
to->Lr = from->ctl.arm_regs.lr;
to->Pc = from->ctl.arm_regs.pc;
to->Cpsr = from->ctl.arm_regs.cpsr;
}
if (from->flags & SERVER_CTX_INTEGER)
{
to->ContextFlags |= CONTEXT_INTEGER;
to->R0 = from->integer.arm_regs.r[0];
to->R1 = from->integer.arm_regs.r[1];
to->R2 = from->integer.arm_regs.r[2];
to->R3 = from->integer.arm_regs.r[3];
to->R4 = from->integer.arm_regs.r[4];
to->R5 = from->integer.arm_regs.r[5];
to->R6 = from->integer.arm_regs.r[6];
to->R7 = from->integer.arm_regs.r[7];
to->R8 = from->integer.arm_regs.r[8];
to->R9 = from->integer.arm_regs.r[9];
to->R10 = from->integer.arm_regs.r[10];
to->R11 = from->integer.arm_regs.r[11];
to->R12 = from->integer.arm_regs.r[12];
}
if (from->flags & SERVER_CTX_FLOATING_POINT)
{
to->ContextFlags |= CONTEXT_FLOATING_POINT;
for (i = 0; i < 32; i++) to->u.D[i] = from->fp.arm_regs.d[i];
to->Fpscr = from->fp.arm_regs.fpscr;
}
if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
{
to->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->Bvr[i] = from->debug.arm_regs.bvr[i];
for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->Bcr[i] = from->debug.arm_regs.bcr[i];
for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->Wvr[i] = from->debug.arm_regs.wvr[i];
for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->Wcr[i] = from->debug.arm_regs.wcr[i];
}
return STATUS_SUCCESS;
}
/**********************************************************************
* get_thread_ldt_entry
*/
......
......@@ -74,6 +74,104 @@ static pthread_key_t teb_key;
static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
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;
if (flags & CONTEXT_CONTROL)
{
to->flags |= SERVER_CTX_CONTROL;
to->integer.arm64_regs.x[29] = from->u.s.Fp;
to->integer.arm64_regs.x[30] = from->u.s.Lr;
to->ctl.arm64_regs.sp = from->Sp;
to->ctl.arm64_regs.pc = from->Pc;
to->ctl.arm64_regs.pstate = from->Cpsr;
}
if (flags & CONTEXT_INTEGER)
{
to->flags |= SERVER_CTX_INTEGER;
for (i = 0; i <= 28; i++) to->integer.arm64_regs.x[i] = from->u.X[i];
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->flags |= SERVER_CTX_FLOATING_POINT;
for (i = 0; i < 32; i++)
{
to->fp.arm64_regs.q[i].low = from->V[i].s.Low;
to->fp.arm64_regs.q[i].high = from->V[i].s.High;
}
to->fp.arm64_regs.fpcr = from->Fpcr;
to->fp.arm64_regs.fpsr = from->Fpsr;
}
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->flags |= SERVER_CTX_DEBUG_REGISTERS;
for (i = 0; i < ARM64_MAX_BREAKPOINTS; i++) to->debug.arm64_regs.bcr[i] = from->Bcr[i];
for (i = 0; i < ARM64_MAX_BREAKPOINTS; i++) to->debug.arm64_regs.bvr[i] = from->Bvr[i];
for (i = 0; i < ARM64_MAX_WATCHPOINTS; i++) to->debug.arm64_regs.wcr[i] = from->Wcr[i];
for (i = 0; i < ARM64_MAX_WATCHPOINTS; i++) to->debug.arm64_regs.wvr[i] = from->Wvr[i];
}
return STATUS_SUCCESS;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
DWORD i;
if (from->cpu != CPU_ARM64) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_ARM64;
if (from->flags & SERVER_CTX_CONTROL)
{
to->ContextFlags |= CONTEXT_CONTROL;
to->u.s.Fp = from->integer.arm64_regs.x[29];
to->u.s.Lr = from->integer.arm64_regs.x[30];
to->Sp = from->ctl.arm64_regs.sp;
to->Pc = from->ctl.arm64_regs.pc;
to->Cpsr = from->ctl.arm64_regs.pstate;
}
if (from->flags & SERVER_CTX_INTEGER)
{
to->ContextFlags |= CONTEXT_INTEGER;
for (i = 0; i <= 28; i++) to->u.X[i] = from->integer.arm64_regs.x[i];
}
if (from->flags & SERVER_CTX_FLOATING_POINT)
{
to->ContextFlags |= CONTEXT_FLOATING_POINT;
for (i = 0; i < 32; i++)
{
to->V[i].s.Low = from->fp.arm64_regs.q[i].low;
to->V[i].s.High = from->fp.arm64_regs.q[i].high;
}
to->Fpcr = from->fp.arm64_regs.fpcr;
to->Fpsr = from->fp.arm64_regs.fpsr;
}
if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
{
to->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
for (i = 0; i < ARM64_MAX_BREAKPOINTS; i++) to->Bcr[i] = from->debug.arm64_regs.bcr[i];
for (i = 0; i < ARM64_MAX_BREAKPOINTS; i++) to->Bvr[i] = from->debug.arm64_regs.bvr[i];
for (i = 0; i < ARM64_MAX_WATCHPOINTS; i++) to->Wcr[i] = from->debug.arm64_regs.wcr[i];
for (i = 0; i < ARM64_MAX_WATCHPOINTS; i++) to->Wvr[i] = from->debug.arm64_regs.wvr[i];
}
return STATUS_SUCCESS;
}
/**********************************************************************
* get_thread_ldt_entry
*/
......
......@@ -169,6 +169,148 @@ static inline int is_gdt_sel( WORD sel )
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
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;
if (flags & CONTEXT_CONTROL)
{
to->flags |= SERVER_CTX_CONTROL;
to->ctl.i386_regs.ebp = from->Ebp;
to->ctl.i386_regs.esp = from->Esp;
to->ctl.i386_regs.eip = from->Eip;
to->ctl.i386_regs.cs = from->SegCs;
to->ctl.i386_regs.ss = from->SegSs;
to->ctl.i386_regs.eflags = from->EFlags;
}
if (flags & CONTEXT_INTEGER)
{
to->flags |= SERVER_CTX_INTEGER;
to->integer.i386_regs.eax = from->Eax;
to->integer.i386_regs.ebx = from->Ebx;
to->integer.i386_regs.ecx = from->Ecx;
to->integer.i386_regs.edx = from->Edx;
to->integer.i386_regs.esi = from->Esi;
to->integer.i386_regs.edi = from->Edi;
}
if (flags & CONTEXT_SEGMENTS)
{
to->flags |= SERVER_CTX_SEGMENTS;
to->seg.i386_regs.ds = from->SegDs;
to->seg.i386_regs.es = from->SegEs;
to->seg.i386_regs.fs = from->SegFs;
to->seg.i386_regs.gs = from->SegGs;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->flags |= SERVER_CTX_FLOATING_POINT;
to->fp.i386_regs.ctrl = from->FloatSave.ControlWord;
to->fp.i386_regs.status = from->FloatSave.StatusWord;
to->fp.i386_regs.tag = from->FloatSave.TagWord;
to->fp.i386_regs.err_off = from->FloatSave.ErrorOffset;
to->fp.i386_regs.err_sel = from->FloatSave.ErrorSelector;
to->fp.i386_regs.data_off = from->FloatSave.DataOffset;
to->fp.i386_regs.data_sel = from->FloatSave.DataSelector;
to->fp.i386_regs.cr0npx = from->FloatSave.Cr0NpxState;
memcpy( to->fp.i386_regs.regs, from->FloatSave.RegisterArea, sizeof(to->fp.i386_regs.regs) );
}
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->flags |= SERVER_CTX_DEBUG_REGISTERS;
to->debug.i386_regs.dr0 = from->Dr0;
to->debug.i386_regs.dr1 = from->Dr1;
to->debug.i386_regs.dr2 = from->Dr2;
to->debug.i386_regs.dr3 = from->Dr3;
to->debug.i386_regs.dr6 = from->Dr6;
to->debug.i386_regs.dr7 = from->Dr7;
}
if (flags & CONTEXT_EXTENDED_REGISTERS)
{
to->flags |= SERVER_CTX_EXTENDED_REGISTERS;
memcpy( to->ext.i386_regs, from->ExtendedRegisters, sizeof(to->ext.i386_regs) );
}
return STATUS_SUCCESS;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
if (from->cpu != CPU_x86) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_i386;
if (from->flags & SERVER_CTX_CONTROL)
{
to->ContextFlags |= CONTEXT_CONTROL;
to->Ebp = from->ctl.i386_regs.ebp;
to->Esp = from->ctl.i386_regs.esp;
to->Eip = from->ctl.i386_regs.eip;
to->SegCs = from->ctl.i386_regs.cs;
to->SegSs = from->ctl.i386_regs.ss;
to->EFlags = from->ctl.i386_regs.eflags;
}
if (from->flags & SERVER_CTX_INTEGER)
{
to->ContextFlags |= CONTEXT_INTEGER;
to->Eax = from->integer.i386_regs.eax;
to->Ebx = from->integer.i386_regs.ebx;
to->Ecx = from->integer.i386_regs.ecx;
to->Edx = from->integer.i386_regs.edx;
to->Esi = from->integer.i386_regs.esi;
to->Edi = from->integer.i386_regs.edi;
}
if (from->flags & SERVER_CTX_SEGMENTS)
{
to->ContextFlags |= CONTEXT_SEGMENTS;
to->SegDs = from->seg.i386_regs.ds;
to->SegEs = from->seg.i386_regs.es;
to->SegFs = from->seg.i386_regs.fs;
to->SegGs = from->seg.i386_regs.gs;
}
if (from->flags & SERVER_CTX_FLOATING_POINT)
{
to->ContextFlags |= CONTEXT_FLOATING_POINT;
to->FloatSave.ControlWord = from->fp.i386_regs.ctrl;
to->FloatSave.StatusWord = from->fp.i386_regs.status;
to->FloatSave.TagWord = from->fp.i386_regs.tag;
to->FloatSave.ErrorOffset = from->fp.i386_regs.err_off;
to->FloatSave.ErrorSelector = from->fp.i386_regs.err_sel;
to->FloatSave.DataOffset = from->fp.i386_regs.data_off;
to->FloatSave.DataSelector = from->fp.i386_regs.data_sel;
to->FloatSave.Cr0NpxState = from->fp.i386_regs.cr0npx;
memcpy( to->FloatSave.RegisterArea, from->fp.i386_regs.regs, sizeof(to->FloatSave.RegisterArea) );
}
if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
{
to->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
to->Dr0 = from->debug.i386_regs.dr0;
to->Dr1 = from->debug.i386_regs.dr1;
to->Dr2 = from->debug.i386_regs.dr2;
to->Dr3 = from->debug.i386_regs.dr3;
to->Dr6 = from->debug.i386_regs.dr6;
to->Dr7 = from->debug.i386_regs.dr7;
}
if (from->flags & SERVER_CTX_EXTENDED_REGISTERS)
{
to->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
memcpy( to->ExtendedRegisters, from->ext.i386_regs, sizeof(to->ExtendedRegisters) );
}
return STATUS_SUCCESS;
}
/***********************************************************************
* LDT support
*/
......
......@@ -66,6 +66,208 @@
static pthread_key_t teb_key;
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
{
DWORD flags = from->ContextFlags; /* no CPU id? */
memset( to, 0, sizeof(*to) );
to->cpu = CPU_POWERPC;
if (flags & CONTEXT_CONTROL)
{
to->flags |= SERVER_CTX_CONTROL;
to->ctl.powerpc_regs.iar = from->Iar;
to->ctl.powerpc_regs.msr = from->Msr;
to->ctl.powerpc_regs.ctr = from->Ctr;
to->ctl.powerpc_regs.lr = from->Lr;
to->ctl.powerpc_regs.dar = from->Dar;
to->ctl.powerpc_regs.dsisr = from->Dsisr;
to->ctl.powerpc_regs.trap = from->Trap;
}
if (flags & CONTEXT_INTEGER)
{
to->flags |= SERVER_CTX_INTEGER;
to->integer.powerpc_regs.gpr[0] = from->Gpr0;
to->integer.powerpc_regs.gpr[1] = from->Gpr1;
to->integer.powerpc_regs.gpr[2] = from->Gpr2;
to->integer.powerpc_regs.gpr[3] = from->Gpr3;
to->integer.powerpc_regs.gpr[4] = from->Gpr4;
to->integer.powerpc_regs.gpr[5] = from->Gpr5;
to->integer.powerpc_regs.gpr[6] = from->Gpr6;
to->integer.powerpc_regs.gpr[7] = from->Gpr7;
to->integer.powerpc_regs.gpr[8] = from->Gpr8;
to->integer.powerpc_regs.gpr[9] = from->Gpr9;
to->integer.powerpc_regs.gpr[10] = from->Gpr10;
to->integer.powerpc_regs.gpr[11] = from->Gpr11;
to->integer.powerpc_regs.gpr[12] = from->Gpr12;
to->integer.powerpc_regs.gpr[13] = from->Gpr13;
to->integer.powerpc_regs.gpr[14] = from->Gpr14;
to->integer.powerpc_regs.gpr[15] = from->Gpr15;
to->integer.powerpc_regs.gpr[16] = from->Gpr16;
to->integer.powerpc_regs.gpr[17] = from->Gpr17;
to->integer.powerpc_regs.gpr[18] = from->Gpr18;
to->integer.powerpc_regs.gpr[19] = from->Gpr19;
to->integer.powerpc_regs.gpr[20] = from->Gpr20;
to->integer.powerpc_regs.gpr[21] = from->Gpr21;
to->integer.powerpc_regs.gpr[22] = from->Gpr22;
to->integer.powerpc_regs.gpr[23] = from->Gpr23;
to->integer.powerpc_regs.gpr[24] = from->Gpr24;
to->integer.powerpc_regs.gpr[25] = from->Gpr25;
to->integer.powerpc_regs.gpr[26] = from->Gpr26;
to->integer.powerpc_regs.gpr[27] = from->Gpr27;
to->integer.powerpc_regs.gpr[28] = from->Gpr28;
to->integer.powerpc_regs.gpr[29] = from->Gpr29;
to->integer.powerpc_regs.gpr[30] = from->Gpr30;
to->integer.powerpc_regs.gpr[31] = from->Gpr31;
to->integer.powerpc_regs.xer = from->Xer;
to->integer.powerpc_regs.cr = from->Cr;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->flags |= SERVER_CTX_FLOATING_POINT;
to->fp.powerpc_regs.fpr[0] = from->Fpr0;
to->fp.powerpc_regs.fpr[1] = from->Fpr1;
to->fp.powerpc_regs.fpr[2] = from->Fpr2;
to->fp.powerpc_regs.fpr[3] = from->Fpr3;
to->fp.powerpc_regs.fpr[4] = from->Fpr4;
to->fp.powerpc_regs.fpr[5] = from->Fpr5;
to->fp.powerpc_regs.fpr[6] = from->Fpr6;
to->fp.powerpc_regs.fpr[7] = from->Fpr7;
to->fp.powerpc_regs.fpr[8] = from->Fpr8;
to->fp.powerpc_regs.fpr[9] = from->Fpr9;
to->fp.powerpc_regs.fpr[10] = from->Fpr10;
to->fp.powerpc_regs.fpr[11] = from->Fpr11;
to->fp.powerpc_regs.fpr[12] = from->Fpr12;
to->fp.powerpc_regs.fpr[13] = from->Fpr13;
to->fp.powerpc_regs.fpr[14] = from->Fpr14;
to->fp.powerpc_regs.fpr[15] = from->Fpr15;
to->fp.powerpc_regs.fpr[16] = from->Fpr16;
to->fp.powerpc_regs.fpr[17] = from->Fpr17;
to->fp.powerpc_regs.fpr[18] = from->Fpr18;
to->fp.powerpc_regs.fpr[19] = from->Fpr19;
to->fp.powerpc_regs.fpr[20] = from->Fpr20;
to->fp.powerpc_regs.fpr[21] = from->Fpr21;
to->fp.powerpc_regs.fpr[22] = from->Fpr22;
to->fp.powerpc_regs.fpr[23] = from->Fpr23;
to->fp.powerpc_regs.fpr[24] = from->Fpr24;
to->fp.powerpc_regs.fpr[25] = from->Fpr25;
to->fp.powerpc_regs.fpr[26] = from->Fpr26;
to->fp.powerpc_regs.fpr[27] = from->Fpr27;
to->fp.powerpc_regs.fpr[28] = from->Fpr28;
to->fp.powerpc_regs.fpr[29] = from->Fpr29;
to->fp.powerpc_regs.fpr[30] = from->Fpr30;
to->fp.powerpc_regs.fpr[31] = from->Fpr31;
to->fp.powerpc_regs.fpscr = from->Fpscr;
}
return STATUS_SUCCESS;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
if (from->cpu != CPU_POWERPC) return STATUS_INVALID_PARAMETER;
to->ContextFlags = 0; /* no CPU id? */
if (from->flags & SERVER_CTX_CONTROL)
{
to->ContextFlags |= CONTEXT_CONTROL;
to->Msr = from->ctl.powerpc_regs.msr;
to->Ctr = from->ctl.powerpc_regs.ctr;
to->Iar = from->ctl.powerpc_regs.iar;
to->Lr = from->ctl.powerpc_regs.lr;
to->Dar = from->ctl.powerpc_regs.dar;
to->Dsisr = from->ctl.powerpc_regs.dsisr;
to->Trap = from->ctl.powerpc_regs.trap;
}
if (from->flags & SERVER_CTX_INTEGER)
{
to->ContextFlags |= CONTEXT_INTEGER;
to->Gpr0 = from->integer.powerpc_regs.gpr[0];
to->Gpr1 = from->integer.powerpc_regs.gpr[1];
to->Gpr2 = from->integer.powerpc_regs.gpr[2];
to->Gpr3 = from->integer.powerpc_regs.gpr[3];
to->Gpr4 = from->integer.powerpc_regs.gpr[4];
to->Gpr5 = from->integer.powerpc_regs.gpr[5];
to->Gpr6 = from->integer.powerpc_regs.gpr[6];
to->Gpr7 = from->integer.powerpc_regs.gpr[7];
to->Gpr8 = from->integer.powerpc_regs.gpr[8];
to->Gpr9 = from->integer.powerpc_regs.gpr[9];
to->Gpr10 = from->integer.powerpc_regs.gpr[10];
to->Gpr11 = from->integer.powerpc_regs.gpr[11];
to->Gpr12 = from->integer.powerpc_regs.gpr[12];
to->Gpr13 = from->integer.powerpc_regs.gpr[13];
to->Gpr14 = from->integer.powerpc_regs.gpr[14];
to->Gpr15 = from->integer.powerpc_regs.gpr[15];
to->Gpr16 = from->integer.powerpc_regs.gpr[16];
to->Gpr17 = from->integer.powerpc_regs.gpr[17];
to->Gpr18 = from->integer.powerpc_regs.gpr[18];
to->Gpr19 = from->integer.powerpc_regs.gpr[19];
to->Gpr20 = from->integer.powerpc_regs.gpr[20];
to->Gpr21 = from->integer.powerpc_regs.gpr[21];
to->Gpr22 = from->integer.powerpc_regs.gpr[22];
to->Gpr23 = from->integer.powerpc_regs.gpr[23];
to->Gpr24 = from->integer.powerpc_regs.gpr[24];
to->Gpr25 = from->integer.powerpc_regs.gpr[25];
to->Gpr26 = from->integer.powerpc_regs.gpr[26];
to->Gpr27 = from->integer.powerpc_regs.gpr[27];
to->Gpr28 = from->integer.powerpc_regs.gpr[28];
to->Gpr29 = from->integer.powerpc_regs.gpr[29];
to->Gpr30 = from->integer.powerpc_regs.gpr[30];
to->Gpr31 = from->integer.powerpc_regs.gpr[31];
to->Xer = from->integer.powerpc_regs.xer;
to->Cr = from->integer.powerpc_regs.cr;
}
if (from->flags & SERVER_CTX_FLOATING_POINT)
{
to->ContextFlags |= CONTEXT_FLOATING_POINT;
to->Fpr0 = from->fp.powerpc_regs.fpr[0];
to->Fpr1 = from->fp.powerpc_regs.fpr[1];
to->Fpr2 = from->fp.powerpc_regs.fpr[2];
to->Fpr3 = from->fp.powerpc_regs.fpr[3];
to->Fpr4 = from->fp.powerpc_regs.fpr[4];
to->Fpr5 = from->fp.powerpc_regs.fpr[5];
to->Fpr6 = from->fp.powerpc_regs.fpr[6];
to->Fpr7 = from->fp.powerpc_regs.fpr[7];
to->Fpr8 = from->fp.powerpc_regs.fpr[8];
to->Fpr9 = from->fp.powerpc_regs.fpr[9];
to->Fpr10 = from->fp.powerpc_regs.fpr[10];
to->Fpr11 = from->fp.powerpc_regs.fpr[11];
to->Fpr12 = from->fp.powerpc_regs.fpr[12];
to->Fpr13 = from->fp.powerpc_regs.fpr[13];
to->Fpr14 = from->fp.powerpc_regs.fpr[14];
to->Fpr15 = from->fp.powerpc_regs.fpr[15];
to->Fpr16 = from->fp.powerpc_regs.fpr[16];
to->Fpr17 = from->fp.powerpc_regs.fpr[17];
to->Fpr18 = from->fp.powerpc_regs.fpr[18];
to->Fpr19 = from->fp.powerpc_regs.fpr[19];
to->Fpr20 = from->fp.powerpc_regs.fpr[20];
to->Fpr21 = from->fp.powerpc_regs.fpr[21];
to->Fpr22 = from->fp.powerpc_regs.fpr[22];
to->Fpr23 = from->fp.powerpc_regs.fpr[23];
to->Fpr24 = from->fp.powerpc_regs.fpr[24];
to->Fpr25 = from->fp.powerpc_regs.fpr[25];
to->Fpr26 = from->fp.powerpc_regs.fpr[26];
to->Fpr27 = from->fp.powerpc_regs.fpr[27];
to->Fpr28 = from->fp.powerpc_regs.fpr[28];
to->Fpr29 = from->fp.powerpc_regs.fpr[29];
to->Fpr30 = from->fp.powerpc_regs.fpr[30];
to->Fpr31 = from->fp.powerpc_regs.fpr[31];
to->Fpscr = from->fp.powerpc_regs.fpscr;
}
return STATUS_SUCCESS;
}
/**********************************************************************
* get_thread_ldt_entry
*/
......
......@@ -113,6 +113,140 @@ enum i386_trap_code
static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
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;
if (flags & CONTEXT_CONTROL)
{
to->flags |= SERVER_CTX_CONTROL;
to->ctl.x86_64_regs.rbp = from->Rbp;
to->ctl.x86_64_regs.rip = from->Rip;
to->ctl.x86_64_regs.rsp = from->Rsp;
to->ctl.x86_64_regs.cs = from->SegCs;
to->ctl.x86_64_regs.ss = from->SegSs;
to->ctl.x86_64_regs.flags = from->EFlags;
}
if (flags & CONTEXT_INTEGER)
{
to->flags |= SERVER_CTX_INTEGER;
to->integer.x86_64_regs.rax = from->Rax;
to->integer.x86_64_regs.rcx = from->Rcx;
to->integer.x86_64_regs.rdx = from->Rdx;
to->integer.x86_64_regs.rbx = from->Rbx;
to->integer.x86_64_regs.rsi = from->Rsi;
to->integer.x86_64_regs.rdi = from->Rdi;
to->integer.x86_64_regs.r8 = from->R8;
to->integer.x86_64_regs.r9 = from->R9;
to->integer.x86_64_regs.r10 = from->R10;
to->integer.x86_64_regs.r11 = from->R11;
to->integer.x86_64_regs.r12 = from->R12;
to->integer.x86_64_regs.r13 = from->R13;
to->integer.x86_64_regs.r14 = from->R14;
to->integer.x86_64_regs.r15 = from->R15;
}
if (flags & CONTEXT_SEGMENTS)
{
to->flags |= SERVER_CTX_SEGMENTS;
to->seg.x86_64_regs.ds = from->SegDs;
to->seg.x86_64_regs.es = from->SegEs;
to->seg.x86_64_regs.fs = from->SegFs;
to->seg.x86_64_regs.gs = from->SegGs;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->flags |= SERVER_CTX_FLOATING_POINT;
memcpy( to->fp.x86_64_regs.fpregs, &from->u.FltSave, sizeof(to->fp.x86_64_regs.fpregs) );
}
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->flags |= SERVER_CTX_DEBUG_REGISTERS;
to->debug.x86_64_regs.dr0 = from->Dr0;
to->debug.x86_64_regs.dr1 = from->Dr1;
to->debug.x86_64_regs.dr2 = from->Dr2;
to->debug.x86_64_regs.dr3 = from->Dr3;
to->debug.x86_64_regs.dr6 = from->Dr6;
to->debug.x86_64_regs.dr7 = from->Dr7;
}
return STATUS_SUCCESS;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
if (from->cpu != CPU_x86_64) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_AMD64;
if (from->flags & SERVER_CTX_CONTROL)
{
to->ContextFlags |= CONTEXT_CONTROL;
to->Rbp = from->ctl.x86_64_regs.rbp;
to->Rip = from->ctl.x86_64_regs.rip;
to->Rsp = from->ctl.x86_64_regs.rsp;
to->SegCs = from->ctl.x86_64_regs.cs;
to->SegSs = from->ctl.x86_64_regs.ss;
to->EFlags = from->ctl.x86_64_regs.flags;
}
if (from->flags & SERVER_CTX_INTEGER)
{
to->ContextFlags |= CONTEXT_INTEGER;
to->Rax = from->integer.x86_64_regs.rax;
to->Rcx = from->integer.x86_64_regs.rcx;
to->Rdx = from->integer.x86_64_regs.rdx;
to->Rbx = from->integer.x86_64_regs.rbx;
to->Rsi = from->integer.x86_64_regs.rsi;
to->Rdi = from->integer.x86_64_regs.rdi;
to->R8 = from->integer.x86_64_regs.r8;
to->R9 = from->integer.x86_64_regs.r9;
to->R10 = from->integer.x86_64_regs.r10;
to->R11 = from->integer.x86_64_regs.r11;
to->R12 = from->integer.x86_64_regs.r12;
to->R13 = from->integer.x86_64_regs.r13;
to->R14 = from->integer.x86_64_regs.r14;
to->R15 = from->integer.x86_64_regs.r15;
}
if (from->flags & SERVER_CTX_SEGMENTS)
{
to->ContextFlags |= CONTEXT_SEGMENTS;
to->SegDs = from->seg.x86_64_regs.ds;
to->SegEs = from->seg.x86_64_regs.es;
to->SegFs = from->seg.x86_64_regs.fs;
to->SegGs = from->seg.x86_64_regs.gs;
}
if (from->flags & SERVER_CTX_FLOATING_POINT)
{
to->ContextFlags |= CONTEXT_FLOATING_POINT;
memcpy( &to->u.FltSave, from->fp.x86_64_regs.fpregs, sizeof(from->fp.x86_64_regs.fpregs) );
to->MxCsr = to->u.FltSave.MxCsr;
}
if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
{
to->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
to->Dr0 = from->debug.x86_64_regs.dr0;
to->Dr1 = from->debug.x86_64_regs.dr1;
to->Dr2 = from->debug.x86_64_regs.dr2;
to->Dr3 = from->debug.x86_64_regs.dr3;
to->Dr6 = from->debug.x86_64_regs.dr6;
to->Dr7 = from->debug.x86_64_regs.dr7;
}
return STATUS_SUCCESS;
}
/**********************************************************************
* get_thread_ldt_entry
*/
......
......@@ -61,6 +61,12 @@ extern void virtual_init(void) DECLSPEC_HIDDEN;
extern void CDECL dbg_init(void) DECLSPEC_HIDDEN;
extern unsigned int CDECL server_call_unlocked( void *req_ptr ) DECLSPEC_HIDDEN;
extern unsigned int CDECL server_select( const select_op_t *select_op, data_size_t size, UINT flags,
timeout_t abs_timeout, CONTEXT *context, RTL_CRITICAL_SECTION *cs,
user_apc_t *user_apc ) DECLSPEC_HIDDEN;
extern unsigned int CDECL server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
extern unsigned int CDECL server_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result ) DECLSPEC_HIDDEN;
extern void CDECL server_send_fd( int fd ) DECLSPEC_HIDDEN;
extern int CDECL server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
int *needs_close, enum server_fd_type *type,
......@@ -95,6 +101,9 @@ extern void server_enter_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset
extern void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sigset ) DECLSPEC_HIDDEN;
extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC_HIDDEN;
extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
extern void signal_init_threading(void) DECLSPEC_HIDDEN;
extern NTSTATUS signal_alloc_thread( TEB *teb ) DECLSPEC_HIDDEN;
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
......
......@@ -27,7 +27,7 @@
struct ldt_copy;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 12
#define NTDLL_UNIXLIB_VERSION 13
struct unix_funcs
{
......@@ -73,6 +73,12 @@ struct unix_funcs
/* server functions */
unsigned int (CDECL *server_call_unlocked)( void *req_ptr );
unsigned int (CDECL *server_call)( void *req_ptr );
unsigned int (CDECL *server_select)( const select_op_t *select_op, data_size_t size, UINT flags,
timeout_t abs_timeout, CONTEXT *context, RTL_CRITICAL_SECTION *cs,
user_apc_t *user_apc );
unsigned int (CDECL *server_wait)( const select_op_t *select_op, data_size_t size, UINT flags,
const LARGE_INTEGER *timeout );
unsigned int (CDECL *server_queue_process_apc)( HANDLE process, const apc_call_t *call, apc_result_t *result );
void (CDECL *server_send_fd)( int fd );
int (CDECL *server_get_unix_fd)( HANDLE handle, unsigned int wanted_access, int *unix_fd,
int *needs_close, enum server_fd_type *type, unsigned int *options );
......
......@@ -2987,7 +2987,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
call.virtual_alloc.zero_bits = zero_bits;
call.virtual_alloc.op_type = type;
call.virtual_alloc.prot = protect;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_alloc.status == STATUS_SUCCESS)
......@@ -3115,7 +3115,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
call.virtual_free.addr = wine_server_client_ptr( addr );
call.virtual_free.size = size;
call.virtual_free.op_type = type;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_free.status == STATUS_SUCCESS)
......@@ -3204,7 +3204,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH NtProtectVirtualMemory( HANDLE process, PVOID
call.virtual_protect.addr = wine_server_client_ptr( addr );
call.virtual_protect.size = size;
call.virtual_protect.prot = new_prot;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_protect.status == STATUS_SUCCESS)
......@@ -3308,7 +3308,7 @@ static NTSTATUS get_basic_memory_info( HANDLE process, LPCVOID addr,
call.virtual_query.type = APC_VIRTUAL_QUERY;
call.virtual_query.addr = wine_server_client_ptr( addr );
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_query.status == STATUS_SUCCESS)
......@@ -3520,7 +3520,7 @@ NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size,
call.virtual_lock.type = APC_VIRTUAL_LOCK;
call.virtual_lock.addr = wine_server_client_ptr( *addr );
call.virtual_lock.size = *size;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_lock.status == STATUS_SUCCESS)
......@@ -3557,7 +3557,7 @@ NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size
call.virtual_unlock.type = APC_VIRTUAL_UNLOCK;
call.virtual_unlock.addr = wine_server_client_ptr( *addr );
call.virtual_unlock.size = *size;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_unlock.status == STATUS_SUCCESS)
......@@ -3697,7 +3697,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
call.map_view.zero_bits = zero_bits;
call.map_view.alloc_type = alloc_type;
call.map_view.prot = protect;
res = server_queue_process_apc( process, &call, &result );
res = unix_funcs->server_queue_process_apc( process, &call, &result );
if (res != STATUS_SUCCESS) return res;
if ((NTSTATUS)result.map_view.status >= 0)
......@@ -3733,7 +3733,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
call.unmap_view.type = APC_UNMAP_VIEW;
call.unmap_view.addr = wine_server_client_ptr( addr );
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status == STATUS_SUCCESS) status = result.unmap_view.status;
return status;
}
......@@ -3872,7 +3872,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
call.virtual_flush.type = APC_VIRTUAL_FLUSH;
call.virtual_flush.addr = wine_server_client_ptr( addr );
call.virtual_flush.size = *size_ptr;
status = server_queue_process_apc( process, &call, &result );
status = unix_funcs->server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status;
if (result.virtual_flush.status == STATUS_SUCCESS)
......
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