De-include xnu_threads.c and xnu_excthreads.c
With XNU_USE_PTRACE removed, these source files can now be compiled as standalone objects unconditionally.
This commit is contained in:
parent
c671083925
commit
c90ebb6b68
6 changed files with 105 additions and 92 deletions
|
|
@ -93,8 +93,8 @@ if has_debugger
|
|||
'p/native/xnu/xnu_debug.c',
|
||||
#'p/native/xnu/trap_arm.c',
|
||||
#'p/native/xnu/trap_x86.c',
|
||||
#'p/native/xnu/xnu_excthreads.c',
|
||||
#'p/native/xnu/xnu_threads.c',
|
||||
'p/native/xnu/xnu_excthreads.c',
|
||||
'p/native/xnu/xnu_threads.c',
|
||||
]
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
// SPDX-FileCopyrightText: 2015-2019 alvaro_fe <alvaro.felipe91@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_userconf.h>
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
#include <rz_debug.h>
|
||||
#include <rz_reg.h>
|
||||
#include <rz_lib.h>
|
||||
|
|
@ -21,8 +17,7 @@
|
|||
|
||||
static task_t task_dbg = 0;
|
||||
#include "xnu_debug.h"
|
||||
#include "xnu_threads.c"
|
||||
#include "xnu_excthreads.c"
|
||||
#include "xnu_threads.h"
|
||||
|
||||
extern int proc_regionfilename(int pid, uint64_t address, void *buffer, uint32_t buffersize);
|
||||
|
||||
|
|
@ -59,50 +54,6 @@ typedef struct {
|
|||
ut64 image_file_mod_date;
|
||||
} DyldImageInfo64;
|
||||
|
||||
/* XXX: right now it just returns the first thread, not the one selected in dbg->tid */
|
||||
static thread_t getcurthread(RzDebug *dbg) {
|
||||
thread_t th;
|
||||
thread_array_t threads = NULL;
|
||||
unsigned int n_threads = 0;
|
||||
task_t t = pid_to_task(dbg->pid);
|
||||
if (!t) {
|
||||
return -1;
|
||||
}
|
||||
if (task_threads(t, &threads, &n_threads) != KERN_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
if (n_threads > 0) {
|
||||
memcpy(&th, threads, sizeof(th));
|
||||
} else {
|
||||
th = -1;
|
||||
}
|
||||
vm_deallocate(t, (vm_address_t)threads, n_threads * sizeof(thread_act_t));
|
||||
return th;
|
||||
}
|
||||
|
||||
static xnu_thread_t *get_xnu_thread(RzDebug *dbg, int tid) {
|
||||
if (!dbg || tid < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!xnu_update_thread_list(dbg)) {
|
||||
eprintf("Failed to update thread_list xnu_udpate_thread_list\n");
|
||||
return NULL;
|
||||
}
|
||||
// TODO get the current thread
|
||||
RzListIter *it = rz_list_find(dbg->threads, (const void *)(size_t)&tid,
|
||||
(RzListComparator)&thread_find);
|
||||
if (!it) {
|
||||
tid = getcurthread(dbg);
|
||||
it = rz_list_find(dbg->threads, (const void *)(size_t)&tid,
|
||||
(RzListComparator)&thread_find);
|
||||
if (!it) {
|
||||
eprintf("Thread not found get_xnu_thread\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (xnu_thread_t *)it->data;
|
||||
}
|
||||
|
||||
static task_t task_for_pid_workaround(int Pid) {
|
||||
host_t myhost = mach_host_self();
|
||||
mach_port_t psDefault = 0;
|
||||
|
|
@ -154,10 +105,6 @@ static task_t task_for_pid_ios9pangu(int pid) {
|
|||
return task;
|
||||
}
|
||||
|
||||
int xnu_wait(RzDebug *dbg, int pid) {
|
||||
return __xnu_wait(dbg, pid);
|
||||
}
|
||||
|
||||
bool xnu_step(RzDebug *dbg) {
|
||||
// we must find a way to get the current thread not just the first one
|
||||
task_t task = pid_to_task(dbg->pid);
|
||||
|
|
@ -165,11 +112,11 @@ bool xnu_step(RzDebug *dbg) {
|
|||
eprintf("step failed on task %d for pid %d\n", task, dbg->tid);
|
||||
return false;
|
||||
}
|
||||
xnu_thread_t *th = get_xnu_thread(dbg, getcurthread(dbg));
|
||||
xnu_thread_t *th = rz_xnu_get_thread(dbg, rz_xnu_get_cur_thread(dbg));
|
||||
if (!th) {
|
||||
return false;
|
||||
}
|
||||
int ret = set_trace_bit(dbg, th);
|
||||
int ret = xnu_set_trace_bit(dbg, th);
|
||||
if (!ret) {
|
||||
eprintf("xnu_step modificy_trace_bit error\n");
|
||||
return false;
|
||||
|
|
@ -257,14 +204,14 @@ int xnu_continue(RzDebug *dbg, int pid, int tid, int sig) {
|
|||
return false;
|
||||
}
|
||||
// TODO free refs count threads
|
||||
xnu_thread_t *th = get_xnu_thread(dbg, getcurthread(dbg));
|
||||
xnu_thread_t *th = rz_xnu_get_thread(dbg, rz_xnu_get_cur_thread(dbg));
|
||||
if (!th) {
|
||||
eprintf("failed to get thread in xnu_continue\n");
|
||||
return false;
|
||||
}
|
||||
// disable trace bit if enable
|
||||
if (th->stepping) {
|
||||
if (!clear_trace_bit(dbg, th)) {
|
||||
if (!xnu_clear_trace_bit(dbg, th)) {
|
||||
eprintf("error clearing trace bit in xnu_continue\n");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -305,7 +252,7 @@ char *xnu_reg_profile(RzDebug *dbg) {
|
|||
// is not implemented yet i don't care so much
|
||||
int xnu_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
|
||||
bool ret;
|
||||
xnu_thread_t *th = get_xnu_thread(dbg, getcurthread(dbg));
|
||||
xnu_thread_t *th = rz_xnu_get_thread(dbg, rz_xnu_get_cur_thread(dbg));
|
||||
if (!th) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -324,7 +271,7 @@ int xnu_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
|
|||
#elif __arm || __armv7 || __arm__ || __armv7__
|
||||
memcpy(&th->debug.drx, buf, RZ_MIN(size, sizeof(th->debug.drx)));
|
||||
#endif
|
||||
ret = xnu_thread_set_drx(dbg, th);
|
||||
ret = rz_xnu_thread_set_drx(dbg, th);
|
||||
break;
|
||||
default:
|
||||
// th->gpr has a header and the state we should copy on the state only
|
||||
|
|
@ -333,14 +280,14 @@ int xnu_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
|
|||
#else
|
||||
memcpy(&th->gpr.uts, buf, RZ_MIN(size, sizeof(th->gpr.uts)));
|
||||
#endif
|
||||
ret = xnu_thread_set_gpr(dbg, th);
|
||||
ret = rz_xnu_thread_set_gpr(dbg, th);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xnu_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
|
||||
xnu_thread_t *th = get_xnu_thread(dbg, getcurthread(dbg));
|
||||
xnu_thread_t *th = rz_xnu_get_thread(dbg, rz_xnu_get_cur_thread(dbg));
|
||||
if (!th) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -348,12 +295,12 @@ int xnu_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
|
|||
case RZ_REG_TYPE_SEG:
|
||||
case RZ_REG_TYPE_FLG:
|
||||
case RZ_REG_TYPE_GPR:
|
||||
if (!xnu_thread_get_gpr(dbg, th)) {
|
||||
if (!rz_xnu_thread_get_gpr(dbg, th)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case RZ_REG_TYPE_DRX:
|
||||
if (!xnu_thread_get_drx(dbg, th)) {
|
||||
if (!rz_xnu_thread_get_drx(dbg, th)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
|
@ -373,7 +320,7 @@ int xnu_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
|
|||
RzDebugMap *xnu_map_alloc(RzDebug *dbg, ut64 addr, int size) {
|
||||
kern_return_t ret;
|
||||
ut8 *base = (ut8 *)addr;
|
||||
xnu_thread_t *th = get_xnu_thread(dbg, dbg->tid);
|
||||
xnu_thread_t *th = rz_xnu_get_thread(dbg, dbg->tid);
|
||||
bool anywhere = !VM_FLAGS_ANYWHERE;
|
||||
if (!th) {
|
||||
return NULL;
|
||||
|
|
@ -393,7 +340,7 @@ RzDebugMap *xnu_map_alloc(RzDebug *dbg, ut64 addr, int size) {
|
|||
}
|
||||
|
||||
int xnu_map_dealloc(RzDebug *dbg, ut64 addr, int size) {
|
||||
xnu_thread_t *th = get_xnu_thread(dbg, dbg->tid);
|
||||
xnu_thread_t *th = rz_xnu_get_thread(dbg, dbg->tid);
|
||||
if (!th) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -488,10 +435,10 @@ RzList *xnu_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
|||
RzListIter *iter;
|
||||
xnu_thread_t *thread;
|
||||
RZ_REG_T state;
|
||||
xnu_update_thread_list(dbg);
|
||||
rz_xnu_update_thread_list(dbg);
|
||||
list->free = (RzListFree)&rz_debug_pid_free;
|
||||
rz_list_foreach (dbg->threads, iter, thread) {
|
||||
if (!xnu_thread_get_gpr(dbg, thread)) {
|
||||
if (!rz_xnu_thread_get_gpr(dbg, thread)) {
|
||||
eprintf("Failed to get gpr registers xnu_thread_list\n");
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#define _XNU_DEBUG_H
|
||||
|
||||
#include <rz_util/rz_log.h>
|
||||
#include <rz_debug.h>
|
||||
|
||||
#define LOG_MACH_ERROR(name, rc) \
|
||||
do { \
|
||||
|
|
@ -282,7 +283,7 @@ RzDebugMap *xnu_map_alloc(RzDebug *dbg, ut64 addr, int size);
|
|||
int xnu_map_dealloc(RzDebug *dbg, ut64 addr, int size);
|
||||
int xnu_map_protect(RzDebug *dbg, ut64 addr, int size, int perms);
|
||||
int xnu_init(void);
|
||||
int xnu_wait(RzDebug *dbg, int pid);
|
||||
RZ_IPI int xnu_wait(RzDebug *dbg, int pid);
|
||||
RzDebugPid *xnu_get_pid(int pid);
|
||||
RzList *xnu_dbg_maps(RzDebug *dbg, int only_modules);
|
||||
RzList *xnu_thread_list(RzDebug *dbg, int pid, RzList *list);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2022 Florian Märkl <info@florianmaerkl.de>
|
||||
// SPDX-FileCopyrightText: 2015 alvarofe <alvaro.felipe91@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
// FIXME deallocate all the port when they are not longer needed
|
||||
|
||||
#include "xnu_debug.h"
|
||||
#include "xnu_threads.h"
|
||||
|
||||
#define set_trace_bit(dbg, thread) modify_trace_bit(dbg, thread, 1)
|
||||
#define clear_trace_bit(dbg, thread) modify_trace_bit(dbg, thread, 0)
|
||||
|
||||
#if defined __i386__ || __x86_64__ // intel processors
|
||||
|
||||
/* Set/clear bit 8 (Trap Flag) of the EFLAGS processor control
|
||||
|
|
@ -15,10 +14,10 @@
|
|||
ENABLE is a boolean, indicating whether to set (1) the Trap Flag
|
||||
or clear it (0). */
|
||||
|
||||
static bool modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
||||
RZ_IPI bool xnu_modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
||||
RZ_REG_T *state;
|
||||
int ret;
|
||||
ret = xnu_thread_get_gpr(dbg, th);
|
||||
ret = rz_xnu_thread_get_gpr(dbg, th);
|
||||
if (!ret) {
|
||||
eprintf("error to get gpr registers in trace bit intel\n");
|
||||
return false;
|
||||
|
|
@ -36,7 +35,7 @@ static bool modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
|||
eprintf("Invalid bit size\n");
|
||||
return false;
|
||||
}
|
||||
if (!xnu_thread_set_gpr(dbg, th)) {
|
||||
if (!rz_xnu_thread_set_gpr(dbg, th)) {
|
||||
eprintf("error xnu_thread_set_gpr in modify_trace_bit intel\n");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -46,11 +45,11 @@ static bool modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
|||
#elif __POWERPC__ // ppc processor
|
||||
// XXX poor support at this stage i don't care so much. Once intel and arm done it could be done
|
||||
// TODO add better support for ppc
|
||||
static bool modify_trace_bit(RzDebug *dbg, void *th, int enable) {
|
||||
RZ_IPI bool xnu_modify_trace_bit(RzDebug *dbg, void *th, int enable) {
|
||||
return false;
|
||||
}
|
||||
#if 0
|
||||
static bool modify_trace_bit(RzDebug *dbg, xnu_thread *th, int enable) {
|
||||
static bool xnu_modify_trace_bit(RzDebug *dbg, xnu_thread *th, int enable) {
|
||||
return false;
|
||||
RZ_REG_T state;
|
||||
unsigned int state_count = RZ_REG_STATE_SZ;
|
||||
|
|
@ -115,8 +114,8 @@ static bool is_thumb_32(ut16 op) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static int modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
||||
int ret = xnu_thread_get_drx(dbg, th);
|
||||
RZ_IPI bool xnu_modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
||||
int ret = rz_xnu_thread_get_drx(dbg, th);
|
||||
if (!ret) {
|
||||
eprintf("error to get drx registers modificy_trace_bit arm\n");
|
||||
return false;
|
||||
|
|
@ -142,7 +141,7 @@ static int modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
|||
int i = 0;
|
||||
arm_debug_state_t *state = &th->debug.drx;
|
||||
RZ_REG_T *regs;
|
||||
ret = xnu_thread_get_gpr(dbg, th);
|
||||
ret = rz_xnu_thread_get_gpr(dbg, th);
|
||||
if (!ret) {
|
||||
eprintf("error to get gpr register modificy_trace_bit arm\n");
|
||||
return false;
|
||||
|
|
@ -205,7 +204,7 @@ static int modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable) {
|
|||
return false;
|
||||
}
|
||||
// set state
|
||||
if (!xnu_thread_set_drx(dbg, th)) {
|
||||
if (!rz_xnu_thread_set_drx(dbg, th)) {
|
||||
eprintf("error to set drx modificy_trace_bit arm\n");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -224,7 +223,7 @@ static int modify_trace_bit(RzDebug *dbg, xnu_thread *th, int enable) {
|
|||
// TODO: Tuck this into RzDebug; `void *user` seems like a good candidate.
|
||||
static xnu_exception_info ex = { { 0 } };
|
||||
|
||||
static bool xnu_restore_exception_ports(int pid) {
|
||||
RZ_IPI bool xnu_restore_exception_ports(int pid) {
|
||||
kern_return_t kr;
|
||||
int i;
|
||||
task_t task = pid_to_task(pid);
|
||||
|
|
@ -375,7 +374,7 @@ static int handle_exception_message(RzDebug *dbg, exc_msg *msg, int *ret_code) {
|
|||
}
|
||||
|
||||
// TODO improve this code
|
||||
static int __xnu_wait(RzDebug *dbg, int pid) {
|
||||
RZ_IPI int xnu_wait(RzDebug *dbg, int pid) {
|
||||
// here comes the important thing
|
||||
kern_return_t kr;
|
||||
int ret_code, reason = RZ_DEBUG_REASON_UNKNOWN;
|
||||
|
|
@ -440,7 +439,7 @@ static int __xnu_wait(RzDebug *dbg, int pid) {
|
|||
return reason;
|
||||
}
|
||||
|
||||
bool xnu_create_exception_thread(RzDebug *dbg) {
|
||||
RZ_IPI bool xnu_create_exception_thread(RzDebug *dbg) {
|
||||
#if __POWERPC__
|
||||
return false;
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2009-2019 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_userconf.h>
|
||||
#include <rz_debug.h>
|
||||
|
||||
// TODO much work remains to be done
|
||||
#include "xnu_debug.h"
|
||||
|
|
@ -23,7 +23,7 @@ static void xnu_thread_free(xnu_thread_t *thread) {
|
|||
}
|
||||
|
||||
// XXX this should work as long as in arm trace bit relies on this
|
||||
static bool xnu_thread_get_drx(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
RZ_IPI bool rz_xnu_thread_get_drx(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
rz_return_val_if_fail(dbg && thread, false);
|
||||
kern_return_t rc;
|
||||
#if __x86_64__ || __i386__
|
||||
|
|
@ -67,7 +67,7 @@ static bool xnu_thread_get_drx(RzDebug *dbg, xnu_thread_t *thread) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool xnu_thread_set_drx(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
RZ_IPI bool rz_xnu_thread_set_drx(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
rz_return_val_if_fail(dbg && thread, false);
|
||||
kern_return_t rc;
|
||||
#if __i386__ || __x86_64__
|
||||
|
|
@ -127,7 +127,7 @@ static bool xnu_thread_set_drx(RzDebug *dbg, xnu_thread_t *thread) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool xnu_thread_set_gpr(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
RZ_IPI bool rz_xnu_thread_set_gpr(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
rz_return_val_if_fail(dbg && thread, false);
|
||||
kern_return_t rc;
|
||||
RZ_REG_T *regs = (RZ_REG_T *)&thread->gpr;
|
||||
|
|
@ -181,7 +181,7 @@ static bool xnu_thread_set_gpr(RzDebug *dbg, xnu_thread_t *thread) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool xnu_thread_get_gpr(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
RZ_IPI bool rz_xnu_thread_get_gpr(RzDebug *dbg, xnu_thread_t *thread) {
|
||||
rz_return_val_if_fail(dbg && thread, false);
|
||||
RZ_REG_T *regs = &thread->gpr;
|
||||
if (!regs) {
|
||||
|
|
@ -287,7 +287,7 @@ static int thread_find(thread_t *port, xnu_thread_t *a) {
|
|||
return (a && port && (a->port == *port)) ? 0 : 1;
|
||||
}
|
||||
|
||||
static int xnu_update_thread_list(RzDebug *dbg) {
|
||||
RZ_IPI int rz_xnu_update_thread_list(RzDebug *dbg) {
|
||||
thread_array_t thread_list = NULL;
|
||||
unsigned int thread_count = 0;
|
||||
xnu_thread_t *thread;
|
||||
|
|
@ -374,3 +374,47 @@ static int xnu_update_thread_list(RzDebug *dbg) {
|
|||
thread_count * sizeof(thread_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_IPI xnu_thread_t *rz_xnu_get_thread(RzDebug *dbg, int tid) {
|
||||
if (!dbg || tid < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!rz_xnu_update_thread_list(dbg)) {
|
||||
eprintf("Failed to update thread_list xnu_udpate_thread_list\n");
|
||||
return NULL;
|
||||
}
|
||||
// TODO get the current thread
|
||||
RzListIter *it = rz_list_find(dbg->threads, (const void *)(size_t)&tid,
|
||||
(RzListComparator)&thread_find);
|
||||
if (!it) {
|
||||
tid = rz_xnu_get_cur_thread(dbg);
|
||||
it = rz_list_find(dbg->threads, (const void *)(size_t)&tid,
|
||||
(RzListComparator)&thread_find);
|
||||
if (!it) {
|
||||
eprintf("Thread not found get_xnu_thread\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (xnu_thread_t *)it->data;
|
||||
}
|
||||
|
||||
/* XXX: right now it just returns the first thread, not the one selected in dbg->tid */
|
||||
RZ_IPI thread_t rz_xnu_get_cur_thread(RzDebug *dbg) {
|
||||
thread_t th;
|
||||
thread_array_t threads = NULL;
|
||||
unsigned int n_threads = 0;
|
||||
task_t t = pid_to_task(dbg->pid);
|
||||
if (!t) {
|
||||
return -1;
|
||||
}
|
||||
if (task_threads(t, &threads, &n_threads) != KERN_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
if (n_threads > 0) {
|
||||
memcpy(&th, threads, sizeof(th));
|
||||
} else {
|
||||
th = -1;
|
||||
}
|
||||
vm_deallocate(t, (vm_address_t)threads, n_threads * sizeof(thread_act_t));
|
||||
return th;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#ifndef _INCLUDE_XNU_THREADS_H_
|
||||
#define _INCLUDE_XNU_THREADS_H_
|
||||
|
||||
#include <rz_debug.h>
|
||||
#include <mach/mach_vm.h>
|
||||
|
||||
#if __POWERPC__
|
||||
// TODO add better support for PPC
|
||||
#define RZ_REG_T ppc_thread_state_t
|
||||
|
|
@ -91,4 +94,23 @@ typedef struct _rep_msg {
|
|||
kern_return_t ret_code;
|
||||
} rep_msg;
|
||||
|
||||
RZ_IPI int rz_xnu_update_thread_list(RzDebug *dbg);
|
||||
RZ_IPI xnu_thread_t *rz_xnu_get_thread(RzDebug *dbg, int tid);
|
||||
RZ_IPI thread_t rz_xnu_get_cur_thread(RzDebug *dbg);
|
||||
RZ_IPI bool rz_xnu_thread_set_drx(RzDebug *dbg, xnu_thread_t *thread);
|
||||
RZ_IPI bool rz_xnu_thread_set_gpr(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);
|
||||
|
||||
RZ_IPI bool xnu_modify_trace_bit(RzDebug *dbg, xnu_thread_t *th, int enable);
|
||||
static inline bool xnu_set_trace_bit(RzDebug *dbg, xnu_thread_t *th) {
|
||||
return xnu_modify_trace_bit(dbg, th, 1);
|
||||
}
|
||||
static inline bool xnu_clear_trace_bit(RzDebug *dbg, xnu_thread_t *th) {
|
||||
return xnu_modify_trace_bit(dbg, th, 0);
|
||||
}
|
||||
|
||||
RZ_IPI bool xnu_create_exception_thread(RzDebug *dbg);
|
||||
RZ_IPI bool xnu_restore_exception_ports(int pid);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue