ntdll: Move NtSetContextThread implementation to the platform-specific files.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1e48417567
commit
675e8218f0
|
@ -53,10 +53,10 @@ extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context ) DECLSPEC_HIDDEN;
|
extern NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||||
extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN;
|
extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||||
extern void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
|
extern void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
|
||||||
extern void set_cpu_context( const CONTEXT *context ) DECLSPEC_HIDDEN;
|
|
||||||
extern void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags ) DECLSPEC_HIDDEN;
|
extern void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) 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 NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
|
||||||
|
extern NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
|
||||||
extern void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
|
extern void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* debug helpers */
|
/* debug helpers */
|
||||||
|
|
|
@ -294,6 +294,7 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 4,
|
||||||
* Set the new CPU context.
|
* Set the new CPU context.
|
||||||
*/
|
*/
|
||||||
/* FIXME: What about the CPSR? */
|
/* FIXME: What about the CPSR? */
|
||||||
|
void set_cpu_context( const CONTEXT *context );
|
||||||
__ASM_GLOBAL_FUNC( set_cpu_context,
|
__ASM_GLOBAL_FUNC( set_cpu_context,
|
||||||
"mov IP, r0\n\t"
|
"mov IP, r0\n\t"
|
||||||
"ldr r0, [IP, #0x4]\n\t" /* context->R0 */
|
"ldr r0, [IP, #0x4]\n\t" /* context->R0 */
|
||||||
|
@ -427,6 +428,21 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtSetContextThread (NTDLL.@)
|
||||||
|
* ZwSetContextThread (NTDLL.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
||||||
|
{
|
||||||
|
NTSTATUS ret;
|
||||||
|
BOOL self;
|
||||||
|
|
||||||
|
ret = set_thread_context( handle, context, &self );
|
||||||
|
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void raise_func_trampoline_thumb( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
|
extern void raise_func_trampoline_thumb( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
|
||||||
__ASM_GLOBAL_FUNC( raise_func_trampoline_thumb,
|
__ASM_GLOBAL_FUNC( raise_func_trampoline_thumb,
|
||||||
".thumb\n\t"
|
".thumb\n\t"
|
||||||
|
|
|
@ -231,7 +231,7 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 8,
|
||||||
*
|
*
|
||||||
* Set the new CPU context.
|
* Set the new CPU context.
|
||||||
*/
|
*/
|
||||||
void set_cpu_context( const CONTEXT *context )
|
static void set_cpu_context( const CONTEXT *context )
|
||||||
{
|
{
|
||||||
FIXME( "Not implemented on ARM64\n" );
|
FIXME( "Not implemented on ARM64\n" );
|
||||||
}
|
}
|
||||||
|
@ -330,6 +330,21 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtSetContextThread (NTDLL.@)
|
||||||
|
* ZwSetContextThread (NTDLL.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
||||||
|
{
|
||||||
|
NTSTATUS ret;
|
||||||
|
BOOL self;
|
||||||
|
|
||||||
|
ret = set_thread_context( handle, context, &self );
|
||||||
|
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* setup_exception_record
|
* setup_exception_record
|
||||||
*
|
*
|
||||||
|
|
|
@ -1230,7 +1230,7 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 4,
|
||||||
*
|
*
|
||||||
* Set the new CPU context. Used by NtSetContextThread.
|
* Set the new CPU context. Used by NtSetContextThread.
|
||||||
*/
|
*/
|
||||||
void set_cpu_context( const CONTEXT *context )
|
static void set_cpu_context( const CONTEXT *context )
|
||||||
{
|
{
|
||||||
DWORD flags = context->ContextFlags & ~CONTEXT_i386;
|
DWORD flags = context->ContextFlags & ~CONTEXT_i386;
|
||||||
|
|
||||||
|
@ -1460,6 +1460,31 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtSetContextThread (NTDLL.@)
|
||||||
|
* ZwSetContextThread (NTDLL.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
||||||
|
{
|
||||||
|
NTSTATUS ret = STATUS_SUCCESS;
|
||||||
|
BOOL self = (handle == GetCurrentThread());
|
||||||
|
|
||||||
|
/* debug registers require a server call */
|
||||||
|
if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)))
|
||||||
|
self = (ntdll_get_thread_data()->dr0 == context->Dr0 &&
|
||||||
|
ntdll_get_thread_data()->dr1 == context->Dr1 &&
|
||||||
|
ntdll_get_thread_data()->dr2 == context->Dr2 &&
|
||||||
|
ntdll_get_thread_data()->dr3 == context->Dr3 &&
|
||||||
|
ntdll_get_thread_data()->dr6 == context->Dr6 &&
|
||||||
|
ntdll_get_thread_data()->dr7 == context->Dr7);
|
||||||
|
|
||||||
|
if (!self) ret = set_thread_context( handle, context, &self );
|
||||||
|
|
||||||
|
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* is_privileged_instr
|
* is_privileged_instr
|
||||||
*
|
*
|
||||||
|
|
|
@ -267,7 +267,7 @@ void WINAPI RtlCaptureContext( CONTEXT *context )
|
||||||
*
|
*
|
||||||
* Set the new CPU context.
|
* Set the new CPU context.
|
||||||
*/
|
*/
|
||||||
void set_cpu_context( const CONTEXT *context )
|
static void set_cpu_context( const CONTEXT *context )
|
||||||
{
|
{
|
||||||
FIXME("not implemented\n");
|
FIXME("not implemented\n");
|
||||||
}
|
}
|
||||||
|
@ -568,6 +568,21 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtSetContextThread (NTDLL.@)
|
||||||
|
* ZwSetContextThread (NTDLL.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
||||||
|
{
|
||||||
|
NTSTATUS ret;
|
||||||
|
BOOL self;
|
||||||
|
|
||||||
|
ret = set_thread_context( handle, context, &self );
|
||||||
|
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* call_stack_handlers
|
* call_stack_handlers
|
||||||
*
|
*
|
||||||
|
|
|
@ -1858,7 +1858,7 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
|
||||||
*
|
*
|
||||||
* Set the new CPU context. Used by NtSetContextThread.
|
* Set the new CPU context. Used by NtSetContextThread.
|
||||||
*/
|
*/
|
||||||
void set_cpu_context( const CONTEXT *context )
|
static void set_cpu_context( const CONTEXT *context )
|
||||||
{
|
{
|
||||||
DWORD flags = context->ContextFlags & ~CONTEXT_AMD64;
|
DWORD flags = context->ContextFlags & ~CONTEXT_AMD64;
|
||||||
if (flags & CONTEXT_FULL)
|
if (flags & CONTEXT_FULL)
|
||||||
|
@ -2063,6 +2063,21 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* NtSetContextThread (NTDLL.@)
|
||||||
|
* ZwSetContextThread (NTDLL.@)
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
||||||
|
{
|
||||||
|
NTSTATUS ret;
|
||||||
|
BOOL self;
|
||||||
|
|
||||||
|
ret = set_thread_context( handle, context, &self );
|
||||||
|
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
|
extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
|
||||||
__ASM_GLOBAL_FUNC( raise_func_trampoline,
|
__ASM_GLOBAL_FUNC( raise_func_trampoline,
|
||||||
__ASM_CFI(".cfi_signal_frame\n\t")
|
__ASM_CFI(".cfi_signal_frame\n\t")
|
||||||
|
@ -3929,7 +3944,7 @@ __ASM_GLOBAL_FUNC( RtlRaiseException,
|
||||||
"movq %rcx,0x80(%rdx)\n\t" /* context->Rcx */
|
"movq %rcx,0x80(%rdx)\n\t" /* context->Rcx */
|
||||||
"call " __ASM_NAME("__regs_RtlRaiseException") "\n\t"
|
"call " __ASM_NAME("__regs_RtlRaiseException") "\n\t"
|
||||||
"leaq 0x20(%rsp),%rdi\n\t" /* context pointer */
|
"leaq 0x20(%rsp),%rdi\n\t" /* context pointer */
|
||||||
"call " __ASM_NAME("set_cpu_context") /* does not return */ );
|
"call " __ASM_NAME("set_full_cpu_context") /* does not return */ );
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
|
@ -771,7 +771,7 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* set_thread_context
|
* set_thread_context
|
||||||
*/
|
*/
|
||||||
static NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
|
NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
|
||||||
{
|
{
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
DWORD dummy, i;
|
DWORD dummy, i;
|
||||||
|
@ -817,42 +817,6 @@ static NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* NtSetContextThread (NTDLL.@)
|
|
||||||
* ZwSetContextThread (NTDLL.@)
|
|
||||||
*/
|
|
||||||
NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
|
||||||
{
|
|
||||||
NTSTATUS ret;
|
|
||||||
BOOL self;
|
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
/* on i386 debug registers always require a server call */
|
|
||||||
self = (handle == GetCurrentThread());
|
|
||||||
if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)))
|
|
||||||
{
|
|
||||||
self = (ntdll_get_thread_data()->dr0 == context->Dr0 &&
|
|
||||||
ntdll_get_thread_data()->dr1 == context->Dr1 &&
|
|
||||||
ntdll_get_thread_data()->dr2 == context->Dr2 &&
|
|
||||||
ntdll_get_thread_data()->dr3 == context->Dr3 &&
|
|
||||||
ntdll_get_thread_data()->dr6 == context->Dr6 &&
|
|
||||||
ntdll_get_thread_data()->dr7 == context->Dr7);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
self = FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!self)
|
|
||||||
{
|
|
||||||
ret = set_thread_context( handle, context, &self );
|
|
||||||
if (ret) return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self) set_cpu_context( context );
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* convert CPU-specific flags to generic server flags */
|
/* convert CPU-specific flags to generic server flags */
|
||||||
static inline unsigned int get_server_context_flags( DWORD flags )
|
static inline unsigned int get_server_context_flags( DWORD flags )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue