ntdll: Don't copy xstate from / to syscall frame in usr1_handler().
This commit is contained in:
parent
ba1e2d5dda
commit
efd3d31082
2 changed files with 61 additions and 19 deletions
|
@ -2107,24 +2107,46 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
|||
*/
|
||||
static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||
{
|
||||
struct xcontext xcontext;
|
||||
ucontext_t *ucontext = sigcontext;
|
||||
|
||||
init_handler( sigcontext );
|
||||
if (is_inside_syscall( sigcontext ))
|
||||
{
|
||||
DECLSPEC_ALIGN(64) XSTATE xs;
|
||||
xcontext.c.ContextFlags = CONTEXT_FULL;
|
||||
context_init_xstate( &xcontext.c, &xs );
|
||||
|
||||
NtGetContextThread( GetCurrentThread(), &xcontext.c );
|
||||
wait_suspend( &xcontext.c );
|
||||
NtSetContextThread( GetCurrentThread(), &xcontext.c );
|
||||
if (is_inside_syscall( ucontext ))
|
||||
{
|
||||
struct syscall_frame *frame = x86_thread_data()->syscall_frame;
|
||||
ULONG64 saved_compaction = 0;
|
||||
struct xcontext *context;
|
||||
|
||||
context = (struct xcontext *)(((ULONG_PTR)ESP_sig(ucontext) - sizeof(*context)) & ~15);
|
||||
if ((char *)context < (char *)ntdll_get_thread_data()->kernel_stack)
|
||||
{
|
||||
ERR_(seh)( "kernel stack overflow.\n" );
|
||||
return;
|
||||
}
|
||||
context->c.ContextFlags = CONTEXT_FULL;
|
||||
NtGetContextThread( GetCurrentThread(), &context->c );
|
||||
if (xstate_extended_features())
|
||||
{
|
||||
context_init_xstate( &context->c, &frame->xstate );
|
||||
saved_compaction = frame->xstate.CompactionMask;
|
||||
}
|
||||
wait_suspend( &context->c );
|
||||
if (xstate_extended_features()) frame->xstate.CompactionMask = saved_compaction;
|
||||
if (context->c.ContextFlags & 0x40)
|
||||
{
|
||||
/* xstate is updated directly in frame's xstate */
|
||||
context->c.ContextFlags &= ~0x40;
|
||||
frame->restore_flags |= 0x40;
|
||||
}
|
||||
NtSetContextThread( GetCurrentThread(), &context->c );
|
||||
}
|
||||
else
|
||||
{
|
||||
save_context( &xcontext, sigcontext );
|
||||
wait_suspend( &xcontext.c );
|
||||
restore_context( &xcontext, sigcontext );
|
||||
struct xcontext context;
|
||||
|
||||
save_context( &context, ucontext );
|
||||
wait_suspend( &context.c );
|
||||
restore_context( &context, ucontext );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2145,20 +2145,40 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
|||
static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
|
||||
{
|
||||
ucontext_t *ucontext = init_handler( sigcontext );
|
||||
struct xcontext context;
|
||||
|
||||
if (is_inside_syscall( ucontext ))
|
||||
{
|
||||
DECLSPEC_ALIGN(64) XSTATE xs;
|
||||
context.c.ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS;
|
||||
context_init_xstate( &context.c, &xs );
|
||||
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
|
||||
ULONG64 saved_compaction = 0;
|
||||
struct xcontext *context;
|
||||
|
||||
NtGetContextThread( GetCurrentThread(), &context.c );
|
||||
wait_suspend( &context.c );
|
||||
NtSetContextThread( GetCurrentThread(), &context.c );
|
||||
context = (struct xcontext *)(((ULONG_PTR)RSP_sig(ucontext) - sizeof(*context)) & ~15);
|
||||
if ((char *)context < (char *)ntdll_get_thread_data()->kernel_stack)
|
||||
{
|
||||
ERR_(seh)( "kernel stack overflow.\n" );
|
||||
return;
|
||||
}
|
||||
context->c.ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS;
|
||||
NtGetContextThread( GetCurrentThread(), &context->c );
|
||||
if (xstate_extended_features())
|
||||
{
|
||||
context_init_xstate( &context->c, &frame->xstate );
|
||||
saved_compaction = frame->xstate.CompactionMask;
|
||||
}
|
||||
wait_suspend( &context->c );
|
||||
if (xstate_extended_features()) frame->xstate.CompactionMask = saved_compaction;
|
||||
if (context->c.ContextFlags & 0x40)
|
||||
{
|
||||
/* xstate is updated directly in frame's xstate */
|
||||
context->c.ContextFlags &= ~0x40;
|
||||
frame->restore_flags |= 0x40;
|
||||
}
|
||||
NtSetContextThread( GetCurrentThread(), &context->c );
|
||||
}
|
||||
else
|
||||
{
|
||||
struct xcontext context;
|
||||
|
||||
save_context( &context, ucontext );
|
||||
wait_suspend( &context.c );
|
||||
restore_context( &context, ucontext );
|
||||
|
|
Loading…
Add table
Reference in a new issue