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_process.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 <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <glib.h>
23 
24 #include "common.h"
25 #include "glib_wrapper.h"
26 #include "object.h"
27 #include "binfile.h"
28 #include "target.h"
29 #include "target_api.h"
30 #include "target_event.h"
31 #include "target_os.h"
33 #include "target_os.h"
34 #include "target_os_process.h"
35 
37  return NULL;
38 }
39 
41  return;
42 }
43 
44 /*
45  * Prototypes.
46  */
47 static int os_process_snprintf(struct target *target,char *buf,int bufsiz);
48 static int os_process_init(struct target *target);
49 static int os_process_postloadinit(struct target *target);
50 static int os_process_attach(struct target *target);
51 static int os_process_detach(struct target *target,int stay_paused);
52 static int os_process_fini(struct target *target);
53 static int os_process_loadspaces(struct target *target);
54 static int os_process_loadregions(struct target *target,struct addrspace *space);
55 static int os_process_loaddebugfiles(struct target *target,
56  struct addrspace *space,
57  struct memregion *region);
58 static target_status_t
59 os_process_handle_overlay_exception(struct target *overlay,
61  tid_t tid,ADDR ipval,int *again);
62 static void os_process_handle_event(struct target *target,
63  struct target_event *event);
64 static struct target *
65 os_process_instantiate_overlay(struct target *target,
66  struct target_thread *tthread,
67  struct target_spec *spec,
68  struct target_thread **ntthread);
69 static struct target_thread *
70 os_process_lookup_overlay_thread_by_id(struct target *target,int id);
71 static struct target_thread *
72 os_process_lookup_overlay_thread_by_name(struct target *target,char *name);
73 
74 static target_status_t os_process_status(struct target *target);
75 static int os_process_pause(struct target *target,int nowait);
76 static int os_process_resume(struct target *target);
77 static unsigned char *os_process_read(struct target *target,ADDR addr,
78  unsigned long length,unsigned char *buf);
79 static unsigned long os_process_write(struct target *target,ADDR addr,
80  unsigned long length,unsigned char *buf);
81 
82 static tid_t os_process_gettid(struct target *target);
83 static void os_process_free_thread_state(struct target *target,void *state);
84 static struct array_list *os_process_list_available_tids(struct target *target);
85 static struct target_thread *os_process_load_thread(struct target *target,
86  tid_t tid,int force);
87 static struct target_thread *os_process_load_current_thread(struct target *target,
88  int force);
89 static int os_process_load_all_threads(struct target *target,int force);
90 static int os_process_load_available_threads(struct target *target,int force);
91 static int os_process_flush_thread(struct target *target,tid_t tid);
92 static int os_process_flush_current_thread(struct target *target);
93 static int os_process_flush_all_threads(struct target *target);
94 static int os_process_thread_snprintf(struct target *target,
95  struct target_thread *tthread,
96  char *buf,int bufsiz,
97  int detail,char *sep,char *kvsep);
98 
99 static REGVAL os_process_read_reg(struct target *target,tid_t tid,REG reg);
100 static int os_process_write_reg(struct target *target,tid_t tid,REG reg,
101  REGVAL value);
102 static struct target_memmod *
103 os_process_insert_sw_breakpoint(struct target *target,
104  tid_t tid,ADDR addr);
105 static int os_process_remove_sw_breakpoint(struct target *target,tid_t tid,
106  struct target_memmod *mmod);
107 static int os_process_enable_sw_breakpoint(struct target *target,tid_t tid,
108  struct target_memmod *mmod);
109 static int os_process_disable_sw_breakpoint(struct target *target,tid_t tid,
110  struct target_memmod *mmod);
111 static int os_process_change_sw_breakpoint(struct target *target,tid_t tid,
112  struct target_memmod *mmod,
113  unsigned char *code,
114  unsigned long code_len);
115 static REG os_process_get_unused_debug_reg(struct target *target,tid_t tid);
116 static int os_process_set_hw_breakpoint(struct target *target,tid_t tid,
117  REG num,ADDR addr);
118 static int os_process_set_hw_watchpoint(struct target *target,tid_t tid,
119  REG num,ADDR addr,
120  probepoint_whence_t whence,
121  probepoint_watchsize_t watchsize);
122 static int os_process_unset_hw_breakpoint(struct target *target,tid_t tid,
123  REG num);
124 static int os_process_unset_hw_watchpoint(struct target *target,tid_t tid,
125  REG num);
129  REG dreg);
131  REG dreg);
133  int notification);
134 int os_process_singlestep(struct target *target,tid_t tid,int isbp,
135  struct target *overlay);
137  struct target *overlay);
138 
140  .snprintf = os_process_snprintf,
141 
142  .init = os_process_init,
143  .fini = os_process_fini,
144  .attach = os_process_attach,
145  .detach = os_process_detach,
146  .kill = NULL,
147  .loadspaces = os_process_loadspaces,
148  .loadregions = os_process_loadregions,
149  .loaddebugfiles = os_process_loaddebugfiles,
150  .postloadinit = os_process_postloadinit,
151 
152  .set_active_probing = NULL,
153 
154  .instantiate_overlay = os_process_instantiate_overlay,
155  .lookup_overlay_thread_by_id = os_process_lookup_overlay_thread_by_id,
156  .lookup_overlay_thread_by_name = os_process_lookup_overlay_thread_by_name,
157 
158  .handle_overlay_exception = os_process_handle_overlay_exception,
159  .handle_break = probepoint_bp_handler,
160  .handle_step = probepoint_ss_handler,
161  .handle_interrupted_step = probepoint_interrupted_ss_handler,
162  .handle_event = os_process_handle_event,
163 
164  .status = os_process_status,
165  .pause = os_process_pause,
166  .resume = os_process_resume,
167  .monitor = NULL,
168  .poll = NULL,
169  .read = os_process_read,
170  .write = os_process_write,
171 
172  .gettid = os_process_gettid,
173  .free_thread_state = os_process_free_thread_state,
174 
175  /* There are never any untracked threads in this target. */
176  .list_available_tids = target_list_tids,
177  /* There are never any untracked threads in this target. */
178  .load_available_threads = os_process_load_all_threads,
179  .load_thread = os_process_load_thread,
180  .load_current_thread = os_process_load_current_thread,
181  .load_all_threads = os_process_load_all_threads,
182  .pause_thread = NULL,
183  .flush_thread = os_process_flush_thread,
184  .flush_current_thread = os_process_flush_current_thread,
185  .flush_all_threads = os_process_flush_all_threads,
186  .thread_snprintf = os_process_thread_snprintf,
187 
188  .attach_evloop = NULL,
189  .detach_evloop = NULL,
190 
191  .readreg = os_process_read_reg,
192  .writereg = os_process_write_reg,
193  .insert_sw_breakpoint = os_process_insert_sw_breakpoint,
194  .remove_sw_breakpoint = os_process_remove_sw_breakpoint,
195  .enable_sw_breakpoint = os_process_enable_sw_breakpoint,
196  .disable_sw_breakpoint = os_process_disable_sw_breakpoint,
197  .change_sw_breakpoint = os_process_change_sw_breakpoint,
198  .get_unused_debug_reg = os_process_get_unused_debug_reg,
199  //.set_hw_breakpoint = os_process_set_hw_breakpoint,
200  //.set_hw_watchpoint = os_process_set_hw_watchpoint,
201  //.unset_hw_breakpoint = os_process_unset_hw_breakpoint,
202  //.unset_hw_watchpoint = os_process_unset_hw_watchpoint,
203  //.disable_hw_breakpoints = os_process_disable_hw_breakpoints,
204  //.enable_hw_breakpoints = os_process_enable_hw_breakpoints,
205  //.disable_hw_breakpoint = os_process_disable_hw_breakpoint,
206  //.enable_hw_breakpoint = os_process_enable_hw_breakpoint,
207  .notify_sw_breakpoint = os_process_notify_sw_breakpoint,
208  .singlestep = os_process_singlestep,
209  .singlestep_end = os_process_singlestep_end,
210 };
211 
212 static int os_process_snprintf(struct target *target,
213  char *buf,int bufsiz) {
214  return snprintf(buf,bufsiz,"task(%d)",target->base_tid);
215 }
216 
217 static int os_process_init(struct target *target) {
218  struct target_thread *base_thread = target->base_thread;
219  struct target *base = target->base;
220  tid_t base_tid = target->base_tid;
221 
222  if (target->spec->stay_paused) {
223  verror("OS Process driver cannot leave target process closed on exit!\n");
224  errno = EINVAL;
225  return -1;
226  }
227 
228  /*
229  * Setup target mode stuff.
230  */
231  target->threadctl = base->threadctl;
232  target->nodisablehwbponss = base->nodisablehwbponss;
233  target->live = base->live;
234  target->writeable = base->writeable;
235  target->mmapable = base->mmapable;
236  target->no_adjust_bp_ip = 0;
237  /* NB: only native arch supported! i.e., no 32-bit emu on 64-bit host. */
238  target->arch = base->arch;
239 
240  target->fbregno = base->fbregno;
241  target->spregno = base->spregno;
242  target->ipregno = base->ipregno;
243 
244  /*
245  * Make sure the base thread is loaded.
246  */
247  if (!(base_thread = target_load_thread(base,base_tid,0))) {
248  verror("could not load base tid %d!\n",base_tid);
249  return -1;
250  }
251  else if (base_thread != target->base_thread) {
252  /*
253  * Catch stale threads; if there is a huge delay between
254  * target_instantiate and target_open, this could potentially
255  * happen -- but PID wraparound in the kernel would have to
256  * happen mighty fast! Unlikely.
257  */
258  vwarn("target->base_thread does not match with just-loaded thread"
259  " for %d; pid wraparound caused stale thread??\n",base_tid);
260  target->base_thread = base_thread;
261  }
262 
263  /*
264  * Just adjust for the user, don't error :)
265  */
266  if (target->spec->bpmode == THREAD_BPMODE_STRICT) {
267  vwarn("auto-enabling SEMI_STRICT bpmode on Xen Process target.\n");
269  }
270 
271  /*
272  * Initialize our state.
273  */
274  target->state = calloc(1,sizeof(struct os_process_state));
275 
276  /*
277  * Don't do anything else here; do it in attach().
278  */
279  return 0;
280 }
281 
282 static int os_process_fini(struct target *target) {
283  if (target->state)
284  free(target->state);
285  return 0;
286 }
287 
288 static int os_process_attach(struct target *target) {
289  if (target_pause(target->base)) {
290  verror("could not pause base target %s!\n",target->base->name);
291  return -1;
292  }
293 
295 
296  /*
297  * Just grab all the threads in the thread group and create them.
298  */
299  target->current_thread = target_create_thread(target,target->base_tid,
300  NULL,NULL);
302 
304 
305  return 0;
306 }
307 
308 static int os_process_detach(struct target *target,int stay_paused) {
309  /*
310  * Just detach all our threads.
311  */
312  return 0;
313 }
314 
315 static int os_process_loadspaces(struct target *target) {
316  struct os_process_state *ospstate;
317  struct target_process *process;
318  char nbuf[32];
319 
320  ospstate = (struct os_process_state *)target->state;
321  /*
322  * NB: between os_process_handle_event, os_process_loadregions, and
323  * target_os_process_get(), there is a loop! Break it by not
324  * allowing any memory events that are bubbled up into
325  * os_process_handle_event() to cause os_process_loadregions() to
326  * get called multiple times -- or in this case, right here, we
327  * don't want os_process_loadregions() to get called until after
328  * os_process_loadspaces() finishes.
329  */
330  if (ospstate->loading_memory)
331  return 0;
332  else
333  ospstate->loading_memory = 1;
334 
335  process = target_os_process_get(target->base,target->base_tid);
336  if (!process) {
337  verror("could not load process from underlying OS; not updating!\n");
338  ospstate->loading_memory = 0;
339  return -1;
340  }
341  snprintf(nbuf,sizeof(nbuf),"os_process(%d)",target->base_tid);
342  addrspace_create(target,nbuf,process->space->tag);
343  ospstate->loading_memory = 0;
344 
345  return 0;
346 }
347 
348 static int os_process_loadregions(struct target *target,
349  struct addrspace *space) {
350  struct os_process_state *ospstate;
351  struct target_process *process;
352  GList *t1,*t2,*t11,*t22,*t2x,*t22x;
353  struct memregion *region1,*region2;
354  struct memrange *range1,*range2;
355  struct target_event *event;
356  REFCNT trefcnt;
357 
358  ospstate = (struct os_process_state *)target->state;
359  if (ospstate->loading_memory)
360  return 0;
361  else
362  ospstate->loading_memory = 1;
363 
364  process = target_os_process_get(target->base,target->base_tid);
365  if (!process) {
366  verror("could not load process from underlying OS; not updating!\n");
367  ospstate->loading_memory = 0;
368  return -1;
369  }
370 
371  /*
372  * Take process->space, and update our target->space to mirror it!
373  */
374 
375  /* Mark our existing space, regions, and ranges as dead. */
376  OBJSDEAD(space,addrspace);
377 
378  if (process->space->tag != space->tag) {
379  /*
380  * NB: necessary to catch processes whose VM is replaced,
381  * i.e. on exec(). Just update our tag; not much else we can
382  * do.
383  */
384  space->tag = process->space->tag;
385  }
386 
387  /*
388  * Now, update, add, or mark live the ones that match.
389  */
390 
391  /* Now compare the regions and ranges in the spaces: */
392  v_g_list_foreach(process->space->regions,t1,region1) {
393  v_g_list_foreach(space->regions,t2,region2) {
394  if (region1->type == region2->type
395  && region1->base_load_addr == region2->base_load_addr
396  && ((region1->name == NULL && region2->name == NULL)
397  || (region1->name && region2->name
398  && strcmp(region1->name,region2->name) == 0)))
399  break;
400  else
401  region2 = NULL;
402  }
403 
404 #warning "generate MOD events"
405 
406  if (region2 == NULL) {
407  region2 = memregion_create(space,region1->type,region1->name);
408  event = target_create_event(target,NULL,
410  target_broadcast_event(target,event);
411  }
412 
413  /* Now compare the ranges. */
414  v_g_list_foreach(region1->ranges,t11,range1) {
415  v_g_list_foreach(region2->ranges,t22,range2) {
416  if (range1->start == range2->start)
417  break;
418  else
419  range2 = NULL;
420  }
421 
422  if (range2 == NULL) {
423  range2 = memrange_create(region2,range1->start,range1->end,
424  range1->offset,range1->prot_flags);
425  event = target_create_event(target,NULL,
427  target_broadcast_event(target,event);
428  }
429  else if (range1->end != range2->end
430  || range1->prot_flags != range2->prot_flags
431  || range1->offset != range2->offset) {
432  event = target_create_event(target,NULL,
434  target_broadcast_event(target,event);
435  OBJSMOD(range2);
436  }
437 
438  OBJSLIVE(range2,memrange);
439  }
440 
441  /* Now delete any dead ranges: */
442  v_g_list_foreach_safe(region2->ranges,t22,t22x,range2) {
443  if (!OBJLIVE(range2)) {
444  event = target_create_event(target,NULL,
446  target_broadcast_event(target,event);
447 
448  v_g_list_foreach_remove(region2->ranges,t22,t22x);
449  RPUT(range2,memrange,region2,trefcnt);
450  }
451  }
452 
453  /* Mark the region (and all its ranges) as live. */
454  OBJSLIVE(region2,memregion);
455  }
456 
457  /* Now delete any dead regions: */
458  v_g_list_foreach_safe(space->regions,t2,t2x,region2) {
459  if (!OBJLIVE(region2)) {
460  event = target_create_event(target,NULL,
462  target_broadcast_event(target,event);
463 
464  v_g_list_foreach_remove(space->regions,t2,t2x);
465  RPUT(region2,memregion,space,trefcnt);
466  }
467  }
468 
469  /*
470  * Finally, mark it all as live.
471  */
472  OBJSLIVE(space,addrspace);
473 
474  ospstate->loading_memory = 0;
475 
476  return 0;
477 }
478 
479 static int os_process_loaddebugfiles(struct target *target,
480  struct addrspace *space,
481  struct memregion *region) {
482  int retval = -1;
483  struct debugfile *debugfile = NULL;
484  char rbuf[PATH_MAX];
485  char *file;
486  struct lsymbol *mainsymbol;
487  int bfn = 0;
488  int bfpn = 0;
489 
490  vdebug(5,LA_TARGET,LF_OSP,"tid %d\n",target->base_tid);
491 
492  if (!(region->type == REGION_TYPE_MAIN
493  || region->type == REGION_TYPE_LIB)) {
494  vdebug(4,LA_TARGET,LF_OSP,"region %s is not MAIN nor LIB; skipping!\n",
495  region->name);
496  return 0;
497  }
498 
499  if (!region->name || strlen(region->name) == 0)
500  return -1;
501 
502  /* Try to find it, given all our paths and prefixes... */
503  file = region->name;
504  debugfile = debugfile_from_file(file,
505  target->spec->debugfile_root_prefix,
506  target->spec->debugfile_load_opts_list);
507  if (!debugfile) {
508  if (!debugfile_search_path(region->name,
509  target->spec->debugfile_root_prefix,
510  NULL,NULL,rbuf,PATH_MAX)) {
511  verror("could not find debugfile for region '%s': %s\n",
512  region->name,strerror(errno));
513  return -1;
514  }
515 
516  file = rbuf;
517  debugfile = debugfile_from_file(file,
518  target->spec->debugfile_root_prefix,
519  target->spec->debugfile_load_opts_list);
520  if (!debugfile) {
521  verror("still could not find debugfile for region '%s': %s\n",
522  region->name,strerror(errno));
523  return -1;
524  }
525  }
526 
527  if (target_associate_debugfile(target,region,debugfile)) {
528  goto out;
529  }
530 
531  /*
532  * Try to figure out which binfile has the info we need. On
533  * different distros, they're stripped different ways.
534  */
535  if (debugfile->binfile_pointing) {
536  binfile_get_root_scope_sizes(debugfile->binfile,&bfn,NULL,NULL,NULL);
538  NULL,NULL,NULL);
539  if (bfpn > bfn) {
540  RHOLD(debugfile->binfile_pointing,region);
541  region->binfile = debugfile->binfile_pointing;
542  }
543  }
544 
545  if (!region->binfile) {
546  RHOLD(debugfile->binfile,region);
547  region->binfile = debugfile->binfile;
548  }
549 
550  if (!target->arch) {
551  target->arch = debugfile->binfile->arch;
552  }
553 
554  /*
555  * Change type to REGION_TYPE_MAIN if it had a main() function.
556  */
557  if (region->type == REGION_TYPE_LIB) {
558  mainsymbol = debugfile_lookup_sym(debugfile,"main",NULL,NULL,SYMBOL_TYPE_FUNC);
559  if (mainsymbol) {
560  if (!mainsymbol->symbol->isdeclaration)
561  region->type = REGION_TYPE_MAIN;
562  lsymbol_release(mainsymbol);
563  }
564  }
565 
566  /*
567  * Propagate some binfile info...
568  */
569  region->base_phys_addr = region->binfile->base_phys_addr;
570  region->base_virt_addr = region->binfile->base_virt_addr;
571 
572  retval = 0;
573 
574  out:
575  return retval;
576 
577 }
578  /* Once regions and debugfiles are loaded, we call this -- it's a
579  * second-pass init, basically.
580  */
581 static int os_process_postloadinit(struct target *target) {
582 
583  return 0;
584 }
585 
586 static int os_process_set_active_probing(struct target *target,
587  active_probe_flags_t flags) {
588  active_probe_flags_t baseflags = 0;
589 
590  /*
591  * Filter out the default flags according to our personality.
592  */
593  if (flags & APF_THREAD_ENTRY) {
594  flags &= ~APF_THREAD_ENTRY;
595  flags |= APF_PROCESS_THREAD_ENTRY;
596  /*
597  * Just use the OS thread tracking; it's the same (at least for
598  * Linux -- probably shouldn't assume it in general...
599  */
600  baseflags |= APF_OS_THREAD_ENTRY;
601  }
602  if (flags & APF_THREAD_EXIT) {
603  flags &= ~APF_THREAD_EXIT;
604  flags |= APF_PROCESS_THREAD_EXIT;
605  /*
606  * Just use the OS thread tracking; it's the same (at least for
607  * Linux -- probably shouldn't assume it in general...
608  */
609  baseflags |= APF_OS_THREAD_EXIT;
610  }
611  if (flags & APF_MEMORY) {
612  flags &= ~APF_MEMORY;
613  flags |= APF_PROCESS_MEMORY;
614  }
615 
616  /*
617  * XXX: only allow user to set/unset process flags; we're going to
618  * pass this to underlying target; so the user should not be able to
619  * disable anything. This isn't really good enough... we should
620  * track who needs which flags.
621  */
622  flags &= APF_PROCESS | APF_OS;
623 
624  /* XXX: should we pass baseflags | target->base->ap_flags ? */
625  return target_set_active_probing(target->base,baseflags);
626 
627 }
628 
629 static struct target *
630 os_process_instantiate_overlay(struct target *target,
631  struct target_thread *tthread,
632  struct target_spec *spec,
633  struct target_thread **ntthread) {
634  struct target *overlay;
635 
636  if (!spec) {
637  errno = EINVAL;
638  return NULL;
639  }
640 
641  if (spec->target_type != TARGET_TYPE_PHP) {
642  errno = EINVAL;
643  return NULL;
644  }
645 
646  /*
647  * All we want to do here is create the overlay target.
648  */
649  overlay = target_create("php",spec);
650 
651  return overlay;
652 }
653 
654 static struct target_thread *
655 os_process_lookup_overlay_thread_by_id(struct target *target,int id) {
656  struct target_thread *retval;
657 
658  if (id < 0)
659  id = TID_GLOBAL;
660 
661  retval = os_process_load_thread(target,id,0);
662  if (!retval) {
663  if (!errno)
664  errno = ESRCH;
665  return NULL;
666  }
667 
668  return retval;
669 }
670 
671 static struct target_thread *
672 os_process_lookup_overlay_thread_by_name(struct target *target,char *name) {
673  struct target_thread *retval = NULL;
674  struct target_thread *tthread;
675  int rc;
676  GHashTableIter iter;
677 
678  if ((rc = os_process_load_all_threads(target,0)))
679  vwarn("could not load %d threads; continuing anyway!\n",-rc);
680 
681  g_hash_table_iter_init(&iter,target->threads);
682  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
683  if (tthread == target->global_thread)
684  continue;
685  else if (tthread->name && strcmp(tthread->name,name) == 0) {
686  retval = tthread;
687  break;
688  }
689  }
690 
691  if (retval) {
693  "found overlay thread %"PRIiTID"\n",retval->tid);
694  return tthread;
695  }
696  else {
697  errno = ESRCH;
698  return NULL;
699  }
700 }
701 
702 static target_status_t
703 os_process_handle_overlay_exception(struct target *overlay,
705  tid_t tid,ADDR ipval,int *again) {
706  struct target_thread *tthread;
707  struct target_thread *uthread;
708  struct probepoint *dpp;
709  struct os_state *xstate;
710 
711  xstate = (struct os_state *)overlay->base->state;
712 
713  tthread = target_lookup_thread(overlay,tid);
714  if (!tthread) {
715  /*
716  * This is a new thread the overlay is insisting we manage!
717  * Just Do It.
718  */
719  tthread = target_create_thread(overlay,tid,NULL,NULL);
721  target_attach_overlay_thread(overlay->base,overlay,tid);
722  }
723 
724  /*
725  * If not active probing memory, we kind of want to update our
726  * addrspaces aggressively (by checking the underlying OS target's
727  * process addrspace) so that if a user lookups a module symbol, we
728  * already have it. Really we should do this more lazily, like if a
729  * lookup failed, maybe.
730  */
731  if (!(overlay->ap_flags & APF_PROCESS_MEMORY)) {
732  os_process_loadregions(overlay,(struct addrspace *) \
733  g_list_nth_data(overlay->spaces,0));
734  }
735 
736  if (flags & EXCEPTION_BREAKPOINT) {
737  vdebug(3,LA_TARGET,LF_OSP,"new (breakpoint?) debug event\n");
738 
739  dpp = (struct probepoint *) \
740  g_hash_table_lookup(overlay->soft_probepoints,
741  (gpointer)(ipval - overlay->arch->breakpoint_instrs_len));
742  if (dpp) {
743  /* Run the breakpoint handler. */
744  overlay->ops->handle_break(overlay,tthread,dpp,
745  (flags & EXCEPTION_SINGLESTEP)
746  | (flags & EXCEPTION_SINGLESTEP_CMD));
747 
748  OBJSDIRTY(tthread);
749  vdebug(5,LA_TARGET,LF_OSP,"cleared status debug reg 6\n");
750 
751  goto out_bp_again;
752  }
753  }
754 
755  /* It will be loaded and valid; so just read regs and handle. */
756  if (flags & EXCEPTION_SINGLESTEP || flags & EXCEPTION_SINGLESTEP_CMD) {
757  vdebug(3,LA_TARGET,LF_OSP,"new single step debug event\n");
758 
759  if (!tthread->tpc) {
760  verror("unexpected singlestep event at ip 0x%"PRIxADDR
761  " in tid %"PRIiTID"!\n",
762  ipval,tid);
763  goto out_err;
764  }
765 
766  /*
767  * If this was supposed to be a single step in userspace, but
768  * instead we have stepped into the kernel, we have to abort the
769  * single step. This can only happen in the HVM case when we
770  * use the Monitor Trap Flag.
771  */
772  if (flags & EXCEPTION_SINGLESTEP_BOGUS) {
773  /*xstate->hvm && xstate->hvm_monitor_trap_flag_set
774  && ipval >= xstate->kernel_start_addr*/
776  "single step event in overlay tid %"PRIiTID" INTO KERNEL"
777  " (at 0x%"PRIxADDR"); aborting breakpoint singlestep;"
778  " will be hit again!\n",
779  tid,ipval);
780  overlay->ops->handle_interrupted_step(overlay,tthread,
781  tthread->tpc->probepoint);
782  }
783  else
784  overlay->ops->handle_step(overlay,tthread,tthread->tpc->probepoint);
785 
786  OBJSDIRTY(tthread);
787  /*
788  * MUST DO THIS. If we are going to modify both the
789  * current thread's CPU state possibly, and possibly
790  * operate on the global thread's CPU state, we need
791  * to clear the global thread's debug reg status
792  * here; this also has the important side effect of
793  * forcing a merge of the global thread's debug reg
794  * state; see flush_global_thread !
795  */
796  /*
797  gtstate->context.debugreg[6] = 0;
798  target->global_thread->dirty = 1;
799  vdebug(5,LA_TARGET,LF_XV,"cleared status debug reg 6\n");
800  */
801  goto out_ss_again;
802  }
803 
804  verror("unhandled overlay exception; will return ERROR!\n");
805 
806  out_err:
807  if (again)
808  *again = 0;
809  return TSTATUS_ERROR;
810 
811  out_bp_again:
812  if (again)
813  *again = 1;
814  return TSTATUS_PAUSED;
815 
816  out_ss_again:
817  if (again)
818  *again = 2;
819  return TSTATUS_PAUSED;
820 }
821 
822 static void os_process_handle_event(struct target *target,
823  struct target_event *event) {
824  struct addrspace *space;
825  target_event_t et;
826  struct target_thread *tthread,*othread;
827 
828  et = event->type;
829  tthread = event->thread;
830  space = (struct addrspace *)g_list_nth_data(target->spaces,0);
831 
832  if (T_EVENT_IS_OS_PROCESS(event)
833  && (T_EVENT_IS_SPACE(event,OS_PROCESS)
834  || T_EVENT_IS_REGION(event,OS_PROCESS)
835  || T_EVENT_IS_RANGE(event,OS_PROCESS))) {
836  /*
837  * We definitely could optimize this, and only handle the
838  * specific change in the event... but eh.
839  */
840  os_process_loadregions(target,space);
841  }
842  else if (et == T_EVENT_OS_THREAD_CREATED
844  if (!tthread) {
845  verror("malformed THREAD_CREATED event without thread set!\n");
846  return;
847  }
848  if (tthread->tid == target->base_tid)
849  /* Ignore our main thread; we already created it. */
850  return;
851  if (target_lookup_thread(target,tthread->tid)) {
852  /* Ignore; we already have it (somehow?) */
854  "underlying target tid %d is new; but already have it!\n",
855  tthread->tid);
856  return;
857  }
858  else {
859  /*
860  * Create a new thread.
861  */
862  target_create_thread(target,tthread->tid,NULL,NULL);
863  }
864  }
865  else if (et == T_EVENT_OS_THREAD_EXITED
869  if (!tthread) {
870  verror("malformed THREAD_EXIT(ED|ING) event without thread set!\n");
871  return;
872  }
873  if (tthread->tid == target->base_tid)
874  /* Ignore our main thread; let it get detached with target */
875  return;
876  othread = target_lookup_thread(target,tthread->tid);
877  if (!othread) {
878  /* Ignore; we never hda it (somehow?) */
880  "underlying target tid %d is exit(ed|ing);"
881  " but we do not have it!\n",tthread->tid);
882  return;
883  }
884  else {
885  /*
886  * Detach this thread from the target.
887  */
888  target_detach_thread(target,othread);
889  }
890  }
891 
892  return;
893 }
894 
895 static target_status_t os_process_status(struct target *target) {
896  return target_status(target->base);
897 }
898 
899 static int os_process_pause(struct target *target,int nowait) {
900  int rc;
901 
902  rc = target_pause(target->base);
903  if (rc)
904  return rc;
905  target_set_status(target,target->base->status);
906 
907  return 0;
908 }
909 
910 static int os_process_resume(struct target *target) {
911  int rc;
912 
913  rc = target_resume(target->base);
914  if (rc)
915  return rc;
916  target_set_status(target,target->base->status);
917 
918  return 0;
919 }
920 
921 /*
922  * XXX:
923  *
924  * Need to load/unload any new/stale threads in this function;
925  * everything calls it, basically. We need to keep a state bit in the
926  * os_process_state struct saying if we scanned the list this pass
927  * yet or not (and we can replace this with active probing, of course).
928  */
929 static int __is_our_tid(struct target *target,tid_t tid) {
930  if (g_hash_table_lookup(target->threads,(gpointer)(uintptr_t)tid))
931  return 1;
932  else
933  return 0;
934 }
935 
936 static int __we_are_current(struct target *target) {
937  if (target->base->current_thread
938  && __is_our_tid(target,target->base->current_thread->tid))
939  return 1;
940  else
941  return 0;
942 }
943 
944 static unsigned char *os_process_read(struct target *target,ADDR addr,
945  unsigned long length,unsigned char *buf) {
946  ADDR paddr = 0;
947 
948  /*
949  * If we are the current thread in the base target, this is easy --
950  * just read the current thread in the base. Otherwise, do v2p
951  * translation and read phys.
952  *
953  * XXX: for future, backend API read/write calls probably should
954  * have just been parameterized by tid! But this is what the
955  * underlying target would have to do anyway...
956  */
957  if (__we_are_current(target))
958  return target_read_addr(target->base,addr,length,buf);
959  else {
960  /* Resolve the phys page. */
961  if (target_addr_v2p(target->base,target->base_tid,addr,&paddr)) {
962  verror("could not translate vaddr 0x%"PRIxADDR" in tid %"PRIiTID"!\n",
963  addr,target->base_tid);
964  return NULL;
965  }
966 
967  return target_read_physaddr(target->base,paddr,length,buf);
968  }
969 }
970 
971 static unsigned long os_process_write(struct target *target,ADDR addr,
972  unsigned long length,unsigned char *buf) {
973  ADDR paddr = 0;
974 
975  if (__we_are_current(target))
976  return target_write_addr(target->base,addr,length,buf);
977  else {
978  /* Resolve the phys page. */
979  if (target_addr_v2p(target->base,target->base_tid,addr,&paddr)) {
980  verror("could not translate vaddr 0x%"PRIxADDR" in tid %"PRIiTID"!\n",
981  addr,target->base_tid);
982  return 0;
983  }
984 
985  return target_write_physaddr(target->base,paddr,length,buf);
986  }
987 }
988 
989 static tid_t os_process_gettid(struct target *target) {
990  struct target_thread *tthread;
991 
992  // XXX: fix!
993  return target->base_tid;
994 
995  if (target->current_thread && OBJVALID(target->current_thread))
996  return target->current_thread->tid;
997 
998  tthread = os_process_load_current_thread(target,0);
999  if (!tthread) {
1000  verror("could not load current thread to get TID!\n");
1001  return 0;
1002  }
1003 
1004  return tthread->tid;
1005 }
1006 
1007 static void os_process_free_thread_state(struct target *target,void *state) {
1008  if (state)
1009  free(state);
1010 }
1011 
1012 /* XXX: obviously, need to reload the tgid list. */
1013 static struct array_list *
1014 os_process_list_available_tids(struct target *target) {
1015  struct array_list *retval;
1016 
1017  retval = array_list_create(1);
1018  array_list_append(retval,(void *)(uintptr_t)target->base_tid);
1019 
1020  return retval;
1021 }
1022 
1023 static struct target_thread *
1024 os_process_load_thread(struct target *target,tid_t tid,int force) {
1025  if (!__is_our_tid(target,tid)) {
1026  verror("tid %d is not in tgid %d!\n",tid,target->base_tid);
1027  errno = ESRCH;
1028  return NULL;
1029  }
1030 
1031  if (!target_load_thread(target->base,tid,force))
1032  return NULL;
1033 
1034  return target_lookup_thread(target,tid);
1035 }
1036 
1037 static struct target_thread *
1038 os_process_load_current_thread(struct target *target,int force) {
1039  struct target_thread *uthread;
1040 
1041  uthread = target_load_current_thread(target->base,force);
1042  if (!uthread) {
1043  verror("could not load base target current thread: %s\n",
1044  strerror(errno));
1045  target->current_thread = NULL;
1046  return NULL;
1047  }
1048 
1049  /* XXX: should we return the primary thread, or NULL? */
1050  if (!__is_our_tid(target,uthread->tid)) {
1052  "base target current tid %d is not in tgid %d!\n",
1053  uthread->tid,target->base_tid);
1054  errno = ESRCH;
1055  target->current_thread = NULL;
1056  return NULL;
1057  }
1058 
1059  target->current_thread = target_lookup_thread(target,uthread->tid);
1060 
1061  return target->current_thread;
1062 }
1063 
1064 /* XXX: need to actually do them all! */
1065 static int os_process_load_all_threads(struct target *target,int force) {
1066  if (os_process_load_thread(target,target->base_tid,force))
1067  return 0;
1068  return 1;
1069 }
1070 
1071 static int os_process_load_available_threads(struct target *target,
1072  int force) {
1073  if (os_process_load_thread(target,target->base_tid,force))
1074  return 0;
1075  return -1;
1076 }
1077 
1078 static int os_process_flush_thread(struct target *target,tid_t tid) {
1079  struct target_thread *tthread;
1080  int rc;
1081 
1082  tthread = target_lookup_thread(target,tid);
1083  if (!OBJDIRTY(tthread))
1084  return 0;
1085 
1086  if (!__is_our_tid(target,tid)) {
1087  verror("tid %d is not in tgid %d!\n",tid,target->base_tid);
1088  errno = ESRCH;
1089  return -1;
1090  }
1091 
1092  rc = target->base->ops->flush_thread(target->base,tid);
1093  if (rc) {
1094  verror("could not flush base target tid %d: %s\n",tid,strerror(errno));
1095  return rc;
1096  }
1097 
1098  OBJSCLEAN(tthread);
1099 
1100  return 0;
1101 }
1102 
1103 static int os_process_flush_current_thread(struct target *target) {
1104  if (target->current_thread)
1105  return os_process_flush_thread(target,target->current_thread->tid);
1106  return 0;
1107 }
1108 
1109 static int os_process_flush_all_threads(struct target *target) {
1110  struct array_list *tlist;
1111  void *tid;
1112  int i;
1113  int rc = 0;
1114 
1115  tlist = target_list_tids(target);
1116  array_list_foreach(tlist,i,tid) {
1117  rc += os_process_flush_thread(target,(tid_t)(uintptr_t)tid);
1118  }
1119 
1120  return rc;
1121 }
1122 
1123 static int os_process_thread_snprintf(struct target *target,
1124  struct target_thread *tthread,
1125  char *buf,int bufsiz,
1126  int detail,char *sep,char *kvsep) {
1127  if (!__is_our_tid(target,tthread->tid)) {
1128  verror("tid %d is not in tgid %d!\n",
1129  tthread->tid,tthread->target->base_tid);
1130  errno = ESRCH;
1131  return -1;
1132  }
1133 
1134  return target->base->ops->thread_snprintf(target->base,target->base_thread,
1135  buf,bufsiz,detail,sep,kvsep);
1136 }
1137 
1138 static REGVAL os_process_read_reg(struct target *target,tid_t tid,REG reg) {
1139  struct target_thread *base_tthread;
1140 
1141  if (!__is_our_tid(target,tid)) {
1142  verror("tid %d is not in tgid %d!\n",tid,target->base_tid);
1143  errno = ESRCH;
1144  return -1;
1145  }
1146 
1147  base_tthread = target_load_thread(target->base,tid,0);
1148  if (base_tthread->tidctxt == THREAD_CTXT_KERNEL
1149  && target->base->ops->readreg_tidctxt)
1150  return target->base->ops->readreg_tidctxt(target->base,tid,
1151  THREAD_CTXT_USER,reg);
1152  else
1153  return target->base->ops->readreg(target->base,tid,reg);
1154 }
1155 
1156 static int os_process_write_reg(struct target *target,tid_t tid,REG reg,
1157  REGVAL value) {
1158  struct target_thread *tthread;
1159  struct target_thread *base_tthread;
1160 
1161  if (!__is_our_tid(target,tid)) {
1162  verror("tid %d is not in tgid %d!\n",tid,target->base_tid);
1163  errno = ESRCH;
1164  return -1;
1165  }
1166 
1167  tthread = target_lookup_thread(target,tid);
1168  OBJSDIRTY(tthread);
1169 
1170  base_tthread = target_load_thread(target->base,tid,0);
1171  if (base_tthread->tidctxt == THREAD_CTXT_KERNEL
1172  && target->base->ops->readreg_tidctxt)
1173  return target->base->ops->writereg_tidctxt(target->base,tid,
1174  THREAD_CTXT_USER,reg,value);
1175  else
1176  return target->base->ops->writereg(target->base,tid,reg,value);
1177 }
1178 
1179 /*
1180  * NB: we return mmods bound to the underlying target -- not to us!
1181  */
1182 static struct target_memmod *
1183 os_process_insert_sw_breakpoint(struct target *target,
1184  tid_t tid,ADDR addr) {
1185  struct target_thread *tthread;
1186  ADDR paddr = 0;
1187 
1188  tthread = target_lookup_thread(target,tid);
1189  if (!tthread) {
1190  verror("tid %"PRIiTID" does not exist!\n",tid);
1191  errno = ESRCH;
1192  return NULL;
1193  }
1194 
1195  /*
1196  * XXX NB: assume for now that anytime we put a breakpoint into a
1197  * text page in userspace, that this page might be shared between
1198  * processes. We could check if the page is writeable, and then not
1199  * do this, but that will be a rare occurence, so don't bother for
1200  * now.
1201  */
1202 
1203  /* Resolve the phys page. */
1204  if (target_addr_v2p(target->base,tid,addr,&paddr)) {
1205  verror("could not translate vaddr 0x%"PRIxADDR" in tid %"PRIiTID"!\n",
1206  addr,tid);
1207  return NULL;
1208  }
1209 
1210  return _target_insert_sw_breakpoint(target->base,tid,paddr,1,0);
1211 }
1212 static int os_process_remove_sw_breakpoint(struct target *target,tid_t tid,
1213  struct target_memmod *mmod) {
1214  return _target_remove_sw_breakpoint(target->base,tid,mmod);
1215 }
1216 
1217 static int os_process_enable_sw_breakpoint(struct target *target,tid_t tid,
1218  struct target_memmod *mmod) {
1219  return target_memmod_set(target->base,tid,mmod);
1220 }
1221 
1222 static int os_process_disable_sw_breakpoint(struct target *target,tid_t tid,
1223  struct target_memmod *mmod) {
1224  return target_memmod_unset(target->base,tid,mmod);
1225 }
1226 
1227 static int os_process_change_sw_breakpoint(struct target *target,tid_t tid,
1228  struct target_memmod *mmod,
1229  unsigned char *code,
1230  unsigned long code_len) {
1231  return target_memmod_set_tmp(target->base,tid,mmod,code,code_len);
1232 }
1233 
1234 static REG os_process_get_unused_debug_reg(struct target *target,tid_t tid) {
1235  errno = ENOTSUP;
1236  return -1;
1237 }
1238 
1239 int os_process_notify_sw_breakpoint(struct target *target,ADDR addr,
1240  int notification) {
1241  return target_notify_sw_breakpoint(target->base,addr,notification);
1242 }
1243 
1244 int os_process_singlestep(struct target *target,tid_t tid,int isbp,
1245  struct target *overlay) {
1246  return target_os_thread_singlestep(target->base,tid,isbp,target,0);
1247 }
1248 
1249 int os_process_singlestep_end(struct target *target,tid_t tid,
1250  struct target *overlay) {
1251  return target_os_thread_singlestep_end(target->base,tid,target,0);
1252 }
#define OBJSCLEAN(obj)
Definition: object.h:116
target_event_t
Definition: target_event.h:28
ADDR base_virt_addr
Definition: binfile.h:286
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
#define T_EVENT_IS_RANGE(event, ttype)
Definition: target_event.h:106
struct addrspace * space
int os_process_disable_hw_breakpoint(struct target *target, tid_t tid, REG dreg)
struct target * base
Definition: target_api.h:2614
void * state
Definition: target_api.h:2488
void target_broadcast_event(struct target *target, struct target_event *event)
Definition: target_event.c:56
struct debugfile * debugfile_from_file(char *filename, char *root_prefix, struct array_list *debugfile_load_opts_list)
Definition: debug.c:1584
thread_bpmode_t bpmode
Definition: target_api.h:2174
int32_t tid_t
Definition: common.h:36
REFCNT lsymbol_release(struct lsymbol *lsymbol)
Definition: debug.c:4805
target_status_t
Definition: target_api.h:197
result_t probepoint_ss_handler(struct target *target, struct target_thread *tthread, struct probepoint *probepoint)
Definition: probe.c:3021
uint32_t no_adjust_bp_ip
Definition: target_api.h:2427
struct symbol * symbol
Definition: dwdebug.h:1010
GHashTable * soft_probepoints
Definition: target_api.h:2695
#define T_EVENT_IS_REGION(event, ttype)
Definition: target_event.h:103
#define v_g_list_foreach_remove(glhead, glcur, glnext)
Definition: glib_wrapper.h:55
int target_resume(struct target *target)
Definition: target_api.c:973
ADDR end
Definition: target.h:984
#define v_g_list_foreach(glhead, glcur, elm)
Definition: glib_wrapper.h:34
probepoint_whence_t
Definition: probe_api.h:234
#define OBJSLIVE(obj, type)
Definition: object.h:121
target_debug_bp_handler_t handle_break
Definition: target_api.h:2829
struct target_thread * base_thread
Definition: target_api.h:2615
struct os_process_spec * os_process_build_spec(void)
active_probe_flags_t ap_flags
Definition: target_api.h:2439
char * debugfile_search_path(char *filename, char *root_prefix, char *debug_postfix, const char *DFPATH[], char *buf, int buflen)
Definition: debug.c:1510
int target_pause(struct target *target)
Definition: target_api.c:988
struct target_thread * global_thread
Definition: target_api.h:2645
struct target * target_create(char *type, struct target_spec *spec)
Definition: target.c:1849
char * name
Definition: target.h:928
struct target_ops os_process_ops
int target_associate_debugfile(struct target *target, struct memregion *region, struct debugfile *debugfile)
Definition: target.c:1963
ADDR start
Definition: target.h:983
uint8_t stay_paused
Definition: target_api.h:2176
int(* writereg)(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target_api.h:3024
#define verror(format,...)
Definition: log.h:30
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1014
void target_detach_thread(struct target *target, struct target_thread *tthread)
Definition: target.c:4073
int(* writereg_tidctxt)(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg, REGVAL value)
Definition: target_api.h:3029
uint32_t mmapable
Definition: target_api.h:2427
struct memregion * memregion_create(struct addrspace *space, region_type_t type, char *name)
Definition: memory.c:242
ADDR base_phys_addr
Definition: target.h:966
#define vwarn(format,...)
Definition: log.h:33
unsigned char * target_read_physaddr(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1039
uint32_t threadctl
Definition: target_api.h:2427
int(* thread_snprintf)(struct target *target, struct target_thread *tthread, char *buf, int bufsiz, int detail, char *sep, char *key_val_sep)
Definition: target_api.h:2967
result_t probepoint_bp_handler(struct target *target, struct target_thread *tthread, struct probepoint *probepoint, int was_stepping)
Definition: probe.c:2593
Definition: log.h:173
struct target_thread * target_load_thread(struct target *target, tid_t tid, int force)
Definition: target_api.c:1246
#define OBJLIVE(obj)
Definition: object.h:84
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
struct arch * arch
Definition: binfile.h:216
struct memrange * memrange_create(struct memregion *region, ADDR start, ADDR end, OFFSET offset, unsigned int prot_flags)
Definition: memory.c:538
struct target_thread * target_load_current_thread(struct target *target, int force)
Definition: target_api.c:1240
struct target_thread * current_thread
Definition: target_api.h:2640
#define OBJDIRTY(obj)
Definition: object.h:80
int os_process_singlestep_end(struct target *target, tid_t tid, struct target *overlay)
struct array_list * target_list_tids(struct target *target)
Definition: target_api.c:1145
int os_process_enable_hw_breakpoints(struct target *target, tid_t tid)
probepoint_watchsize_t
Definition: probe_api.h:241
tid_t base_tid
Definition: target_api.h:2617
int target_attach_overlay_thread(struct target *base, struct target *overlay, tid_t newtid)
Definition: target.c:4488
int target_set_active_probing(struct target *target, active_probe_flags_t flags)
Definition: target_api.c:616
int(* flush_thread)(struct target *target, tid_t tid)
Definition: target_api.h:2962
uint32_t live
Definition: target_api.h:2427
unsigned long target_write_physaddr(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1052
#define THREAD_CTXT_USER
Definition: target_os.h:33
GHashTable * threads
Definition: target_api.h:2632
int target_memmod_unset(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:5046
ADDR tag
Definition: target.h:886
#define THREAD_CTXT_KERNEL
Definition: target_os.h:32
#define RHOLD(x, hx)
Definition: common.h:622
ADDR addr
Definition: target.h:381
target_type_t target_type
Definition: target_api.h:2166
GList * spaces
Definition: target_api.h:2603
REGVAL(* readreg_tidctxt)(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg)
Definition: target_api.h:3027
int os_process_disable_hw_breakpoints(struct target *target, tid_t tid)
#define APF_OS
Definition: target_api.h:457
#define v_g_list_foreach_safe(glhead, glcur, glnext, elm)
Definition: glib_wrapper.h:46
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
int target_notify_sw_breakpoint(struct target *target, ADDR addr, int notification)
Definition: target_api.c:1826
struct thread_probepoint_context * tpc
Definition: target_api.h:2131
#define OBJSMOD(obj)
Definition: object.h:137
struct target_process * target_os_process_get(struct target *target, tid_t tid)
Definition: target_os.c:392
unsigned int isdeclaration
Definition: dwdebug_priv.h:839
struct lsymbol * debugfile_lookup_sym(struct debugfile *debugfile, char *name, const char *delim, struct rfilter *srcfile_filter, symbol_type_flag_t flags)
Definition: debug.c:1021
#define T_EVENT_IS_SPACE(event, ttype)
Definition: target_event.h:100
#define OBJVALID(obj)
Definition: object.h:76
struct arch * arch
Definition: target_api.h:2563
#define OBJSDIRTY(obj)
Definition: object.h:111
ADDR offset
Definition: target.h:985
unsigned int prot_flags
Definition: target.h:986
void os_process_free_spec(struct os_process_spec *spec)
struct array_list * debugfile_load_opts_list
Definition: target_api.h:2199
struct binfile * binfile
Definition: dwdebug.h:808
void target_thread_set_status(struct target_thread *tthread, thread_status_t status)
Definition: target.c:3999
struct target * target
Definition: target_api.h:2041
int os_process_notify_sw_breakpoint(struct target *target, ADDR addr, int notification)
Definition: log.h:70
GList * ranges
Definition: target.h:936
uint32_t REGVAL
Definition: common.h:66
target_status_t target_status(struct target *target)
Definition: target_api.c:1007
#define PRIiTID
Definition: common.h:37
struct binfile * binfile_pointing
Definition: dwdebug.h:830
void target_reuse_thread_as_global(struct target *target, struct target_thread *thread)
Definition: target.c:4063
int8_t REG
Definition: common.h:93
unsigned int breakpoint_instrs_len
Definition: arch.h:150
uint32_t ADDR
Definition: common.h:64
int os_process_enable_hw_breakpoint(struct target *target, tid_t tid, REG dreg)
char * name
Definition: target_api.h:2483
struct target_ops * ops
Definition: target_api.h:2510
int _target_remove_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1673
target_exception_flags_t
Definition: target_api.h:386
int target_memmod_set(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:4965
REG spregno
Definition: target_api.h:2469
thread_ctxt_t tidctxt
Definition: target_api.h:2043
target_status_t status
Definition: target_api.h:2465
int os_process_singlestep(struct target *target, tid_t tid, int isbp, struct target *overlay)
REG fbregno
Definition: target_api.h:2468
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
int binfile_get_root_scope_sizes(struct binfile *binfile, int *named, int *duplicated, int *anon, int *numscopes)
Definition: binfile.c:326
int(* snprintf)(struct target *target, char *buf, int bufsiz)
Definition: target_api.h:2758
struct target_spec * spec
Definition: target_api.h:2565
int target_memmod_set_tmp(struct target *target, tid_t tid, struct target_memmod *mmod, unsigned char *code, unsigned long code_len)
Definition: target.c:5123
uint32_t nodisablehwbponss
Definition: target_api.h:2427
#define RPUT(x, objtype, hx, rc)
Definition: common.h:624
ADDR base_virt_addr
Definition: target.h:967
REGVAL(* readreg)(struct target *target, tid_t tid, REG reg)
Definition: target_api.h:3023
active_probe_flags_t
Definition: target_api.h:432
char * debugfile_root_prefix
Definition: target_api.h:2197
region_type_t type
Definition: target.h:929
#define APF_PROCESS
Definition: target_api.h:459
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
Definition: target.c:3981
void target_set_status(struct target *target, target_status_t status)
Definition: target.c:3993
ADDR base_load_addr
Definition: target.h:957
struct target_event * target_create_event(struct target *target, struct target_thread *thread, target_event_t type, void *priv)
Definition: target_event.c:26
unsigned long target_write_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1021
struct target_memmod * _target_insert_sw_breakpoint(struct target *target, tid_t tid, ADDR addr, int is_phys, int nowrite)
Definition: target_api.c:1611
target_debug_handler_t handle_step
Definition: target_api.h:2830
result_t probepoint_interrupted_ss_handler(struct target *target, struct target_thread *tthread, struct probepoint *probepoint)
Definition: probe.c:3357
ADDR base_phys_addr
Definition: binfile.h:285
int target_addr_v2p(struct target *target, tid_t tid, ADDR vaddr, ADDR *paddr)
Definition: target_api.c:1028
struct binfile * binfile
Definition: target.h:950
struct target_thread * target_create_thread(struct target *target, tid_t tid, void *tstate, void *tpstate)
Definition: target.c:4021
#define T_EVENT_IS_OS_PROCESS(event)
Definition: target_event.h:94
REG ipregno
Definition: target_api.h:2470
#define TID_GLOBAL
Definition: target_api.h:145
target_debug_handler_t handle_interrupted_step
Definition: target_api.h:2853
int target_os_thread_singlestep_end(struct target *target, tid_t tid, struct target *overlay, int force_emulate)
Definition: target_os.c:79
GList * regions
Definition: target.h:898
struct probepoint * probepoint
Definition: probe.h:207
#define OBJSDEAD(obj, type)
Definition: object.h:127
struct addrspace * addrspace_create(struct target *target, char *name, ADDR tag)
Definition: memory.c:41
uint32_t writeable
Definition: target_api.h:2427