Rizin
unix-like reverse engineering framework and cli tools
xnu_threads.c File Reference
#include <rz_debug.h>
#include "xnu_debug.h"
#include "xnu_threads.h"

Go to the source code of this file.

Functions

static void xnu_thread_free (xnu_thread_t *thread)
 
RZ_IPI bool rz_xnu_thread_get_drx (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_set_gpr (RzDebug *dbg, xnu_thread_t *thread)
 
RZ_IPI bool rz_xnu_thread_get_gpr (RzDebug *dbg, xnu_thread_t *thread)
 
static bool xnu_fill_info_thread (RzDebug *dbg, xnu_thread_t *thread)
 
static xnu_thread_txnu_get_thread_with_info (RzDebug *dbg, thread_t port)
 
static int xnu_update_thread_info (RzDebug *dbg, xnu_thread_t *thread)
 
static int thread_find (thread_t *port, xnu_thread_t *a)
 
RZ_IPI int rz_xnu_update_thread_list (RzDebug *dbg)
 
RZ_IPI xnu_thread_trz_xnu_get_thread (RzDebug *dbg, int tid)
 
RZ_IPI thread_t rz_xnu_get_cur_thread (RzDebug *dbg)
 

Function Documentation

◆ rz_xnu_get_cur_thread()

RZ_IPI thread_t rz_xnu_get_cur_thread ( RzDebug dbg)

Definition at line 402 of file xnu_threads.c.

402  {
403  thread_t th;
404  thread_array_t threads = NULL;
405  unsigned int n_threads = 0;
406  task_t t = pid_to_task(dbg->pid);
407  if (!t) {
408  return -1;
409  }
410  if (task_threads(t, &threads, &n_threads) != KERN_SUCCESS) {
411  return -1;
412  }
413  if (n_threads > 0) {
414  memcpy(&th, threads, sizeof(th));
415  } else {
416  th = -1;
417  }
418  vm_deallocate(mach_task_self(), (vm_address_t)threads, n_threads * sizeof(thread_act_t));
419  return th;
420 }
#define NULL
Definition: cris-opc.c:27
RzDebug * dbg
Definition: desil.c:30
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static uv_thread_t * threads
Definition: threadpool.c:38
task_t pid_to_task(int pid)
Definition: xnu_debug.c:498

References dbg, memcpy(), NULL, rz_debug_t::pid, pid_to_task(), and threads.

Referenced by rz_xnu_get_thread(), xnu_continue(), xnu_reg_read(), xnu_reg_write(), and xnu_step().

◆ rz_xnu_get_thread()

RZ_IPI xnu_thread_t* rz_xnu_get_thread ( RzDebug dbg,
int  tid 
)

Definition at line 378 of file xnu_threads.c.

378  {
379  if (!dbg || tid < 0) {
380  return NULL;
381  }
383  eprintf("Failed to update thread_list xnu_udpate_thread_list\n");
384  return NULL;
385  }
386  // TODO get the current thread
387  RzListIter *it = rz_list_find(dbg->threads, (const void *)(size_t)&tid,
389  if (!it) {
390  tid = rz_xnu_get_cur_thread(dbg);
391  it = rz_list_find(dbg->threads, (const void *)(size_t)&tid,
393  if (!it) {
394  eprintf("Thread not found get_xnu_thread\n");
395  return NULL;
396  }
397  }
398  return (xnu_thread_t *)it->data;
399 }
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
#define eprintf(x, y...)
Definition: rlcc.c:7
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
RzList * threads
Definition: rz_debug.h:251
void * data
Definition: rz_list.h:14
RZ_IPI int rz_xnu_update_thread_list(RzDebug *dbg)
Definition: xnu_threads.c:290
RZ_IPI thread_t rz_xnu_get_cur_thread(RzDebug *dbg)
Definition: xnu_threads.c:402
static int thread_find(thread_t *port, xnu_thread_t *a)
Definition: xnu_threads.c:286

References rz_list_iter_t::data, dbg, eprintf, NULL, rz_list_find(), rz_xnu_get_cur_thread(), rz_xnu_update_thread_list(), thread_find(), and rz_debug_t::threads.

Referenced by xnu_continue(), xnu_map_alloc(), xnu_map_dealloc(), xnu_reg_read(), xnu_reg_write(), and xnu_step().

◆ rz_xnu_thread_get_drx()

RZ_IPI bool rz_xnu_thread_get_drx ( RzDebug dbg,
xnu_thread_t thread 
)

Definition at line 26 of file xnu_threads.c.

26  {
27  rz_return_val_if_fail(dbg && thread, false);
28  kern_return_t rc;
29 #if __x86_64__ || __i386__
30  thread->flavor = x86_DEBUG_STATE;
31  thread->count = x86_DEBUG_STATE_COUNT;
32  thread->state_size = (dbg->bits == RZ_SYS_BITS_64)
33  ? sizeof(x86_debug_state64_t)
34  : sizeof(x86_debug_state32_t);
35  thread->state = &thread->drx.uds;
36  rc = thread_get_state(thread->port, thread->flavor,
37  (thread_state_t)&thread->drx, &thread->count);
38 #elif __arm64__ || __arm64 || __aarch64 || __aarch64__
39  if (dbg->bits == RZ_SYS_BITS_64) {
40  thread->count = ARM_DEBUG_STATE64_COUNT;
41  thread->flavor = ARM_DEBUG_STATE64;
42  rc = thread_get_state(thread->port, thread->flavor,
43  (thread_state_t)&thread->debug.drx64,
44  &thread->count);
45  } else {
46  thread->count = ARM_DEBUG_STATE32_COUNT;
47  thread->flavor = ARM_DEBUG_STATE32;
48  rc = thread_get_state(thread->port, thread->flavor,
49  (thread_state_t)&thread->debug.drx32,
50  &thread->count);
51  }
52 #elif __arm__ || __arm || __armv7__
53  thread->count = ARM_DEBUG_STATE_COUNT;
54  thread->flavor = ARM_DEBUG_STATE;
55  rc = thread_get_state(thread->port, thread->flavor,
56  (thread_state_t)&thread->debug.drx,
57  &thread->count);
58 #else
59 #warning xnu_thread_get_drx: Unsupported architecture
60  rc = KERN_FAILURE;
61 #endif
62  if (rc != KERN_SUCCESS) {
63  LOG_MACH_ERROR("thread_get_state", rc);
64  thread->count = 0;
65  return false;
66  }
67  return true;
68 }
@ x86_DEBUG_STATE
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
thread_t port
Definition: xnu_threads.h:51
ut32 state_size
Definition: xnu_threads.h:57
void * state
Definition: xnu_threads.h:56
int bits
Definition: rz_debug.h:243
#define LOG_MACH_ERROR(name, rc)
Definition: xnu_debug.h:17

References rz_debug_t::bits, _xnu_thread::count, dbg, _xnu_thread::flavor, LOG_MACH_ERROR, _xnu_thread::port, rz_return_val_if_fail, RZ_SYS_BITS_64, _xnu_thread::state, _xnu_thread::state_size, and x86_DEBUG_STATE.

Referenced by xnu_reg_read().

◆ rz_xnu_thread_get_gpr()

RZ_IPI bool rz_xnu_thread_get_gpr ( RzDebug dbg,
xnu_thread_t thread 
)

Definition at line 184 of file xnu_threads.c.

184  {
185  rz_return_val_if_fail(dbg && thread, false);
186  RZ_REG_T *regs = &thread->gpr;
187  if (!regs) {
188  return false;
189  }
190  kern_return_t rc;
191 #if __POWERPC__
192  thread->state = regs;
193 #elif __arm64 || __aarch64 || __aarch64__ || __arm64__
194  // thread->state = regs;
195  thread->state = &regs->uts;
196  if (dbg->bits == RZ_SYS_BITS_64) {
197  thread->flavor = ARM_THREAD_STATE64;
198  thread->count = ARM_THREAD_STATE64_COUNT;
199  thread->state_size = sizeof(arm_thread_state64_t);
200  } else {
201  thread->flavor = ARM_THREAD_STATE;
202  thread->count = ARM_THREAD_STATE_COUNT;
203  thread->state_size = sizeof(arm_thread_state32_t);
204  }
205 #elif __arm || __arm__ || __armv7__
206  thread->state = regs;
207  thread->flavor = ARM_THREAD_STATE;
208  thread->count = ARM_THREAD_STATE_COUNT;
209  thread->state_size = sizeof(arm_thread_state_t);
210 #elif __x86_64__ || __i386__
211  thread->state = &regs->uts;
212  thread->flavor = x86_THREAD_STATE;
213  thread->count = x86_THREAD_STATE_COUNT;
214  thread->state_size = (dbg->bits == RZ_SYS_BITS_64) ? sizeof(x86_thread_state64_t) : sizeof(x86_thread_state32_t);
215 #endif
216  rc = thread_get_state(thread->port, thread->flavor,
217  (thread_state_t)regs, &thread->count);
218  if (rc != KERN_SUCCESS) {
219  LOG_MACH_ERROR("thread_get_state", rc);
220  thread->count = 0;
221  return false;
222  }
223  return true;
224 }
static char * regs[]
Definition: analysis_sh.c:203
#define x86_THREAD_STATE_COUNT
@ x86_THREAD_STATE
RZ_REG_T gpr
Definition: xnu_threads.h:55

References rz_debug_t::bits, _xnu_thread::count, dbg, _xnu_thread::flavor, _xnu_thread::gpr, LOG_MACH_ERROR, _xnu_thread::port, regs, rz_return_val_if_fail, RZ_SYS_BITS_64, _xnu_thread::state, _xnu_thread::state_size, x86_THREAD_STATE, and x86_THREAD_STATE_COUNT.

Referenced by xnu_reg_read(), and xnu_thread_list().

◆ rz_xnu_thread_set_drx()

RZ_IPI bool rz_xnu_thread_set_drx ( RzDebug dbg,
xnu_thread_t thread 
)

Definition at line 70 of file xnu_threads.c.

70  {
71  rz_return_val_if_fail(dbg && thread, false);
72  kern_return_t rc;
73 #if __i386__ || __x86_64__
74  x86_debug_state_t *regs = &thread->drx;
75  if (!regs) {
76  return false;
77  }
78  thread->flavor = x86_DEBUG_STATE;
79  thread->count = x86_DEBUG_STATE_COUNT;
80  if (dbg->bits == RZ_SYS_BITS_64) {
81  regs->dsh.flavor = x86_DEBUG_STATE64;
82  regs->dsh.count = x86_DEBUG_STATE64_COUNT;
83  } else {
84  regs->dsh.flavor = x86_DEBUG_STATE32;
85  regs->dsh.count = x86_DEBUG_STATE32_COUNT;
86  }
87  rc = thread_set_state(thread->port, thread->flavor,
88  (thread_state_t)regs, thread->count);
89 #elif __arm64__ || __arm64 || __aarch64 || __aarch64__
90  if (dbg->bits == RZ_SYS_BITS_64) {
91  thread->count = ARM_DEBUG_STATE64_COUNT;
92  thread->flavor = ARM_DEBUG_STATE64;
93  rc = thread_set_state(thread->port, thread->flavor,
94  (thread_state_t)&thread->debug.drx64,
95  thread->count);
96  } else {
97  thread->count = ARM_DEBUG_STATE32_COUNT;
98  thread->flavor = ARM_DEBUG_STATE32;
99  rc = thread_set_state(thread->port, thread->flavor,
100  (thread_state_t)&thread->debug.drx32,
101  thread->count);
102  }
103 #elif __arm__ || __arm || __armv7__
104  thread->count = ARM_DEBUG_STATE_COUNT;
105  thread->flavor = ARM_DEBUG_STATE;
106  rc = thread_set_state(thread->port, thread->flavor,
107  (thread_state_t)&thread->debug.drx,
108  &thread->count);
109 #elif __POWERPC__
110 /* not supported */
111 #ifndef PPC_DEBUG_STATE32
112 #define PPC_DEBUG_STATE32 1
113 #endif
114  ppc_debug_state_t *regs;
115  // thread->flavor = PPC_DEBUG_STATE32;
116  // thread->count = RZ_MIN (thread->count, sizeof (regs->uds.ds32));
117  return false;
118 #else
119  regs->dsh.flavor = 0;
120  thread->count = 0;
121 #endif
122  if (rc != KERN_SUCCESS) {
123  LOG_MACH_ERROR("thread_set_state", rc);
124  thread->count = 0;
125  return false;
126  }
127  return true;
128 }
@ x86_DEBUG_STATE64
@ x86_DEBUG_STATE32

References rz_debug_t::bits, _xnu_thread::count, dbg, _xnu_thread::flavor, LOG_MACH_ERROR, _xnu_thread::port, regs, rz_return_val_if_fail, RZ_SYS_BITS_64, x86_DEBUG_STATE, x86_DEBUG_STATE32, and x86_DEBUG_STATE64.

Referenced by xnu_reg_write().

◆ rz_xnu_thread_set_gpr()

RZ_IPI bool rz_xnu_thread_set_gpr ( RzDebug dbg,
xnu_thread_t thread 
)

Definition at line 130 of file xnu_threads.c.

130  {
131  rz_return_val_if_fail(dbg && thread, false);
132  kern_return_t rc;
133  RZ_REG_T *regs = (RZ_REG_T *)&thread->gpr;
134  if (!regs) {
135  return false;
136  }
137 #if __i386__ || __x86_64__
138  // thread->flavor is used in a switch+case but in regs->tsh.flavor we
139  // specify
140  thread->state = &regs->uts;
141  // thread->state = regs;
142  thread->flavor = x86_THREAD_STATE;
143  thread->count = x86_THREAD_STATE_COUNT;
144  if (dbg->bits == RZ_SYS_BITS_64) {
145  regs->tsh.flavor = x86_THREAD_STATE64;
146  regs->tsh.count = x86_THREAD_STATE64_COUNT;
147  } else {
148  regs->tsh.flavor = x86_THREAD_STATE32;
149  regs->tsh.count = x86_THREAD_STATE32_COUNT;
150  }
151 #elif __arm64 || __aarch64 || __arm64__ || __aarch64__
152 #if 0
153  /* unified doesnt seems to work */
154  thread->flavor = ARM_UNIFIED_THREAD_STATE;
155  thread->count = ARM_UNIFIED_THREAD_STATE_COUNT;
156 #endif
157  // thread->state = regs;
158  thread->state = &regs->uts;
159  if (dbg->bits == RZ_SYS_BITS_64) {
160  thread->flavor = ARM_THREAD_STATE64;
161  thread->count = ARM_THREAD_STATE64_COUNT;
162  thread->state_size = sizeof(arm_thread_state64_t);
163  } else {
164  thread->flavor = ARM_THREAD_STATE32;
165  thread->count = ARM_THREAD_STATE32_COUNT;
166  thread->state_size = sizeof(arm_thread_state32_t);
167  }
168 #elif __arm || __arm__ || __armv7__
169  thread->flavor = ARM_THREAD_STATE;
170  thread->count = ARM_THREAD_STATE_COUNT;
171  thread->state_size = sizeof(arm_thread_state_t);
172 
173 #endif
174  rc = thread_set_state(thread->port, thread->flavor,
175  (thread_state_t)regs, thread->count);
176  if (rc != KERN_SUCCESS) {
177  LOG_MACH_ERROR("thread_set_state", rc);
178  thread->count = 0;
179  return false;
180  }
181  return true;
182 }
@ x86_THREAD_STATE64
@ x86_THREAD_STATE32
#define x86_THREAD_STATE64_COUNT
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References rz_debug_t::bits, _xnu_thread::count, dbg, _xnu_thread::flavor, _xnu_thread::gpr, if(), LOG_MACH_ERROR, _xnu_thread::port, regs, rz_return_val_if_fail, RZ_SYS_BITS_64, _xnu_thread::state, _xnu_thread::state_size, x86_THREAD_STATE, x86_THREAD_STATE32, x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT, and x86_THREAD_STATE_COUNT.

Referenced by xnu_reg_write().

◆ rz_xnu_update_thread_list()

RZ_IPI int rz_xnu_update_thread_list ( RzDebug dbg)

Definition at line 290 of file xnu_threads.c.

290  {
291  thread_array_t thread_list = NULL;
292  unsigned int thread_count = 0;
293  xnu_thread_t *thread;
294  kern_return_t kr;
295  task_t task;
296  int i;
297 
298  if (!dbg->threads) {
300  if (!dbg->threads) {
301  return false;
302  }
303  }
304  // ok we have the list that will hold our threads, now is time to get
305  // them
306  task = pid_to_task(dbg->pid);
307  if (!task) {
308  return false;
309  }
310  kr = task_threads(task, &thread_list, &thread_count);
311  if (kr != KERN_SUCCESS) {
312  // we can get into this when the process has terminated but we
313  // still hold the old task because we are caching it
314  eprintf("Failed to get list of task's threads\n");
315  return false;
316  }
317  if (rz_list_empty(dbg->threads)) {
318  // it's the first time write all threads inside the list
319  for (i = 0; i < thread_count; i++) {
320  thread = xnu_get_thread_with_info(dbg, thread_list[i]);
321  if (!thread) {
322  eprintf("Failed to fill_thread\n");
323  continue;
324  }
325  if (!rz_list_append(dbg->threads, thread)) {
326  eprintf("Failed to add thread to list\n");
327  xnu_thread_free(thread);
328  }
329  }
330  } else {
331  RzListIter *iter, *iter2;
332  // first pass to get rid of those threads that are not longer
333  // alive
334  rz_list_foreach_safe (dbg->threads, iter, iter2, thread) {
335  bool flag = true; // this flag will denote when delete
336  // a thread
337  for (i = 0; i < thread_count; i++) {
338  if (thread->port == thread_list[i]) {
339  flag = false;
340  break;
341  }
342  }
343  if (flag) {
344  // it is not longer alive so remove from the
345  // list
347  } else {
348  // otherwise update the info
349  xnu_update_thread_info(dbg, thread);
350  }
351  }
352  // ok now we have to insert those threads that we don't have
353  for (i = 0; i < thread_count; i++) {
354  xnu_thread_t *t;
355  iter = rz_list_find(dbg->threads, &thread_list[i],
357  // it means is already in our list
358  if (iter) {
359  // free the ownership over the thread
360  kr = mach_port_deallocate(mach_task_self(),
361  thread_list[i]);
362  if (kr != KERN_SUCCESS) {
363  eprintf("Failed to deallocate port\n");
364  }
365  continue;
366  }
367  // otherwise insert it
368  t = xnu_get_thread_with_info(dbg, thread_list[i]);
370  }
371  }
372  // once that is over we need to free the buffer
373  (void)vm_deallocate(mach_task_self(), (mach_vm_address_t)thread_list,
374  thread_count * sizeof(thread_t));
375  return true;
376 }
lzma_index ** i
Definition: index.h:629
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
static void xnu_thread_free(xnu_thread_t *thread)
Definition: xnu_threads.c:10
static int xnu_update_thread_info(RzDebug *dbg, xnu_thread_t *thread)
Definition: xnu_threads.c:278
static xnu_thread_t * xnu_get_thread_with_info(RzDebug *dbg, thread_t port)
Definition: xnu_threads.c:265

References dbg, eprintf, i, NULL, rz_debug_t::pid, pid_to_task(), _xnu_thread::port, rz_list_append(), rz_list_delete(), rz_list_find(), rz_list_newf(), thread_find(), rz_debug_t::threads, xnu_get_thread_with_info(), xnu_thread_free(), and xnu_update_thread_info().

Referenced by rz_xnu_get_thread(), and xnu_thread_list().

◆ thread_find()

static int thread_find ( thread_t *  port,
xnu_thread_t a 
)
static

Definition at line 286 of file xnu_threads.c.

286  {
287  return (a && port && (a->port == *port)) ? 0 : 1;
288 }
#define a(i)
Definition: sha256.c:41

References a.

Referenced by rz_xnu_get_thread(), and rz_xnu_update_thread_list().

◆ xnu_fill_info_thread()

static bool xnu_fill_info_thread ( RzDebug dbg,
xnu_thread_t thread 
)
static

Definition at line 226 of file xnu_threads.c.

226  {
227 #if __POWERPC__
228  thread->name = strdup("unknown");
229  return false;
230 #else
231  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
232  thread_identifier_info_data_t identifier_info;
233  kern_return_t kr = thread_info(thread->port, THREAD_BASIC_INFO,
234  (thread_info_t)&thread->basic_info, &count);
235  if (kr != KERN_SUCCESS) {
236  eprintf("Fail to get thread_basic_info\n");
237  return false;
238  }
239  count = THREAD_IDENTIFIER_INFO_COUNT;
240  kr = thread_info(thread->port, THREAD_IDENTIFIER_INFO,
241  (thread_info_t)&identifier_info, &count);
242  if (kr != KERN_SUCCESS) {
243  eprintf("Fail to get thread_identifier_info\n");
244  return false;
245  }
246  RZ_FREE(thread->name);
247 #if TARGET_OS_IPHONE
248  // TODO proc_pidinfo here
249  thread->name = strdup("unknown");
250 #else
251  struct proc_threadinfo proc_threadinfo;
252  int ret_proc = proc_pidinfo(dbg->pid, PROC_PIDTHREADINFO,
253  identifier_info.thread_handle,
254  &proc_threadinfo, PROC_PIDTHREADINFO_SIZE);
255  if (ret_proc && proc_threadinfo.pth_name[0]) {
256  thread->name = strdup(proc_threadinfo.pth_name);
257  } else {
258  thread->name = strdup("unknown");
259  }
260 #endif
261 #endif
262  return true;
263 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define RZ_FREE(x)
Definition: rz_types.h:369
thread_basic_info_data_t basic_info
Definition: xnu_threads.h:53
char * name
Definition: xnu_threads.h:52

References _xnu_thread::basic_info, count, dbg, eprintf, _xnu_thread::name, rz_debug_t::pid, _xnu_thread::port, RZ_FREE, and strdup().

Referenced by xnu_get_thread_with_info(), and xnu_update_thread_info().

◆ xnu_get_thread_with_info()

static xnu_thread_t* xnu_get_thread_with_info ( RzDebug dbg,
thread_t  port 
)
static

Definition at line 265 of file xnu_threads.c.

265  {
266  xnu_thread_t *thread = RZ_NEW0(xnu_thread_t);
267  if (!thread) {
268  return NULL;
269  }
270  thread->port = port;
271  if (!xnu_fill_info_thread(dbg, thread)) {
272  free(thread->name);
273  thread->name = strdup("unknown");
274  }
275  return thread;
276 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define RZ_NEW0(x)
Definition: rz_types.h:284
static bool xnu_fill_info_thread(RzDebug *dbg, xnu_thread_t *thread)
Definition: xnu_threads.c:226

References dbg, free(), _xnu_thread::name, NULL, _xnu_thread::port, RZ_NEW0, strdup(), and xnu_fill_info_thread().

Referenced by rz_xnu_update_thread_list().

◆ xnu_thread_free()

static void xnu_thread_free ( xnu_thread_t thread)
static

Definition at line 10 of file xnu_threads.c.

10  {
11  kern_return_t kr;
12  if (!thread) {
13  return;
14  }
15  free(thread->name);
16  // if we free our thread from the list we need to decrement the ref
17  // count
18  kr = mach_port_deallocate(mach_task_self(), thread->port);
19  if (kr != KERN_SUCCESS) {
20  eprintf("failed to deallocate thread port\n");
21  }
22  free(thread);
23 }

References eprintf, free(), _xnu_thread::name, and _xnu_thread::port.

Referenced by rz_xnu_update_thread_list().

◆ xnu_update_thread_info()

static int xnu_update_thread_info ( RzDebug dbg,
xnu_thread_t thread 
)
static

Definition at line 278 of file xnu_threads.c.

278  {
279  if (!xnu_fill_info_thread(dbg, thread)) {
280  free(thread->name);
281  thread->name = strdup("unknown");
282  }
283  return true;
284 }

References dbg, free(), _xnu_thread::name, strdup(), and xnu_fill_info_thread().

Referenced by rz_xnu_update_thread_list().