Commit ce46de5a authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move NtGetContextThread implementation to the platform-specific files.

parent 675e8218
......@@ -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 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 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_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 NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
extern void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
/* debug helpers */
......
......@@ -320,7 +320,7 @@ __ASM_GLOBAL_FUNC( set_cpu_context,
*
* Copy a register context according to the flags.
*/
void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
{
flags &= ~CONTEXT_ARM; /* get rid of CPU id */
if (flags & CONTEXT_CONTROL)
......@@ -443,6 +443,33 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
DWORD needed_flags = context->ContextFlags;
BOOL self = (handle == GetCurrentThread());
if (!self)
{
if ((ret = get_thread_context( handle, context, &self ))) return ret;
needed_flags &= ~context->ContextFlags;
}
if (self && needed_flags)
{
CONTEXT ctx;
RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags;
}
return STATUS_SUCCESS;
}
extern void raise_func_trampoline_thumb( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
__ASM_GLOBAL_FUNC( raise_func_trampoline_thumb,
".thumb\n\t"
......
......@@ -241,7 +241,7 @@ static void set_cpu_context( const CONTEXT *context )
*
* Copy a register context according to the flags.
*/
void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
{
flags &= ~CONTEXT_ARM64; /* get rid of CPU id */
if (flags & CONTEXT_CONTROL)
......@@ -346,6 +346,33 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
DWORD needed_flags = context->ContextFlags;
BOOL self = (handle == GetCurrentThread());
if (!self)
{
if ((ret = get_thread_context( handle, context, &self ))) return ret;
needed_flags &= ~context->ContextFlags;
}
if (self && needed_flags)
{
CONTEXT ctx;
RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags;
}
return STATUS_SUCCESS;
}
/***********************************************************************
* setup_exception_record
*
* Setup the exception record and context on the thread stack.
......
......@@ -1270,7 +1270,7 @@ static void set_cpu_context( const CONTEXT *context )
*
* Copy a register context according to the flags.
*/
void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
{
flags &= ~CONTEXT_i386; /* get rid of CPU id */
if (flags & CONTEXT_INTEGER)
......@@ -1486,6 +1486,49 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
DWORD needed_flags = context->ContextFlags;
BOOL self = (handle == GetCurrentThread());
/* debug registers require a server call */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)) self = FALSE;
if (!self)
{
if ((ret = get_thread_context( handle, context, &self ))) return ret;
needed_flags &= ~context->ContextFlags;
}
if (self)
{
if (needed_flags)
{
CONTEXT ctx;
RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags;
}
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
{
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;
}
}
return STATUS_SUCCESS;
}
/***********************************************************************
* is_privileged_instr
*
* Check if the fault location is a privileged instruction.
......
......@@ -278,7 +278,7 @@ static void set_cpu_context( const CONTEXT *context )
*
* Copy a register context according to the flags.
*/
void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
{
if (flags & CONTEXT_CONTROL)
{
......@@ -583,6 +583,33 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
DWORD needed_flags = context->ContextFlags;
BOOL self = (handle == GetCurrentThread());
if (!self)
{
if ((ret = get_thread_context( handle, context, &self ))) return ret;
needed_flags &= ~context->ContextFlags;
}
if (self && needed_flags)
{
CONTEXT ctx;
RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags;
}
return STATUS_SUCCESS;
}
/**********************************************************************
* call_stack_handlers
*
......
......@@ -1876,7 +1876,7 @@ static void set_cpu_context( const CONTEXT *context )
*
* Copy a register context according to the flags.
*/
void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
{
flags &= ~CONTEXT_AMD64; /* get rid of CPU id */
if (flags & CONTEXT_CONTROL)
......@@ -2078,6 +2078,36 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
DWORD needed_flags = context->ContextFlags;
BOOL self = (handle == GetCurrentThread());
/* debug registers require a server call */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64)) self = FALSE;
if (!self)
{
if ((ret = get_thread_context( handle, context, &self ))) return ret;
needed_flags &= ~context->ContextFlags;
}
if (self && needed_flags)
{
CONTEXT ctx;
RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags;
}
return STATUS_SUCCESS;
}
extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
__ASM_GLOBAL_FUNC( raise_func_trampoline,
__ASM_CFI(".cfi_signal_frame\n\t")
......
......@@ -843,7 +843,7 @@ static inline unsigned int get_server_context_flags( DWORD flags )
/***********************************************************************
* get_thread_context
*/
static NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
{
NTSTATUS ret;
DWORD dummy, i;
......@@ -890,56 +890,6 @@ static NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
DWORD needed_flags = context->ContextFlags;
BOOL self = (handle == GetCurrentThread());
/* on i386/amd64 debug registers always require a server call */
#ifdef __i386__
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386)) self = FALSE;
#elif defined(__x86_64__)
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64)) self = FALSE;
#endif
if (!self)
{
ret = get_thread_context( handle, context, &self );
if (ret) return ret;
needed_flags &= ~context->ContextFlags;
}
if (self)
{
if (needed_flags)
{
CONTEXT ctx;
RtlCaptureContext( &ctx );
copy_context( context, &ctx, ctx.ContextFlags & needed_flags );
context->ContextFlags |= ctx.ContextFlags & needed_flags;
}
#ifdef __i386__
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
{
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;
}
#endif
}
return STATUS_SUCCESS;
}
/******************************************************************************
* NtQueryInformationThread (NTDLL.@)
* ZwQueryInformationThread (NTDLL.@)
......
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