Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - no changes.
server/ptrace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/server/ptrace.c b/server/ptrace.c index 3621e8d82ad..b2d23d89aaf 100644 --- a/server/ptrace.c +++ b/server/ptrace.c @@ -571,15 +571,15 @@ void get_thread_context( struct thread *thread, context_t *context, unsigned int /* all other regs are handled on the client side */ assert( flags == SERVER_CTX_DEBUG_REGISTERS );
- if (!suspend_for_ptrace( thread )) return; - if (!(thread->system_regs & SERVER_CTX_DEBUG_REGISTERS)) { /* caller has initialized everything to 0 already, just return */ context->flags |= SERVER_CTX_DEBUG_REGISTERS; - goto done; + return; }
+ if (!suspend_for_ptrace( thread )) return; + for (i = 0; i < 8; i++) { if (i == 4 || i == 5) continue;
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - no changes.
server/thread.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/server/thread.c b/server/thread.c index eb8b0de84b1..d56ecd51a80 100644 --- a/server/thread.c +++ b/server/thread.c @@ -117,9 +117,10 @@ static const struct object_ops thread_apc_ops =
struct context { - struct object obj; /* object header */ - unsigned int status; /* status of the context */ - context_t regs; /* context data */ + struct object obj; /* object header */ + unsigned int status; /* status of the context */ + context_t regs; /* context data */ + unsigned int update_flags; /* updated context parts */ };
static void dump_context( struct object *obj, int verbose ); @@ -285,6 +286,7 @@ static struct context *create_thread_context( struct thread *thread ) context->status = STATUS_PENDING; memset( &context->regs, 0, sizeof(context->regs) ); context->regs.machine = thread->process->machine; + context->update_flags = 0; return context; }
@@ -1654,7 +1656,7 @@ DECL_HANDLER(select) if (current->context->regs.flags) { unsigned int system_flags = get_context_system_regs(current->process->machine) & - current->context->regs.flags; + current->context->update_flags; if (system_flags) set_thread_context( current, ¤t->context->regs, system_flags ); set_reply_data( ¤t->context->regs, sizeof(context_t) ); } @@ -1868,6 +1870,7 @@ DECL_HANDLER(set_thread_context) { copy_context( &thread->context->regs, context, context->flags ); thread->context->regs.flags |= context->flags; + thread->context->update_flags |= context->flags; } } else if (context->machine == IMAGE_FILE_MACHINE_AMD64 &&
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - added patch.
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 da635c0f516..ee88f178c91 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2473,6 +2473,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 b2cda5eef13..8f04818411b 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2745,6 +2745,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 {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91096
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
ntdll: om.c:2307: Test failed: got 89 om.c:2322: Test failed: got 87
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - no changes.
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 ee88f178c91..11493535641 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 8f04818411b..ba0caf28715 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 ))) {