10 #if defined __i386__ || __x86_64__
22 eprintf(
"error to get gpr registers in trace bit intel\n");
27 state->uts.ts32.__eflags = (
state->uts.ts32.__eflags &
29 (enable ? 0x100UL : 0);
31 state->uts.ts64.__rflags = (
state->uts.ts64.__rflags &
33 (enable ? 0x100UL : 0);
39 eprintf(
"error xnu_thread_set_gpr in modify_trace_bit intel\n");
55 unsigned int state_count = RZ_REG_STATE_SZ;
57 kr = thread_get_state (th->tid, RZ_REG_STATE_T,
58 (thread_state_t)&
state, &state_count);
59 if (kr != KERN_SUCCESS) {
60 eprintf (
"error modify_trace_bit\n");
63 state.srr1 = (
state.srr1 & ~0x400UL) | (enable ? 0x400UL : 0);
64 kr = thread_set_state (th->tid, RZ_REG_STATE_T,
65 (thread_state_t)&
state, state_count);
66 if (kr != KERN_SUCCESS) {
67 eprintf (
"Error to set thread state modificy_trace_bit ppc\n");
74 #elif __arm || __arm64 || __aarch64
77 #define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21))
78 #define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21))
79 #define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21))
80 #define BCR_M_RESERVED ((uint32_t)(3u << 21))
83 #define E_ENABLE_LINKING ((uint32_t)(1u << 20))
86 #define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5))
87 #define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6))
88 #define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7))
89 #define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8))
90 #define BAS_IMVA_0_1 ((uint32_t)(3u << 5))
91 #define BAS_IMVA_2_3 ((uint32_t)(3u << 7))
92 #define BAS_IMVA_ALL ((uint32_t)(0xfu << 5))
95 #define S_RSVD ((uint32_t)(0u << 1))
96 #define S_PRIV ((uint32_t)(1u << 1))
97 #define S_USER ((uint32_t)(2u << 1))
98 #define S_PRIV_USER ((S_PRIV) | (S_USER))
100 #define BCR_ENABLE ((uint32_t)(1u))
101 #define WCR_ENABLE ((uint32_t)(1u))
104 #define WCR_LOAD ((uint32_t)(1u << 3))
105 #define WCR_STORE ((uint32_t)(1u << 4))
109 #define SS_ENABLE ((uint32_t)(1u))
111 #if __arm || __arm__ || __armv7 || __armv7__
112 static bool is_thumb_32(
ut16 op) {
113 return (((
op & 0xE000) == 0xE000) && (
op & 0x1800));
120 eprintf(
"error to get drx registers modificy_trace_bit arm\n");
123 #if __arm64 || __arm64__ || __aarch64 || __aarch64__
124 if (th->
flavor == ARM_DEBUG_STATE32) {
125 arm_debug_state32_t *
state = &th->debug.drx32;
127 state->__mdscr_el1 =
state->__mdscr_el1 | SS_ENABLE;
129 state->__mdscr_el1 =
state->__mdscr_el1 & ~SS_ENABLE;
131 }
else if (th->
flavor == ARM_DEBUG_STATE64) {
132 arm_debug_state64_t *
state = &th->debug.drx64;
134 state->__mdscr_el1 =
state->__mdscr_el1 | SS_ENABLE;
136 state->__mdscr_el1 =
state->__mdscr_el1 & ~SS_ENABLE;
139 #elif __arm || __arm__ || __armv7 || __armv7__
140 if (th->
flavor == ARM_DEBUG_STATE) {
142 arm_debug_state_t *
state = &th->debug.drx;
146 eprintf(
"error to get gpr register modificy_trace_bit arm\n");
151 static ut64 chained_address = 0;
156 if (chained_address) {
157 state->__bvr[
i] = chained_address & 0xFFFFFFFCu;
160 state->__bvr[
i] =
regs->ts_32.__pc & 0xFFFFFFFCu;
162 state->__bcr[
i] = BCR_M_IMVA_MISMATCH |
167 if (
regs->ts_32.__cpsr & 0x20) {
170 if (
regs->ts_32.__pc & 2)
171 state->__bcr[
i] |= BAS_IMVA_2_3;
173 state->__bcr[
i] |= BAS_IMVA_0_1;
175 eprintf(
"Failed to read opcode modify_trace_bit\n");
178 if (is_thumb_32(
op)) {
179 chained_address =
regs->ts_32.__pc + 2;
182 state->__bcr[
i] |= BAS_IMVA_ALL;
186 state->__bcr[
i] |= BAS_IMVA_ALL;
189 for (
i =
i + 1;
i < 16;
i++) {
195 if (
state->__bcr[
i] & BCR_ENABLE) {
203 eprintf(
"Bad flavor modificy_trace_bit arm\n");
208 eprintf(
"error to set drx modificy_trace_bit arm\n");
216 static int modify_trace_bit(
RzDebug *
dbg, xnu_thread *th,
int enable) {
220 #error "unknown architecture"
235 if (kr != KERN_SUCCESS) {
236 eprintf(
"fail to restore exception ports\n");
241 if (kr != KERN_SUCCESS) {
242 eprintf(
"failed to deallocate exception port\n");
250 mach_msg_header_t *rh = &reply->Head;
251 rh->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(hdr->msgh_bits), 0);
252 rh->msgh_remote_port = hdr->msgh_remote_port;
253 rh->msgh_size = (mach_msg_size_t)
sizeof(mig_reply_error_t);
254 rh->msgh_local_port = MACH_PORT_NULL;
255 rh->msgh_id = hdr->msgh_id + 100;
256 reply->NDR = NDR_record;
257 reply->RetCode =
code;
270 if (!(
msg->hdr.msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
275 if (
msg->hdr.msgh_id > 2405 ||
msg->hdr.msgh_id < 2401) {
279 if (
msg->hdr.msgh_size <
280 sizeof(mach_msg_header_t) +
sizeof(mach_msg_body_t) +
281 2 *
sizeof(mach_msg_port_descriptor_t) +
282 sizeof(NDR_record_t) +
sizeof(exception_type_t) +
283 sizeof(mach_msg_type_number_t) +
284 sizeof(mach_exception_data_t))
287 if (
msg->NDR.mig_vers != NDR_PROTOCOL_2_0 ||
288 msg->NDR.if_vers != NDR_PROTOCOL_2_0 ||
289 msg->NDR.mig_encoding != NDR_record.mig_encoding ||
290 msg->NDR.int_rep != NDR_record.int_rep ||
291 msg->NDR.char_rep != NDR_record.char_rep ||
292 msg->NDR.float_rep != NDR_record.float_rep) {
300 kr = mach_port_deallocate(mach_task_self(),
msg->task.name);
301 if (kr != KERN_SUCCESS) {
302 eprintf(
"validate_mach_message: failed to deallocate task port\n");
304 kr = mach_port_deallocate(mach_task_self(),
msg->thread.name);
305 if (kr != KERN_SUCCESS) {
306 eprintf(
"validate_mach_message2: failed to deallocated task port\n");
315 if (
msg->hdr.msgh_id == 0x48) {
325 *ret_code = KERN_SUCCESS;
328 switch (
msg->exception) {
331 *ret_code = KERN_FAILURE;
332 kr = task_suspend(
msg->task.name);
333 if (kr != KERN_SUCCESS) {
334 eprintf(
"failed to suspend task bad access\n");
338 case EXC_BAD_INSTRUCTION:
340 *ret_code = KERN_FAILURE;
341 kr = task_suspend(
msg->task.name);
342 if (kr != KERN_SUCCESS) {
343 eprintf(
"failed to suspend task bad instruction\n");
345 eprintf(
"EXC_BAD_INSTRUCTION\n");
360 if (
code == EXC_SOFT_SIGNAL) {
376 kr = task_suspend(
msg->task.name);
377 if (kr != KERN_SUCCESS) {
382 kr = task_suspend(
msg->task.name);
383 if (kr != KERN_SUCCESS) {
384 eprintf(
"failed to suspend task breakpoint\n");
392 kr = mach_port_deallocate(mach_task_self(),
msg->task.name);
393 if (kr != KERN_SUCCESS) {
394 eprintf(
"failed to deallocate task port\n");
396 kr = mach_port_deallocate(mach_task_self(),
msg->thread.name);
397 if (kr != KERN_SUCCESS) {
398 eprintf(
"failed to deallocated task port\n");
414 mig_reply_error_t reply;
425 MACH_RCV_MSG | MACH_RCV_INTERRUPT | (timeout_ms ? MACH_RCV_TIMEOUT : 0), 0,
427 timeout_ms ? timeout_ms : MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
428 if (kr == MACH_RCV_INTERRUPTED) {
431 }
else if (kr == MACH_RCV_TIMED_OUT) {
435 }
else if (kr != MACH_MSG_SUCCESS) {
449 kr = mach_msg(&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
450 reply.Head.msgh_size, 0,
451 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
453 if (reply.Head.msgh_remote_port != 0 && kr != MACH_MSG_SUCCESS) {
454 kr = mach_port_deallocate(mach_task_self(), reply.Head.msgh_remote_port);
455 if (kr != KERN_SUCCESS) {
456 eprintf(
"failed to deallocate reply port\n");
464 kr = mach_msg(&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
465 reply.Head.msgh_size, 0,
468 if (reply.Head.msgh_remote_port != 0 && kr != MACH_MSG_SUCCESS) {
469 kr = mach_port_deallocate(mach_task_self(), reply.Head.msgh_remote_port);
470 if (kr != KERN_SUCCESS)
471 eprintf(
"failed to deallocate reply port\n");
484 mach_port_t exception_port = MACH_PORT_NULL;
485 mach_port_t req_port;
487 mach_port_t task_self = mach_task_self();
490 eprintf(
"error to get task for the debuggee process"
491 " xnu_start_exception_thread\n");
494 if (!MACH_PORT_VALID(task_self)) {
495 eprintf(
"error to get the task for the current process"
496 " xnu_start_exception_thread\n");
500 kr = mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE,
504 kr = mach_port_insert_right(task_self, exception_port, exception_port,
505 MACH_MSG_TYPE_MAKE_SEND);
510 kr = task_swap_exception_ports(task, EXC_MASK_ALL, exception_port,
511 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE,
515 kr = mach_port_request_notification(task_self, task, MACH_NOTIFY_DEAD_NAME,
516 0, exception_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &req_port);
517 if (kr != KERN_SUCCESS) {
518 eprintf(
"Termination notification request failed\n");
RZ_API ut64 rz_debug_reg_get(RzDebug *dbg, const char *name)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
#define rz_return_val_if_fail(expr, val)
@ RZ_DEBUG_REASON_ILLEGAL
@ RZ_DEBUG_REASON_UNKNOWN
@ RZ_DEBUG_REASON_BREAKPOINT
@ RZ_DEBUG_REASON_SEGFAULT
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API const char * rz_signal_to_string(int code)
static struct sockaddr static addrlen static backlog const void msg
mach_msg_type_number_t count
mach_port_t exception_port
mach_port_t ports[EXC_TYPES_COUNT]
thread_state_flavor_t flavors[EXC_TYPES_COUNT]
exception_mask_t masks[EXC_TYPES_COUNT]
exception_behavior_t behaviors[EXC_TYPES_COUNT]
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
task_t pid_to_task(int pid)
#define RZ_DEBUG_REASON_MACH_RCV_INTERRUPTED
static bool validate_mach_message(RzDebug *dbg, exc_msg *msg)
static bool handle_dead_notify(RzDebug *dbg, exc_msg *msg)
static xnu_exception_info ex
static int handle_exception_message(RzDebug *dbg, exc_msg *msg, int *ret_code, bool quiet_signal)
RZ_IPI bool xnu_restore_exception_ports(int pid)
RZ_IPI RzDebugReasonType xnu_wait_for_exception(RzDebug *dbg, int pid, ut32 timeout_ms, bool quiet_signal)
RZ_IPI bool xnu_create_exception_thread(RzDebug *dbg)
static void encode_reply(mig_reply_error_t *reply, mach_msg_header_t *hdr, int code)
RZ_IPI bool rz_xnu_thread_set_gpr(RzDebug *dbg, xnu_thread_t *thread)
RZ_IPI bool rz_xnu_thread_set_drx(RzDebug *dbg, xnu_thread_t *thread)
RZ_IPI bool rz_xnu_thread_get_gpr(RzDebug *dbg, xnu_thread_t *thread)
RZ_IPI bool rz_xnu_thread_get_drx(RzDebug *dbg, xnu_thread_t *thread)
#define RETURN_ON_MACH_ERROR(msg, retval)
RZ_IPI bool xnu_modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable)