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_api.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-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 "config.h"
20 #include "common.h"
21 #include "glib_wrapper.h"
22 #include "arch.h"
23 
24 #include "target_api.h"
25 #include "target.h"
26 #include "target_os.h"
27 #include "target_process.h"
28 #include "probe_api.h"
29 #include "probe.h"
30 
31 #include <errno.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <inttypes.h>
37 #include <signal.h>
38 #include <glib.h>
39 
40 #include "target_linux_userproc.h"
41 #ifdef ENABLE_XENSUPPORT
42 #include "target_xen_vm.h"
43 #endif
44 #include "target_os_process.h"
45 #include "target_php.h"
46 #include "target_gdb.h"
47 
52 /*
53  * Generic function that launches or attaches to a target, given @spec.
54  */
56  struct evloop *evloop) {
57  struct target *target = NULL;
58 
59  if (spec->target_type == TARGET_TYPE_PTRACE) {
60  target = linux_userproc_instantiate(spec,evloop);
61  }
62 #ifdef ENABLE_XENSUPPORT
63  else if (spec->target_type == TARGET_TYPE_XEN) {
64  target = xen_vm_instantiate(spec,evloop);
65  }
66 #endif
67  else if (spec->target_type == TARGET_TYPE_OS_PROCESS) {
68  verror("cannot directly instantiate TARGET_TYPE_OS_PROCESS;"
69  " call target_instantiate_overlay instead.\n");
70  errno = EINVAL;
71  return NULL;
72  }
73  else if (spec->target_type == TARGET_TYPE_PHP) {
74  verror("cannot directly instantiate TARGET_TYPE_PHP;"
75  " call target_instantiate_overlay instead.\n");
76  errno = EINVAL;
77  return NULL;
78  }
79  else if (spec->target_type == TARGET_TYPE_GDB) {
80  target = gdb_instantiate(spec,evloop);
81  }
82 
83  if (target) {
84  target->spec = spec;
85  return target;
86  }
87 
88  errno = EINVAL;
89  return NULL;
90 }
91 
92 GList *target_instantiate_and_open(struct target_spec *primary_target_spec,
93  GList *base_target_specs,
94  GList *overlay_target_specs,
95  struct evloop *evloop,
96  GList **error_specs) {
97  struct target *primary_target = NULL,*target = NULL,*base_target;
98  struct target_spec *spec;
99  int i;
100  GList *tmp;
101  GList *lcopy = NULL;
102  GList *retval = NULL;
103 
104  i = 0;
105 
106  /*
107  * Instantiate the primary target first; then the base targets;
108  * then the overlay targets. If an overlay target doesn't have a
109  * base target id, then we assume and try the primary target created
110  * from the primary target spec; otherwise we fail.
111  */
112 
113  if (primary_target_spec) {
114  primary_target = target_instantiate(primary_target_spec,evloop);
115  if (!primary_target) {
116  if (error_specs) {
117  vwarn("could not instantiate primary target; skipping!\n");
118  *error_specs = g_list_append(*error_specs,primary_target_spec);
119  }
120  else {
121  verror("could not instantiate primary target; aborting\n!");
122  goto errout;
123  }
124  }
125  else {
126  vdebug(5,LA_TARGET,LF_TARGET,"instantiated primary target\n");
127  }
128  }
129 
130  if (base_target_specs) {
131  lcopy = g_list_copy(base_target_specs);
132  v_g_list_foreach(lcopy,tmp,spec) {
133  ++i;
134  target = target_instantiate(spec,evloop);
135 
136  if (target) {
137  target->spec = spec;
138  }
139  else if (error_specs) {
140  vwarn("could not instantiate target spec %d\n",i);
141  *error_specs = g_list_append(*error_specs,spec);
142  }
143  else {
144  verror("could not instantiate target spec %d\n",i);
145  goto errout;
146  }
147 
148  if (!target_open(target)) {
149  retval = g_list_append(retval,target);
150  }
151  else if (error_specs) {
152  vwarn("could not instantiate target spec %d\n",i);
153  target_close(target);
154  target_finalize(target);
155  *error_specs = g_list_append(*error_specs,spec);
156  }
157  else {
158  verror("could not instantiate target spec %d\n",i);
159  target_close(target);
160  target_finalize(target);
161  target = NULL;
162  goto errout;
163  }
164  }
165  g_list_free(lcopy);
166  lcopy = NULL;
167  }
168 
169  if (overlay_target_specs) {
170  lcopy = g_list_copy(overlay_target_specs);
171  v_g_list_foreach(lcopy,tmp,spec) {
172  ++i;
173  if (spec->base_target_id <= 0)
174  base_target = primary_target;
175  else
176  base_target = target_lookup_target_id(spec->base_target_id);
177 
178  if (!base_target) {
179  if (!error_specs) {
180  verror("could not instantiate overlay target spec %d;"
181  " no base target with id %d\n",
182  i,spec->base_target_id);
183  goto errout;
184  }
185  else {
186  vwarn("could not instantiate overlay target spec %d;"
187  " no base target with id %d\n",
188  i,spec->base_target_id);
189  *error_specs = g_list_append(*error_specs,spec);
190  continue;
191  }
192  }
193 
194  if (spec->base_thread_name) {
195  spec->base_thread_id =
197  spec->base_thread_name);
198  if (spec->base_thread_id < 0) {
199  if (!error_specs) {
200  verror("could not instantiate overlay target spec %d;"
201  " no base target thread named %s\n",
202  i,spec->base_thread_name);
203  goto errout;
204  }
205  else {
206  vwarn("could not instantiate overlay target spec %d;"
207  " no base target thread named %s\n",
208  i,spec->base_thread_name);
209  *error_specs = g_list_append(*error_specs,spec);
210  }
211  }
212  }
213 
214  target = target_instantiate_overlay(base_target,
215  spec->base_thread_id,spec);
216  if (target) {
217  target->spec = spec;
218  retval = g_list_append(retval,target);
219  }
220  else if (!error_specs) {
221  verror("could not instantiate overlay target spec %d"
222  " on base thread %d\n",
223  i,spec->base_thread_id);
224  goto errout;
225  }
226  else {
227  vwarn("could not instantiate overlay target spec %d"
228  " on base thread %d\n",
229  i,spec->base_thread_id);
230  *error_specs = g_list_append(*error_specs,spec);
231  }
232 
233  if (!target_open(target)) {
234  retval = g_list_append(retval,target);
235  }
236  else if (error_specs) {
237  vwarn("could not instantiate target spec %d\n",i);
238  target_close(target);
239  target_finalize(target);
240  *error_specs = g_list_append(*error_specs,spec);
241  }
242  else {
243  verror("could not instantiate target spec %d\n",i);
244  target_close(target);
245  target_finalize(target);
246  target = NULL;
247  goto errout;
248  }
249  }
250  g_list_free(lcopy);
251  lcopy = NULL;
252  }
253 
254  return retval;
255 
256  errout:
257  if (lcopy) {
258  g_list_free(lcopy);
259  lcopy = NULL;
260  }
261  if (retval) {
262  retval = g_list_reverse(retval);
263  v_g_list_foreach(retval,tmp,target) {
264  target_finalize(target);
265  }
266  g_list_free(retval);
267  }
268  return NULL;
269 }
270 
271 GList *target_instantiate_and_open_list(GList *target_specs,
272  struct evloop *evloop,
273  GList **error_specs) {
274  struct target *target = NULL;
275  struct target_spec *spec;
276  int i;
277  GList *tmp,*tmp2;
278  GList *lcopy;
279  GList *retval = NULL;
280  int progress,last_progress;
281  struct target *base_target;
282  tid_t base_thread_id;
283 
284  lcopy = g_list_copy(target_specs);
285 
286  /*
287  * Instantiate all the base targets first, removing them as we go;
288  * then instantiate the overlay targets if there is a matching
289  * target, or if any target will accept them.
290  */
291  i = 0;
292  /* Force at least two trips through the loop before we start giving
293  * up on lookups.
294  */
295  progress = 1;
296  while (1) {
297  last_progress = progress;
298  progress = 0;
299  v_g_list_foreach_safe(lcopy,tmp,tmp2,spec) {
300  if (spec->target_type == TARGET_TYPE_PTRACE) {
301  target = linux_userproc_instantiate(spec,evloop);
302  }
303 #ifdef ENABLE_XENSUPPORT
304  else if (spec->target_type == TARGET_TYPE_XEN) {
305  target = xen_vm_instantiate(spec,evloop);
306  }
307 #endif
308  else if (spec->target_type == TARGET_TYPE_GDB) {
309  target = gdb_instantiate(spec,evloop);
310  }
311  else {
312  base_target = target_lookup_target_id(spec->base_target_id);
313 
314  if (!base_target && !last_progress) {
315  if (!error_specs) {
316  verror("could not lookup base target id %d for"
317  " overlay target spec\n",spec->base_target_id);
318  goto errout;
319  }
320  else {
321  vwarn("could not lookup base target id %d for"
322  " target spec; skipping\n",spec->base_target_id);
323  v_g_list_foreach_remove(lcopy,tmp,tmp2);
324  *error_specs = g_list_append(*error_specs,spec);
325  continue;
326  }
327  }
328  else if (!base_target) {
329  /* Try again until there is no progress */
330  continue;
331  }
332 
333  if (!spec->base_thread_name)
334  base_thread_id = spec->base_thread_id;
335  else {
336  base_thread_id =
338  spec->base_thread_name);
339  if (base_thread_id < 0) {
340  if (!error_specs) {
341  verror("could not lookup base target thread name %s"
342  " for overlay target spec\n",
343  spec->base_thread_name);
344  goto errout;
345  }
346  else {
347  vwarn("could not lookup base target thread name %s"
348  " for overlay target spec; skipping\n",
349  spec->base_thread_name);
350  v_g_list_foreach_remove(lcopy,tmp,tmp2);
351  *error_specs = g_list_append(*error_specs,spec);
352  continue;
353  }
354  }
355  }
356 
357  target = target_instantiate_overlay(base_target,base_thread_id,
358  spec);
359  }
360  }
361 
362  if (target) {
363  ++progress;
364  target->spec = spec;
365  retval = g_list_append(retval,target);
366  }
367  else if (error_specs) {
368  vwarn("could not instantiate target spec %d\n",i);
369  *error_specs = g_list_append(*error_specs,spec);
370  }
371  else {
372  vwarn("could not instantiate target spec %d\n",i);
373  goto errout;
374  }
375 
376  v_g_list_foreach_remove(lcopy,tmp,tmp2);
377  }
378 
379  g_list_free(lcopy);
380  return retval;
381 
382  errout:
383  g_list_free(lcopy);
384  if (retval) {
385  retval = g_list_reverse(retval);
386  v_g_list_foreach(retval,tmp,target) {
387  target_finalize(target);
388  }
389  g_list_free(retval);
390  }
391  return NULL;
392 }
393 
395  struct target_spec *tspec;
396 
397  if (type == TARGET_TYPE_NONE) {
398  tspec = calloc(1,sizeof(*tspec));
399  }
400  else if (type == TARGET_TYPE_PTRACE) {
401  tspec = calloc(1,sizeof(*tspec));
403  }
404 #ifdef ENABLE_XENSUPPORT
405  else if (type == TARGET_TYPE_XEN) {
406  tspec = calloc(1,sizeof(*tspec));
407  tspec->backend_spec = xen_vm_build_spec();
408  }
409 #endif
410  else if (type == TARGET_TYPE_OS_PROCESS) {
411  tspec = calloc(1,sizeof(*tspec));
413  }
414  else if (type == TARGET_TYPE_PHP) {
415  tspec = calloc(1,sizeof(*tspec));
416  tspec->backend_spec = php_build_spec();
417  }
418  else if (type == TARGET_TYPE_GDB) {
419  tspec = calloc(1,sizeof(*tspec));
420  tspec->backend_spec = gdb_build_spec();
421  }
422  else {
423  errno = EINVAL;
424  return NULL;
425  }
426 
427  tspec->target_id = -1;
428  tspec->target_type = type;
429  tspec->target_mode = mode;
430  tspec->style = PROBEPOINT_FASTEST;
431  tspec->kill_on_close_sig = SIGKILL;
432 
433  return tspec;
434 }
435 
436 void target_free_spec(struct target_spec *spec) {
437  int i;
438 
439  if (spec->backend_spec) {
440  if (spec->target_type == TARGET_TYPE_PTRACE) {
442  }
443 #ifdef ENABLE_XENSUPPORT
444  else if (spec->target_type == TARGET_TYPE_XEN) {
445  xen_vm_free_spec((struct xen_vm_spec *)spec->backend_spec);
446  }
447 #endif
448  else if (spec->target_type == TARGET_TYPE_OS_PROCESS) {
450  }
451  else if (spec->target_type == TARGET_TYPE_PHP) {
452  php_free_spec((struct php_spec *)spec->backend_spec);
453  }
454  else if (spec->target_type == TARGET_TYPE_GDB) {
455  gdb_free_spec((struct gdb_spec *)spec->backend_spec);
456  }
457  }
458 
459  if (spec->debugfile_load_opts_list) {
460  for (i = 0; i < array_list_len(spec->debugfile_load_opts_list); ++i) {
461  struct debugfile_load_opts *dlo_list = (struct debugfile_load_opts *) \
462  array_list_item(spec->debugfile_load_opts_list,i);
463  debugfile_load_opts_free(dlo_list);
464  }
465  array_list_free(spec->debugfile_load_opts_list);
466  spec->debugfile_load_opts_list = NULL;
467  }
468  if (spec->infile) {
469  free(spec->infile);
470  spec->infile = NULL;
471  }
472  if (spec->outfile) {
473  free(spec->outfile);
474  spec->outfile = NULL;
475  }
476  if (spec->errfile) {
477  free(spec->errfile);
478  spec->errfile = NULL;
479  }
480 
481  free(spec);
482 }
483 
485  return target->spec->target_type;
486 }
487 
488 char *target_name(struct target *target) {
489  return target->name;
490 }
491 
492 int target_id(struct target *target) {
493  return target->id;
494 }
495 
496 int target_open(struct target *target) {
497  int rc;
498  struct addrspace *space;
499  struct memregion *region;
500  char buf[128];
501  GList *t1,*t2;
502 
503  if (!target->spec) {
504  verror("cannot open a target without a specification!\n");
505  errno = EINVAL;
506  return -1;
507  }
508 
509  vdebug(5,LA_TARGET,LF_TARGET,"opening target type(%d)\n",target_type(target));
510 
511  /*
512  * Try to load the user-specified personality if one exists, and if
513  * the target did *NOT* load it alrady!
514  */
515  if (target->spec->personality && !target->personality_ops) {
517  "loading user-specified personality '%s' (%s)\n",
518  target->spec->personality,target->spec->personality_lib ? : "");
519  if ((rc = target_personality_attach(target,target->spec->personality,
520  target->spec->personality_lib))) {
521  verror("Failed to initialize user-specified personality (%d)!\n",rc);
522  return -1;
523  }
524  }
525  else if (target->spec->personality_lib) {
526  verror("cannot specify a personality library without a"
527  " personality name!\n");
528  errno = EINVAL;
529  return -1;
530  }
531 
532  vdebug(5,LA_TARGET,LF_TARGET,"target type(%d): init\n",target_type(target));
533  if ((rc = target->ops->init(target))) {
534  return rc;
535  }
536  SAFE_PERSONALITY_OP_WARN(init,rc,0,target);
537 
538  if (target_snprintf(target,buf,sizeof(buf)) < 0)
539  target->name = NULL;
540  else
541  target->name = strdup(buf);
542 
543  if (target->spec->bpmode == THREAD_BPMODE_STRICT && !target->threadctl) {
544  verror("cannot init a target in BPMODE_STRICT that does not have"
545  " threadctl!\n");
546  errno = ENOTSUP;
547  return -1;
548  }
549 
550  SAFE_TARGET_OP(loadspaces,rc,0,target);
551  v_g_list_foreach(target->spaces,t1,space) {
552  SAFE_TARGET_OP(loadregions,rc,0,target,space);
553  }
554 
555  v_g_list_foreach(target->spaces,t1,space) {
556  v_g_list_foreach(space->regions,t2,region) {
557  if (region->type == REGION_TYPE_HEAP
558  || region->type == REGION_TYPE_STACK
559  || region->type == REGION_TYPE_VDSO
560  || region->type == REGION_TYPE_VSYSCALL)
561  continue;
562 
563  SAFE_TARGET_OP_WARN_NORET(loaddebugfiles,rc,0,target,space,region);
564 
565  /*
566  * Once the region has been loaded and associated with a
567  * debuginfo file, we calculate the phys_offset of the
568  * loaded code -- which is the base_phys_addr - base_virt_addr
569  * from the ELF program headers.
570  */
571  if (region->type == REGION_TYPE_MAIN)
572  region->phys_offset = 0;
573  /*
574  * If it got loaded at the base_phys_addr from the binary,
575  * there is no offset.
576  */
577  else if (region->base_load_addr == region->base_phys_addr)
578  region->phys_offset = 0;
579  else
580  region->phys_offset = region->base_load_addr \
581  + (region->base_phys_addr - region->base_virt_addr);
582 
584  "target(%s:%s:0x%"PRIxADDR") finished region(%s:%s,"
585  "base_load_addr=0x%"PRIxADDR",base_phys_addr=0x%"PRIxADDR
586  ",base_virt_addr=0x%"PRIxADDR
587  ",phys_offset=%"PRIiOFFSET" (0x%"PRIxOFFSET"))\n",
588  target->name,space->name,space->tag,
589  region->name,REGION_TYPE(region->type),
590  region->base_load_addr,region->base_phys_addr,
591  region->base_virt_addr,region->phys_offset,
592  region->phys_offset);
593  }
594  }
595 
596  SAFE_TARGET_OP(postloadinit,rc,0,target);
597  SAFE_TARGET_OP(attach,rc,0,target);
598 
599  target->opened = 1;
600 
601  /*
602  * Set up active probing if requested, once we're opened.
603  *
604  * NB: it's better if the backend does everything it can to
605  * pre-setup active probing -- i.e., making sure the necessary
606  * symbols exist, and it will be possible to probe them, in
607  * postloadinit().
608  */
609  SAFE_TARGET_OP(set_active_probing,rc,0,target,target->spec->ap_flags);
610 
611  SAFE_TARGET_OP(postopened,rc,0,target);
612 
613  return 0;
614 }
615 
617  int rc;
618 
619  if (!target->ops->set_active_probing
620  && !target->personality_ops
621  && !target->personality_ops->set_active_probing) {
623  "no active probing support in target(%s)\n",target->name);
624  errno = ENOTSUP;
625  return -1;
626  }
627 
628  SAFE_TARGET_OP(set_active_probing,rc,0,target,flags);
629 
630  return rc;
631 }
632 
634  target_type_t type) {
635  struct array_list *retval;
636  GHashTableIter iter;
637  struct target_thread *tthread;
638 
639  vdebug(8,LA_TARGET,LF_TARGET,"loading available threads\n");
640 
641  if (target_load_available_threads(target,0)) {
642  verror("could not load available threads!\n");
643  return NULL;
644  }
645 
646  retval = array_list_create(g_hash_table_size(target->threads));
647  g_hash_table_iter_init(&iter,target->threads);
648  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
649  if (tthread == target->global_thread)
650  continue;
651 
652  if ((type == TARGET_TYPE_NONE && tthread->supported_overlay_types)
653  || (type & tthread->supported_overlay_types))
654  array_list_append(retval,(void *)(uintptr_t)tthread->tid);
655  }
656  array_list_compact(retval);
657 
658  vdebug(8,LA_TARGET,LF_TARGET,"can overlay available threads\n");
659 
660  return retval;
661 }
662 
664  if (g_hash_table_size(target->overlays) == 0)
665  return NULL;
666 
667  return array_list_create_from_g_hash_table(target->overlays);
668 }
669 
671  struct target_thread *tthread;
672 
673  if (!target->ops->lookup_overlay_thread_by_id) {
674  verror("no overlay support in target(%s)!\n",target->name);
675  errno = ENOTSUP;
676  return -1;
677  }
678 
679  vdebug(16,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
680 
681  tthread = target->ops->lookup_overlay_thread_by_id(target,id);
682  if (tthread)
683  return tthread->tid;
684 
685  if (!errno)
686  errno = ESRCH;
687  return -1;
688 }
689 
691  struct target_thread *tthread;
692 
693  if (!target->ops->lookup_overlay_thread_by_name) {
694  verror("no overlay support in target(%s)!\n",target->name);
695  errno = ENOTSUP;
696  return -1;
697  }
698 
699  vdebug(16,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
700 
701  tthread = target->ops->lookup_overlay_thread_by_name(target,name);
702  if (tthread)
703  return tthread->tid;
704 
705  if (!errno)
706  errno = ESRCH;
707  return -1;
708 
709 }
710 
712  tid_t tid) {
714  "target(%s) tid %"PRIiTID"\n",target->name,tid);
715 
716  if (!target->ops->build_default_overlay_spec) {
717  errno = ENOTSUP;
718  return NULL;
719  }
720 
721  return target->ops->build_default_overlay_spec(target,tid);
722 }
723 
725  struct target_spec *spec) {
726  struct target *overlay;
727  struct target_thread *tthread;
728  struct target_thread *ntthread = NULL;
729 
730  if (!target->ops->instantiate_overlay) {
731  verror("no overlay support in target(%s)!\n",target->name);
732  errno = ENOTSUP;
733  return NULL;
734  }
735 
737  "target(%s) tid %"PRIiTID"\n",target->name,tid);
738 
739  if (g_hash_table_lookup(target->overlays,(gpointer)(uintptr_t)tid)
740  || g_hash_table_lookup(target->overlay_aliases,(gpointer)(uintptr_t)tid)) {
741  verror("target(%s) tid %"PRIiTID" already has overlay!\n",
742  target->name,tid);
743  errno = EALREADY;
744  return NULL;
745  }
746 
747  tthread = target_load_thread(target,tid,0);
748  if (!tthread) {
749  verror("target(%s) tid %d could not be loaded!\n",target->name,tid);
750  errno = ESRCH;
751  return NULL;
752  }
753 
754  overlay = target->ops->instantiate_overlay(target,tthread,spec,&ntthread);
755  if (!overlay) {
756  verror("target(%s) tid %"PRIiTID" failed to create overlay!\n",
757  target->name,tid);
758  return NULL;
759  }
760 
761  if (ntthread)
762  tthread = ntthread;
763 
764  overlay->base = target;
765  RHOLDW(overlay->base,overlay);
766  overlay->base_id = target->id;
767  overlay->base_thread = tthread;
768  RHOLDW(tthread,overlay);
769  overlay->base_tid = tthread->tid;
770 
771  g_hash_table_insert(target->overlays,
772  (gpointer)(uintptr_t)tthread->tid,overlay);
773  RHOLD(overlay,target);
774 
775  if (tid == tthread->tid) {
777  "target(%s) tid %"PRIiTID" new overlay target(%s) (id %d)\n",
778  target->name,tthread->tid,overlay->name,overlay->id);
779  }
780  else {
782  "target(%s) tid %"PRIiTID" new overlay target(%s) (id %d)"
783  " (not using user-supplied thread %d; base target overrode it!)\n",
784  target->name,tthread->tid,overlay->name,overlay->id,tid);
785  }
786 
787  return overlay;
788 }
789 
790 int target_snprintf(struct target *target,char *buf,int bufsiz) {
791  vdebug(16,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
792  return target->ops->snprintf(target,buf,bufsiz);
793 }
794 
796  if (target->evloop) {
797  verror("an evloop is already associated with target(%s)!\n",
798  target->name);
799  errno = EINVAL;
800  return -1;
801  }
802  vdebug(16,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
803  target->evloop = evloop;
804  return target->ops->attach_evloop(target,evloop);
805 }
806 
808  int rc;
809 
810  if (!target->evloop) {
811  vwarn("no evloop is associated with target(%s)!\n",
812  target->name);
813  return -1;
814  }
815 
816  vdebug(16,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
817  rc = target->ops->detach_evloop(target);
818 
819  target->evloop = NULL;
820 
821  return rc;
822 }
823 
825  if (target->evloop && evloop && target->evloop == evloop)
826  return 1;
827  return 0;
828 }
829 
831  if (target->status != TSTATUS_RUNNING) {
832  verror("cannot monitor target(%s) in state %s; ERROR!\n",
833  target->name,TSTATUS(target->status));
834  return TSTATUS_ERROR;
835  }
837  vdebug(8,LA_TARGET,LF_TARGET,"monitoring target(%s)\n",target->name);
838  return target->ops->monitor(target);
839 }
840 
841 int target_monitor_evloop(struct evloop *evloop,struct timeval *timeout,
842  struct target **target,target_status_t *status) {
843  struct evloop_fdinfo *fdinfo;
844  int hrc;
845  int fdtype;
846  int rc = 0;
847  int nfds;
848  struct timeval tv;
849  struct target *t;
850 
852 
853  if (timeout)
854  tv = *timeout;
855 
856  while (evloop_maxsize(evloop) > -1) {
857  if (target)
858  *target = NULL;
859  if (status)
860  *status = TSTATUS_UNKNOWN;
861  fdinfo = NULL;
862  hrc = 0;
863  fdtype = -1;
864 
865  vdebug(9,LA_TARGET,LF_TARGET,"monitoring evloop with up to %d FDs\n",
866  evloop_maxsize(evloop));
867 
868  /* Always reinit the timeout on new pass */
869  if (timeout)
870  *timeout = tv;
871 
872  rc = evloop_handleone(evloop,EVLOOP_RETONINT,timeout,
873  &fdinfo,&fdtype,&hrc);
874 
875  if (rc < 0) {
876  if (errno == EINTR) {
877  /*
878  * Did our default sighandler flag a signal as needing
879  * handling from the user? If so, return; else keep
880  * going.
881  */
883  break;
884  else
885  continue;
886  }
887  else if (errno == EBADF || errno == EINVAL || errno == ENOMEM
888  || errno == ENOENT || errno == EBADSLT || errno == ENOTSUP) {
889  vdebug(9,LA_TARGET,LA_TARGET,"evloop_handlone: '%s'\n",
890  strerror(errno));
891  }
892  else {
894  "evloop_handlone: unexpected error '%s' (%d)\n",
895  strerror(errno),errno);
896  }
897  break;
898  }
899  else if (rc == 0) {
900  if (fdinfo) {
901  /*
902  * Check this target and see if its status is one we
903  * want to punt to the user to notify/handle.
904  */
905  if (fdtype == EVLOOP_FDTYPE_R)
906  t = (struct target *)fdinfo->rhstate;
907  else if (fdtype == EVLOOP_FDTYPE_W)
908  t = (struct target *)fdinfo->whstate;
909  else if (fdtype == EVLOOP_FDTYPE_X)
910  t = (struct target *)fdinfo->xhstate;
911  else
912  t = NULL;
913 
914  if (t) {
915  if (t->status == TSTATUS_RUNNING
916  || t->status == TSTATUS_PAUSED)
917  continue;
918  else
919  break;
920  }
921  else
922  continue;
923  }
924  else if ((nfds = evloop_maxsize(evloop) < 0))
925  /* Nothing left. */
926  break;
927  else if (nfds) {
928  /* Something left; keep going. */
929  continue;
930  }
931  else {
932  verror("evloop_handleone returned 0 but still FDs to handle!\n");
933  errno = EINVAL;
934  rc = -1;
935  break;
936  }
937  }
938  else {
939  verror("evloop_handleone returned unexpected code '%d'; aborting!\n",
940  rc);
941  rc = -1;
942  break;
943  }
944  }
945 
946  if (target) {
947  if (fdtype == EVLOOP_FDTYPE_R)
948  *target = (struct target *)fdinfo->rhstate;
949  else if (fdtype == EVLOOP_FDTYPE_W)
950  *target = (struct target *)fdinfo->whstate;
951  else if (fdtype == EVLOOP_FDTYPE_X)
952  *target = (struct target *)fdinfo->xhstate;
953  else
954  *target = NULL;
955  }
956  if (status && *target)
957  *status = (*target)->status;
958 
959  return rc;
960 }
961 
962 target_status_t target_poll(struct target *target,struct timeval *tv,
963  target_poll_outcome_t *outcome,int *pstatus) {
964  if (target->status != TSTATUS_RUNNING) {
965  verror("cannot poll target(%s) in state %s; ERROR!\n",
966  target->name,TSTATUS(target->status));
967  return TSTATUS_ERROR;
968  }
969  vdebug(8,LA_TARGET,LF_TARGET,"polling target(%s)\n",target->name);
970  return target->ops->poll(target,tv,outcome,pstatus);
971 }
972 
974  if (target->status != TSTATUS_PAUSED && target->status != TSTATUS_EXITING) {
975  verror("cannot resume target(%s) in state %s; ERROR!\n",
976  target->name,TSTATUS(target->status));
977  return TSTATUS_ERROR;
978  }
979  if (target->status == TSTATUS_DONE) {
981  "not pausing target(%s); already finished\n",target->name);
982  return -1;
983  }
984  vdebug(8,LA_TARGET,LF_TARGET,"resuming target(%s)\n",target->name);
985  return target->ops->resume(target);
986 }
987 
988 int target_pause(struct target *target) {
989  if (target->status == TSTATUS_PAUSED) {
991  "not pausing target(%s); already paused\n",target->name);
992  return 0;
993  }
994  if (target->status == TSTATUS_DONE) {
996  "not pausing target(%s); already finished\n",target->name);
997  return -1;
998  }
999  vdebug(8,LA_TARGET,LF_TARGET,"pausing target(%s)\n",target->name);
1000  return target->ops->pause(target,0);
1001 }
1002 
1004  return target->opened;
1005 }
1006 
1009  "calling backend to get target(%s) status\n",target->name);
1010  target->status = target->ops->status(target);
1011  return target->status;
1012 }
1013 
1014 unsigned char *target_read_addr(struct target *target,ADDR addr,
1015  unsigned long length,unsigned char *buf) {
1016  vdebug(16,LA_TARGET,LF_TARGET,"reading target(%s) at 0x%"PRIxADDR" into %p (%d)\n",
1017  target->name,addr,buf,length);
1018  return target->ops->read(target,addr,length,buf);
1019 }
1020 
1021 unsigned long target_write_addr(struct target *target,ADDR addr,
1022  unsigned long length,unsigned char *buf) {
1023  vdebug(16,LA_TARGET,LF_TARGET,"writing target(%s) at 0x%"PRIxADDR" (%d)\n",
1024  target->name,addr,length);
1025  return target->ops->write(target,addr,length,buf);
1026 }
1027 
1028 int target_addr_v2p(struct target *target,tid_t tid,ADDR vaddr,ADDR *paddr) {
1029  if (!target->ops->addr_v2p) {
1030  vwarn("target(%s) does not support v2p addr translation!\n",target->name);
1031  errno = ENOTSUP;
1032  return -1;
1033  }
1035  "translating v 0x%"PRIxADDR" in tid %"PRIiTID"\n",vaddr,tid);
1036  return target->ops->addr_v2p(target,tid,vaddr,paddr);
1037 }
1038 
1039 unsigned char *target_read_physaddr(struct target *target,ADDR paddr,
1040  unsigned long length,unsigned char *buf) {
1041  if (!target->ops->read_phys) {
1042  vwarn("target(%s) does not support phys addr reads!\n",target->name);
1043  errno = ENOTSUP;
1044  return NULL;
1045  }
1047  "reading target(%s) at phys 0x%"PRIxADDR" into %p (%d)\n",
1048  target->name,paddr,buf,length);
1049  return target->ops->read_phys(target,paddr,length,buf);
1050 }
1051 
1052 unsigned long target_write_physaddr(struct target *target,ADDR paddr,
1053  unsigned long length,unsigned char *buf) {
1054  if (!target->ops->write_phys) {
1055  vwarn("target(%s) does not support phys addr writes!\n",target->name);
1056  errno = ENOTSUP;
1057  return 0;
1058  }
1060  "writing target(%s) at phys 0x%"PRIxADDR" (%d)\n",
1061  target->name,paddr,length);
1062  return target->ops->write_phys(target,paddr,length,buf);
1063 }
1064 
1065 const char *target_regname(struct target *target,REG reg) {
1066  vdebug(16,LA_TARGET,LF_TARGET,"target(%s) reg name %d)\n",
1067  target->name,reg);
1068  return arch_regname(target->arch,reg);
1069 }
1070 
1071 int target_regno(struct target *target,char *name,REG *reg) {
1072  vdebug(16,LA_TARGET,LF_TARGET,"target(%s) target reg %s)\n",
1073  target->name,name);
1074  return arch_regno(target->arch,name,reg);
1075 }
1076 
1077 int target_cregno(struct target *target,common_reg_t creg,REG *reg) {
1078  vdebug(16,LA_TARGET,LF_TARGET,"target(%s) common reg %d)\n",
1079  target->name,creg);
1080  return arch_cregno(target->arch,creg,reg);
1081 }
1082 
1084  vdebug(16,LA_TARGET,LF_TARGET,"reading target(%s:%"PRIiTID") reg %d)\n",
1085  target->name,tid,reg);
1086  if (target->ops->readreg)
1087  return target->ops->readreg(target,tid,reg);
1088  else
1089  return target->ops->readreg_tidctxt(target,tid,THREAD_CTXT_DEFAULT,reg);
1090 }
1091 
1094  "writing target(%s:%"PRIiTID") reg %d 0x%"PRIxREGVAL")\n",
1095  target->name,tid,reg,value);
1096  if (target->ops->writereg)
1097  return target->ops->writereg(target,tid,reg,value);
1098  else
1099  return target->ops->writereg_tidctxt(target,tid,THREAD_CTXT_DEFAULT,
1100  reg,value);
1101 }
1102 
1104  REG reg) {
1106  "reading target(%s:%"PRIiTID") reg %d tidctxt %d)\n",
1107  target->name,tid,reg,tidctxt);
1108  return target->ops->readreg_tidctxt(target,tid,tidctxt,reg);
1109 }
1110 
1112  REG reg,REGVAL value) {
1114  "writing target(%s:%"PRIiTID") reg %d tidctxt %d 0x%"PRIxREGVAL")\n",
1115  target->name,tid,reg,tidctxt,value);
1116  return target->ops->writereg_tidctxt(target,tid,tidctxt,reg,value);
1117 }
1118 
1120  REG treg;
1121 
1122  if (target_cregno(target,reg,&treg))
1123  return 0;
1124 
1125  return target_read_reg(target,tid,treg);
1126 }
1127 
1129  REGVAL value) {
1130  REG treg;
1131 
1132  if (target_cregno(target,reg,&treg))
1133  return 0;
1134 
1135  return target_write_reg(target,tid,treg,value);
1136 }
1137 
1138 GHashTable *target_copy_registers(struct target *target,tid_t tid) {
1140  "copying target(%s:%"PRIiTID") regs\n",
1141  target->name,tid);
1142  return target->ops->copy_registers(target,tid);
1143 }
1144 
1146  struct array_list *retval;
1147  GHashTableIter iter;
1148  struct target_thread *tthread;
1149  gpointer key;
1150 
1151  if (g_hash_table_size(target->threads) == 0)
1152  return NULL;
1153 
1154  retval = array_list_create(g_hash_table_size(target->threads));
1155 
1156  g_hash_table_iter_init(&iter,target->threads);
1157  while (g_hash_table_iter_next(&iter,&key,(gpointer)&tthread)) {
1158  if ((tid_t)(uintptr_t)key == TID_GLOBAL
1159  && tthread->tid != TID_GLOBAL)
1160  continue;
1161 
1162  array_list_append(retval,(void *)(ptr_t)tthread->tid);
1163  }
1164 
1165  return retval;
1166 }
1167 
1169  struct array_list *retval;
1170  GHashTableIter iter;
1171  struct target_thread *tthread;
1172  gpointer key;
1173 
1174  retval = array_list_create(g_hash_table_size(target->threads));
1175 
1176  g_hash_table_iter_init(&iter,target->threads);
1177  while (g_hash_table_iter_next(&iter,&key,(gpointer)&tthread)) {
1178  if ((tid_t)(uintptr_t)key == TID_GLOBAL
1179  && tthread->tid != TID_GLOBAL)
1180  continue;
1181 
1182  array_list_append(retval,tthread);
1183  }
1184 
1185  return retval;
1186 }
1187 
1188 GHashTable *target_hash_threads(struct target *target) {
1189  GHashTable *retval;
1190  GHashTableIter iter;
1191  gpointer key;
1192  struct target_thread *tthread;
1193 
1194  retval = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1195 
1196  g_hash_table_iter_init(&iter,target->threads);
1197  while (g_hash_table_iter_next(&iter,&key,(gpointer)&tthread))
1198  if ((tid_t)(uintptr_t)key == TID_GLOBAL
1199  && tthread->tid != TID_GLOBAL)
1200  continue;
1201 
1202  g_hash_table_insert(retval,key,tthread);
1203 
1204  return retval;
1205 }
1206 
1208  vdebug(12,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
1209  return target->ops->list_available_tids(target);
1210 }
1211 
1213  int i;
1214  struct array_list *tids;
1215  GHashTable *retval;
1216  tid_t tid;
1217 
1218  tids = target_list_available_tids(target);
1219  if (!tids) {
1220  verror("could not load available tids!\n");
1221  return NULL;
1222  }
1223 
1224  retval = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1225 
1226  for (i = 0; i < array_list_len(tids); ++i) {
1227  tid = (tid_t)(ptr_t)array_list_item(tids,i);
1228  g_hash_table_insert(retval,(gpointer)(ptr_t)tid,(gpointer)(ptr_t)tid);
1229  }
1230  array_list_free(tids);
1231 
1232  return retval;
1233 }
1234 
1236  vdebug(12,LA_TARGET,LF_TARGET,"target(%s)\n",target->name);
1237  return target->ops->load_available_threads(target,force);
1238 }
1239 
1241  int force) {
1242  vdebug(8,LA_TARGET,LF_TARGET,"loading target(%s) current thread\n",target->name);
1243  return target->ops->load_current_thread(target,force);
1244 }
1245 
1247  int force) {
1248  vdebug(8,LA_TARGET,LF_TARGET,"loading target(%s:%"PRIiTID") thread\n",
1249  target->name,tid);
1250  return target->ops->load_thread(target,tid,force);
1251 }
1252 
1253 int target_load_all_threads(struct target *target,int force) {
1254  vdebug(8,LA_TARGET,LF_TARGET,"loading all target(%s) threads\n",target->name);
1255  return target->ops->load_all_threads(target,force);
1256 }
1257 
1258 int target_pause_thread(struct target *target,tid_t tid,int nowait) {
1259  vdebug(12,LA_TARGET,LF_TARGET,"pausing target(%s) thread %"PRIiTID" (nowait=%d)\n",
1260  target->name,tid,nowait);
1261  return target->ops->pause_thread(target,tid,nowait);
1262 }
1263 
1265  vdebug(8,LA_TARGET,LF_TARGET,"flushing target(%s) current thread\n",target->name);
1266  return target->ops->flush_current_thread(target);
1267 }
1268 
1270  vdebug(8,LA_TARGET,LF_TARGET,"flushing target(%s:%"PRIiTID") thread\n",
1271  target->name,tid);
1272  return target->ops->flush_thread(target,tid);
1273 }
1274 
1276  GHashTableIter iter;
1277  struct target *overlay;
1278  int rc;
1279 
1281  "flushing all target(%s) threads\n",target->name);
1282 
1283  /*
1284  * Do it for all the overlays first.
1285  */
1286  g_hash_table_iter_init(&iter,target->overlays);
1287  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&overlay)) {
1289  "flushing all overlay target(%s) threads\n",overlay->name);
1290  rc = target_flush_all_threads(overlay);
1292  "flushing all overlay target(%s) threads (%d)\n",overlay->name,rc);
1293  }
1294 
1295  if (target->ops->flush_all_threads)
1296  return target->ops->flush_all_threads(target);
1297  else {
1298  errno = ENOTSUP;
1299  return -1;
1300  }
1301 }
1302 
1304  int rc = 0;
1305  int i;
1306  struct array_list *cached_tids;
1307  GHashTable *real_tids;
1308  tid_t tid;
1309  struct target_thread *tthread;
1310 
1311  vdebug(8,LA_TARGET,LF_TARGET,"garbage collecting cached threads (%s)\n",target->name);
1312  if (target->ops->gc_threads)
1313  return target->ops->gc_threads(target);
1314 
1315 
1316  cached_tids = target_list_tids(target);
1317  if (!cached_tids) {
1318  verror("could not list cached threads!\n");
1319  return -1;
1320  }
1321 
1322  real_tids = target_hash_available_tids(target);
1323  if (!real_tids) {
1324  verror("could not load currently available threads!\n");
1325  array_list_free(cached_tids);
1326  return -1;
1327  }
1328 
1329  for (i = 0; i < array_list_len(cached_tids); ++i) {
1330  tid = (tid_t)(ptr_t)array_list_item(cached_tids,i);
1331 
1332  if (tid == TID_GLOBAL)
1333  continue;
1334 
1335  if (!g_hash_table_lookup_extended(real_tids,(gpointer)(ptr_t)tid,
1336  NULL,NULL)) {
1337  if (target->current_thread && target->current_thread->tid == tid) {
1338  vwarn("thread %d seems to no longer exist, but is the"
1339  " current thread; not detaching!\n",tid);
1340  continue;
1341  }
1342 
1344  "cached thread %"PRIiTID" no longer exists; detaching!\n",tid);
1345  tthread = target_lookup_thread(target,tid);
1346  target_detach_thread(target,tthread);
1347  ++rc;
1348  }
1349  }
1350  array_list_free(cached_tids);
1351  g_hash_table_destroy(real_tids);
1352 
1353  if (rc)
1354  vdebug(5,LA_TARGET,LF_TARGET,"garbage collected %d cached threads (%s)\n",
1355  rc,target->name);
1356 
1357  return rc;
1358 }
1359 
1361  char *buf,int bufsiz,
1362  int detail,char *sep,char *kvsep) {
1363  struct target_thread *tthread;
1364  int rc;
1365 
1366  if (!buf) {
1367  errno = EINVAL;
1368  return -1;
1369  }
1370 
1371  vdebug(16,LA_TARGET,LF_TARGET,"target(%s:%"PRIiTID") thread\n",
1372  target->name,tid);
1373 
1374  if (!(tthread = target_lookup_thread(target,tid))) {
1375  verror("thread %"PRIiTID" does not exist?\n",tid);
1376  return -1;
1377  }
1378 
1379  if (!sep)
1380  sep = ",";
1381  if (!kvsep)
1382  kvsep = "=";
1383 
1384  if (detail < -1)
1385  return snprintf(buf,bufsiz,"tid%s%"PRIiTID,kvsep,tthread->tid);
1386  else if (detail < 0)
1387  return snprintf(buf,bufsiz,"tid%s%"PRIiTID "%s" "name%s%s" "%s"
1388  "curctxt%s%d" "%s",
1389  kvsep,tid,sep,kvsep,tthread->name,sep,
1390  kvsep,tthread->tidctxt,sep);
1391  else if (!target->ops->thread_snprintf)
1392  return snprintf(buf,bufsiz,
1393  "tid%s%"PRIiTID "%s" "name%s%s" "%s" "curctxt%s%d" "%s"
1394  "ptid%s%"PRIiTID "%s" "tgid%s%"PRIiTID "%s"
1395  "uid%s%d" "%s" "gid%s%d",
1396  kvsep,tthread->tid,sep,kvsep,tthread->name,sep,
1397  kvsep,tthread->tidctxt,sep,
1398  kvsep,tthread->ptid,sep,kvsep,tthread->tgid,sep,
1399  kvsep,tthread->uid,sep,kvsep,tthread->gid);
1400  else {
1401  rc = snprintf(buf,bufsiz,
1402  "tid%s%"PRIiTID "%s" "name%s%s" "%s" "curctxt%s%d" "%s"
1403  "ptid%s%"PRIiTID "%s" "ptid%s%"PRIiTID "%s"
1404  "uid%s%d" "%s" "gid%s%d" "%s",
1405  kvsep,tthread->tid,sep,kvsep,tthread->name,sep,
1406  kvsep,tthread->tidctxt,sep,
1407  kvsep,tthread->ptid,sep,kvsep,tthread->tgid,sep,
1408  kvsep,tthread->uid,sep,kvsep,tthread->gid,sep);
1409  if (rc >= bufsiz)
1410  rc += target->ops->thread_snprintf(target,tthread,NULL,0,
1411  detail,sep,kvsep);
1412  else
1413  rc += target->ops->thread_snprintf(target,tthread,buf + rc,bufsiz - rc,
1414  detail,sep,kvsep);
1415  return rc;
1416  }
1417 }
1418 
1419 void target_dump_thread(struct target *target,tid_t tid,FILE *stream,int detail) {
1420  char buf[1024];
1421  struct target_thread *tthread;
1422 
1423  vdebug(16,LA_TARGET,LF_TARGET,"dumping target(%s:%"PRIiTID") thread\n",
1424  target->name,tid);
1425 
1426  if (!(tthread = target_lookup_thread(target,tid)))
1427  verror("thread %"PRIiTID" does not exist?\n",tid);
1428 
1429  if (target_thread_snprintf(target,tid,buf,sizeof(buf),detail,NULL,NULL) < 0)
1430  fprintf(stream ? stream : stdout,"tid(%"PRIiTID"): <API ERROR>\n",tid);
1431  else
1432  fprintf(stream ? stream : stdout,"tid(%"PRIiTID"): %s\n",tid,buf);
1433 }
1434 
1435 void target_dump_all_threads(struct target *target,FILE *stream,int detail) {
1436  struct target_thread *tthread;
1437  GHashTableIter iter;
1438 
1439  vdebug(16,LA_TARGET,LF_TARGET,"dumping all target(%s) threads\n",target->name);
1440 
1441  g_hash_table_iter_init(&iter,target->threads);
1442  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread))
1443  target_dump_thread(target,tthread->tid,stream,detail);
1444 }
1445 
1447  int rc;
1448  GHashTableIter iter;
1449  struct probepoint *probepoint;
1450  struct target *overlay;
1451  struct target_memmod *mmod;
1452  unsigned int rlen;
1453 
1454  if (!target->opened) {
1455  vdebug(3,LA_TARGET,LF_TARGET,"target(%s) already closed\n",target->name);
1456  return target->status;
1457  }
1458 
1459  vdebug(5,LA_TARGET,LF_TARGET,"closing target(%s)\n",target->name);
1460 
1461  /* Make sure! */
1462  target_pause(target);
1463 
1464  /*
1465  * Do it for all the overlays first.
1466  */
1467  g_hash_table_iter_init(&iter,target->overlays);
1468  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&overlay)) {
1470  "closing overlay target(%s)\n",overlay->name);
1471  rc = target_close(overlay);
1473  "closed overlay target(%s) (%d)\n",overlay->name,rc);
1474  }
1475 
1476  if (target->evloop)
1477  target_detach_evloop(target);
1478 
1479  target_flush_all_threads(target);
1480 
1481  /*
1482  * We have to free the soft probepoints manually, then remove all. We
1483  * can't remove an element during an iteration, but we *can* free
1484  * the data :).
1485  */
1486  vdebug(2,LA_PROBE,LF_PROBEPOINT,"%d soft probepoints to free!\n",
1487  g_hash_table_size(target->soft_probepoints));
1488  g_hash_table_iter_init(&iter,target->soft_probepoints);
1489  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&probepoint)) {
1490  probepoint_free_ext(probepoint);
1491  }
1492  g_hash_table_remove_all(target->soft_probepoints);
1493 
1494  /*
1495  * Free the memmods, if any are left.
1496  */
1497  g_hash_table_iter_init(&iter,target->mmods);
1498  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&mmod)) {
1499  g_hash_table_iter_remove(&iter);
1500 
1501  if (mmod->tmp)
1502  free(mmod->tmp);
1503  /* Breakpoint hack */
1504  if (mmod->mod && mmod->mod != target->arch->breakpoint_instrs)
1505  free(mmod->mod);
1506 
1507  if (mmod->orig) {
1508  rlen = target_write_addr(target,mmod->addr,mmod->orig_len,mmod->orig);
1509  if (rlen != mmod->orig_len) {
1510  verror("could not restore orig memory at 0x%"PRIxADDR";"
1511  " but cannot do anything!\n",mmod->addr);
1512  }
1513  }
1514 
1515  if (mmod->threads) {
1516  array_list_free(mmod->threads);
1517  }
1518  if (mmod->orig)
1519  free(mmod->orig);
1520 
1521  if (target_notify_sw_breakpoint(target,mmod->addr,0)) {
1523  "sw bp removal notification failed; ignoring\n");
1524  }
1525 
1526  free(mmod);
1527  }
1528 
1529  /* XXX: should we deal with memcache? No, let backends do it. */
1530 
1531  vdebug(5,LA_TARGET,LF_TARGET,"detach target(%s) (stay_paused = %d)\n",
1532  target->name,target->spec->stay_paused);
1533  if ((rc = target->ops->detach(target,target->spec->stay_paused))) {
1534  verror("detach target(%s) failed: %s\n",target->name,strerror(errno));
1535  }
1536 
1537  if (target->spec->kill_on_close)
1538  target_kill(target,target->spec->kill_on_close_sig);
1539 
1540  /*
1541  * Don't delete the threads yet; just unset current_thread.
1542  */
1543  target->current_thread = NULL;
1544 
1545  target->opened = 0;
1546 
1547  /*
1548  * Set the target and its core objects to be non-live.
1549  */
1550  OBJSDEAD(target,target);
1551 
1552  return target->status;
1553 }
1554 
1556  obj_flags_t orf,obj_flags_t nandf) {
1557  int retval;
1558  GHashTableIter iter;
1559  gpointer vp;
1560  struct target_thread *tthread;
1561  GList *t1;
1562  struct addrspace *space;
1563 
1564  /*
1565  * Notify all our children -- threads (which have no children),
1566  * spaces -- and call the target_ops propagation method too, if it
1567  * exists -- or call the personality method.
1568  */
1569  g_hash_table_iter_init(&iter,target->threads);
1570  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
1571  tthread = (struct target_thread *)vp;
1572  tthread->obj_flags |= orf;
1573  tthread->obj_flags &= ~nandf;
1574  }
1575 
1576  v_g_list_foreach(target->spaces,t1,space) {
1577  space->obj_flags |= orf;
1578  space->obj_flags &= ~nandf;
1579  addrspace_obj_flags_propagate(space,orf,nandf);
1580  }
1581 
1582  SAFE_TARGET_OP(obj_flags_propagate,retval,0,target,orf,nandf);
1583 
1584  return retval;
1585 }
1586 
1587 int target_kill(struct target *target,int sig) {
1588  vdebug(5,LA_TARGET,LF_TARGET,"killing target(%s) with %d\n",target->name,sig);
1589  return target->ops->kill(target,sig);
1590 }
1591 
1592 void target_hold(struct target *target) {
1593  RHOLD(target,target);
1594 }
1595 
1597  REFCNT trefcnt;
1598  RPUT(target,target,target,trefcnt);
1599 }
1600 
1601 struct probe *target_lookup_probe(struct target *target,int probe_id) {
1602  return (struct probe *)g_hash_table_lookup(target->probes,
1603  (gpointer)(uintptr_t)probe_id);
1604 }
1605 
1606 struct action *target_lookup_action(struct target *target,int action_id) {
1607  return (struct action *)g_hash_table_lookup(target->actions,
1608  (gpointer)(uintptr_t)action_id);
1609 }
1610 
1612  tid_t tid,ADDR addr,
1613  int is_phys,int nowrite) {
1614  struct target_memmod *mmod;
1615  struct target_thread *tthread;
1616 
1617  tthread = target_lookup_thread(target,tid);
1618  if (!tthread) {
1619  verror("tid %"PRIiTID" does not exist!\n",tid);
1620  errno = ESRCH;
1621  return NULL;
1622  }
1623 
1624  mmod = target_memmod_lookup(target,tid,addr,is_phys);
1625 
1626  if (mmod) {
1627  if (mmod->type != MMT_BP) {
1628  verror("mmod already at 0x%"PRIxADDR"; but not breakpoint!\n",addr);
1629  errno = EADDRINUSE;
1630  return NULL;
1631  }
1632  else if (mmod->state != MMS_SUBST) {
1633  verror("mmod already at 0x%"PRIxADDR"; state is not SUBST (%d)!\n",
1634  addr,mmod->state);
1635  errno = EBUSY;
1636  return NULL;
1637  }
1638  else {
1639  /* Add us to the threads list if necessary. */
1640  if (array_list_find(mmod->threads,tthread) < 0)
1641  array_list_append(mmod->threads,tthread);
1642  else
1643  vwarn("tid %"PRIiTID" already on threads list; BUG!\n",tid);
1644  return mmod;
1645  }
1646  }
1647  else {
1648  mmod = target_memmod_create(target,tid,addr,is_phys,MMT_BP,
1649  target->arch->breakpoint_instrs,
1650  target->arch->breakpoint_instrs_len,nowrite);
1651  if (!mmod) {
1652  verror("could not create memmod for tid %"PRIiTID" at 0x%"PRIxADDR"!\n",
1653  tid,addr);
1654  return NULL;
1655  }
1656 
1657  if (target_notify_sw_breakpoint(target,addr,1))
1658  vwarn("sw bp insertion notification failed; ignoring\n");
1659 
1660  return mmod;
1661  }
1662 }
1663 
1665  tid_t tid,ADDR addr) {
1666  if (target->ops->insert_sw_breakpoint)
1667  return target->ops->insert_sw_breakpoint(target,tid,addr);
1668  else
1669  /* Just default to sw breakpoints on virt addrs. */
1670  return _target_insert_sw_breakpoint(target,tid,addr,0,0);
1671 }
1672 
1674  struct target_memmod *mmod) {
1675  int retval;
1676  ADDR addr;
1677 
1678  addr = mmod->addr;
1679  retval = target_memmod_release(target,tid,mmod);
1680  if (retval) {
1681  verror("could not remove memmod at 0x%"PRIxADDR" for tid %"PRIiTID"\n",
1682  addr,tid);
1683  return -1;
1684  }
1685 
1686  /* If this was the last thread, signal. */
1687  if (!target_memmod_lookup(target,tid,addr,mmod->is_phys)) {
1688  if (target_notify_sw_breakpoint(target,addr,0))
1689  vwarn("sw bp removal notification failed; ignoring\n");
1690  }
1691 
1692  return 0;
1693 }
1694 
1696  struct target_memmod *mmod) {
1697  if (target->ops->remove_sw_breakpoint)
1698  return target->ops->remove_sw_breakpoint(target,tid,mmod);
1699  else
1700  return _target_remove_sw_breakpoint(target,tid,mmod);
1701 }
1702 
1704  struct target_memmod *mmod) {
1705  return target_memmod_set(target,tid,mmod);
1706 }
1707 
1709  struct target_memmod *mmod) {
1710  if (target->ops->enable_sw_breakpoint)
1711  return target->ops->enable_sw_breakpoint(target,tid,mmod);
1712 
1713  return _target_enable_sw_breakpoint(target,tid,mmod);
1714 }
1715 
1717  struct target_memmod *mmod) {
1718  return target_memmod_unset(target,tid,mmod);
1719 }
1720 
1722  struct target_memmod *mmod) {
1723  if (target->ops->disable_sw_breakpoint)
1724  return target->ops->disable_sw_breakpoint(target,tid,mmod);
1725  else
1726  return _target_disable_sw_breakpoint(target,tid,mmod);
1727 }
1728 
1730  struct target_memmod *mmod,
1731  unsigned char *code,unsigned long code_len) {
1732  return target_memmod_set_tmp(target,tid,mmod,code,code_len);
1733 }
1734 
1736  struct target_memmod *mmod,
1737  unsigned char *code,unsigned long code_len) {
1738  if (target->ops->change_sw_breakpoint)
1739  return target->ops->change_sw_breakpoint(target,tid,mmod,code,code_len);
1740  else
1741  return _target_change_sw_breakpoint(target,tid,mmod,code,code_len);
1742 }
1743 
1745  struct target_memmod *mmod) {
1746  return target_memmod_set(target,tid,mmod);
1747 }
1748 
1750  struct target_memmod *mmod) {
1751  if (target->ops->unchange_sw_breakpoint)
1752  return target->ops->unchange_sw_breakpoint(target,tid,mmod);
1753  else
1754  return _target_unchange_sw_breakpoint(target,tid,mmod);
1755 }
1756 
1758  REG retval;
1759  if (!target->ops->get_unused_debug_reg) {
1760  errno = ENOTSUP;
1761  return -1;
1762  }
1763  vdebug(5,LA_TARGET,LF_TARGET,"getting unused debug reg for target(%s):%"PRIiTID"\n",
1764  target->name,tid);
1765  retval = target->ops->get_unused_debug_reg(target,tid);
1766  vdebug(5,LA_TARGET,LF_TARGET,"got unused debug reg for target(%s):%"PRIiTID": %"PRIiREG"\n",
1767  target->name,tid,retval);
1768  return retval;
1769 }
1770 
1773  "setting hw breakpoint at 0x%"PRIxADDR" on target(%s:%"PRIiTID") dreg %d\n",
1774  addr,target->name,tid,reg);
1775  return target->ops->set_hw_breakpoint(target,tid,reg,addr);
1776 }
1777 
1779  probepoint_whence_t whence,int watchsize) {
1781  "setting hw watchpoint at 0x%"PRIxADDR" on target(%s:%"PRIiTID") dreg %d (%d)\n",
1782  addr,target->name,tid,reg,watchsize);
1783  return target->ops->set_hw_watchpoint(target,tid,reg,addr,whence,watchsize);
1784 }
1785 
1788  "removing hw breakpoint on target(%s:%"PRIiTID") dreg %d\n",
1789  target->name,tid,reg);
1790  return target->ops->unset_hw_breakpoint(target,tid,reg);
1791 }
1792 
1795  "removing hw watchpoint on target(%s:%"PRIiTID") dreg %d\n",
1796  target->name,tid,reg);
1797  return target->ops->unset_hw_watchpoint(target,tid,reg);
1798 }
1799 
1802  "disable hw breakpoints on target(%s:%"PRIiTID")\n",target->name,tid);
1803  return target->ops->disable_hw_breakpoints(target,tid);
1804 }
1805 
1808  "enable hw breakpoints on target(%s:%"PRIiTID")\n",target->name,tid);
1809  return target->ops->enable_hw_breakpoints(target,tid);
1810 }
1811 
1814  "disable hw breakpoint %"PRIiREG" on target(%s:%"PRIiTID")\n",
1815  dreg,target->name,tid);
1816  return target->ops->disable_hw_breakpoint(target,tid,dreg);
1817 }
1818 
1821  "enable hw breakpoint %"PRIiREG" on target(%s:%"PRIiTID")\n",
1822  dreg,target->name,tid);
1823  return target->ops->enable_hw_breakpoint(target,tid,dreg);
1824 }
1825 
1827  int notification) {
1828  if (target->ops->notify_sw_breakpoint) {
1830  "notify sw breakpoint (%d) on target(%s)\n",
1831  notification,target->name);
1832  return target->ops->notify_sw_breakpoint(target,addr,notification);
1833  }
1834  else
1835  return 0;
1836 }
1837 
1838 int target_singlestep(struct target *target,tid_t tid,int isbp) {
1839  vdebug(5,LA_TARGET,LF_TARGET,"single stepping target(%s:%"PRIiTID") isbp=%d\n",
1840  target->name,tid,isbp);
1841  return target->ops->singlestep(target,tid,isbp,NULL);
1842 }
1843 
1845  if (target->ops->singlestep_end) {
1846  vdebug(5,LA_TARGET,LF_TARGET,"ending single stepping of target(%s:%"PRIiTID")\n",
1847  target->name,tid);
1848  return target->ops->singlestep_end(target,tid,NULL);
1849  }
1850  return 0;
1851 }
1852 
1854  tid_t retval = 0;
1855 
1856  vdebug(9,LA_TARGET,LF_TARGET,"gettid target(%s)\n",target->name);
1857  retval = target->ops->gettid(target);
1858  vdebug(5,LA_TARGET,LF_TARGET,"gettid target(%s) -> 0x%"PRIx64" \n",
1859  target->name,retval);
1860 
1861  return retval;
1862 }
1863 
1864 uint64_t target_get_tsc(struct target *target) {
1865  if (target->ops->get_tsc)
1866  return target->ops->get_tsc(target);
1867  errno = EINVAL;
1868  return UINT64_MAX;
1869 }
1870 
1871 uint64_t target_get_time(struct target *target) {
1872  if (target->ops->get_time)
1873  return target->ops->get_time(target);
1874  errno = EINVAL;
1875  return UINT64_MAX;
1876 }
1877 
1878 uint64_t target_get_counter(struct target *target) {
1879  if (target->ops->get_counter)
1880  return target->ops->get_counter(target);
1881  errno = EINVAL;
1882  return UINT64_MAX;
1883 }
1884 
1885 int target_enable_feature(struct target *target,int feature,void *arg) {
1886  if (target->ops->enable_feature)
1887  return target->ops->enable_feature(target,feature,arg);
1888  errno = EINVAL;
1889  return -1;
1890 }
1891 
1892 int target_disable_feature(struct target *target,int feature) {
1893  if (target->ops->disable_feature)
1894  return target->ops->disable_feature(target,feature);
1895  errno = EINVAL;
1896  return -1;
1897 }
1898 
1900  struct target_thread *tthread;
1901 
1902  tthread = target_lookup_thread(target,tid);
1903  if (!tthread) {
1904  verror("no such thread %"PRIiTID"\n",tid);
1905  errno = EINVAL;
1906  return THREAD_STATUS_UNKNOWN;
1907  }
1908 
1909  return tthread->status;
1910 }
1911 
#define SAFE_TARGET_OP_WARN_NORET(op, outvar, expoutval, target,...)
Definition: target.h:814
struct target * target_instantiate_overlay(struct target *target, tid_t tid, struct target_spec *spec)
Definition: target_api.c:724
int target_thread_snprintf(struct target *target, tid_t tid, char *buf, int bufsiz, int detail, char *sep, char *kvsep)
Definition: target_api.c:1360
void * xhstate
Definition: evloop.h:90
uint8_t * breakpoint_instrs
Definition: arch.h:149
int target_flush_all_threads(struct target *target)
Definition: target_api.c:1275
tid_t target_lookup_overlay_thread_by_name(struct target *target, char *name)
Definition: target_api.c:690
struct array_list * threads
Definition: target.h:374
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
int(* singlestep)(struct target *target, tid_t tid, int isbp, struct target *overlay)
Definition: target_api.h:3071
int target_change_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod, unsigned char *code, unsigned long code_len)
Definition: target_api.c:1735
int(* flush_current_thread)(struct target *target)
Definition: target_api.h:2963
#define SAFE_TARGET_OP(op, outvar, expoutval, target,...)
Definition: target.h:784
#define PRIiOFFSET
Definition: common.h:70
target_mode_t target_mode
Definition: target_api.h:2173
struct target * base
Definition: target_api.h:2614
#define SAFE_PERSONALITY_OP_WARN(op, outvar, expoutval, target,...)
Definition: target.h:737
#define RHOLDW(x, hx)
Definition: common.h:623
void * backend_spec
Definition: target_api.h:2252
thread_bpmode_t bpmode
Definition: target_api.h:2174
int arch_regno(struct arch *arch, char *name, REG *reg)
Definition: arch.c:58
unsigned char *(* read)(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.h:2913
int32_t tid_t
Definition: common.h:36
int(* addr_v2p)(struct target *target, tid_t tid, ADDR vaddr, ADDR *paddr)
Definition: target_api.h:2935
void * rhstate
Definition: evloop.h:86
target_status_t
Definition: target_api.h:197
int(* disable_hw_breakpoints)(struct target *target, tid_t tid)
Definition: target_api.h:3065
void addrspace_obj_flags_propagate(struct addrspace *space, obj_flags_t orf, obj_flags_t nandf)
Definition: memory.c:162
int target_load_available_threads(struct target *target, int force)
Definition: target_api.c:1235
common_reg_t
Definition: arch.h:73
tid_t target_lookup_overlay_thread_by_id(struct target *target, int id)
Definition: target_api.c:670
struct target_spec * tspec
Definition: dumptarget.c:113
int(* flush_all_threads)(struct target *target)
Definition: target_api.h:2964
uint64_t target_get_tsc(struct target *target)
Definition: target_api.c:1864
GHashTable * overlays
Definition: target_api.h:2623
Definition: probe.h:392
int target_set_hw_watchpoint(struct target *target, tid_t tid, REG reg, ADDR addr, probepoint_whence_t whence, int watchsize)
Definition: target_api.c:1778
struct linux_userproc_spec * linux_userproc_build_spec(void)
int(* unchange_sw_breakpoint)(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.h:3056
GHashTable * soft_probepoints
Definition: target_api.h:2695
#define PRIiREG
Definition: common.h:94
tid_t(* gettid)(struct target *target)
Definition: target_api.h:2951
int target_monitor_evloop(struct evloop *evloop, struct timeval *timeout, struct target **target, target_status_t *status)
Definition: target_api.c:841
struct target_personality_ops * personality_ops
Definition: target_api.h:2547
int target_remove_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1695
int(* set_active_probing)(struct target *target, active_probe_flags_t flags)
Definition: target_api.h:3113
GHashTable * actions
Definition: target_api.h:2736
#define v_g_list_foreach_remove(glhead, glcur, glnext)
Definition: glib_wrapper.h:55
GHashTable * target_copy_registers(struct target *target, tid_t tid)
Definition: target_api.c:1138
struct target_spec *(* build_default_overlay_spec)(struct target *target, tid_t tid)
Definition: target_api.h:2871
struct action * target_lookup_action(struct target *target, int action_id)
Definition: target_api.c:1606
int target_resume(struct target *target)
Definition: target_api.c:973
#define v_g_list_foreach(glhead, glcur, elm)
Definition: glib_wrapper.h:34
int target_is_evloop_attached(struct target *target, struct evloop *evloop)
Definition: target_api.c:824
int target_disable_feature(struct target *target, int feature)
Definition: target_api.c:1892
probepoint_whence_t
Definition: probe_api.h:234
uint8_t kill_on_close
Definition: target_api.h:2176
void target_dump_thread(struct target *target, tid_t tid, FILE *stream, int detail)
Definition: target_api.c:1419
struct target_thread * base_thread
Definition: target_api.h:2615
struct os_process_spec * os_process_build_spec(void)
struct php_spec * php_build_spec(void)
Definition: target_php.c:938
void php_free_spec(struct php_spec *spec)
Definition: target_php.c:946
probepoint_style_t style
Definition: target_api.h:2175
int(* unset_hw_breakpoint)(struct target *target, tid_t tid, REG reg)
Definition: target_api.h:3063
int target_pause(struct target *target)
Definition: target_api.c:988
struct target_memmod * target_memmod_create(struct target *target, tid_t tid, ADDR addr, int is_phys, target_memmod_type_t mmt, unsigned char *code, unsigned int code_len, int nowrite)
Definition: target.c:4726
int target_pause_thread(struct target *target, tid_t tid, int nowait)
Definition: target_api.c:1258
int _target_unchange_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1744
int target_cregno(struct target *target, common_reg_t creg, REG *reg)
Definition: target_api.c:1077
int evloop_handleone(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **handled_fdinfo, int *handled_fdtype, int *handled_hrc)
Definition: evloop.c:434
tid_t target_gettid(struct target *target)
Definition: target_api.c:1853
struct target_thread * global_thread
Definition: target_api.h:2645
int(* disable_sw_breakpoint)(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.h:3051
target_memmod_state_t state
Definition: target.h:377
char * name
Definition: target.h:928
int(* load_available_threads)(struct target *target, int force)
Definition: target_api.h:2959
int(* set_hw_breakpoint)(struct target *target, tid_t tid, REG reg, ADDR addr)
Definition: target_api.h:3059
int target_flush_thread(struct target *target, tid_t tid)
Definition: target_api.c:1269
int target_unchange_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1749
#define ptr_t
Definition: common.h:79
OFFSET phys_offset
Definition: target.h:976
GHashTable * target_hash_threads(struct target *target)
Definition: target_api.c:1188
int target_close(struct target *target)
Definition: target_api.c:1446
uint8_t stay_paused
Definition: target_api.h:2176
target_status_t(* status)(struct target *target)
Definition: target_api.h:2894
int(* writereg)(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target_api.h:3024
#define verror(format,...)
Definition: log.h:30
int base_target_id
Definition: target_api.h:2169
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1014
int target_singlestep(struct target *target, tid_t tid, int isbp)
Definition: target_api.c:1838
int target_is_open(struct target *target)
Definition: target_api.c:1003
void linux_userproc_free_spec(struct linux_userproc_spec *lspec)
int target_regno(struct target *target, char *name, REG *reg)
Definition: target_api.c:1071
void probepoint_free_ext(struct probepoint *probepoint)
Definition: probe.c:570
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
Definition: evloop.h:66
GHashTable * mmods
Definition: target_api.h:2701
char * base_thread_name
Definition: target_api.h:2171
int(* pause)(struct target *target, int nowait)
Definition: target_api.h:2896
ADDR base_phys_addr
Definition: target.h:966
int target_personality_attach(struct target *target, char *personality, char *personality_lib)
Definition: target.c:5965
GList * target_instantiate_and_open_list(GList *target_specs, struct evloop *evloop, GList **error_specs)
Definition: target_api.c:271
struct target_thread *(* lookup_overlay_thread_by_id)(struct target *target, int id)
Definition: target_api.h:2877
thread_status_t status
Definition: target_api.h:2047
#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
struct evloop * evloop
Definition: target_api.h:2598
int target_snprintf(struct target *target, char *buf, int bufsiz)
Definition: target_api.c:790
REGVAL target_read_reg(struct target *target, tid_t tid, REG reg)
Definition: target_api.c:1083
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
uint64_t(* get_tsc)(struct target *target)
Definition: target_api.h:3089
REG target_get_unused_debug_reg(struct target *target, tid_t tid)
Definition: target_api.c:1757
int target_write_reg_ctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg, REGVAL value)
Definition: target_api.c:1111
struct target_thread * target_load_thread(struct target *target, tid_t tid, int force)
Definition: target_api.c:1246
int target_singlestep_end(struct target *target, tid_t tid)
Definition: target_api.c:1844
int target_attach_evloop(struct target *target, struct evloop *evloop)
Definition: target_api.c:795
GHashTable *(* copy_registers)(struct target *target, tid_t tid)
Definition: target_api.h:3025
void target_monitor_clear_global_interrupt(void)
Definition: target.c:228
int target_flush_current_thread(struct target *target)
Definition: target_api.c:1264
thread_status_t target_thread_status(struct target *target, tid_t tid)
Definition: target_api.c:1899
uint64_t target_get_time(struct target *target)
Definition: target_api.c:1871
struct array_list * target_list_available_overlay_tids(struct target *target, target_type_t type)
Definition: target_api.c:633
struct xen_vm_spec * xen_vm_build_spec(void)
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
int target_monitor_was_interrupted(siginfo_t *last_siginfo)
Definition: target.c:219
struct probe * target_lookup_probe(struct target *target, int probe_id)
Definition: target_api.c:1601
int target_enable_hw_breakpoint(struct target *target, tid_t tid, REG dreg)
Definition: target_api.c:1819
struct target_memmod * target_memmod_lookup(struct target *target, tid_t tid, ADDR addr, int is_phys)
Definition: target.c:4841
struct array_list * target_list_tids(struct target *target)
Definition: target_api.c:1145
uint64_t(* get_time)(struct target *target)
Definition: target_api.h:3090
tid_t base_tid
Definition: target_api.h:2617
int(* detach)(struct target *target, int stay_paused)
Definition: target_api.h:2781
void target_free_spec(struct target_spec *spec)
Definition: target_api.c:436
target_memmod_type_t type
Definition: target.h:376
struct target_thread *(* load_thread)(struct target *target, tid_t tid, int force)
Definition: target_api.h:2954
int target_set_active_probing(struct target *target, active_probe_flags_t flags)
Definition: target_api.c:616
struct target * linux_userproc_instantiate(struct target_spec *spec, struct evloop *evloop)
#define TSTATUS(n)
Definition: target_api.h:252
Definition: target.h:331
int(* flush_thread)(struct target *target, tid_t tid)
Definition: target_api.h:2962
unsigned long target_write_physaddr(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1052
struct target_spec * target_build_default_overlay_spec(struct target *target, tid_t tid)
Definition: target_api.c:711
target_mode_t
Definition: target_api.h:187
char * target_name(struct target *target)
Definition: target_api.c:488
void gdb_free_spec(struct gdb_spec *xspec)
Definition: target_gdb.c:580
#define PRIxOFFSET
Definition: common.h:71
const char * target_regname(struct target *target, REG reg)
Definition: target_api.c:1065
int(* set_hw_watchpoint)(struct target *target, tid_t tid, REG reg, ADDR addr, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: target_api.h:3060
REG(* get_unused_debug_reg)(struct target *target, tid_t tid)
Definition: target_api.h:3058
GHashTable * threads
Definition: target_api.h:2632
target_status_t(* monitor)(struct target *target)
Definition: target_api.h:2900
obj_flags_t obj_flags
Definition: target_api.h:2050
int target_memmod_unset(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:5046
int(* resume)(struct target *target)
Definition: target_api.h:2898
#define EVLOOP_FDTYPE_X
Definition: evloop.h:32
int(* load_all_threads)(struct target *target, int force)
Definition: target_api.h:2958
ADDR tag
Definition: target.h:886
#define RHOLD(x, hx)
Definition: common.h:622
struct array_list *(* list_available_tids)(struct target *target)
Definition: target_api.h:2953
ADDR addr
Definition: target.h:381
int target_enable_feature(struct target *target, int feature, void *arg)
Definition: target_api.c:1885
int(* disable_hw_breakpoint)(struct target *target, tid_t tid, REG dreg)
Definition: target_api.h:3067
target_poll_outcome_t
Definition: target_api.h:394
Definition: probe.h:308
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
const char * arch_regname(struct arch *arch, REG reg)
Definition: arch.c:51
obj_flags_t obj_flags
Definition: target.h:902
REGVAL target_read_creg(struct target *target, tid_t tid, common_reg_t reg)
Definition: target_api.c:1119
int(* remove_sw_breakpoint)(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.h:3047
#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
int(* gc_threads)(struct target *target)
Definition: target_api.h:2966
int base_thread_id
Definition: target_api.h:2170
int(* set_active_probing)(struct target *target, active_probe_flags_t flags)
Definition: target_api.h:2813
obj_flags_t
Definition: object.h:43
GHashTable * target_hash_available_tids(struct target *target)
Definition: target_api.c:1212
int target_load_all_threads(struct target *target, int force)
Definition: target_api.c:1253
int arch_cregno(struct arch *arch, common_reg_t creg, REG *reg)
Definition: arch.c:73
int(* attach_evloop)(struct target *target, struct evloop *evloop)
Definition: target_api.h:2909
int _target_enable_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1703
struct target * xen_vm_instantiate(struct target_spec *spec, struct evloop *evloop)
struct array_list * target_list_available_tids(struct target *target)
Definition: target_api.c:1207
int(* enable_sw_breakpoint)(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.h:3049
int target_detach_evloop(struct target *target)
Definition: target_api.c:807
int evloop_maxsize(struct evloop *evloop)
Definition: evloop.c:191
void * whstate
Definition: evloop.h:88
int(* notify_sw_breakpoint)(struct target *target, ADDR addr, int notification)
Definition: target_api.h:3069
struct arch * arch
Definition: target_api.h:2563
void os_process_free_spec(struct os_process_spec *spec)
int(* unset_hw_watchpoint)(struct target *target, tid_t tid, REG reg)
Definition: target_api.h:3064
unsigned int is_phys
Definition: target.h:378
struct array_list * debugfile_load_opts_list
Definition: target_api.h:2199
unsigned int thread_ctxt_t
Definition: target_api.h:300
int target_disable_hw_breakpoints(struct target *target, tid_t tid)
Definition: target_api.c:1800
struct target * target
Definition: target_api.h:2041
GHashTable * overlay_aliases
Definition: target_api.h:2630
#define REGION_TYPE(n)
Definition: target_api.h:384
Definition: log.h:70
uint32_t REGVAL
Definition: common.h:66
#define THREAD_CTXT_DEFAULT
Definition: target_api.h:301
int target_memmod_release(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:4877
Definition: log.h:71
struct target * target_lookup_target_id(int id)
Definition: target.c:325
target_status_t target_status(struct target *target)
Definition: target_api.c:1007
int target_disable_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1721
#define PRIiTID
Definition: common.h:37
void target_hold(struct target *target)
Definition: target_api.c:1592
struct target_spec * target_build_spec(target_type_t type, target_mode_t mode)
Definition: target_api.c:394
int target_write_creg(struct target *target, tid_t tid, common_reg_t reg, REGVAL value)
Definition: target_api.c:1128
int target_kill(struct target *target, int sig)
Definition: target_api.c:1587
int8_t REG
Definition: common.h:93
target_type_t
Definition: target_api.h:163
int target_disable_hw_breakpoint(struct target *target, tid_t tid, REG dreg)
Definition: target_api.c:1812
uint64_t(* get_counter)(struct target *target)
Definition: target_api.h:3091
uint32_t opened
Definition: target_api.h:2427
int target_finalize(struct target *target)
Definition: target.c:1925
unsigned long(* write_phys)(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
Definition: target_api.h:2941
unsigned int breakpoint_instrs_len
Definition: arch.h:150
struct target_thread *(* lookup_overlay_thread_by_name)(struct target *target, char *name)
Definition: target_api.h:2879
int(* enable_feature)(struct target *target, int feature, void *arg)
Definition: target_api.h:3093
uint32_t ADDR
Definition: common.h:64
char * name
Definition: target_api.h:2483
struct target_ops * ops
Definition: target_api.h:2510
Definition: log.h:162
int _target_remove_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1673
char * infile
Definition: target_api.h:2248
REGVAL target_read_reg_ctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg)
Definition: target_api.c:1103
int target_memmod_set(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:4965
struct target_memmod * target_insert_sw_breakpoint(struct target *target, tid_t tid, ADDR addr)
Definition: target_api.c:1664
target_status_t target_poll(struct target *target, struct timeval *tv, target_poll_outcome_t *outcome, int *pstatus)
Definition: target_api.c:962
char * name
Definition: target.h:887
thread_ctxt_t tidctxt
Definition: target_api.h:2043
int _target_disable_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1716
GList * target_instantiate_and_open(struct target_spec *primary_target_spec, GList *base_target_specs, GList *overlay_target_specs, struct evloop *evloop, GList **error_specs)
Definition: target_api.c:92
int target_open(struct target *target)
Definition: target_api.c:496
thread_status_t
Definition: target_api.h:254
void target_release(struct target *target)
Definition: target_api.c:1596
target_status_t status
Definition: target_api.h:2465
int target_obj_flags_propagate(struct target *target, obj_flags_t orf, obj_flags_t nandf)
Definition: target_api.c:1555
#define EVLOOP_FDTYPE_W
Definition: evloop.h:31
int target_unset_hw_breakpoint(struct target *target, tid_t tid, REG reg)
Definition: target_api.c:1786
struct target * gdb_instantiate(struct target_spec *spec, struct evloop *evloop)
Definition: target_gdb.c:591
void target_dump_all_threads(struct target *target, FILE *stream, int detail)
Definition: target_api.c:1435
target_status_t target_monitor(struct target *target)
Definition: target_api.c:830
char * personality
Definition: target_api.h:2190
uint32_t REFCNT
Definition: common.h:124
int target_id(struct target *target)
Definition: target_api.c:492
#define PRIxADDR
Definition: common.h:67
#define EVLOOP_FDTYPE_R
Definition: evloop.h:30
int(* snprintf)(struct target *target, char *buf, int bufsiz)
Definition: target_api.h:2758
int kill_on_close_sig
Definition: target_api.h:2204
int(* detach_evloop)(struct target *target)
Definition: target_api.h:2910
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
struct target * target_instantiate(struct target_spec *spec, struct evloop *evloop)
Definition: target_api.c:55
#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
void debugfile_load_opts_free(struct debugfile_load_opts *opts)
Definition: debug.c:1275
active_probe_flags_t
Definition: target_api.h:432
int target_set_hw_breakpoint(struct target *target, tid_t tid, REG reg, ADDR addr)
Definition: target_api.c:1771
int id
Definition: target_api.h:2476
region_type_t type
Definition: target.h:929
struct target_thread * target_lookup_thread(struct target *target, tid_t tid)
Definition: target.c:3981
int target_gc_threads(struct target *target)
Definition: target_api.c:1303
GHashTable * probes
Definition: target_api.h:2725
int target_enable_hw_breakpoints(struct target *target, tid_t tid)
Definition: target_api.c:1806
ADDR base_load_addr
Definition: target.h:957
int(* disable_feature)(struct target *target, int feature)
Definition: target_api.h:3094
unsigned long(* write)(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.h:2916
target_type_t target_type(struct target *target)
Definition: target_api.c:484
unsigned char *(* read_phys)(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
Definition: target_api.h:2938
unsigned long target_write_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1021
struct gdb_spec * gdb_build_spec(void)
Definition: target_gdb.c:571
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
char * errfile
Definition: target_api.h:2250
int(* singlestep_end)(struct target *target, tid_t tid, struct target *overlay)
Definition: target_api.h:3073
Definition: log.h:177
uint64_t target_get_counter(struct target *target)
Definition: target_api.c:1878
char * outfile
Definition: target_api.h:2249
void xen_vm_free_spec(struct xen_vm_spec *xspec)
int target_addr_v2p(struct target *target, tid_t tid, ADDR vaddr, ADDR *paddr)
Definition: target_api.c:1028
int(* change_sw_breakpoint)(struct target *target, tid_t tid, struct target_memmod *mmod, unsigned char *code, unsigned long code_len)
Definition: target_api.h:3053
int(* init)(struct target *target)
Definition: target_api.h:2770
struct target_thread *(* load_current_thread)(struct target *target, int force)
Definition: target_api.h:2956
int base_id
Definition: target_api.h:2616
int target_enable_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target_api.c:1708
int target_unset_hw_watchpoint(struct target *target, tid_t tid, REG reg)
Definition: target_api.c:1793
int(* pause_thread)(struct target *target, tid_t tid, int nowait)
Definition: target_api.h:2960
struct target *(* instantiate_overlay)(struct target *target, struct target_thread *tthread, struct target_spec *spec, struct target_thread **ntthread)
Definition: target_api.h:2873
struct array_list * target_list_threads(struct target *target)
Definition: target_api.c:1168
int _target_change_sw_breakpoint(struct target *target, tid_t tid, struct target_memmod *mmod, unsigned char *code, unsigned long code_len)
Definition: target_api.c:1729
struct target_memmod *(* insert_sw_breakpoint)(struct target *target, tid_t tid, ADDR addr)
Definition: target_api.h:3045
int(* enable_hw_breakpoint)(struct target *target, tid_t tid, REG dreg)
Definition: target_api.h:3068
int target_write_reg(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target_api.c:1092
int(* kill)(struct target *target, int sig)
Definition: target_api.h:2783
#define TID_GLOBAL
Definition: target_api.h:145
target_status_t(* poll)(struct target *target, struct timeval *tv, target_poll_outcome_t *outcome, int *pstatus)
Definition: target_api.h:2901
struct target * t
Definition: dumptarget.c:48
active_probe_flags_t ap_flags
Definition: target_api.h:2182
GList * regions
Definition: target.h:898
#define OBJSDEAD(obj, type)
Definition: object.h:127
int(* enable_hw_breakpoints)(struct target *target, tid_t tid)
Definition: target_api.h:3066
#define PRIxREGVAL
Definition: common.h:72
struct array_list * target_list_overlays(struct target *target)
Definition: target_api.c:663
char * personality_lib
Definition: target_api.h:2195