[PATCH 3/3] ntdll: Use cached debug registers in NtGetContextThread() if hw debug breakpoints are disabled.
Paul Gofman
pgofman at codeweavers.com
Mon May 24 05:51:48 CDT 2021
Signed-off-by: Paul Gofman <pgofman at 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 da635c0f516..7ee0fa57ce4 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 b2cda5eef13..0ca823ab55b 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 )))
{
--
2.31.1
More information about the wine-devel
mailing list