[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