ntdll: Don't update cached registers if NtGetContextThread() fails.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-06-14 12:55:23 +02:00
parent 9ea58cbfb5
commit bcc587887a
2 changed files with 26 additions and 30 deletions

View File

@ -1047,7 +1047,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if (self)
{
XSTATE *xstate;
if (needed_flags & CONTEXT_INTEGER)
{
context->Eax = frame->eax;
@ -1127,19 +1126,10 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
}
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
{
x86_thread_data()->dr0 = context->Dr0;
x86_thread_data()->dr1 = context->Dr1;
x86_thread_data()->dr2 = context->Dr2;
x86_thread_data()->dr3 = context->Dr3;
x86_thread_data()->dr6 = context->Dr6;
x86_thread_data()->dr7 = context->Dr7;
}
if ((cpu_info.ProcessorFeatureBits & CPU_FEATURE_AVX) && (xstate = xstate_from_context( context )))
if ((needed_flags & CONTEXT_XSTATE) && (cpu_info.ProcessorFeatureBits & CPU_FEATURE_AVX))
{
CONTEXT_EX *context_ex = (CONTEXT_EX *)(context + 1);
XSTATE *xstate = (XSTATE *)((char *)context_ex + context_ex->XState.Offset);
unsigned int mask;
if (context_ex->XState.Length < offsetof(XSTATE, YmmContext)
@ -1152,12 +1142,20 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
memset( xstate->Reserved, 0, sizeof(xstate->Reserved) );
if (xstate->Mask)
{
if (context_ex->XState.Length < sizeof(XSTATE))
return STATUS_BUFFER_OVERFLOW;
if (context_ex->XState.Length < sizeof(XSTATE)) return STATUS_BUFFER_OVERFLOW;
xstate->YmmContext = frame->xstate.YmmContext;
}
}
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
{
x86_thread_data()->dr0 = context->Dr0;
x86_thread_data()->dr1 = context->Dr1;
x86_thread_data()->dr2 = context->Dr2;
x86_thread_data()->dr3 = context->Dr3;
x86_thread_data()->dr6 = context->Dr6;
x86_thread_data()->dr7 = context->Dr7;
}
}
if (context->ContextFlags & (CONTEXT_INTEGER & ~CONTEXT_i386))

View File

@ -1677,7 +1677,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
DWORD needed_flags;
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
BOOL self = (handle == GetCurrentThread());
XSTATE *xstate;
if (!context) return STATUS_INVALID_PARAMETER;
@ -1765,19 +1764,10 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
context->MxCsr = context->u.FltSave.MxCsr;
context->ContextFlags |= CONTEXT_FLOATING_POINT;
}
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64))
{
amd64_thread_data()->dr0 = context->Dr0;
amd64_thread_data()->dr1 = context->Dr1;
amd64_thread_data()->dr2 = context->Dr2;
amd64_thread_data()->dr3 = context->Dr3;
amd64_thread_data()->dr6 = context->Dr6;
amd64_thread_data()->dr7 = context->Dr7;
}
if ((cpu_info.ProcessorFeatureBits & CPU_FEATURE_AVX) && (xstate = xstate_from_context( context )))
if ((needed_flags & CONTEXT_XSTATE) && (cpu_info.ProcessorFeatureBits & CPU_FEATURE_AVX))
{
CONTEXT_EX *context_ex = (CONTEXT_EX *)(context + 1);
XSTATE *xstate = (XSTATE *)((char *)context_ex + context_ex->XState.Offset);
unsigned int mask;
if (context_ex->XState.Length < offsetof(XSTATE, YmmContext)
@ -1790,12 +1780,20 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
memset( xstate->Reserved, 0, sizeof(xstate->Reserved) );
if (xstate->Mask)
{
if (context_ex->XState.Length < sizeof(XSTATE))
return STATUS_BUFFER_OVERFLOW;
if (context_ex->XState.Length < sizeof(XSTATE)) return STATUS_BUFFER_OVERFLOW;
memcpy( &xstate->YmmContext, &frame->xstate.YmmContext, sizeof(xstate->YmmContext) );
}
}
/* update the cached version of the debug registers */
if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64))
{
amd64_thread_data()->dr0 = context->Dr0;
amd64_thread_data()->dr1 = context->Dr1;
amd64_thread_data()->dr2 = context->Dr2;
amd64_thread_data()->dr3 = context->Dr3;
amd64_thread_data()->dr6 = context->Dr6;
amd64_thread_data()->dr7 = context->Dr7;
}
}
return STATUS_SUCCESS;