Signed-off-by: Paul Gofman pgofman@codeweavers.com --- Supersedes 206374-206376. v3: - replaced patch.
server/thread.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/server/thread.c b/server/thread.c index 0c7f11c0da1..6de36d817c1 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1659,12 +1659,7 @@ DECL_HANDLER(select) current->context && current->suspend_cookie == req->cookie) { if (current->context->regs.flags) - { - unsigned int system_flags = get_context_system_regs(current->process->machine) & - current->context->regs.flags; - if (system_flags) set_thread_context( current, ¤t->context->regs, system_flags ); set_reply_data( ¤t->context->regs, sizeof(context_t) ); - } release_object( current->context ); current->context = NULL; } @@ -1870,7 +1865,7 @@ DECL_HANDLER(set_thread_context) unsigned int system_flags = get_context_system_regs( context->machine ) & context->flags;
if (thread != current) stop_thread( thread ); - else if (system_flags) set_thread_context( thread, context, system_flags ); + if (system_flags) set_thread_context( thread, context, system_flags ); if (thread->context && !get_error()) { copy_context( &thread->context->regs, context, context->flags );
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/unix/signal_i386.c | 9 +++++++++ dlls/ntdll/unix/signal_x86_64.c | 9 +++++++++ 2 files changed, 18 insertions(+)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 87024e1bfce..28e95c084db 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2478,6 +2478,15 @@ PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void wait_suspend( &context ); ctx = (CONTEXT *)((ULONG_PTR)context.Esp & ~15) - 1; *ctx = context; + 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; + } } else { diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index dcb0e588c66..2332befdf40 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2754,6 +2754,15 @@ PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void wait_suspend( &context ); ctx = (CONTEXT *)((ULONG_PTR)context.Rsp & ~15) - 1; *ctx = context; + 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; + } } else {
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/unix/signal_i386.c | 35 +++++++++++++++++++++-------- dlls/ntdll/unix/signal_x86_64.c | 39 +++++++++++++++++++++++---------- 2 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 28e95c084db..69bef162d64 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1110,10 +1110,15 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) struct syscall_frame *frame = x86_thread_data()->syscall_frame; DWORD needed_flags = context->ContextFlags & ~CONTEXT_i386; BOOL self = (handle == GetCurrentThread()); + BOOL use_cached_debug_regs = FALSE; NTSTATUS ret;
- /* debug registers require a server call */ - if (needed_flags & CONTEXT_DEBUG_REGISTERS) self = FALSE; + if (self && needed_flags & CONTEXT_DEBUG_REGISTERS) + { + /* debug registers require a server call if hw breakpoints are enabled */ + if (x86_thread_data()->dr7 & 0xff) self = FALSE; + else use_cached_debug_regs = TRUE; + }
if (!self) { @@ -1204,15 +1209,27 @@ 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 (use_cached_debug_regs) + { + context->Dr0 = x86_thread_data()->dr0; + context->Dr1 = x86_thread_data()->dr1; + context->Dr2 = x86_thread_data()->dr2; + context->Dr3 = x86_thread_data()->dr3; + context->Dr6 = x86_thread_data()->dr6; + context->Dr7 = x86_thread_data()->dr7; + } + else + { + /* update the cached version of the debug registers */ + 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 ))) { diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 2332befdf40..448f45474b1 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1718,18 +1718,23 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) */ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) { - NTSTATUS ret; - DWORD needed_flags; struct syscall_frame *frame = amd64_thread_data()->syscall_frame; BOOL self = (handle == GetCurrentThread()); + BOOL use_cached_debug_regs = FALSE; + DWORD needed_flags; XSTATE *xstate; + NTSTATUS ret;
if (!context) return STATUS_INVALID_PARAMETER;
needed_flags = context->ContextFlags & ~CONTEXT_AMD64;
- /* debug registers require a server call */ - if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64)) self = FALSE; + if (self && needed_flags & CONTEXT_DEBUG_REGISTERS) + { + /* debug registers require a server call if hw breakpoints are enabled */ + if (amd64_thread_data()->dr7 & 0xff) self = FALSE; + else use_cached_debug_regs = TRUE; + }
if (!self) { @@ -1812,15 +1817,27 @@ 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 (use_cached_debug_regs) + { + context->Dr0 = amd64_thread_data()->dr0; + context->Dr1 = amd64_thread_data()->dr1; + context->Dr2 = amd64_thread_data()->dr2; + context->Dr3 = amd64_thread_data()->dr3; + context->Dr6 = amd64_thread_data()->dr6; + context->Dr7 = amd64_thread_data()->dr7; + } + else + { + /* update the cached version of the debug registers */ + 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 ))) {