server: Get debug registers on 64-bit Mac OS.

This commit is contained in:
Charles Davis 2015-06-04 16:52:27 -06:00 committed by Alexandre Julliard
parent 82dd799d52
commit b2aa984743
1 changed files with 90 additions and 39 deletions

View File

@ -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);
#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;
#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;
#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
if (!thread_set_state( port, x86_DEBUG_STATE32, (thread_state_t)&state, count ))
{
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.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.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_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