server: Get debug registers on 64-bit Mac OS.
This commit is contained in:
parent
82dd799d52
commit
b2aa984743
129
server/mach.c
129
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);
|
||||
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue