Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
target_os.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <assert.h>
20 #include <glib.h>
21 
22 #include "object.h"
23 #include "glib_wrapper.h"
24 #include "target.h"
25 #include "probe_api.h"
26 #include "probe.h"
27 #include "target_os.h"
28 #include "target_event.h"
29 #include "arch.h"
30 #include "arch_x86.h"
31 #include "arch_x86_64.h"
32 
35  target);
36 }
37 
38 uint64_t target_os_version(struct target *target) {
39  SAFE_TARGET_OS_OP(target,os_version,0,
40  target);
41 }
42 
43 int target_os_version_cmp(struct target *target,uint64_t vers) {
44  SAFE_TARGET_OS_OP(target,os_version_cmp,0,
45  target,vers);
46 }
47 
49  struct target_thread *tthread = target_load_thread(target,tid,0);
50  if (!tthread)
51  return -1;
52  SAFE_TARGET_OS_OP(target,thread_get_pgd_phys,-1,target,tthread,pgdp);
53 }
54 
56  struct target_thread *tthread = target_load_thread(target,tid,0);
57  if (!tthread)
58  return -1;
59  SAFE_TARGET_OS_OP(target,thread_is_user,-1,target,tthread);
60 }
61 
63  struct target_thread *tthread = target_load_thread(target,tid,0);
64  if (!tthread)
65  return -1;
66  SAFE_TARGET_OS_OP_NORET(target,thread_get_leader,NULL,tthread,target,tthread);
67  if (tthread)
68  return tthread->tid;
69  else
70  return -1;
71 }
72 
74  struct target *overlay,int force_emulate) {
75  SAFE_TARGET_OS_OP(target,thread_singlestep,-1,target,tid,isbp,
76  overlay,force_emulate);
77 }
78 
80  struct target *overlay,int force_emulate) {
81  SAFE_TARGET_OS_OP(target,thread_singlestep_end,-1,target,tid,
82  overlay,force_emulate);
83 }
84 
87  struct target_memmod *mmod) {
88  struct target_thread *tthread;
89  REGVAL ipval;
90 
91  tthread = target_lookup_thread(target,tid);
92  if (!tthread) {
93  verror("tid %"PRIiTID" does not exist!\n",tid);
94  errno = ESRCH;
95  return RESULT_ERROR;
96  }
97 
98  if (tthread->emulating_debug_mmod) {
99  verror("tid %"PRIiTID" already is emulating a memmod"
100  " at 0x%"PRIxADDR"; cannot do another one!\n",
101  tid,tthread->emulating_debug_mmod->addr);
102  errno = EBUSY;
103  return RESULT_ERROR;
104  }
105 
106  tthread->emulating_debug_mmod = mmod;
107 
108  /*
109  * If we're in BPMODE_STRICT, we have to pause all the other
110  * threads.
111  */
112  if (target->spec->bpmode == THREAD_BPMODE_STRICT) {
113  if (target_pause(target)) {
114  vwarn("could not pause the target for blocking thread"
115  " %"PRIiTID"!\n",tthread->tid);
116  return RESULT_ERROR;
117  }
118  target->blocking_thread = tthread;
119  }
120 
121  errno = 0;
122  ipval = target_read_reg_ctxt(target,tid,tidctxt,target->ipregno);
123  if (!ipval && errno) {
124  verror("could not read IP in tid %"PRIiTID"!\n",tid);
125  return RESULT_ERROR;
126  }
127 
128  /* Disable the memmod. */
129  if (target_memmod_unset(target,tid,mmod)) {
130  verror("could not disable breakpoint before singlestep;"
131  " assuming breakpoint is left in place and"
132  " skipping single step, but badness will ensue!");
133  goto errout;
134  }
135 
136  /* Enable singlestep. */
137  if (target_os_thread_singlestep(target,tid,1,NULL,0)) {
138  verror("could not singlestep tid %"PRIiTID"!\n",tid);
139  goto errout;
140  }
141 
142  /* Reset ip. */
143  ipval -= target->arch->breakpoint_instrs_len; //target_memmod_length(target,mmod);
144  if (target_write_reg_ctxt(target,tid,tidctxt,target->ipregno,ipval)) {
145  verror("could not write IP!\n");
146  goto errout;
147  }
148 
149  /* Temporarily add this thread to the mmod. */
150  array_list_append(mmod->threads,tthread);
151 
152  return RESULT_SUCCESS;
153 
154  errout:
155  target_os_thread_singlestep_end(target,tid,NULL,0);
156  if (target->blocking_thread == tthread)
157  target->blocking_thread = NULL;
158  tthread->emulating_debug_mmod = NULL;
159 
160  return RESULT_ERROR;
161 }
162 
165  struct target_memmod *mmod) {
166  struct target_thread *tthread;
167 
168  tthread = target_lookup_thread(target,tid);
169  if (!tthread) {
170  verror("tid %"PRIiTID" does not exist!\n",tid);
171  errno = ESRCH;
172  return RESULT_ERROR;
173  }
174 
175  if (tthread->emulating_debug_mmod
176  && tthread->emulating_debug_mmod != mmod) {
177  verror("tid %"PRIiTID" already is emulating a memmod"
178  " at 0x%"PRIxADDR"; cannot do another one!\n",
179  tid,tthread->emulating_debug_mmod->addr);
180  errno = EBUSY;
181  return RESULT_ERROR;
182  }
183  else if (!tthread->emulating_debug_mmod)
184  vwarn("not set to emulate a debug mmod; trying anyway!\n");
185 
186  /* Disable singlestep. */
187  target_os_thread_singlestep_end(target,tid,NULL,0);
188 
189  /* Reenable the memmod. */
190  target_memmod_set(target,tid,mmod);
191 
192  /* Remove this thread from the memmod's list. */
193  array_list_remove_item(mmod->threads,tthread);
194 
195  if (target->spec->bpmode == THREAD_BPMODE_STRICT) {
196  if (target->blocking_thread == tthread)
197  target->blocking_thread = NULL;
198  }
199 
200  if (tthread->emulating_debug_mmod == mmod)
201  tthread->emulating_debug_mmod = NULL;
202  else if (tthread->emulating_debug_mmod) {
203  verror("tid %"PRIiTID" already is emulating a memmod"
204  " at 0x%"PRIxADDR"; cannot clear it!\n",
205  tid,tthread->emulating_debug_mmod->addr);
206  }
207 
208  return RESULT_SUCCESS;
209 }
210 
212  int no_event_send) {
213  tid_t tid;
214  tid_t tgid;
215  tid_t ptid;
216  int done = 0;
217  REFCNT trefcnt;
218  GHashTableIter iter;
219  gpointer vp;
220  struct target_thread *tthread,*othread;
221  struct target_process *child,*child_old,*parent;
222  struct target_event *event;
223  GList *newlist = NULL;
224  GList *t1;
225 
226  tid = process->thread->tid;
227  tgid = process->thread->tgid;
228  ptid = process->thread->ptid;
229 
230  /*
231  * Find all the threads in the process, based on
232  * process->thread->tgid == Nthread->tgid equivalency. This means
233  * we have to load all the threads, then go through them.
234  */
235  if (tgid > -1) {
236  if (!done) {
238  done = 1;
239  }
240 
241  //g_hash_table_remove_all(process->threads);
242  g_hash_table_iter_init(&iter,process->target->threads);
243  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
244  tthread = (struct target_thread *)vp;
245  if (tthread->tid == TID_GLOBAL)
246  continue;
247 
248  if (tthread->tgid == tgid) {
249  othread = (struct target_thread *) \
250  g_hash_table_lookup(process->threads,
251  (gpointer)(uintptr_t)tthread->tid);
252  if (othread) {
253  if (othread != tthread) {
254  RPUT(othread,target_thread,process,trefcnt);
255  g_hash_table_iter_remove(&iter);
256  newlist = g_list_prepend(newlist,tthread);
257  }
258  }
259  else {
260  newlist = g_list_prepend(newlist,tthread);
261  }
262  }
263  }
264  }
265 
266  /* Add new threads. */
267  if (newlist) {
268  v_g_list_foreach(newlist,t1,tthread) {
269  g_hash_table_insert(process->threads,
270  (gpointer)(uintptr_t)tthread->tid,tthread);
271  RHOLD(tthread,process);
272  }
273  g_list_free(newlist);
274  newlist = NULL;
275  }
276 
277 
278  /*
279  * Now, remove any "dead" threads:
280  */
281  g_hash_table_iter_init(&iter,process->threads);
282  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
283  tthread = (struct target_thread *)vp;
284  if (!OBJLIVE(tthread)) {
285  g_hash_table_iter_remove(&iter);
286  RPUT(tthread,target_thread,process,trefcnt);
287  }
288  }
289 
290  /*
291  * Find all the children of the process, based on
292  * process->thread->tid == Nthread->ptid equivalency. This means we
293  * have to load all the threads, then go through them.
294  */
295  if (ptid > -1) {
296  if (!done) {
298  done = 1;
299  }
300 
301  //g_hash_table_remove_all(process->children);
302  g_hash_table_iter_init(&iter,process->target->threads);
303  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
304  tthread = (struct target_thread *)vp;
305  if (tthread->tid == TID_GLOBAL)
306  continue;
307 
308  if (tthread->ptid == tid) {
309  child = target_os_process_get(process->target,tthread->tid);
310  child_old = (struct target_process *) \
311  g_hash_table_lookup(process->children,
312  (gpointer)(uintptr_t)tthread->tid);
313  if (child_old) {
314  if (child_old != child) {
316  "removing old child pid %d for pid %d\n",
317  child_old->tid,process->tid);
318  RPUT(child_old,target_process,process,trefcnt);
319  g_hash_table_iter_remove(&iter);
320  if (child)
321  newlist = g_list_prepend(newlist,child);
322  }
323  }
324  else if (child) {
325  newlist = g_list_prepend(newlist,child);
326  }
327  }
328  }
329  }
330 
331  /* Add new children. */
332  if (newlist) {
333  v_g_list_foreach(newlist,t1,child) {
334  g_hash_table_insert(process->children,
335  (gpointer)(uintptr_t)child->tid,child);
336  RHOLD(child,process);
338  "added child %d to pid %d\n",child->tid,process->tid);
339  }
340  g_list_free(newlist);
341  newlist = NULL;
342  }
343 
344  /*
345  * Now, remove any "dead" threads:
346  */
347  g_hash_table_iter_init(&iter,process->threads);
348  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
349  tthread = (struct target_thread *)vp;
350  if (!OBJLIVE(tthread)) {
351  g_hash_table_iter_remove(&iter);
352  RPUT(tthread,target_thread,process,trefcnt);
354  "removed stale thread %d from pid %d\n",
355  tthread->tid,process->tid);
356  }
357  }
358 
359  /* Fill the parent. */
360  if (process->thread->ptid > -1) {
361  parent = target_os_process_get(process->target,process->thread->ptid);
362 
363  if (!process->parent && parent) {
364  process->parent = parent;
365  RHOLDW(parent,process);
367  "new parent pid %d for pid %d\n",parent->tid,process->tid);
368  }
369  else if (process->parent && !parent) {
370  RPUTW(process->parent,target_process,process,trefcnt);
371  process->parent = NULL;
373  "removed parent pid %d\n",process->tid);
374  }
375  else if (process->parent && parent && process->parent != parent) {
376  RPUTW(process->parent,target_process,process,trefcnt);
377  process->parent = parent;
378  RHOLDW(parent,process);
380  "changed parent to pid %d for pid %d\n",
381  parent->tid,process->tid);
382  }
383  }
384 
385  return 0;
386 }
387 
389  SAFE_TARGET_OS_OP(target,processes_get,NULL,target);
390 }
391 
393  struct target_thread *tthread = target_load_thread(target,tid,0);
394  if (!tthread)
395  return NULL;
396  SAFE_TARGET_OS_OP(target,process_get,NULL,target,tthread);
397 }
398 
400  int signo,void *data) {
401  struct target_thread *tthread = target_load_thread(target,tid,0);
402  if (!tthread)
403  return -1;
404  SAFE_TARGET_OS_OP(target,signal_enqueue,-1,target,tthread,signo,data);
405 }
406 
407 const char *target_os_signal_to_name(struct target *target,int signo) {
408  SAFE_TARGET_OS_OP(target,signal_to_name,NULL,target,signo);
409 }
410 
411 int target_os_signal_from_name(struct target *target,const char *name) {
412  SAFE_TARGET_OS_OP(target,signal_from_name,-1,target,name);
413 }
414 
416  SAFE_TARGET_OS_OP(target,syscall_table_load,-1,
417  target);
418 }
419 
421  SAFE_TARGET_OS_OP(target,syscall_table_unload,-1,
422  target);
423 }
424 
426  SAFE_TARGET_OS_OP(target,syscall_table_get,NULL,
427  target);
428 }
429 
431  GHashTable *sctab = target_os_syscall_table_get(target);
432  if (!sctab)
433  return -1;
434  return g_hash_table_size(sctab);
435 }
436 
438  char *name) {
439  SAFE_TARGET_OS_OP(target,syscall_lookup_name,NULL,
440  target,name);
441 }
442 
444  int num) {
445  SAFE_TARGET_OS_OP(target,syscall_lookup_num,NULL,
446  target,num);
447 }
448 
450  ADDR addr) {
451  SAFE_TARGET_OS_OP(target,syscall_lookup_addr,NULL,
452  target,addr);
453 }
454 
456  SAFE_TARGET_OS_OP(target,syscall_table_reload,-1,
457  target,force);
458 }
459 
461  SAFE_TARGET_OS_OP(target,syscall_table_store,-1,
462  target);
463 }
464 
466  struct target_os_syscall *syscall,
469  void *handler_data) {
470  SAFE_TARGET_OS_OP(target,syscall_probe,NULL,
471  target,tid,syscall,pre_handler,post_handler,handler_data);
472 }
473 
477  void *handler_data) {
478  SAFE_TARGET_OS_OP(target,syscall_probe_all,NULL,
479  target,tid,pre_handler,post_handler,handler_data);
480 }
481 
482 /*
483  * Syscall probe type.
484  */
485 static const char *_target_os_syscall_probe_gettype(struct probe *probe) {
486  return "target_os_syscall_probe";
487 }
488 
489 #define TARGET_OS_SYSCALL_GKV_KEY "target_os_syscall_state"
490 
493 }
494 
497 }
498 
500  .gettype = _target_os_syscall_probe_gettype,
501 
503  .summarize_tid = target_os_syscall_probe_summarize_tid,
504 };
505 
506 static void _target_os_syscall_state_dtor(struct target *target,tid_t tid,
507  char *key,void *value) {
508  struct target_os_syscall_state *scs;
509  int i;
510  struct value *v;
511 
512  if (!value)
513  return;
514 
515  scs = (struct target_os_syscall_state *)value;
516 
517  if (scs->argvals) {
518  array_list_foreach(scs->argvals,i,v) {
519  if (!v)
520  continue;
521  value_free(v);
522  }
523  array_list_free(scs->argvals);
524  }
525  if (scs->regvals)
526  array_list_free(scs->regvals);
527 
528  free(scs);
529 }
530 
532  tid_t tid) {
533  return (struct target_os_syscall_state *) \
535 }
536 
537 int target_os_syscall_record_clear(struct target *target,tid_t tid) {
539  return 0;
540 }
541 
543 target_os_syscall_record_entry(struct target *target,tid_t tid,
544  struct target_os_syscall *syscall) {
545  struct target_os_syscall_state *scs;
546 
548 
549  scs = calloc(1,sizeof(*scs));
550  scs->syscall = syscall;
551 
553  _target_os_syscall_state_dtor)) {
554  verror("could not insert syscall state for tid %"PRIiTID"!\n",tid);
555  free(scs);
556  return NULL;
557  }
558 
559  return scs;
560 }
561 
562 int target_os_syscall_record_argv(struct target *target,tid_t tid,
563  struct array_list *regvals,
564  struct array_list *argvals) {
565  struct target_os_syscall_state *scs;
566 
567  scs = (struct target_os_syscall_state *) \
569  if (!scs) {
570  verror("could not store arg values; no syscall entry recorded!\n");
571  return -1;
572  }
573 
574  scs->regvals = regvals;
575  scs->argvals = argvals;
576 
577  return 0;
578 }
579 
580 int target_os_syscall_record_return(struct target *target,tid_t tid,
581  REGVAL retval) {
582  struct target_os_syscall_state *scs;
583 
584  scs = (struct target_os_syscall_state *) \
586  if (!scs) {
587  verror("could not store return value; no syscall entry recorded!\n");
588  return -1;
589  }
590 
591  scs->returned = 1;
592  scs->retval = retval;
593 
594  return 0;
595 }
void * target_os_syscall_probe_summarize_tid(struct probe *probe, tid_t tid)
Definition: target_os.c:495
#define RPUTW(x, objtype, hx, rc)
Definition: common.h:628
struct array_list * threads
Definition: target.h:385
result_t pre_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:903
#define SAFE_TARGET_OS_OP(target, op, errval,...)
Definition: target_os.h:66
struct target_os_syscall_state * target_os_syscall_probe_last(struct target *target, tid_t tid)
Definition: target_os.c:531
#define RHOLDW(x, hx)
Definition: common.h:623
thread_bpmode_t bpmode
Definition: target_api.h:2211
int32_t tid_t
Definition: common.h:36
int target_load_available_threads(struct target *target, int force)
Definition: target_api.c:1300
void * target_os_syscall_probe_summarize(struct probe *probe)
Definition: target_os.c:491
void target_thread_gkv_remove(struct target *target, tid_t tid, char *key)
Definition: target.c:1580
struct probe_ops target_os_syscall_ret_probe_ops
Definition: target_os.c:499
target_os_type_t target_os_type(struct target *target)
Definition: target_os.c:33
GHashTable * target_os_syscall_table_get(struct target *target)
Definition: target_os.c:425
static uint64_t unsigned int i
struct array_list * argvals
Definition: target_os.h:62
int target_os_version_cmp(struct target *target, uint64_t vers)
Definition: target_os.c:43
#define v_g_list_foreach(glhead, glcur, elm)
Definition: glib_wrapper.h:34
int target_os_thread_is_user(struct target *target, tid_t tid)
Definition: target_os.c:55
int target_pause(struct target *target)
Definition: target_api.c:1027
struct target_os_syscall_state * target_os_syscall_record_entry(struct target *target, tid_t tid, struct target_os_syscall *syscall)
Definition: target_os.c:543
struct target_os_syscall * target_os_syscall_lookup_name(struct target *target, char *name)
Definition: target_os.c:437
#define verror(format,...)
Definition: log.h:30
tid_t target_os_thread_get_leader(struct target *target, tid_t tid)
Definition: target_os.c:62
uint64_t target_os_version(struct target *target)
Definition: target_os.c:38
const char *(* gettype)(struct probe *probe)
Definition: probe_api.h:96
result_t(* probe_handler_t)(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: probe_api.h:70
target_os_type_t
Definition: target_os.h:27
GHashTable * children
int target_os_syscall_table_unload(struct target *target)
Definition: target_os.c:420
#define TARGET_OS_SYSCALL_GKV_KEY
Definition: target_os.c:489
#define vwarn(format,...)
Definition: log.h:33
void free(void *ptr)
Definition: debugserver.c:207
int target_write_reg_ctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg, REGVAL value)
Definition: target_api.c:1165
struct target_thread * target_load_thread(struct target *target, tid_t tid, int force)
Definition: target_api.c:1311
tid_t tid
Definition: probe.h:344
#define OBJLIVE(obj)
Definition: object.h:84
int target_thread_gkv_insert(struct target *target, tid_t tid, char *key, void *value, target_thread_gkv_dtor_t dtor)
Definition: target.c:1507
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
int target_os_syscall_record_argv(struct target *target, tid_t tid, struct array_list *regvals, struct array_list *argvals)
Definition: target_os.c:562
int target_os_thread_get_pgd_phys(struct target *target, tid_t tid, ADDR *pgdp)
Definition: target_os.c:48
int target_os_syscall_record_clear(struct target *target, tid_t tid)
Definition: target_os.c:537
int target_os_syscall_table_load(struct target *target)
Definition: target_os.c:415
struct probe * target_os_syscall_probe(struct target *target, tid_t tid, struct target_os_syscall *syscall, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
Definition: target_os.c:465
struct target_os_syscall * target_os_syscall_lookup_num(struct target *target, int num)
Definition: target_os.c:443
Definition: log.h:178
GHashTable * threads
Definition: target_api.h:2672
GHashTable * target_os_process_table_get(struct target *target)
Definition: target_os.c:388
struct target_os_syscall * syscall
Definition: target_os.h:58
int target_memmod_unset(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:5102
void value_free(struct value *value)
Definition: value.c:282
#define RHOLD(x, hx)
Definition: common.h:622
ADDR addr
Definition: target.h:392
struct target_memmod * emulating_debug_mmod
Definition: target_api.h:2179
Definition: probe.h:308
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
struct target_process * target_os_process_get(struct target *target, tid_t tid)
Definition: target_os.c:392
int target_os_syscall_table_get_max_num(struct target *target)
Definition: target_os.c:430
struct target * target
struct arch * arch
Definition: target_api.h:2603
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
result_t post_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:908
int target_os_syscall_table_reload(struct target *target, int force)
Definition: target_os.c:455
unsigned int thread_ctxt_t
Definition: target_api.h:300
int target_os_signal_from_name(struct target *target, const char *name)
Definition: target_os.c:411
Definition: log.h:70
int target_os_syscall_record_return(struct target *target, tid_t tid, REGVAL retval)
Definition: target_os.c:580
void * target_thread_gkv_lookup(struct target *target, tid_t tid, char *key)
Definition: target.c:1535
result_t
Definition: common.h:25
uint32_t REGVAL
Definition: common.h:66
struct probe * target_os_syscall_probe_all(struct target *target, tid_t tid, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
Definition: target_os.c:474
int target_os_update_process_threads_generic(struct target_process *process, int no_event_send)
Definition: target_os.c:211
#define PRIiTID
Definition: common.h:37
int target_os_syscall_table_store(struct target *target)
Definition: target_os.c:460
unsigned int breakpoint_instrs_len
Definition: arch.h:150
struct target * target
Definition: probe.h:342
const char * target_os_signal_to_name(struct target *target, int signo)
Definition: target_os.c:407
uint32_t ADDR
Definition: common.h:64
REGVAL target_read_reg_ctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg)
Definition: target_api.c:1157
int target_memmod_set(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:5021
thread_ctxt_t tidctxt
Definition: target_api.h:2080
GHashTable * threads
uint32_t REFCNT
Definition: common.h:124
#define PRIxADDR
Definition: common.h:67
int target_os_thread_singlestep(struct target *target, tid_t tid, int isbp, struct target *overlay, int force_emulate)
Definition: target_os.c:73
struct target_process * parent
struct target_spec * spec
Definition: target_api.h:2605
result_t target_os_emulate_ss_handler(struct target *target, tid_t tid, thread_ctxt_t tidctxt, struct target_memmod *mmod)
Definition: target_os.c:163
#define RPUT(x, objtype, hx, rc)
Definition: common.h:624
struct array_list * regvals
Definition: target_os.h:60
#define SAFE_TARGET_OS_OP_NORET(target, op, errval, outvar,...)
Definition: target_os.h:84
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
Definition: target.c:4023
struct target_thread * blocking_thread
Definition: target_api.h:2693
unsigned int returned
Definition: target_os.h:57
void * target_gkv_lookup(struct target *target, char *key)
Definition: target.c:1425
int target_os_signal_enqueue(struct target *target, tid_t tid, int signo, void *data)
Definition: target_os.c:399
struct target_os_syscall * target_os_syscall_lookup_addr(struct target *target, ADDR addr)
Definition: target_os.c:449
struct target_thread * thread
result_t target_os_emulate_bp_handler(struct target *target, tid_t tid, thread_ctxt_t tidctxt, struct target_memmod *mmod)
Definition: target_os.c:85
REG ipregno
Definition: target_api.h:2508
#define TID_GLOBAL
Definition: target_api.h:145
int target_os_thread_singlestep_end(struct target *target, tid_t tid, struct target *overlay, int force_emulate)
Definition: target_os.c:79