[PATCH] server: Get debug registers on 64-bit Mac OS, too.

Charles Davis cdavis5x at gmail.com
Thu Jun 4 17:52:27 CDT 2015


---
 server/mach.c | 125 +++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 88 insertions(+), 37 deletions(-)

diff --git a/server/mach.c b/server/mach.c
index be84457..2ef6e59 100644
--- a/server/mach.c
+++ b/server/mach.c
@@ -151,8 +151,8 @@ void finish_process_tracing( struct process *process )
 /* retrieve the thread x86 registers */
 void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 {
-#ifdef __i386__
-    x86_debug_state32_t state;
+#if defined(__i386__) || defined(__x86_64__)
+    x86_debug_state_t state;
     mach_msg_type_number_t count = sizeof(state) / sizeof(int);
     mach_msg_type_name_t type;
     mach_port_t port, process_port = get_process_port( thread->process );
@@ -168,24 +168,45 @@ void get_thread_context( struct thread *thread, context_t *context, unsigned int
         return;
     }
 
-    if (!thread_get_state( port, x86_DEBUG_STATE32, (thread_state_t)&state, &count ))
+    if (!thread_get_state( port, x86_DEBUG_STATE, (thread_state_t)&state, &count ))
     {
+#ifdef __x86_64__
+        assert( state.dsh.flavor == x86_DEBUG_STATE32 ||
+                state.dsh.flavor == x86_DEBUG_STATE64 );
+#else
+        assert( state.dsh.flavor == x86_DEBUG_STATE32 );
+#endif
+
+#ifdef __x86_64__
+        if (state.dsh.flavor == x86_DEBUG_STATE64)
+        {
+            context->debug.x86_64_regs.dr0 = state.uds.ds64.__dr0;
+            context->debug.x86_64_regs.dr1 = state.uds.ds64.__dr1;
+            context->debug.x86_64_regs.dr2 = state.uds.ds64.__dr2;
+            context->debug.x86_64_regs.dr3 = state.uds.ds64.__dr3;
+            context->debug.x86_64_regs.dr6 = state.uds.ds64.__dr6;
+            context->debug.x86_64_regs.dr7 = state.uds.ds64.__dr7;
+        }
+        else
+#endif
+        {
 /* work around silly renaming of struct members in OS X 10.5 */
 #if __DARWIN_UNIX03 && defined(_STRUCT_X86_DEBUG_STATE32)
-        context->debug.i386_regs.dr0 = state.__dr0;
-        context->debug.i386_regs.dr1 = state.__dr1;
-        context->debug.i386_regs.dr2 = state.__dr2;
-        context->debug.i386_regs.dr3 = state.__dr3;
-        context->debug.i386_regs.dr6 = state.__dr6;
-        context->debug.i386_regs.dr7 = state.__dr7;
+            context->debug.i386_regs.dr0 = state.uds.ds32.__dr0;
+            context->debug.i386_regs.dr1 = state.uds.ds32.__dr1;
+            context->debug.i386_regs.dr2 = state.uds.ds32.__dr2;
+            context->debug.i386_regs.dr3 = state.uds.ds32.__dr3;
+            context->debug.i386_regs.dr6 = state.uds.ds32.__dr6;
+            context->debug.i386_regs.dr7 = state.uds.ds32.__dr7;
 #else
-        context->debug.i386_regs.dr0 = state.dr0;
-        context->debug.i386_regs.dr1 = state.dr1;
-        context->debug.i386_regs.dr2 = state.dr2;
-        context->debug.i386_regs.dr3 = state.dr3;
-        context->debug.i386_regs.dr6 = state.dr6;
-        context->debug.i386_regs.dr7 = state.dr7;
+            context->debug.i386_regs.dr0 = state.uds.ds32.dr0;
+            context->debug.i386_regs.dr1 = state.uds.ds32.dr1;
+            context->debug.i386_regs.dr2 = state.uds.ds32.dr2;
+            context->debug.i386_regs.dr3 = state.uds.ds32.dr3;
+            context->debug.i386_regs.dr6 = state.uds.ds32.dr6;
+            context->debug.i386_regs.dr7 = state.uds.ds32.dr7;
 #endif
+        }
         context->flags |= SERVER_CTX_DEBUG_REGISTERS;
     }
     mach_port_deallocate( mach_task_self(), port );
@@ -195,8 +216,8 @@ void get_thread_context( struct thread *thread, context_t *context, unsigned int
 /* set the thread x86 registers */
 void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 {
-#ifdef __i386__
-    x86_debug_state32_t state;
+#if defined(__i386__) || defined(__x86_64__)
+    x86_debug_state_t state;
     mach_msg_type_number_t count = sizeof(state) / sizeof(int);
     mach_msg_type_name_t type;
     mach_port_t port, process_port = get_process_port( thread->process );
@@ -213,32 +234,62 @@ void set_thread_context( struct thread *thread, const context_t *context, unsign
         return;
     }
 
-    /* Mac OS doesn't allow setting the global breakpoint flags */
-    dr7 = (context->debug.i386_regs.dr7 & ~0xaa) | ((context->debug.i386_regs.dr7 & 0xaa) >> 1);
 
+#ifdef __x86_64__
+    if (thread->process->cpu == CPU_x86_64)
+    {
+        /* Mac OS doesn't allow setting the global breakpoint flags */
+        dr7 = (context->debug.x86_64_regs.dr7 & ~0xaa) | ((context->debug.x86_64_regs.dr7 & 0xaa) >> 1);
+
+        state.dsh.flavor = x86_DEBUG_STATE64;
+        state.dsh.count = sizeof(state.uds.ds64) / sizeof(int);
+        state.uds.ds64.__dr0 = context->debug.x86_64_regs.dr0;
+        state.uds.ds64.__dr1 = context->debug.x86_64_regs.dr1;
+        state.uds.ds64.__dr2 = context->debug.x86_64_regs.dr2;
+        state.uds.ds64.__dr3 = context->debug.x86_64_regs.dr3;
+        state.uds.ds64.__dr4 = 0;
+        state.uds.ds64.__dr5 = 0;
+        state.uds.ds64.__dr6 = context->debug.x86_64_regs.dr6;
+        state.uds.ds64.__dr7 = dr7;
+    }
+    else
+#endif
+    {
+        dr7 = (context->debug.i386_regs.dr7 & ~0xaa) | ((context->debug.i386_regs.dr7 & 0xaa) >> 1);
+
+        state.dsh.flavor = x86_DEBUG_STATE32;
+        state.dsh.count = sizeof(state.uds.ds32) / sizeof(int);
 #if __DARWIN_UNIX03 && defined(_STRUCT_X86_DEBUG_STATE32)
-    state.__dr0 = context->debug.i386_regs.dr0;
-    state.__dr1 = context->debug.i386_regs.dr1;
-    state.__dr2 = context->debug.i386_regs.dr2;
-    state.__dr3 = context->debug.i386_regs.dr3;
-    state.__dr4 = 0;
-    state.__dr5 = 0;
-    state.__dr6 = context->debug.i386_regs.dr6;
-    state.__dr7 = dr7;
+        state.uds.ds32.__dr0 = context->debug.i386_regs.dr0;
+        state.uds.ds32.__dr1 = context->debug.i386_regs.dr1;
+        state.uds.ds32.__dr2 = context->debug.i386_regs.dr2;
+        state.uds.ds32.__dr3 = context->debug.i386_regs.dr3;
+        state.uds.ds32.__dr4 = 0;
+        state.uds.ds32.__dr5 = 0;
+        state.uds.ds32.__dr6 = context->debug.i386_regs.dr6;
+        state.uds.ds32.__dr7 = dr7;
 #else
-    state.dr0 = context->debug.i386_regs.dr0;
-    state.dr1 = context->debug.i386_regs.dr1;
-    state.dr2 = context->debug.i386_regs.dr2;
-    state.dr3 = context->debug.i386_regs.dr3;
-    state.dr4 = 0;
-    state.dr5 = 0;
-    state.dr6 = context->debug.i386_regs.dr6;
-    state.dr7 = dr7;
+        state.uds.ds32.dr0 = context->debug.i386_regs.dr0;
+        state.uds.ds32.dr1 = context->debug.i386_regs.dr1;
+        state.uds.ds32.dr2 = context->debug.i386_regs.dr2;
+        state.uds.ds32.dr3 = context->debug.i386_regs.dr3;
+        state.uds.ds32.dr4 = 0;
+        state.uds.ds32.dr5 = 0;
+        state.uds.ds32.dr6 = context->debug.i386_regs.dr6;
+        state.uds.ds32.dr7 = dr7;
 #endif
-    if (!thread_set_state( port, x86_DEBUG_STATE32, (thread_state_t)&state, count ))
+    }
+    if (!thread_set_state( port, x86_DEBUG_STATE, (thread_state_t)&state, count ))
     {
         if (thread->context)  /* update the cached values */
-            thread->context->debug.i386_regs = context->debug.i386_regs;
+        {
+#ifdef __x86_64__
+            if (thread->process->cpu == CPU_x86_64)
+                thread->context->debug.x86_64_regs = context->debug.x86_64_regs;
+            else
+#endif
+                thread->context->debug.i386_regs = context->debug.i386_regs;
+        }
     }
     mach_port_deallocate( mach_task_self(), port );
 #endif
-- 
2.4.2




More information about the wine-patches mailing list