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.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012, 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 "config.h"
20 
21 #include <errno.h>
22 #include <assert.h>
23 #include <glib.h>
24 #include <dlfcn.h>
25 #include <signal.h>
26 #include "glib_wrapper.h"
27 #include "arch.h"
28 #include "regcache.h"
29 #include "rfilter.h"
30 #include "binfile.h"
31 #include "dwdebug.h"
32 #include "dwdebug_priv.h"
33 #include "target_api.h"
34 #include "target.h"
35 #include "probe.h"
36 
37 #include "target_linux_userproc.h"
38 #ifdef ENABLE_XENSUPPORT
39 #include "target_xen_vm.h"
40 #endif
41 #include "target_os_process.h"
42 #include "target_php.h"
43 #include "target_gdb.h"
44 
48 extern void os_linux_generic_register(void);
49 
50 /*
51  * A simple global target ID counter. Callers of target_instantiate or
52  * target_create are free to supply their own IDs; if they do not, we
53  * generate IDs starting at 1.
54  *
55  * The target RPC server makes use of this, but calls it with locks
56  * held, so its use in that server is thread-safe. The reason the
57  * counter is here, then, and not there, is because the ID must be
58  * strongly associated with the target object. Silly.
59  */
60 static int next_target_id = 1;
61 
62 static int init_done = 0;
63 
64 static GHashTable *target_id_tab = NULL;
65 static GHashTable *target_personality_tab = NULL;
66 
67 void target_init(void) {
68  if (init_done)
69  return;
70 
71  dwdebug_init();
72 
73  target_id_tab = g_hash_table_new_full(g_direct_hash,g_direct_equal,
74  NULL,NULL);
75  target_personality_tab = g_hash_table_new_full(g_str_hash,g_str_equal,
76  NULL,NULL);
77 
78  /* Register the default personalities. */
80 
81  init_done = 1;
82 }
83 
84 void target_fini(void) {
85  GHashTableIter iter;
86  struct target *t;
87  gpointer kp,vp;
88 
89  if (!init_done)
90  return;
91 
92  /* Double-iterate so that internal loop can remove hashtable nodes. */
93  while (g_hash_table_size(target_id_tab) > 0) {
94  g_hash_table_iter_init(&iter,target_id_tab);
95  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&t)) {
96  target_finalize(t);
97  break;
98  }
99  }
100  g_hash_table_destroy(target_id_tab);
101  target_id_tab = NULL;
102 
103  /*
104  * Don't free the struct target_personality_ops; it should be
105  * statically linked in.
106  */
107  g_hash_table_iter_init(&iter,target_personality_tab);
108  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
109  free(kp);
110  free(vp);
111  break;
112  }
113  g_hash_table_destroy(target_personality_tab);
114  target_personality_tab = NULL;
115 
116  dwdebug_fini();
117 
118  init_done = 0;
119 }
120 
122  static int cleaning = 0;
123 
124  struct target *target;
125  GList *targets,*t1;
126 
127  if (cleaning)
128  return;
129  cleaning = 1;
130 
131  if (target_id_tab)
132  targets = g_hash_table_get_values(target_id_tab);
133  else
134  targets = NULL;
135 
136  /* Pause them all. */
137  v_g_list_foreach(targets,t1,target) {
138  target_pause(target);
139  }
140 
141  /* Close and finalize them all; there is no turning back. */
142  v_g_list_foreach(targets,t1,target) {
145  else {
146  target_close(target);
147  target_finalize(target);
148  }
149  }
150 
151  if (targets)
152  g_list_free(targets);
153 }
154 
155 static sigset_t user_ignored,user_interrupt,user_exit;
156 static void (*user_sighandler)(int signo,siginfo_t *siginfo,void *x);
157 static int __target_global_interrupt = 0;
158 static siginfo_t __target_monitor_last_siginfo;
159 static struct sigaction __target_default_sigaction = {
160  .sa_sigaction = target_default_sighandler,
161  .sa_flags = SA_SIGINFO,
162 };
163 static struct sigaction __target_default_sigaction_ign = {
164  .sa_handler = SIG_IGN,
165 };
166 
167 void target_default_sighandler(int signo,siginfo_t *siginfo,void *x) {
168  static int handling = 0;
169  GHashTableIter iter;
170  gpointer vp;
171  struct target *target;
172 
173  if (handling)
174  return;
175  else
176  handling = 1;
177 
178  if (siginfo)
179  __target_monitor_last_siginfo = *siginfo;
180  else {
181  memset(&__target_monitor_last_siginfo,0,
182  sizeof(__target_monitor_last_siginfo));
183  __target_monitor_last_siginfo.si_signo = signo;
184  }
185 
186  if (user_sighandler)
187  user_sighandler(signo,siginfo,x);
188 
189  if (sigismember(&user_interrupt,signo)) {
190  /* Set the global interrupt bit so we know what to do. */
191  __target_global_interrupt = 1;
192 
193  /*
194  * If a driver's exception handler is in crit sec, tell it to
195  * stay paused when it finishes!
196  */
197  g_hash_table_iter_init(&iter,target_id_tab);
198  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
199  target = (struct target *)vp;
200 
203  else
204  target_pause(target);
205  }
206  }
207  else {
208  /* Need to pause, then cleanup, if the base and any overlays are
209  not in monitor_handling -- otherwise, have to schedule death
210  interrupt and cleanup then. */
212  exit(1);
213  }
214 
215  sigaction(signo,&__target_default_sigaction,NULL);
216  handling = 0;
217 }
218 
219 int target_monitor_was_interrupted(siginfo_t *last_siginfo) {
220  if (__target_global_interrupt) {
221  if (last_siginfo)
222  *last_siginfo = __target_monitor_last_siginfo;
223  }
224 
225  return __target_global_interrupt;
226 }
227 
229  __target_global_interrupt = 0;
230 }
231 
233  (void (*sighandler)(int signo,siginfo_t *siginfo,void *x)) {
234 
235  sigset_t ignored,interrupt,exit;
236 
237  sigemptyset(&ignored);
238  sigemptyset(&exit);
239  sigemptyset(&interrupt);
240 
241  sigaddset(&exit,SIGHUP);
242  sigaddset(&exit,SIGINT);
243  sigaddset(&exit,SIGQUIT);
244  sigaddset(&exit,SIGILL);
245  sigaddset(&exit,SIGABRT);
246  sigaddset(&exit,SIGFPE);
247  sigaddset(&exit,SIGSEGV);
248  sigaddset(&exit,SIGPIPE);
249  sigaddset(&exit,SIGTERM);
250  sigaddset(&exit,SIGBUS);
251  sigaddset(&exit,SIGXCPU);
252  sigaddset(&exit,SIGXFSZ);
253 
254  sigaddset(&ignored,SIGUSR1);
255  sigaddset(&ignored,SIGUSR2);
256  sigaddset(&ignored,SIGALRM);
257 
258  return target_install_custom_sighandlers(&ignored,&interrupt,&exit,
259  sighandler);
260 }
261 
263  (sigset_t *ignored,sigset_t *interrupt,sigset_t *exit,
264  void (*sighandler)(int signo,siginfo_t *siginfo,void *x)) {
265 
266  int i;
267 
268  /*
269  * Waitpipe needs SIGCHLD; just skip it and error. Documented.
270  */
271  if ((ignored && sigismember(ignored,SIGCHLD))
272  || (exit && sigismember(exit,SIGCHLD))) {
273  verror("cannot specify SIGCHLD in any mask");
274  errno = EINVAL;
275  return -1;
276  }
277 
278  if (ignored)
279  user_ignored = *ignored;
280  else
281  sigemptyset(&user_ignored);
282  if (interrupt)
283  user_interrupt = *interrupt;
284  else
285  sigemptyset(&user_interrupt);
286  if (exit)
287  user_exit = *exit;
288  else
289  sigemptyset(&user_exit);
290 
291  user_sighandler = sighandler;
292 
293  for (i = 1; i < 32; ++i) {
294  if ((i == SIGKILL || i == SIGSTOP)
295  && (sigismember(&user_ignored,i) || sigismember(&user_interrupt,i)
296  || sigismember(&user_exit,i))) {
297  vwarn("cannot catch, block, nor ignore SIGKILL nor SIGSTOP; ignoring!\n");
298  continue;
299  }
300 
301  if (sigismember(&user_ignored,i))
302  sigaction(i,&__target_default_sigaction_ign,NULL);
303  else if (sigismember(&user_interrupt,i) || sigismember(&user_exit,i))
304  sigaction(i,&__target_default_sigaction,NULL);
305  }
306 
307  return 0;
308 }
309 
311  return target->monitorhandling;
312 }
313 
315  __target_global_interrupt = 1;
316 }
317 
319  if (!target->monitorhandling)
320  return -1;
321  target->needmonitorinterrupt = 1;
322  return 0;
323 }
324 
326  if (!target_id_tab)
327  return NULL;
328 
329  return (struct target *) \
330  g_hash_table_lookup(target_id_tab,(gpointer)(uintptr_t)id);
331 }
332 
353 error_t target_argp_parse_opt(int key,char *arg,struct argp_state *state);
354 
355 #define TARGET_ARGP_BASE 0x333331
356 #define TARGET_ARGP_OVERLAY 0x333332
357 #define TARGET_ARGP_PERSONALITY 0x333333
358 #define TARGET_ARGP_PERSONALITY_LIB 0x333334
359 #define TARGET_ARGP_START_PAUSED 0x333335
360 
361 #ifdef ENABLE_XENSUPPORT
362 #define __XEN_ARGP_TYPE ",xen"
363 #else
364 #define __XEN_ARGP_TYPE
365 #endif
366 
367 #define TARGET_ARGP_CORE_OPTS \
368  { "debug",'d',"LEVEL",0,"Set/increase the debugging level.",-3 }, \
369  { "log-flags",'l',"FLAG,FLAG,...",0,"Set the debugging flags",-3 }, \
370  { "warn",'w',"LEVEL",0,"Set/increase the warning level.",-3 }, \
371  { "target-type",'t',"TYPENAME",0, \
372  "Forcibly set the target type (ptrace" __XEN_ARGP_TYPE ",gdb,os-process,php).",-3 }, \
373  { "personality",TARGET_ARGP_PERSONALITY,"PERSONALITY",0, \
374  "Forcibly set the target personality (linux,process,php).",-3 }, \
375  { "personality-lib",TARGET_ARGP_PERSONALITY_LIB,"PERSONALITY_LIB_FILENAME",0, \
376  "Specify a shared library where the personality specified by --personality should be loaded from.",-3 }, \
377  { "start-paused",TARGET_ARGP_START_PAUSED,0,0,"Leave target paused after launch.",-3 }, \
378  { "stay-paused",'P',0,0,"Keep target paused at detach.",-3 }, \
379  { "soft-breakpoints",'s',0,0,"Force software breakpoints.",-3 }, \
380  { "debugfile-load-opts",'F',"LOAD-OPTS",0,"Add a set of debugfile load options.",-3 }, \
381  { "breakpoint-mode",'L',"STRICT-LEVEL",0,"Set/increase the breakpoint mode level.",-3 }, \
382  { "target-id",'i',"ID",0,"Specify a numeric ID for the target.",0 }, \
383  { "in-file",'I',"FILE",0,"Deliver contents of FILE to target on stdin (if avail).",-4 }, \
384  { "out-file",'O',"FILE",0,"Log stdout (if avail) to FILE.",-4 }, \
385  { "err-file",'E',"FILE",0,"Log stderr (if avail) to FILE.",-4 }, \
386  { "kill-on-close",'k',NULL,0,"Destroy target on close (SIGKILL).",-4 }, \
387  { "debugfile-root-prefix",'R',"DIR",0, \
388  "Set an alternate root prefix for debuginfo and binfile resolution.",0 }, \
389  { "active-probing",'a',"FLAG,FLAG,...",0, \
390  "A list of active probing flags to enable (disabled by default)" \
391  " (thread_entry thread_exit memory other)",0 }
392 
393 struct argp_option target_argp_opts[] = {
395  { "base",TARGET_ARGP_BASE,"TARGET_OPTIONS",0,
396  "Specify an entire base target in a single argument. Any standard target option other than --base and --overlay may be used.",-3 },
397  { "overlay",TARGET_ARGP_OVERLAY,"OVERLAY_PREFIX:TARGET_OPTIONS",0,
398  "Specify an entire overlay target in a single argument. Your argument must be of the form [<base_target_id>:]<thread_name_or_id>:TARGET_OPTIONS",-3 },
399  { 0,0,0,0,0,0 }
400 };
401 
402 struct argp_option target_argp_opts_only_one[] = {
404  { 0,0,0,0,0,0 }
405 };
406 
407 int target_spec_to_argv(struct target_spec *spec,char *arg0,
408  int *argc,char ***argv) {
409  int rc;
410  char **backend_argv = NULL;
411  int backend_argc = 0;
412  char **av = NULL;
413  int ac = 0;
414  int j;
415  int i;
416  int len;
417 
418  /* Do the backend first. */
419  if (spec->target_type == TARGET_TYPE_PTRACE) {
420  if ((rc = linux_userproc_spec_to_argv(spec,&backend_argc,&backend_argv))) {
421  verror("linux_userproc_spec_to_argv failed!\n");
422  return -1;
423  }
424  }
425 #ifdef ENABLE_XENSUPPORT
426  else if (spec->target_type == TARGET_TYPE_XEN) {
427  if ((rc = xen_vm_spec_to_argv(spec,&backend_argc,&backend_argv))) {
428  verror("xen_vm_spec_to_argv failed!\n");
429  return -1;
430  }
431  }
432 #endif
433  else if (spec->target_type == TARGET_TYPE_OS_PROCESS) {
434  /* NB: os_process_spec has nothing; don't do anything. */
435  /*
436  if ((rc = os_process_spec_to_argv(spec,&backend_argc,&backend_argv))) {
437  verror("os_process_spec_to_argv failed!\n");
438  return -1;
439  }
440  */
441  }
442  else if (spec->target_type == TARGET_TYPE_PHP) {
443  /* NB: php_spec has nothing; don't do anything. */
444  /*
445  if ((rc = php_spec_to_argv(spec,&backend_argc,&backend_argv))) {
446  verror("php_spec_to_argv failed!\n");
447  return -1;
448  }
449  */
450  }
451  else if (spec->target_type == TARGET_TYPE_GDB) {
452  if ((rc = gdb_spec_to_argv(spec,&backend_argc,&backend_argv))) {
453  verror("gdb_spec_to_argv failed!\n");
454  return -1;
455  }
456  }
457  else {
458  verror("unsupported backend type %d!\n",spec->target_type);
459  return -1;
460  }
461 
462  /*
463  * Count arg0.
464  */
465  if (arg0)
466  ac += 1;
467 
468  /*
469  * Do the backend type.
470  */
471  ac += 2;
472 
473  /*
474  * Now count the generic opts.
475  *
476  * NB: XXX: for now, we don't do debug levels/flags, since the XML
477  * server doesn't expose them to the user, and that is the only
478  * caller of this function.
479  */
480  if (spec->start_paused)
481  ac += 1;
482  if (spec->stay_paused)
483  ac += 1;
484  if (spec->style == PROBEPOINT_SW)
485  ac += 1;
486  if (spec->bpmode > 0)
487  ac += 2;
488  if (spec->target_id > -1)
489  ac += 2;
490  if (spec->infile)
491  ac += 2;
492  if (spec->outfile)
493  ac += 2;
494  if (spec->errfile)
495  ac += 2;
496  if (spec->kill_on_close)
497  ac += 1;
498  if (spec->personality)
499  ac += 2;
500  if (spec->personality_lib)
501  ac += 2;
502  if (spec->debugfile_root_prefix)
503  ac += 2;
504  if (spec->ap_flags & APF_ALL)
505  ac += 2;
506 
507  ac += backend_argc;
508  av = calloc(ac + 1,sizeof(char *));
509 
510  j = 0;
511 
512  /*
513  * Handle arg0.
514  */
515  if (arg0) {
516  av[j++] = strdup(arg0);
517  }
518 
519  /*
520  * Do the backend type.
521  */
522  av[j++] = strdup("-t");
523  if (spec->target_type == TARGET_TYPE_PTRACE)
524  av[j++] = strdup("ptrace");
525 #ifdef ENABLE_XENSUPPORT
526  else if (spec->target_type == TARGET_TYPE_XEN)
527  av[j++] = strdup("xen");
528 #endif
529  else if (spec->target_type == TARGET_TYPE_GDB)
530  av[j++] = strdup("gdb");
531  else if (spec->target_type == TARGET_TYPE_OS_PROCESS)
532  av[j++] = strdup("os-process");
533  else if (spec->target_type == TARGET_TYPE_PHP)
534  av[j++] = strdup("php");
535  else
536  av[j++] = strdup("UNKNOWN");
537 
538  /* Do the generic opts. */
539  if (spec->start_paused) {
540  av[j++] = strdup("--start-paused");
541  }
542  if (spec->stay_paused) {
543  av[j++] = strdup("--stay-paused");
544  }
545  if (spec->style == PROBEPOINT_SW) {
546  av[j++] = strdup("-s");
547  }
548  if (spec->bpmode > 0) {
549  av[j++] = strdup("-L");
550  av[j] = malloc(11);
551  snprintf(av[j],11,"%d",spec->bpmode);
552  ++j;
553  }
554  if (spec->target_id > -1) {
555  av[j++] = strdup("-i");
556  av[j] = malloc(11);
557  snprintf(av[j],11,"%d",spec->target_id);
558  ++j;
559  }
560  if (spec->infile) {
561  av[j++] = strdup("-I");
562  av[j++] = strdup(spec->infile);
563  }
564  if (spec->outfile) {
565  av[j++] = strdup("-O");
566  av[j++] = strdup(spec->outfile);
567  }
568  if (spec->errfile) {
569  av[j++] = strdup("-E");
570  av[j++] = strdup(spec->errfile);
571  }
572  if (spec->kill_on_close) {
573  av[j++] = strdup("-k");
574  }
575  if (spec->personality) {
576  av[j++] = strdup("--personality");
577  av[j++] = strdup(spec->personality);
578  }
579  if (spec->personality_lib) {
580  av[j++] = strdup("--personality-lib");
581  av[j++] = strdup(spec->personality_lib);
582  }
583  if (spec->debugfile_root_prefix) {
584  av[j++] = strdup("-R");
585  av[j++] = strdup(spec->debugfile_root_prefix);
586  }
587  if (spec->ap_flags & APF_ALL) {
588  av[j++] = strdup("-a");
589  len = 0;
590 
591  if (spec->ap_flags & APF_THREAD_ENTRY)
592  len += sizeof("thread_entry,");
593  if (spec->ap_flags & APF_THREAD_EXIT)
594  len += sizeof("thread_exit,");
595  if (spec->ap_flags & APF_MEMORY)
596  len += sizeof("memory,");
597  if (spec->ap_flags & APF_OTHER)
598  len += sizeof("other,");
599 
600  if (spec->ap_flags & APF_OS_THREAD_ENTRY)
601  len += sizeof("os_thread_entry,");
602  if (spec->ap_flags & APF_OS_THREAD_EXIT)
603  len += sizeof("os_thread_exit,");
604  if (spec->ap_flags & APF_OS_MEMORY)
605  len += sizeof("os_memory,");
606  if (spec->ap_flags & APF_OS_OTHER)
607  len += sizeof("os_other,");
608 
610  len += sizeof("process_thread_entry,");
611  if (spec->ap_flags & APF_PROCESS_THREAD_EXIT)
612  len += sizeof("process_thread_exit,");
613  if (spec->ap_flags & APF_PROCESS_MEMORY)
614  len += sizeof("process_memory,");
615  if (spec->ap_flags & APF_PROCESS_OTHER)
616  len += sizeof("process_other,");
617 
618  if (spec->ap_flags & APF_APP_THREAD_ENTRY)
619  len += sizeof("app_thread_entry,");
620  if (spec->ap_flags & APF_APP_THREAD_EXIT)
621  len += sizeof("app_thread_exit,");
622  if (spec->ap_flags & APF_APP_MEMORY)
623  len += sizeof("app_memory,");
624  if (spec->ap_flags & APF_APP_OTHER)
625  len += sizeof("app_other,");
626 
627  len += 1;
628  av[j] = malloc(len);
629  rc = 0;
630 
631  if (spec->ap_flags & APF_THREAD_ENTRY)
632  rc += snprintf(av[j] + rc,len - rc,"%s","thread_entry,");
633  if (spec->ap_flags & APF_THREAD_EXIT)
634  rc += snprintf(av[j] + rc,len - rc,"%s","thread_exit,");
635  if (spec->ap_flags & APF_MEMORY)
636  rc += snprintf(av[j] + rc,len - rc,"%s","memory,");
637  if (spec->ap_flags & APF_OTHER)
638  rc += snprintf(av[j] + rc,len - rc,"%s","other,");
639 
640  if (spec->ap_flags & APF_OS_THREAD_ENTRY)
641  rc += snprintf(av[j] + rc,len - rc,"%s","os_thread_entry,");
642  if (spec->ap_flags & APF_OS_THREAD_EXIT)
643  rc += snprintf(av[j] + rc,len - rc,"%s","os_thread_exit,");
644  if (spec->ap_flags & APF_OS_MEMORY)
645  rc += snprintf(av[j] + rc,len - rc,"%s","os_memory,");
646  if (spec->ap_flags & APF_OS_OTHER)
647  rc += snprintf(av[j] + rc,len - rc,"%s","os_other,");
648 
650  rc += snprintf(av[j] + rc,len - rc,"%s","process_thread_entry,");
651  if (spec->ap_flags & APF_PROCESS_THREAD_EXIT)
652  rc += snprintf(av[j] + rc,len - rc,"%s","process_thread_exit,");
653  if (spec->ap_flags & APF_PROCESS_MEMORY)
654  rc += snprintf(av[j] + rc,len - rc,"%s","process_memory,");
655  if (spec->ap_flags & APF_PROCESS_OTHER)
656  rc += snprintf(av[j] + rc,len - rc,"%s","process_other,");
657 
658  if (spec->ap_flags & APF_APP_THREAD_ENTRY)
659  rc += snprintf(av[j] + rc,len - rc,"%s","app_thread_entry,");
660  if (spec->ap_flags & APF_APP_THREAD_EXIT)
661  rc += snprintf(av[j] + rc,len - rc,"%s","app_thread_exit,");
662  if (spec->ap_flags & APF_APP_MEMORY)
663  rc += snprintf(av[j] + rc,len - rc,"%s","app_memory,");
664  if (spec->ap_flags & APF_APP_OTHER)
665  rc += snprintf(av[j] + rc,len - rc,"%s","app_other,");
666 
667  ++j;
668  }
669 
670  for (i = 0; i < backend_argc; ++i)
671  av[j++] = backend_argv[i];
672 
673  av[j] = NULL;
674 
675  if (backend_argc > 0)
676  free(backend_argv);
677 
678  if (argc)
679  *argc = ac;
680  if (argv)
681  *argv = av;
682 
683  return 0;
684 }
685 
686 /*
687  * The children this library will utilize.
688  */
689 extern struct argp linux_userproc_argp;
690 extern char *linux_userproc_argp_header;
691 #ifdef ENABLE_XENSUPPORT
692 extern struct argp xen_vm_argp;
693 extern char *xen_vm_argp_header;
694 #endif
695 
696 struct target_spec *target_argp_target_spec(struct argp_state *state) {
697  if (!state)
698  return NULL;
699 
700  return ((struct target_argp_parser_state *) \
701  state->input)->spec;
702 }
703 void *target_argp_driver_state(struct argp_state *state) {
704  if (!state)
705  return NULL;
706 
707  return ((struct target_argp_parser_state *) \
708  state->input)->driver_state;
709 }
710 
711 static int __str2argvlist(char *argptr,struct array_list *argv_list) {
712  int inesc,inquote;
713  char quotechar;
714  char *nargptr,*vargptr;
715 
716  while (*argptr == ' ')
717  ++argptr;
718 
719  inesc = 0;
720  inquote = 0;
721  quotechar = 0;
722  nargptr = argptr;
723  vargptr = argptr;
724  while (*argptr != '\0') {
725  if (*argptr == '\\') {
726  if (inesc) {
727  inesc = 0;
728  *nargptr = '\\';
729  ++nargptr;
730  }
731  else {
732  /* Don't copy the escape char. */
733  inesc = 1;
734  ++argptr;
735  continue;
736  }
737  }
738  else if (inesc) {
739  inesc = 0;
740  /* Just copy it. */
741  *nargptr = *argptr;
742  ++nargptr;
743  }
744  else if (inquote && *argptr == quotechar) {
745  /* Ended the quoted sequence; don't copy quotes. */
746  inquote = 0;
747  quotechar = 0;
748  ++argptr;
749  continue;
750  }
751  else if (*argptr == '\'' || *argptr == '"') {
752  inquote = 1;
753  quotechar = *argptr;
754  ++argptr;
755  continue;
756  }
757  else if (!inquote && *argptr == ' ') {
758  *nargptr = *argptr = '\0';
759  if (vargptr) {
760  array_list_append(argv_list,vargptr);
761  //printf("vargptr (%p) = '%s'\n",vargptr,vargptr);
762  vargptr = NULL;
763  }
764  vargptr = NULL;
765  nargptr = ++argptr;
766  continue;
767  }
768  else {
769  if (!vargptr)
770  vargptr = nargptr;
771 
772  *nargptr = *argptr;
773  ++nargptr;
774  }
775 
776  /* Default increment. */
777  ++argptr;
778  }
779  if (vargptr) {
780  *nargptr = '\0';
781  array_list_append(argv_list,vargptr);
782  //printf("vargptr (%p) = '%s'\n",vargptr,vargptr);
783  }
784  array_list_append(argv_list,NULL);
785 
786  return 0;
787 }
788 
789 struct target_spec *target_argp_driver_parse_one(struct argp *driver_parser,
790  void *driver_state,
791  int argc,char **argv,
792  target_type_t target_types,
793  int filter_quoted) {
794  error_t retval;
795  int i;
796  struct target_argp_parser_state tstate;
797  /*
798  * These are our subparsers. They are optional, so we have to build
799  * them manually.
800  */
801  struct argp_child target_argp_children[4];
802  /*
803  * This is the "main" target arg parser, to be used if the caller
804  * has no arguments.
805  */
806  struct argp target_argp = {
808  NULL,NULL,target_argp_children,NULL,NULL
809  };
810  /*
811  * This is the main child target arg parser, to be used if the
812  * caller has its own arguments.
813  */
814  struct argp_child target_argp_child[] = {
815  { &target_argp,0,"Generic Target Options",0 },
816  { 0,0,0,0 },
817  };
818 
819  if (!target_types) {
820  errno = EINVAL;
821  return NULL;
822  }
823 
824  memset(&tstate,0,sizeof(tstate));
825 
826  tstate.driver_state = driver_state;
828  tstate.base_target_specs = NULL;
829  tstate.overlay_target_specs = NULL;
830 
831  if (filter_quoted) {
832  for (i = 0; i < argc; ++i) {
833  if (strncmp("--",argv[i],2) == 0 && argv[i][2] == '\0') {
834  argv[i] = NULL;
835  if (++i < argc) {
836  tstate.quoted_start = i;
837  tstate.quoted_argc = argc - i;
838  tstate.quoted_argv = &argv[i];
839  }
840  argc = i - 1;
841  break;
842  }
843  }
844  }
845 
846  tstate.num_children = 0;
847  if (target_types & TARGET_TYPE_PTRACE) {
848  target_argp_children[tstate.num_children].argp = &linux_userproc_argp;
849  target_argp_children[tstate.num_children].flags = 0;
850  target_argp_children[tstate.num_children].header = linux_userproc_argp_header;
851  target_argp_children[tstate.num_children].group = 0;
852  ++tstate.num_children;
853  }
854 #ifdef ENABLE_XENSUPPORT
855  if (target_types & TARGET_TYPE_XEN) {
856  target_argp_children[tstate.num_children].argp = &xen_vm_argp;
857  target_argp_children[tstate.num_children].flags = 0;
858  target_argp_children[tstate.num_children].header = xen_vm_argp_header;
859  target_argp_children[tstate.num_children].group = 0;
860  ++tstate.num_children;
861  }
862 #endif
863  if (target_types & TARGET_TYPE_GDB) {
864  target_argp_children[tstate.num_children].argp = &gdb_argp;
865  target_argp_children[tstate.num_children].flags = 0;
866  target_argp_children[tstate.num_children].header = gdb_argp_header;
867  target_argp_children[tstate.num_children].group = 0;
868  ++tstate.num_children;
869  }
870 
871  target_argp_children[tstate.num_children].argp = NULL;
872  target_argp_children[tstate.num_children].flags = 0;
873  target_argp_children[tstate.num_children].header = NULL;
874  target_argp_children[tstate.num_children].group = 0;
875 
876  if (driver_parser) {
877  driver_parser->children = target_argp_child;
878 
879  retval = argp_parse(driver_parser,argc,argv,0,NULL,&tstate);
880 
881  driver_parser->children = NULL;
882  }
883  else {
884  retval = argp_parse(&target_argp,argc,argv,0,NULL,&tstate);
885  }
886 
887  if (retval) {
888  if (tstate.spec && tstate.spec->backend_spec)
889  free(tstate.spec->backend_spec);
890  if (tstate.spec)
891  free(tstate.spec);
892  tstate.spec = NULL;
893 
894  return NULL;
895  }
896 
897  return tstate.spec;
898 }
899 
900 int target_argp_driver_parse(struct argp *driver_parser,void *driver_state,
901  int argc,char **argv,
902  target_type_t target_types,int filter_quoted,
903  struct target_spec **primary_target_spec,
904  GList **base_target_specs,
905  GList **overlay_target_specs) {
906  error_t retval;
907  int i;
908  GList *tmp;
909  struct target_spec *tspec2;
910  struct target_argp_parser_state tstate;
911  /*
912  * These are our subparsers. They are optional, so we have to build
913  * them manually.
914  */
915  struct argp_child target_argp_children[4];
916  /*
917  * This is the "main" target arg parser, to be used if the caller
918  * has no arguments.
919  */
920  struct argp target_argp = {
922  NULL,NULL,target_argp_children,NULL,NULL
923  };
924  /*
925  * This is the main child target arg parser, to be used if the
926  * caller has its own arguments.
927  */
928  struct argp_child target_argp_child[] = {
929  { &target_argp,0,"Generic Target Options",0 },
930  { 0,0,0,0 },
931  };
932 
933  if (!target_types) {
934  errno = EINVAL;
935  return -1;
936  }
937 
938  memset(&tstate,0,sizeof(tstate));
939 
940  tstate.driver_state = driver_state;
942  tstate.base_target_specs = base_target_specs;
943  tstate.overlay_target_specs = overlay_target_specs;
944 
945  if (filter_quoted) {
946  for (i = 0; i < argc; ++i) {
947  if (strncmp("--",argv[i],2) == 0 && argv[i][2] == '\0') {
948  argv[i] = NULL;
949  if (++i < argc) {
950  tstate.quoted_start = i;
951  tstate.quoted_argc = argc - i;
952  tstate.quoted_argv = &argv[i];
953  }
954  argc = i - 1;
955  break;
956  }
957  }
958  }
959 
960  tstate.num_children = 0;
961  if (target_types & TARGET_TYPE_PTRACE) {
962  target_argp_children[tstate.num_children].argp = &linux_userproc_argp;
963  target_argp_children[tstate.num_children].flags = 0;
964  target_argp_children[tstate.num_children].header = linux_userproc_argp_header;
965  target_argp_children[tstate.num_children].group = 0;
966  ++tstate.num_children;
967  }
968 #ifdef ENABLE_XENSUPPORT
969  if (target_types & TARGET_TYPE_XEN) {
970  target_argp_children[tstate.num_children].argp = &xen_vm_argp;
971  target_argp_children[tstate.num_children].flags = 0;
972  target_argp_children[tstate.num_children].header = xen_vm_argp_header;
973  target_argp_children[tstate.num_children].group = 0;
974  ++tstate.num_children;
975  }
976 #endif
977  if (target_types & TARGET_TYPE_GDB) {
978  target_argp_children[tstate.num_children].argp = &gdb_argp;
979  target_argp_children[tstate.num_children].flags = 0;
980  target_argp_children[tstate.num_children].header = gdb_argp_header;
981  target_argp_children[tstate.num_children].group = 0;
982  ++tstate.num_children;
983  }
984 
985  target_argp_children[tstate.num_children].argp = NULL;
986  target_argp_children[tstate.num_children].flags = 0;
987  target_argp_children[tstate.num_children].header = NULL;
988  target_argp_children[tstate.num_children].group = 0;
989 
990  if (driver_parser) {
991  driver_parser->children = target_argp_child;
992 
993  retval = argp_parse(driver_parser,argc,argv,0,NULL,&tstate);
994 
995  driver_parser->children = NULL;
996  }
997  else {
998  retval = argp_parse(&target_argp,argc,argv,0,NULL,&tstate);
999  }
1000 
1001  if (tstate.spec && !primary_target_spec) {
1002  verror("primary target specification supplied, but not allowed!\n");
1003  errno = EINVAL;
1004  retval = -1;
1005  }
1006 
1007  if (retval) {
1008  if (base_target_specs && *base_target_specs) {
1009  v_g_list_foreach(*base_target_specs,tmp,tspec2) {
1010  if (tspec2->backend_spec)
1011  free(tspec2->backend_spec);
1012  free(tspec2);
1013  }
1014  g_list_free(*base_target_specs);
1015  *base_target_specs = NULL;
1016  }
1017 
1018  if (overlay_target_specs && *overlay_target_specs) {
1019  v_g_list_foreach(*overlay_target_specs,tmp,tspec2) {
1020  if (tspec2->backend_spec)
1021  free(tspec2->backend_spec);
1022  free(tspec2);
1023  }
1024  g_list_free(*overlay_target_specs);
1025  *overlay_target_specs = NULL;
1026  }
1027 
1028  if (tstate.spec && tstate.spec->backend_spec)
1029  free(tstate.spec->backend_spec);
1030  if (tstate.spec)
1031  free(tstate.spec);
1032  tstate.spec = NULL;
1033 
1034  return retval;
1035  }
1036  else {
1037  if (tstate.spec)
1038  *primary_target_spec = tstate.spec;
1039 
1040  return 0;
1041  }
1042 }
1043 
1044 void target_driver_argp_init_children(struct argp_state *state) {
1045  state->child_inputs[0] = state->input;
1046 }
1047 
1048 error_t target_argp_parse_opt(int key,char *arg,struct argp_state *state) {
1049  struct target_argp_parser_state *tstate = \
1050  (struct target_argp_parser_state *)state->input;
1051  struct target_spec *spec = NULL;
1052  char *argcopy;
1053  struct debugfile_load_opts *opts;
1054  int i;
1055  target_type_t tmptype;
1056  char *saveptr;
1057  char *token;
1058  int shf;
1059  struct array_list *argv_list;
1060  char *argptr,*argptr2;
1061  char *base_thread_name_or_id;
1062  int base_target_id = -1;
1063  struct target_spec *ospec,*bspec;
1064 
1065  if (tstate)
1066  spec = tstate->spec;
1067 
1068  switch (key) {
1069  case ARGP_KEY_ARG:
1070  case ARGP_KEY_ARGS:
1071  return ARGP_ERR_UNKNOWN;
1072  case ARGP_KEY_INIT:
1073  for (i = 0; i < tstate->num_children; ++i)
1074  state->child_inputs[i] = tstate;
1075  break;
1076  case ARGP_KEY_END:
1077  case ARGP_KEY_NO_ARGS:
1078  case ARGP_KEY_SUCCESS:
1079  case ARGP_KEY_ERROR:
1080  return 0;
1081  case ARGP_KEY_FINI:
1082  /*
1083  * Check for at least *something*. But if they specified --base
1084  * at least once, allow the "default" target to be NULL.
1085  */
1087  && tstate->base_target_specs && *(tstate->base_target_specs)
1088  && g_list_length(*(tstate->base_target_specs))) {
1089  target_free_spec(tstate->spec);
1090  tstate->spec = NULL;
1091  }
1092  else if (spec && spec->target_type == TARGET_TYPE_NONE) {
1093  verror("you must specify at least one kind of target!\n");
1094  return EINVAL;
1095  }
1096  return 0;
1097 
1098  case 't':
1099  /*
1100  * If the child parser already autoselect a type based on prior
1101  * args, error!
1102  */
1103  if (strcmp(arg,"ptrace") == 0)
1104  tmptype = TARGET_TYPE_PTRACE;
1105 #ifdef ENABLE_XENSUPPORT
1106  else if (strcmp(arg,"xen") == 0)
1107  tmptype = TARGET_TYPE_XEN;
1108 #endif
1109  else if (strcmp(arg,"os-process") == 0)
1110  tmptype = TARGET_TYPE_OS_PROCESS;
1111  else if (strcmp(arg,"php") == 0)
1112  tmptype = TARGET_TYPE_PHP;
1113  else if (strcmp(arg,"gdb") == 0)
1114  tmptype = TARGET_TYPE_GDB;
1115  else {
1116  verror("bad target type %s!\n",arg);
1117  return EINVAL;
1118  }
1119 
1121  && spec->target_type != tmptype) {
1122  verror("target type already inferred or set; cannot set type %s!\n",
1123  arg);
1124  return EINVAL;
1125  }
1126  else if (spec->target_type == TARGET_TYPE_NONE) {
1127  spec->target_type = tmptype;
1128  if (tmptype == TARGET_TYPE_PTRACE)
1130 #ifdef ENABLE_XENSUPPORT
1131  else if (strcmp(arg,"xen") == 0)
1133 #endif
1134  else if (strcmp(arg,"os-process") == 0)
1136  else if (strcmp(arg,"php") == 0)
1138  else if (tmptype == TARGET_TYPE_GDB)
1140  }
1141 
1142  break;
1143  case 'd':
1144  if (arg) {
1145  if (*arg == 'd') {
1146  arg = &arg[1];
1148  while (*arg == 'd') {
1150  arg = &arg[1];
1151  }
1152  }
1153  else
1154  vmi_set_log_level(atoi(arg));
1155  }
1156  else
1158  break;
1159  case 'w':
1160  if (arg) {
1161  if (*arg == 'w') {
1162  arg = &arg[1];
1164  while (*arg == 'w') {
1166  arg = &arg[1];
1167  }
1168  }
1169  else
1170  vmi_set_warn_level(atoi(arg));
1171  }
1172  else
1174  break;
1175  case 'l':
1176  if (vmi_add_log_area_flaglist(arg,NULL)) {
1177  verror("bad log level flag in '%s'!\n",arg);
1178  return EINVAL;
1179  }
1180  break;
1181 
1182  case 's':
1184  break;
1185  case 'F':
1186  argcopy = strdup(arg);
1187 
1188  opts = debugfile_load_opts_parse(argcopy);
1189 
1190  if (!opts) {
1191  verror("bad debugfile_load_opts '%s'!\n",argcopy);
1192  free(argcopy);
1193  for (i = 0; i < array_list_len(spec->debugfile_load_opts_list); ++i)
1195  array_list_item(spec->debugfile_load_opts_list,i));
1196  array_list_free(spec->debugfile_load_opts_list);
1198 
1199  return EINVAL;
1200  }
1201  else {
1203  spec->debugfile_load_opts_list = array_list_create(4);
1204  array_list_append(spec->debugfile_load_opts_list,opts);
1205  break;
1206  }
1208  spec->start_paused = 1;
1209  break;
1210  case 'P':
1211  spec->stay_paused = 1;
1212  break;
1213  case 'L':
1214  if (arg)
1215  spec->bpmode = atoi(arg);
1216  else
1217  ++spec->bpmode;
1218  break;
1219  case 'i':
1220  spec->target_id = atoi(arg);
1221  break;
1222  case 'I':
1223  spec->infile = strdup(arg);
1224  break;
1225  case 'E':
1226  spec->errfile = strdup(arg);
1227  break;
1228  case 'O':
1229  spec->outfile = strdup(arg);
1230  break;
1231  case 'k':
1232  spec->kill_on_close = 1;
1233  break;
1235  spec->personality = strdup(arg);
1236  break;
1238  spec->personality_lib = strdup(arg);
1239  break;
1240  case 'R':
1241  spec->debugfile_root_prefix = strdup(arg);
1242  break;
1243  case 'a':
1244  argcopy = strdup(arg);
1245  saveptr = NULL;
1246  while ((token = strtok_r((!saveptr) ? argcopy : NULL,",",&saveptr))) {
1247  if (strncmp(token,"os_",2) == 0) {
1248  token += 3;
1249  shf = 8;
1250  }
1251  else if (strncmp(token,"process_",8) == 0) {
1252  token += 8;
1253  shf = 16;
1254  }
1255  else if (strncmp(token,"proc_",5) == 0) {
1256  token += 5;
1257  shf = 16;
1258  }
1259  else if (strncmp(token,"app_",4) == 0) {
1260  token += 4;
1261  shf = 24;
1262  }
1263  else
1264  shf = 0;
1265 
1266  if (strcmp("thread_entry",token) == 0)
1267  spec->ap_flags |= (APF_THREAD_ENTRY << shf);
1268  else if (strcmp("thread_exit",token) == 0)
1269  spec->ap_flags |= (APF_THREAD_EXIT << shf);
1270  else if (strcmp("memory",token) == 0)
1271  spec->ap_flags |= (APF_MEMORY << shf);
1272  else if (strcmp("other",token) == 0)
1273  spec->ap_flags |= (APF_OTHER << shf);
1274  else {
1275  verror("unrecognized active probe flag '%s'!\n",token);
1276  return EINVAL;
1277  }
1278  }
1279  break;
1280  case TARGET_ARGP_BASE:
1281  if (!tstate->base_target_specs) {
1282  verror("program does not support extra base target specs!\n");
1283  return EINVAL;
1284  }
1285 
1286  argcopy = strdup(arg);
1287 
1288  argv_list = array_list_create(32);
1289  array_list_append(argv_list,"target_argp_base_parse_one");
1290 
1291  __str2argvlist(argcopy,argv_list);
1292 
1293  bspec = target_argp_driver_parse_one(NULL,NULL,
1294  array_list_len(argv_list) - 1,
1295  (char **)argv_list->list,
1297  if (!bspec) {
1298  verror("could not parse base spec %d!\n",
1299  g_list_length(*tstate->base_target_specs));
1300  free(argcopy);
1301  array_list_free(argv_list);
1302  return EINVAL;
1303  }
1304 
1305  bspec->spec_was_base = 1;
1306 
1307  *tstate->base_target_specs =
1308  g_list_append(*tstate->base_target_specs,bspec);
1309 
1310  free(argcopy);
1311  array_list_free(argv_list);
1312  break;
1313  case TARGET_ARGP_OVERLAY:
1314  if (!tstate->overlay_target_specs) {
1315  verror("program does not support extra overlay target specs!\n");
1316  return EINVAL;
1317  }
1318 
1319  /*
1320  * We need to split the <name_or_id>:<spec> part; then split
1321  * <spec> into an argv. Simple rules: \ escapes the next char;
1322  * space not in ' or " causes us to end the current argv[i] and
1323  * start the next one.
1324  */
1325  argcopy = strdup(arg);
1326  argptr = index(argcopy,':');
1327  if (!argptr) {
1328  verror("bad overlay spec!\n");
1329  return EINVAL;
1330  }
1331 
1332  argv_list = array_list_create(32);
1333  array_list_append(argv_list,"target_argp_overlay_parse_one");
1334 
1335  base_thread_name_or_id = argcopy;
1336  *argptr = '\0';
1337  ++argptr;
1338 
1339  argptr2 = index(argptr,':');
1340  if (argptr2) {
1341  base_target_id = atoi(base_thread_name_or_id);
1342  base_thread_name_or_id = argptr;
1343  *argptr2 = '\0';
1344  argptr = ++argptr2;
1345  }
1346 
1347  __str2argvlist(argptr,argv_list);
1348 
1349  ospec = target_argp_driver_parse_one(NULL,NULL,
1350  array_list_len(argv_list) - 1,
1351  (char **)argv_list->list,
1353  if (!ospec) {
1354  verror("could not parse overlay spec %d!\n",
1355  g_list_length(*tstate->overlay_target_specs));
1356  free(argcopy);
1357  array_list_free(argv_list);
1358  return EINVAL;
1359  }
1360 
1361  ospec->base_target_id = base_target_id;
1362  if (isdigit(*base_thread_name_or_id)) {
1363  ospec->base_thread_id = atoi(base_thread_name_or_id);
1364  ospec->base_thread_name = NULL;
1365  }
1366  else {
1367  ospec->base_thread_id = -1;
1368  ospec->base_thread_name = strdup(base_thread_name_or_id);
1369  }
1370  ospec->spec_was_overlay = 1;
1371 
1372  *tstate->overlay_target_specs =
1373  g_list_append(*tstate->overlay_target_specs,ospec);
1374 
1375  free(argcopy);
1376  array_list_free(argv_list);
1377  break;
1378 
1379  default:
1380  return ARGP_ERR_UNKNOWN;
1381  }
1382 
1383  return 0;
1384 }
1385 
1387  void *value;
1389 };
1390 
1391 int target_gkv_insert(struct target *target,char *key,void *value,
1392  target_gkv_dtor_t dtor) {
1393  struct target_gkv_info *gkvi;
1394 
1395  if (g_hash_table_lookup_extended(target->gkv_store,key,NULL,NULL) == TRUE) {
1396  errno = EEXIST;
1397  return -1;
1398  }
1399 
1400  gkvi = calloc(1,sizeof(*gkvi));
1401  gkvi->value = value;
1402  gkvi->dtor = dtor;
1403 
1404  g_hash_table_insert(target->gkv_store,strdup(key),gkvi);
1405 
1406  return 0;
1407 }
1408 
1409 void *target_gkv_lookup(struct target *target,char *key) {
1410  struct target_gkv_info *gkvi;
1411 
1412  if (!(gkvi = (struct target_gkv_info *) \
1413  g_hash_table_lookup(target->gkv_store,key))) {
1414  return NULL;
1415  }
1416 
1417  return gkvi->value;
1418 }
1419 
1420 void *target_gkv_steal(struct target *target,char *key) {
1421  struct target_gkv_info *gkvi;
1422  void *value;
1423  gpointer rval;
1424 
1425  if (g_hash_table_lookup_extended(target->gkv_store,key,
1426  NULL,&rval) == FALSE) {
1427  return NULL;
1428  }
1429  gkvi = (struct target_gkv_info *)rval;
1430 
1431  g_hash_table_remove(target->gkv_store,key);
1432  value = gkvi->value;
1433  free(gkvi);
1434 
1435  return value;
1436 }
1437 
1438 void target_gkv_remove(struct target *target,char *key) {
1439  struct target_gkv_info *gkvi;
1440  gpointer rval;
1441 
1442  if (g_hash_table_lookup_extended(target->gkv_store,key,
1443  NULL,&rval) == FALSE) {
1444  return;
1445  }
1446  gkvi = (struct target_gkv_info *)rval;
1447 
1448  g_hash_table_remove(target->gkv_store,key);
1449  if (gkvi->dtor)
1450  gkvi->dtor(target,key,gkvi->value);
1451  free(gkvi);
1452 
1453  return;
1454 }
1455 
1457  GHashTableIter iter;
1458  gpointer kp,vp;
1459  char *key;
1460  struct target_gkv_info *gkvi;
1461 
1462  if (!target->gkv_store)
1463  return;
1464 
1465  g_hash_table_iter_init(&iter,target->gkv_store);
1466  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
1467  gkvi = (struct target_gkv_info *)vp;
1468  key = (char *)kp;
1469  /*
1470  * Steal it so the key destructor (free()) isn't called before
1471  * we pass it to the dtor -- but so that the value is still not in
1472  * the hashtable.
1473  */
1474  g_hash_table_iter_steal(&iter);
1475  if (gkvi->dtor)
1476  gkvi->dtor(target,key,gkvi->value);
1477  free(key);
1478  free(gkvi);
1479  }
1480 
1481  g_hash_table_destroy(target->gkv_store);
1482  target->gkv_store = NULL;
1483 }
1484 
1486  void *value;
1489 };
1490 
1492  char *key,void *value,
1493  target_thread_gkv_dtor_t dtor) {
1494  struct target_thread_gkv_info *gkvi;
1495  struct target_thread *tthread;
1496 
1497  tthread = target_lookup_thread(target,tid);
1498  if (!tthread) {
1499  errno = ESRCH;
1500  verror("could not lookup thread %"PRIiTID"; forgot to load?\n",tid);
1501  return -1;
1502  }
1503 
1504  if (g_hash_table_lookup_extended(tthread->gkv_store,key,NULL,NULL) == TRUE) {
1505  errno = EEXIST;
1506  return -1;
1507  }
1508 
1509  gkvi = calloc(1,sizeof(*gkvi));
1510  gkvi->value = value;
1511  gkvi->tid = tid;
1512  gkvi->dtor = dtor;
1513 
1514  g_hash_table_insert(tthread->gkv_store,strdup(key),gkvi);
1515 
1516  return 0;
1517 }
1518 
1519 void *target_thread_gkv_lookup(struct target *target,tid_t tid,char *key) {
1520  struct target_thread_gkv_info *gkvi;
1521  struct target_thread *tthread;
1522 
1523  tthread = target_lookup_thread(target,tid);
1524  if (!tthread) {
1525  errno = ESRCH;
1526  verror("could not lookup thread %"PRIiTID"; forgot to load?\n",tid);
1527  return NULL;
1528  }
1529 
1530  if (!(gkvi = (struct target_thread_gkv_info *) \
1531  g_hash_table_lookup(tthread->gkv_store,key))) {
1532  return NULL;
1533  }
1534 
1535  return gkvi->value;
1536 }
1537 
1538 void *target_thread_gkv_steal(struct target *target,tid_t tid,char *key) {
1539  struct target_thread_gkv_info *gkvi;
1540  void *value;
1541  struct target_thread *tthread;
1542  gpointer rval;
1543 
1544  tthread = target_lookup_thread(target,tid);
1545  if (!tthread) {
1546  errno = ESRCH;
1547  verror("could not lookup thread %"PRIiTID"; forgot to load?\n",tid);
1548  return NULL;
1549  }
1550 
1551  if (g_hash_table_lookup_extended(tthread->gkv_store,key,
1552  NULL,&rval) == FALSE) {
1553  return NULL;
1554  }
1555  gkvi = (struct target_thread_gkv_info *)rval;
1556 
1557  g_hash_table_remove(tthread->gkv_store,key);
1558  value = gkvi->value;
1559  free(gkvi);
1560 
1561  return value;
1562 }
1563 
1565  struct target_thread_gkv_info *gkvi;
1566  struct target_thread *tthread;
1567  gpointer rval;
1568 
1569  tthread = target_lookup_thread(target,tid);
1570  if (!tthread) {
1571  errno = ESRCH;
1572  verror("could not lookup thread %"PRIiTID"; forgot to load?\n",tid);
1573  return;
1574  }
1575 
1576  if (g_hash_table_lookup_extended(tthread->gkv_store,key,
1577  NULL,&rval) == FALSE) {
1578  return;
1579  }
1580  gkvi = (struct target_thread_gkv_info *)rval;
1581 
1582  g_hash_table_remove(tthread->gkv_store,key);
1583  if (gkvi->dtor)
1584  gkvi->dtor(target,gkvi->tid,key,gkvi->value);
1585  free(gkvi);
1586 
1587  return;
1588 }
1589 
1591  struct target_thread *tthread) {
1592  GHashTableIter iter;
1593  gpointer kp,vp;
1594  char *key;
1595  struct target_thread_gkv_info *gkvi;
1596 
1597  if (!tthread->gkv_store)
1598  return;
1599 
1600  g_hash_table_iter_init(&iter,tthread->gkv_store);
1601  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
1602  gkvi = (struct target_thread_gkv_info *)vp;
1603  key = (char *)kp;
1604  /*
1605  * Steal it so the key destructor (free()) isn't called before
1606  * we pass it to the dtor -- but so that the value is still not in
1607  * the hashtable.
1608  */
1609  g_hash_table_iter_steal(&iter);
1610  if (gkvi->dtor)
1611  gkvi->dtor(target,gkvi->tid,key,gkvi->value);
1612  free(key);
1613  free(gkvi);
1614  }
1615 
1616  g_hash_table_destroy(tthread->gkv_store);
1617  tthread->gkv_store = NULL;
1618 }
1619 
1620 REFCNT target_free(struct target *target,int force) {
1621  struct addrspace *space;
1622  int rc;
1623  struct action *action;
1624  struct probe *probe;
1625  GList *list;
1626  GHashTableIter iter;
1627  struct target *overlay;
1628  char *tmpname;
1629  struct target_thread *tthread;
1630  REFCNT trefcnt;
1631  REFCNT retval;
1632  GList *t1,*t2;
1633 
1634  assert(target);
1635 
1636  if (target->refcnt) {
1637  if (!force) {
1638  verror("cannot free (%d refs) target %s\n",
1639  target->refcnt,target->name);
1640  return target->refcnt;
1641  }
1642  else {
1643  vwarn("forcing free (%d refs) target %s\n",
1644  target->refcnt,target->name);
1645  }
1646  }
1647 
1648  /* NB: take a temp ref so that any RPUTWs don't double-call; see common.h */
1649  RWGUARD(target);
1650 
1651  /*
1652  * Close target first. This will also close any overlays atop us.
1653  * NB: do this first to make sure all live state is closed, before
1654  * we free anything else.
1655  */
1656  if (target->opened) {
1658  "target(%s) not closed; closing first!\n",target->name);
1659  target_close(target);
1660  }
1661 
1662  vdebug(5,LA_TARGET,LF_TARGET,"freeing target(%s)\n",target->name);
1663 
1664  /*
1665  * Do it for all the overlays first. Since we might be calling
1666  * target_free either from the underlying target, or the user might
1667  * have called on this target directly (and this would result in
1668  * target_detach_overlay getting called on us), we need to protect
1669  * the iter while loop and restart it over and over again.
1670  */
1671  while (g_hash_table_size(target->overlays) > 0) {
1672  g_hash_table_iter_init(&iter,target->overlays);
1673  g_hash_table_iter_next(&iter,NULL,(gpointer)&overlay);
1674 
1675  tmpname = strdup(overlay->name);
1677  "detaching overlay target(%s)\n",tmpname);
1678  target_detach_overlay(target,overlay->base_tid);
1680  "detached overlay target(%s)\n",tmpname);
1681  free(tmpname);
1682  }
1683  g_hash_table_destroy(target->overlays);
1684  target->overlays = NULL;
1685  g_hash_table_destroy(target->overlay_aliases);
1686  target->overlay_aliases = NULL;
1687 
1688  /*
1689  * If we were an overlay, remove ourself from the underlying
1690  * target.
1691  */
1692  if (target->base) {
1693  target_detach_overlay(target->base,target->base_tid);
1694  RPUTW(target->base,target,target,trefcnt);
1695  target->base = NULL;
1696  if (target->base_thread) {
1697  RPUTW(target->base_thread,target_thread,target,trefcnt);
1698  target->base_thread = NULL;
1699  }
1700  target->base_tid = 0;
1701  }
1702 
1703  /*
1704  * Ok, now we can actually free the target data structures.
1705  */
1706 
1707  /*
1708  * Free actions, then probes, We cannot call probe_free/action_free
1709  * from a GHashTableIter, because those functions call our
1710  * target_detach_(action|probe) functions -- which remove the
1711  * action/probe from its hashtable. So we copy values to a temp
1712  * list to avoid this problem.
1713  *
1714  * BUT, we would then have to check each list item's addr to make
1715  * sure it is still in the hashtable; it might have been freed
1716  * already as a side effect -- i.e., freeing a top-level probe that
1717  * was a sink of an underlying probe could free the underlying probe
1718  * too. So, since our tmp list is values -- we cannot get a freed
1719  * probe's key to check the hashtable. So we have to iterate over
1720  * keys!
1721  */
1722  list = g_hash_table_get_values(target->actions);
1723  v_g_list_foreach(list,t1,action) {
1724  if (action)
1725  action_free(action,1);
1726  }
1727  g_list_free(list);
1728  g_hash_table_destroy(target->actions);
1729  target->actions = NULL;
1730 
1731  list = g_hash_table_get_values(target->probes);
1732  v_g_list_foreach(list,t1,probe) {
1733  if (probe)
1734  probe_free(probe,1);
1735  }
1736  g_hash_table_destroy(target->probes);
1737  target->probes = NULL;
1738  g_list_free(list);
1739 
1740  g_hash_table_destroy(target->soft_probepoints);
1741  target->soft_probepoints = NULL;
1742 
1743  /* These were freed when we closed the target. */
1744  g_hash_table_destroy(target->mmods);
1745  target->mmods = NULL;
1746  g_hash_table_destroy(target->phys_mmods);
1747  target->phys_mmods = NULL;
1748 
1749  /*
1750  * If the target backend didn't already do it,
1751  * delete all the threads except the global thread (which we remove
1752  * manually because targets are allowed to "reuse" one of their real
1753  * threads as the "global" thread.
1754  */
1755  list = g_hash_table_get_values(target->threads);
1756  v_g_list_foreach(list,t1,tthread) {
1757  target_detach_thread(target,tthread);
1758  }
1759  g_list_free(list);
1760  target->global_thread = NULL;
1761  target->current_thread = NULL;
1762 
1763  /* Unload the debugfiles we might hold, if we can */
1764  v_g_list_foreach_safe(target->spaces,t1,t2,space) {
1765  RPUT(space,addrspace,target,trefcnt);
1766  }
1767  g_list_free(target->spaces);
1768  target->spaces = NULL;
1769 
1770  /*
1771  * NB: must fini the personality in case it held refs to any of our
1772  * threads, or to the target itself.
1773  */
1774  if (target->personality_ops && target->personality_ops->fini) {
1775  vdebug(5,LA_TARGET,LF_TARGET,"fini target(%s) (personality)\n",
1776  target->name);
1777  if ((rc = target->personality_ops->fini(target))) {
1778  verror("fini target(%s) (personality) failed; continuing anyway!!\n",
1779  target->name);
1780  }
1781  }
1782 
1783  /*
1784  * Ok, now that we've removed our live state, and (attempted) to
1785  * remove our children, see if anything still holds a weak ref to
1786  * us. If not, continue!
1787  */
1788 
1789  if (target->refcntw) {
1790  if (!force) {
1791  verror("cannot free (%d wrefs) target %s\n",
1792  target->refcntw,target->name);
1793  return target->refcntw;
1794  }
1795  else {
1796  vwarn("forcing free (%d wrefs) target %s\n",
1797  target->refcntw,target->name);
1798  }
1799  }
1800 
1801  vdebug(5,LA_TARGET,LF_TARGET,"fini target(%s)\n",target->name);
1802  if ((rc = target->ops->fini(target))) {
1803  verror("fini target(%s) failed; continuing anyway!\n",target->name);
1804  }
1805 
1806  target_gkv_destroy(target);
1807 
1808  g_hash_table_destroy(target->threads);
1809  target->threads = NULL;
1810 
1811  g_hash_table_destroy(target->config);
1812  target->config = NULL;
1813 
1814  /* Unload the binfile */
1815  if (target->binfile) {
1816  binfile_release(target->binfile);
1817  target->binfile = NULL;
1818  }
1819 
1820  if (target->name) {
1821  free(target->name);
1822  target->name = NULL;
1823  }
1824 
1825  retval = target->refcnt + target->refcntw - 1;
1826 
1827  free(target);
1828 
1829  return retval;
1830 }
1831 
1833  if (target_type == TARGET_TYPE_PTRACE)
1835 #ifdef ENABLE_XENSUPPORT
1836  else if (target_type == TARGET_TYPE_XEN)
1837  return &xen_vm_ops;
1838 #endif
1839  else if (target_type == TARGET_TYPE_OS_PROCESS)
1840  return &os_process_ops;
1841  else if (target_type == TARGET_TYPE_PHP)
1842  return &php_ops;
1843  else if (target_type == TARGET_TYPE_GDB)
1844  return &gdb_ops;
1845  else
1846  return NULL;
1847 }
1848 
1849 struct target *target_create(char *type,struct target_spec *spec) {
1850  struct target_ops *ops;
1851  struct target *retval;
1852 
1853  ops = target_get_ops(spec->target_type);
1854  if (!ops) {
1855  verror("could not find target_ops for target type %d!\n",
1856  spec->target_type);
1857  errno = EINVAL;
1858  return NULL;
1859  }
1860 
1861  retval = calloc(1,sizeof(*retval));
1862 
1863  if (spec->target_id < 0)
1864  retval->id = next_target_id++;
1865  else {
1866  if (target_id_tab
1867  && g_hash_table_lookup(target_id_tab,
1868  (gpointer)(uintptr_t)spec->target_id)) {
1869  verror("target with id %d already exists!\n",spec->target_id);
1870  free(retval);
1871  errno = EINVAL;
1872  return NULL;
1873  }
1874  retval->id = spec->target_id;
1875  }
1876 
1877  retval->ops = ops;
1878  retval->spec = spec;
1879 
1880  retval->infd = retval->outfd = retval->errfd = -1;
1881 
1882  retval->config = g_hash_table_new_full(g_str_hash,g_str_equal,free,free);
1883 
1884  /* Keys are always copied; values get user-custom dtors */
1885  retval->gkv_store = g_hash_table_new_full(g_str_hash,g_str_equal,free,NULL);
1886 
1887  retval->code_ranges = clrange_create();
1888 
1889  retval->overlays = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1890  NULL,NULL);
1891  retval->overlay_aliases = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1892  NULL,NULL);
1893 
1894  retval->threads = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1895  /* No names to free! */
1896  NULL,NULL);
1897 
1898  retval->actions = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1899  NULL,NULL);
1900  retval->probes = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1901  NULL,NULL);
1902  retval->action_id_counter = 1;
1903  retval->probe_id_counter = 1;
1904 
1905  retval->soft_probepoints = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1906  NULL,NULL);
1907 
1908  retval->mmods = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
1909 
1910  retval->phys_mmods = g_hash_table_new_full(g_direct_hash,g_direct_equal,
1911  NULL,NULL);
1912 
1913  //*(((gint *)retval->soft_probepoints)+1) = 1;
1914  //*(((gint *)retval->soft_probepoints)) = 0;
1915 
1916  if (target_id_tab) {
1917  g_hash_table_insert(target_id_tab,
1918  (gpointer)(uintptr_t)retval->id,retval);
1919  RHOLD(retval,target_id_tab);
1920  }
1921 
1922  return retval;
1923 }
1924 
1926  REFCNT trefcnt;
1927 
1928  /*
1929  * If we were an overlay, remove ourself from the underlying
1930  * target.
1931  */
1932  if (target->base) {
1933  target_detach_overlay(target->base,target->base_tid);
1934  RPUTW(target->base,target,target,trefcnt);
1935  target->base = NULL;
1936  if (target->base_thread) {
1937  RPUTW(target->base_thread,target_thread,target,trefcnt);
1938  target->base_thread = NULL;
1939  }
1940  target->base_tid = 0;
1941  }
1942 
1943  if (!target_id_tab) {
1944  errno = EINVAL;
1945  return -1;
1946  }
1947 
1948  if (g_hash_table_lookup(target_id_tab,(gpointer)(uintptr_t)target->id)
1949  != target) {
1950  errno = ESRCH;
1951  return -1;
1952  }
1953 
1954  g_hash_table_remove(target_id_tab,(gpointer)(uintptr_t)target->id);
1955  RPUT(target,target,target_id_tab,trefcnt);
1956 
1957  return 0;
1958 }
1959 
1960 /*
1961  * A utility function that loads a debugfile with the given opts.
1962  */
1964  struct memregion *region,
1965  struct debugfile *debugfile) {
1966 
1967  /* if they already loaded this debugfile into this region, error */
1968  if (g_hash_table_lookup(region->debugfiles,debugfile->filename)) {
1969  verror("debugfile(%s) already in use in region(%s) in space (%s:0x%"PRIxADDR")!\n",
1970  debugfile->filename,region->name,region->space->name,region->space->tag);
1971  errno = EBUSY;
1972  return -1;
1973  }
1974 
1975  RHOLD(debugfile,region);
1976 
1977  g_hash_table_insert(region->debugfiles,debugfile->filename,debugfile);
1978 
1980  "loaded and associated debugfile(%s) for region(%s,"
1981  "base_phys=0x%"PRIxADDR",base_virt=0x%"PRIxADDR")"
1982  " in space (%s:0x%PRIxADDR)\n",
1983  debugfile->filename,region->name,
1984  region->base_phys_addr,region->base_virt_addr,
1985  region->space->name,region->space->name,region->space->tag);
1986 
1987  return 0;
1988 }
1989 
1991  GList *t1,*t2;
1992  struct addrspace *space;
1993  struct memregion *region;
1994  GHashTableIter iter;
1995  gpointer key;
1996  struct debugfile *debugfile;
1997  struct memrange *range;
1998 
1999  if (!target->spaces)
2000  return NULL;
2001 
2003  "trying to find debugfile for address 0x%"PRIxADDR"\n",addr);
2004 
2005  v_g_list_foreach(target->spaces,t1,space) {
2006  v_g_list_foreach(space->regions,t2,region) {
2007  if ((range = memregion_find_range_real(region,addr)))
2008  goto found;
2009  }
2010  }
2011 
2012  return NULL;
2013 
2014  found:
2015  g_hash_table_iter_init(&iter,region->debugfiles);
2016  while (g_hash_table_iter_next(&iter,
2017  (gpointer)&key,(gpointer)&debugfile))
2018  return debugfile;
2019 
2020  return NULL;
2021 }
2022 
2023 struct scope *target_lookup_addr(struct target *target,uint64_t addr) {
2024  GList *t1,*t2;
2025  struct addrspace *space;
2026  struct memregion *region;
2027  struct symbol *root;
2028  struct scope *scope;
2029  GHashTableIter iter, iter2;
2030  gpointer value;
2031  ADDR obj_addr;
2032 
2033  v_g_list_foreach(target->spaces,t1,space) {
2034  v_g_list_foreach(space->regions,t2,region) {
2035  if (memregion_contains_real(region,addr))
2036  goto found;
2037  }
2038  }
2039 
2040  return NULL;
2041 
2042  found:
2043  errno = 0;
2044  obj_addr = memregion_unrelocate(region,addr,NULL);
2045  if (errno) {
2046  return NULL;
2047  }
2048  g_hash_table_iter_init(&iter,region->debugfiles);
2049  while (g_hash_table_iter_next(&iter,NULL,&value)) {
2050  g_hash_table_iter_init(&iter2,((struct debugfile *)value)->srcfiles);
2051  while (g_hash_table_iter_next(&iter2,NULL,(gpointer *)&root)) {
2052  scope = symbol_read_owned_scope(root);
2053  if (scope)
2054  scope = scope_lookup_addr(scope,obj_addr);
2055  if (scope)
2056  return scope;
2057  }
2058  }
2059 
2060  return NULL;
2061 }
2062 
2064  GList *t1,*t2;
2065  struct addrspace *space;
2066  struct memregion *region;
2067  GHashTableIter iter;
2068  gpointer key;
2069  struct debugfile *debugfile;
2070  struct bsymbol *bsymbol;
2071  struct lsymbol *lsymbol;
2072  struct memrange *range;
2073 
2075  "trying to find symbol at address 0x%"PRIxADDR"\n",
2076  addr);
2077 
2078  v_g_list_foreach(target->spaces,t1,space) {
2079  v_g_list_foreach(space->regions,t2,region) {
2080  if ((range = memregion_find_range_real(region,addr)))
2081  goto found;
2082  }
2083  }
2084 
2085  return NULL;
2086 
2087  found:
2088  g_hash_table_iter_init(&iter,region->debugfiles);
2089  while (g_hash_table_iter_next(&iter,
2090  (gpointer)&key,(gpointer)&debugfile)) {
2091  if ((lsymbol = debugfile_lookup_addr__int(debugfile,
2092  memrange_unrelocate(range,addr)))) {
2093  bsymbol = bsymbol_create(lsymbol,region);
2094  /* Take a ref to bsymbol on the user's behalf, since this is
2095  * a lookup function.
2096  */
2097  RHOLD(bsymbol,bsymbol);
2098  return bsymbol;
2099  }
2100  }
2101 
2102  return NULL;
2103 }
2104 
2106  struct bsymbol **primary,struct bsymbol **alt) {
2107  struct addrspace *space;
2108  struct memregion *region;
2109  GHashTableIter iter;
2110  gpointer key;
2111  struct debugfile *debugfile;
2112  struct bsymbol *bsymbol;
2113  struct lsymbol *primary_ls,*alt_ls;
2114  struct memrange *range;
2115  GList *t1,*t2;
2116 
2117  if (!target->spaces)
2118  return -1;
2119 
2121  "trying to find symbol at address 0x%"PRIxADDR"\n",
2122  addr);
2123 
2124  v_g_list_foreach(target->spaces,t1,space) {
2125  v_g_list_foreach(space->regions,t2,region) {
2126  if ((range = memregion_find_range_real(region,addr)))
2127  goto found;
2128  }
2129  }
2130 
2131  return -1;
2132 
2133  found:
2134  g_hash_table_iter_init(&iter,region->debugfiles);
2135  while (g_hash_table_iter_next(&iter,
2136  (gpointer)&key,(gpointer)&debugfile)) {
2137  primary_ls = alt_ls = NULL;
2138 
2139  if (debugfile_lookup_addr_alt__int(debugfile,
2140  memrange_unrelocate(range,addr),
2141  (primary) ? &primary_ls : NULL,
2142  (alt) ? &alt_ls : NULL))
2143  continue;
2144 
2145  if (primary_ls) {
2146  bsymbol = bsymbol_create(primary_ls,region);
2147  /* Take a ref to bsymbol on the user's behalf, since this is
2148  * a lookup function.
2149  */
2150  RHOLD(bsymbol,bsymbol);
2151  *primary = bsymbol;
2152  }
2153 
2154  if (alt_ls) {
2155  bsymbol = bsymbol_create(alt_ls,region);
2156  /* Take a ref to bsymbol on the user's behalf, since this is
2157  * a lookup function.
2158  */
2159  RHOLD(bsymbol,bsymbol);
2160  *alt = bsymbol;
2161  }
2162 
2163  return 0;
2164  }
2165 
2166  return -1;
2167 }
2168 
2170  const char *name,const char *delim,
2171  char *srcfile,symbol_type_flag_t ftype) {
2172  GList *t1,*t2;
2173  struct addrspace *space;
2174  struct bsymbol *bsymbol;
2175  struct lsymbol *lsymbol = NULL;
2176  struct memregion *region;
2177  struct debugfile *debugfile;
2178  GHashTableIter iter;
2179  gpointer key;
2180  struct rfilter *rf = NULL;
2181 
2182  if (!target->spaces)
2183  return NULL;
2184 
2185  if (srcfile) {
2186  rf = rfilter_create(RF_REJECT);
2187  rfilter_add(rf,srcfile,RF_ACCEPT,NULL);
2188  }
2189 
2190  v_g_list_foreach(target->spaces,t1,space) {
2191  v_g_list_foreach(space->regions,t2,region) {
2192  g_hash_table_iter_init(&iter,region->debugfiles);
2193  while (g_hash_table_iter_next(&iter,(gpointer)&key,
2194  (gpointer)&debugfile)) {
2195  lsymbol = debugfile_lookup_sym__int(debugfile,(char *)name,
2196  delim,rf,ftype);
2197  if (lsymbol)
2198  goto out;
2199  }
2200  }
2201  }
2202  if (rf)
2203  rfilter_free(rf);
2204  return NULL;
2205 
2206  out:
2207  bsymbol = bsymbol_create(lsymbol,region);
2208  /* Take a ref to bsymbol on the user's behalf, since this is
2209  * a lookup function.
2210  */
2211  RHOLD(bsymbol,bsymbol);
2212 
2213  if (rf)
2214  rfilter_free(rf);
2215  return bsymbol;
2216 }
2217 
2219  struct bsymbol *bsymbol,
2220  const char *name,const char *delim) {
2221  struct bsymbol *bsymbol_new;
2222  struct lsymbol *lsymbol;
2223 
2224  lsymbol = lsymbol_lookup_sym__int(bsymbol->lsymbol,name,delim);
2225  if (!lsymbol)
2226  return NULL;
2227 
2228  bsymbol_new = bsymbol_create(lsymbol,bsymbol->region);
2229  /* Take a ref to bsymbol_new on the user's behalf, since this is
2230  * a lookup function.
2231  */
2232  RHOLD(bsymbol_new,bsymbol_new);
2233 
2234  return bsymbol_new;
2235 }
2236 
2238  char *filename,int line,
2239  SMOFFSET *offset,ADDR *addr) {
2240  GList *t1,*t2;
2241  struct addrspace *space;
2242  struct bsymbol *bsymbol;
2243  struct lsymbol *lsymbol = NULL;
2244  struct memregion *region;
2245  struct debugfile *debugfile;
2246  GHashTableIter iter;
2247  gpointer key;
2248  ADDR taddr;
2249  SMOFFSET toffset;
2250 
2251  if (!target->spaces)
2252  return NULL;
2253 
2254  v_g_list_foreach(target->spaces,t1,space) {
2255  v_g_list_foreach(space->regions,t2,region) {
2256  g_hash_table_iter_init(&iter,region->debugfiles);
2257  while (g_hash_table_iter_next(&iter,(gpointer)&key,
2258  (gpointer)&debugfile)) {
2259  lsymbol = debugfile_lookup_sym_line__int(debugfile,filename,line,
2260  &toffset,&taddr);
2261  if (lsymbol)
2262  goto out;
2263  }
2264  }
2265  }
2266  return NULL;
2267 
2268  out:
2269  errno = 0;
2270  taddr = memregion_relocate(region,taddr,NULL);
2271  if (errno) {
2272  verror("could not relocate obj addr 0x%"PRIxADDR"!\n",taddr);
2273  lsymbol_release(lsymbol);
2274  return NULL;
2275  }
2276  bsymbol = bsymbol_create(lsymbol,region);
2277  /* Take a ref to bsymbol on the user's behalf, since this is
2278  * a lookup function.
2279  */
2280  RHOLD(bsymbol,bsymbol);
2281  if (offset)
2282  *offset = toffset;
2283  if (addr)
2284  *addr = taddr;
2285 
2286  return bsymbol;
2287 }
2288 
2289 int target_lookup_line_addr(struct target *target,char *srcfile,ADDR addr) {
2290  GList *t1,*t2;
2291  struct addrspace *space;
2292  struct memregion *region;
2293  GHashTableIter iter;
2294  gpointer key;
2295  struct debugfile *debugfile;
2296  struct memrange *range;
2297  int line = -1;
2298 
2299  if (!target->spaces)
2300  return -1;
2301 
2303  "trying to find line for address 0x%"PRIxADDR"\n",
2304  addr);
2305 
2306  v_g_list_foreach(target->spaces,t1,space) {
2307  v_g_list_foreach(space->regions,t2,region) {
2308  if ((range = memregion_find_range_real(region,addr)))
2309  goto found;
2310  }
2311  }
2312 
2313  return -1;
2314 
2315  found:
2316  g_hash_table_iter_init(&iter,region->debugfiles);
2317  while (g_hash_table_iter_next(&iter,
2318  (gpointer)&key,(gpointer)&debugfile)) {
2319  line = debugfile_lookup_line_addr(debugfile,srcfile,
2320  memrange_unrelocate(range,addr));
2321  if (line)
2322  return line;
2323  }
2324 
2325  return -1;
2326 }
2327 
2329  ADDR addr,char **filename,int *line) {
2330  struct addrspace *space;
2331  struct memregion *region;
2332  GHashTableIter iter;
2333  gpointer key;
2334  struct debugfile *debugfile;
2335  struct memrange *range;
2336  int rline = -1;
2337  GList *t1,*t2;
2338 
2339  if (!target->spaces)
2340  return -1;
2341 
2343  "trying to find line for address 0x%"PRIxADDR"\n",
2344  addr);
2345 
2346  v_g_list_foreach(target->spaces,t1,space) {
2347  v_g_list_foreach(space->regions,t2,region) {
2348  if ((range = memregion_find_range_real(region,addr)))
2349  goto found;
2350  }
2351  }
2352 
2353  return -1;
2354 
2355  found:
2356  g_hash_table_iter_init(&iter,region->debugfiles);
2357  while (g_hash_table_iter_next(&iter,
2358  (gpointer)&key,(gpointer)&debugfile)) {
2359  rline = debugfile_lookup_filename_line_addr(debugfile,
2360  memrange_unrelocate(range,addr),
2361  filename,line);
2362  if (rline > 0)
2363  return rline;
2364  }
2365 
2366  return -1;
2367 }
2368 
2369 /*
2370  * Thin wrappers around [l]symbol_resolve_bounds[_alt].
2371  */
2373  struct target_location_ctxt *tlctxt,
2374  struct symbol *symbol,
2375  ADDR *start,ADDR *end,int *is_noncontiguous,
2376  ADDR *alt_start,ADDR *alt_end) {
2377  if (!tlctxt) {
2378  errno = EINVAL;
2379  verror("must supply a context (tid,region) for raw symbol resolution!\n");
2380  return -1;
2381  }
2382 
2383  return symbol_resolve_bounds(symbol,tlctxt->lctxt,
2384  start,end,is_noncontiguous,alt_start,alt_end);
2385 }
2386 
2388  struct target_location_ctxt *tlctxt,
2389  struct lsymbol *lsymbol,ADDR base_addr,
2390  ADDR *start,ADDR *end,int *is_noncontiguous,
2391  ADDR *alt_start,ADDR *alt_end) {
2392  if (!tlctxt) {
2393  errno = EINVAL;
2394  verror("must supply a context (tid,region) for raw lsymbol resolution!\n");
2395  return -1;
2396  }
2397 
2398  return lsymbol_resolve_bounds(lsymbol,base_addr,tlctxt->lctxt,
2399  start,end,is_noncontiguous,alt_start,alt_end);
2400 }
2401 
2403  struct target_location_ctxt *tlctxt,
2404  struct bsymbol *bsymbol,ADDR base_addr,
2405  ADDR *start,ADDR *end,int *is_noncontiguous,
2406  ADDR *alt_start,ADDR *alt_end) {
2407  if (!tlctxt) {
2408  errno = EINVAL;
2409  verror("must supply a context (tid,region) for bsymbol resolution!\n");
2410  return -1;
2411  }
2412 
2413  return lsymbol_resolve_bounds(bsymbol->lsymbol,base_addr,tlctxt->lctxt,
2414  start,end,is_noncontiguous,alt_start,alt_end);
2415 }
2416 
2417 /*
2418  * This is a thin wrapper around lsymbol_resolve_location that handles
2419  * the load_flags_t in flags.
2420  */
2422  struct target_location_ctxt *tlctxt,
2423  struct lsymbol *lsymbol,
2424  ADDR base_addr,
2425  load_flags_t flags,
2426  struct location *o_loc,
2427  struct symbol **o_datatype,
2428  struct memrange **o_range) {
2429  loctype_t rc;
2430  tid_t tid;
2431  ADDR addr;
2432  REG reg;
2433  struct symbol *symbol;
2434  struct symbol *datatype;
2435  struct memrange *range = NULL;
2436  struct location tloc;
2437 
2438  if (!tlctxt) {
2439  errno = EINVAL;
2440  verror("must supply a context (tid,region) for raw lsymbol resolution!\n");
2441  return LOCTYPE_UNKNOWN;
2442  }
2443 
2444  tid = tlctxt->thread->tid;
2445 
2446  memset(&tloc,0,sizeof(tloc));
2447  rc = lsymbol_resolve_location(lsymbol,base_addr,tlctxt->lctxt,&tloc);
2448  if (rc == LOCTYPE_ADDR) {
2449  /* Grab the range. */
2450  addr = LOCATION_ADDR(&tloc);
2451  if (!target_find_memory_real(target,addr,NULL,NULL,&range)) {
2452  verror("could not find memory for 0x%"PRIxADDR
2453  " for symbol %s: %s!\n",
2454  addr,lsymbol_get_name(lsymbol),strerror(errno));
2455  errno = ERANGE;
2456  goto errout;
2457  }
2458  }
2459  else if (rc <= LOCTYPE_UNKNOWN) {
2461  "failed to resolve location type %s (%d)!\n",LOCTYPE(-rc),rc);
2462  goto errout;
2463  }
2464 
2465  symbol = lsymbol_last_symbol(lsymbol);
2466  datatype = symbol_get_datatype(symbol);
2467  if (datatype)
2468  datatype = symbol_type_skip_qualifiers(datatype);
2469 
2470  again:
2471  if (datatype && SYMBOL_IST_PTR(datatype)
2472  && ((flags & LOAD_FLAG_AUTO_DEREF)
2473  || (flags & LOAD_FLAG_AUTO_STRING
2474  && symbol_type_is_char(symbol_type_skip_ptrs(datatype))))) {
2475 
2476  if (rc == LOCTYPE_REG) {
2477  reg = LOCATION_REG(&tloc);
2478  /*
2479  * Try to load the ptr value from a register; might or might
2480  * not be an address; only is if the current symbol was a
2481  * pointer; we handle that below. There's a termination
2482  * condition below this loop that if we end after having
2483  * resolved the location to a register, we can't calculate
2484  * the address for it.
2485  */
2486  addr = target_read_reg(target,tid,reg);
2487  if (errno) {
2488  verror("could not read reg %"PRIiREG" that ptr symbol %s"
2489  " resolved to: %s!\n",
2490  reg,symbol_get_name(symbol),strerror(errno));
2491  goto errout;
2492  }
2493 
2494  /* We might have changed ranges... */
2495  if (!target_find_memory_real(target,addr,NULL,NULL,&range)) {
2497  "could not find memory for 0x%"PRIxADDR
2498  " for symbol %s: %s!\n",
2499  addr,symbol_get_name(symbol),strerror(errno));
2500  goto errout;
2501  }
2502 
2504  "ptr var (in reg) %s = 0x%"PRIxADDR"\n",
2505  symbol_get_name(symbol),addr);
2506 
2507  /* We have to skip one pointer type */
2508  datatype = symbol_get_datatype(datatype);
2509 
2510  /*
2511  * Set loctype to be an addr, since we autoloaded the pointer!
2512  */
2513  rc = LOCTYPE_ADDR;
2514 
2515  /* Do we need to keep trying to load through the pointer? */
2516  goto again;
2517  }
2518  else if (rc == LOCTYPE_IMPLICIT_WORD) {
2519  verror("unexpected implicit value instead of pointer!\n");
2520  errno = EINVAL;
2521  goto errout;
2522  }
2523  else if (rc == LOCTYPE_ADDR) {
2524  addr = target_autoload_pointers(target,datatype,addr,
2525  flags,&datatype,&range);
2526  if (errno) {
2527  verror("could not load pointer for symbol %s\n",
2528  symbol_get_name(symbol));
2529  goto errout;
2530  }
2531 
2533  "autoloaded pointer(s) for var %s = 0x%"PRIxADDR"\n",
2534  symbol_get_name(symbol),addr);
2535 
2536  /* We might have changed ranges... */
2537  if (!target_find_memory_real(target,addr,NULL,NULL,&range)) {
2539  "could not find memory for 0x%"PRIxADDR
2540  " for symbol %s: %s!\n",
2541  addr,symbol_get_name(symbol),strerror(errno));
2542  goto errout;
2543  }
2544  }
2545  else {
2546  verror("unexpected location type %s for pointer!\n",
2547  LOCTYPE(rc));
2548  errno = EINVAL;
2549  goto errout;
2550  }
2551  }
2552 
2553  /* Return! */
2554  if (rc == LOCTYPE_ADDR) {
2555  if (o_loc)
2556  location_set_addr(o_loc,addr);
2557  if (o_range)
2558  *o_range = range;
2559  if (o_datatype)
2560  *o_datatype = datatype;
2561  }
2562  else if (rc == LOCTYPE_REG) {
2563  if (o_loc)
2564  location_set_reg(o_loc,LOCATION_REG(&tloc));
2565  if (o_datatype)
2566  *o_datatype = datatype;
2567  }
2568  else if (rc == LOCTYPE_IMPLICIT_WORD) {
2569  if (o_loc)
2571  if (o_datatype)
2572  *o_datatype = datatype;
2573  }
2574 
2575  location_internal_free(&tloc);
2576  return rc;
2577 
2578  errout:
2579  location_internal_free(&tloc);
2580  return rc;
2581 }
2582 
2584  struct target_location_ctxt *tlctxt,
2585  struct bsymbol *bsymbol,ADDR *o_addr,
2586  struct memrange **o_range) {
2587  loctype_t rc;
2588  struct location tloc;
2589  int retval;
2590 
2591  if (!tlctxt) {
2592  errno = EINVAL;
2593  verror("must supply a context (tid,region) for bsymbol resolution!\n");
2594  return LOCTYPE_UNKNOWN;
2595  }
2596 
2597  memset(&tloc,0,sizeof(tloc));
2598  rc = target_lsymbol_resolve_location(target,tlctxt,bsymbol->lsymbol,0,
2599  LOAD_FLAG_NONE,&tloc,NULL,o_range);
2600  if (rc != LOCTYPE_ADDR) {
2602  "could not resolve base for symbol %s: %s (%d)\n",
2603  lsymbol_get_name(bsymbol->lsymbol),strerror(errno),rc);
2604  location_internal_free(&tloc);
2605  retval = -1;
2606  goto errout;
2607  }
2608 
2609  retval = 0;
2610  if (o_addr)
2611  *o_addr = LOCATION_ADDR(&tloc);
2612 
2613  errout:
2614  location_internal_free(&tloc);
2615  return retval;
2616 }
2617 
2618 struct value *target_load_type(struct target *target,struct symbol *type,
2619  ADDR addr,load_flags_t flags) {
2620  struct symbol *datatype = type;
2621  struct value *value;
2622  struct memrange *range;
2623  ADDR ptraddr;
2624 
2625  datatype = symbol_type_skip_qualifiers(type);
2626 
2627  if (!SYMBOL_IS_TYPE(datatype)) {
2628  verror("symbol %s is not a full type (is %s)!\n",
2629  symbol_get_name(type),SYMBOL_TYPE(type->type));
2630  errno = EINVAL;
2631  return NULL;
2632  }
2633 
2634  if (datatype != type)
2635  vdebug(9,LA_TARGET,LF_TSYMBOL,"skipped from %s to %s for type %s\n",
2636  DATATYPE(type->datatype_code),
2637  DATATYPE(datatype->datatype_code),symbol_get_name(type));
2638  else
2639  vdebug(9,LA_TARGET,LF_TSYMBOL,"no skip; type for type %s is %s\n",
2640  symbol_get_name(type),DATATYPE(datatype->datatype_code));
2641 
2642  /* Get range/region info for the addr. */
2643  if (!target_find_memory_real(target,addr,NULL,NULL,&range)) {
2644  verror("could not find range for addr 0x%"PRIxADDR"!\n",addr);
2645  errno = EFAULT;
2646  return NULL;
2647  }
2648 
2649  /* If they want pointers automatically dereferenced, do it! */
2650  errno = 0;
2651  ptraddr = target_autoload_pointers(target,datatype,addr,flags,
2652  &datatype,&range);
2653  if (errno) {
2654  verror("failed to autoload pointers for type %s at addr 0x%"PRIxADDR"\n",
2655  symbol_get_name(type),addr);
2656  return NULL;
2657  }
2658 
2659  if (!ptraddr) {
2660  verror("last pointer was NULL!\n");
2661  errno = EFAULT;
2662  return NULL;
2663  }
2664 
2665  /*
2666  * Now allocate the value struct for various cases and return.
2667  */
2668 
2669  /* If we're autoloading pointers and we want to load char * pointers
2670  * as strings, do it!
2671  */
2672  if (ptraddr != addr
2673  && flags & LOAD_FLAG_AUTO_STRING
2674  && symbol_type_is_char(datatype)) {
2675  /* XXX: should we use datatype, or the last pointer to datatype? */
2676  value = value_create_noalloc(NULL,range,NULL,datatype);
2677  if (!value) {
2678  verror("could not create value: %s\n",strerror(errno));
2679  goto errout;
2680  }
2681 
2682  if (!(value->buf = (char *)__target_load_addr_real(target,range,
2683  ptraddr,flags,
2684  NULL,0))) {
2685  verror("failed to autoload char * for type %s at addr 0x%"PRIxADDR"\n",
2686  symbol_get_name(type),addr);
2687  goto errout;
2688  }
2689  value_set_strlen(value,strlen(value->buf) + 1);
2690  value_set_addr(value,ptraddr);
2691 
2693  "autoloaded char * with len %d\n",value->bufsiz);
2694 
2695  /* success! */
2696  goto out;
2697  }
2698  else {
2699  value = value_create_type(NULL,range,datatype);
2700  if (!value) {
2701  verror("could not create value for type (ptr is %p) %s\n",
2702  datatype,datatype ? datatype->name : NULL);
2703  goto errout;
2704  }
2705 
2706  if (!__target_load_addr_real(target,range,ptraddr,flags,
2707  (unsigned char *)value->buf,
2708  value->bufsiz)) {
2709  verror("could not load addr 0x%"PRIxADDR"!\n",ptraddr);
2710  goto errout;
2711  }
2712 
2713  value_set_addr(value,ptraddr);
2714  }
2715 
2716  out:
2717  return value;
2718 
2719  errout:
2720  if (value)
2721  value_free(value);
2722 
2723  return NULL;
2724 
2725 }
2726 
2728  tid_t tid,REG reg,REGVAL regval,
2729  load_flags_t flags) {
2730  struct symbol *datatype;
2731  struct value *value;
2732  struct memrange *range;
2733  ADDR ptraddr;
2734  size_t sz;
2735  struct target_thread *tthread;
2736 
2737  tthread = target_lookup_thread(target,tid);
2738  if (!tthread) {
2739  errno = EINVAL;
2740  verror("could not lookup thread %"PRIiTID"; forgot to load?\n",tid);
2741  return NULL;
2742  }
2743 
2744  datatype = symbol_type_skip_qualifiers(type);
2745 
2746  if (!SYMBOL_IS_TYPE(datatype)) {
2747  verror("symbol %s is not a full type (is %s)!\n",
2748  symbol_get_name(type),SYMBOL_TYPE(type->type));
2749  errno = EINVAL;
2750  return NULL;
2751  }
2752 
2753  if (datatype != type)
2754  vdebug(9,LA_TARGET,LF_TSYMBOL,"skipped from %s to %s for type %s\n",
2755  DATATYPE(type->datatype_code),
2756  DATATYPE(datatype->datatype_code),symbol_get_name(type));
2757  else
2758  vdebug(9,LA_TARGET,LF_TSYMBOL,"no skip; type for type %s is %s\n",
2759  symbol_get_name(type),DATATYPE(datatype->datatype_code));
2760 
2761  /*
2762  * If the user wants pointers deref'd, get range/region info for the
2763  * regval, and deref.
2764  */
2765  if (((flags & LOAD_FLAG_AUTO_DEREF) && SYMBOL_IST_PTR(datatype))
2766  || ((flags & LOAD_FLAG_AUTO_STRING)
2767  && SYMBOL_IST_PTR(datatype)
2768  && symbol_type_is_char(symbol_type_skip_ptrs(datatype)))) {
2769  if (!target_find_memory_real(target,regval,NULL,NULL,&range)) {
2770  verror("could not find range for regval addr 0x%"PRIxADDR"\n!",
2771  regval);
2772  errno = EFAULT;
2773  return NULL;
2774  }
2775  /* If they want pointers automatically dereferenced, do it! */
2776  errno = 0;
2777  ptraddr = target_autoload_pointers(target,datatype,regval,flags,
2778  &datatype,&range);
2779  if (errno) {
2780  verror("failed to autoload pointers for type %s"
2781  " at regval addr 0x%"PRIxADDR"\n",
2782  symbol_get_name(type),regval);
2783  return NULL;
2784  }
2785 
2786  if (!ptraddr) {
2787  verror("last pointer was NULL!\n");
2788  errno = EFAULT;
2789  return NULL;
2790  }
2791  }
2792  else {
2793  range = NULL;
2794  ptraddr = 0;
2795  }
2796 
2797  /*
2798  * Now allocate the value struct for various cases and return.
2799  */
2800 
2801  /*
2802  * If we're autoloading pointers and we want to load char * pointers
2803  * as strings, do it!
2804  */
2805  if (ptraddr
2806  && (flags & LOAD_FLAG_AUTO_STRING)
2807  && symbol_type_is_char(datatype)) {
2808  /* XXX: should we use datatype, or the last pointer to datatype? */
2809  value = value_create_noalloc(tthread,range,NULL,datatype);
2810  if (!value) {
2811  verror("could not create value: %s\n",strerror(errno));
2812  goto errout;
2813  }
2814 
2815  if (!(value->buf = (char *) \
2816  __target_load_addr_real(target,range,ptraddr,flags,NULL,0))) {
2817  verror("failed to autoload char * for type %s"
2818  " at regval ptr addr 0x%"PRIxADDR"\n",
2819  symbol_get_name(type),ptraddr);
2820  goto errout;
2821  }
2822  value_set_strlen(value,strlen(value->buf) + 1);
2823  value_set_addr(value,ptraddr);
2824 
2826  "autoloaded char * with len %d\n",value->bufsiz);
2827 
2828  /* success! */
2829  goto out;
2830  }
2831  else if (ptraddr) {
2832  value = value_create_type(tthread,range,datatype);
2833  if (!value) {
2834  verror("could not create value for type (ptr is %p) %s\n",
2835  datatype,datatype ? datatype->name : NULL);
2836  goto errout;
2837  }
2838 
2839  if (!__target_load_addr_real(target,range,ptraddr,flags,
2840  (unsigned char *)value->buf,
2841  value->bufsiz)) {
2842  verror("could not load addr 0x%"PRIxADDR"!\n",ptraddr);
2843  goto errout;
2844  }
2845 
2846  value_set_addr(value,ptraddr);
2847  }
2848  else {
2849  value = value_create_type(tthread,NULL,datatype);
2850  if (!value) {
2851  verror("could not create value for type (ptr is %p) %s\n",
2852  datatype,datatype ? datatype->name : NULL);
2853  goto errout;
2854  }
2855 
2856  if (value->bufsiz > (int)sizeof(REGVAL))
2857  sz = sizeof(REGVAL);
2858  else
2859  sz = value->bufsiz;
2860  memcpy(value->buf,&regval,sz);
2861 
2862  value_set_reg(value,reg);
2863  }
2864 
2865  out:
2866  return value;
2867 
2868  errout:
2869  if (value)
2870  value_free(value);
2871 
2872  return NULL;
2873 }
2874 
2876  tid_t tid,REG reg,load_flags_t flags) {
2877  REGVAL regval;
2878 
2879  errno = 0;
2880  regval = target_read_reg(target,tid,reg);
2881 
2882  return target_load_type_regval(target,type,tid,reg,regval,flags);
2883 }
2884 
2886  struct target_location_ctxt *tlctxt,
2887  struct bsymbol *bsymbol,
2888  const char *member,const char *delim,
2889  load_flags_t flags) {
2890  struct bsymbol *bmember;
2891  struct value *retval = NULL;
2892 
2893  bmember = target_lookup_sym_member(target,bsymbol,member,delim);
2894  if (!bmember) {
2895  verror("could not find member '%s' in symbol %s!\n",
2896  member,bsymbol_get_name(bsymbol));
2897  return NULL;
2898  }
2899 
2900  retval = target_load_symbol(target,tlctxt,bmember,flags);
2901 
2902  bsymbol_release(bmember);
2903 
2904  return retval;
2905 }
2906 
2908  struct target_location_ctxt *tlctxt,
2909  struct value *old_value,
2910  const char *member,const char *delim,
2911  load_flags_t flags) {
2912  struct value *value = NULL;
2913  struct symbol *symbol;
2914  struct symbol *tdatatype;
2915  struct lsymbol *ls = NULL;
2916  struct memrange *range;
2917  struct symbol *datatype;
2918  char *rbuf = NULL;
2919  ADDR oldaddr,addr;
2920  struct target_thread *tthread;
2921  tid_t tid;
2922  loctype_t rc;
2923  REG reg;
2924  REGVAL regval;
2925  int newlen;
2926  ADDR word;
2927  struct location tloc;
2928  int created = 0;
2929 
2930  tthread = old_value->thread;
2931  tid = tthread->tid;
2932 
2933  tdatatype = symbol_type_skip_qualifiers(old_value->type);
2934 
2936  "looking up '%s' in type ",member);
2937  LOGDUMPSYMBOL(9,LA_TARGET,LF_SYMBOL,old_value->type);
2939  " (skipping to type ");
2940  LOGDUMPSYMBOL_NL(9,LA_TARGET,LF_SYMBOL,tdatatype);
2941 
2942  memset(&tloc,0,sizeof(tloc));
2943 
2944  /*
2945  * We have to handle two levels of pointers, potentially. Suppose
2946  * that the @value's type is a pointer. Then we have to load that
2947  * pointer (and any others), then find the member offset inside the
2948  * pointed-to struct/union, and then... if THAT member is itself a
2949  * pointer, we read THAT pointer (and any others) until we don't
2950  * have any more pointers.
2951  *
2952  * Of course, that behavior is only enabled when
2953  * LOAD_FLAG_AUTO_DEREF is set.
2954  */
2955 
2956  /* If the value's datatype is a pointer, we have to autoload pointers;
2957  * then try to find a struct/union type that is pointed to!
2958  */
2959  if (SYMBOL_IST_PTR(tdatatype)) {
2960  tdatatype = symbol_type_skip_ptrs(tdatatype);
2961  oldaddr = v_addr(old_value);
2962 
2964  "datatype is ptr; skipping to real type ");
2965  LOGDUMPSYMBOL(9,LA_TARGET,LF_SYMBOL,tdatatype);
2967  " starting at addr 0x%"PRIxADDR"\n",oldaddr);
2968  }
2969  else {
2970  oldaddr = old_value->res.addr;
2971 
2973  "datatype is not ptr; starting at addr 0x%"PRIxADDR"\n",
2974  oldaddr);
2975  }
2976 
2977  if (!SYMBOL_IST_STUNC(tdatatype)) {
2978  vwarn("symbol %s: not a full struct/union/class type (is %s)!\n",
2979  symbol_get_name(tdatatype),SYMBOL_TYPE(tdatatype->type));
2980  errno = EINVAL;
2981  goto errout;
2982  }
2983 
2984  /*
2985  * Resolve the member symbol within tdatatype, the struct/union real
2986  * datatype. Take a self-ref to it, and release it at the end
2987  * whether we succeed or fail! If we succeed, value_create takes a
2988  * ref to it too, and we don't need ours.
2989  */
2990  ls = symbol_lookup_sym(tdatatype,member,delim);
2991  if (!ls)
2992  goto errout;
2993  symbol = lsymbol_last_symbol(ls);
2994 
2995  vdebug(9,LA_TARGET,LF_SYMBOL,"found member symbol ");
2997 
2998  /*
2999  * If this symbol has a constant value, load that!
3000  */
3001  if (SYMBOLX_VAR(symbol) && SYMBOLX_VAR(symbol)->constval) {
3002  value = value_create_type(tthread,NULL,symbol_get_datatype(symbol));
3003  memcpy(value->buf,SYMBOLX_VAR(symbol)->constval,value->bufsiz);
3004 
3006  "symbol %s: loaded const value len %d\n",
3007  symbol_get_name(symbol),value->bufsiz);
3008 
3009  return value;
3010  }
3011 
3012  /*
3013  * Compute either an address or register location, and load!
3014  */
3015  if (!tlctxt) {
3016  tlctxt = target_location_ctxt_create(target,old_value->thread->tid,
3017  old_value->range->region);
3018  created = 1;
3019  }
3020  range = NULL;
3021  reg = -1;
3022  addr = 0;
3023  datatype = NULL;
3024  rc = target_lsymbol_resolve_location(target,tlctxt,ls,oldaddr,
3025  flags,&tloc,&datatype,&range);
3026  if (rc == LOCTYPE_ADDR) {
3027  addr = LOCATION_ADDR(&tloc);
3028 
3029  tdatatype = symbol_type_skip_qualifiers(datatype);
3030  newlen = symbol_type_full_bytesize(datatype);
3031 
3032  /*
3033  * Check for AUTO_STRING first, before checking if the addr +
3034  * newlen is already contained in the original value -- because
3035  * an AUTO_STRING'd value will *not* be contained in the
3036  * original value anyway. If we checked that first, we miss the
3037  * AUTO_STRING chance.
3038  */
3039  if (flags & LOAD_FLAG_AUTO_STRING
3040  && SYMBOL_IST_PTR(symbol_get_datatype(symbol))
3041  && symbol_type_is_char(tdatatype)) {
3042  value = value_create_noalloc(tthread,range,ls,tdatatype);
3043  if (!value) {
3044  verror("symbol %s: could not create value: %s\n",
3045  lsymbol_get_name(ls),strerror(errno));
3046  goto errout;
3047  }
3048 
3049  if (!(value->buf = (char *)__target_load_addr_real(target,range,
3050  addr,flags,
3051  NULL,0))) {
3053  "symbol %s: failed to autostring char pointer\n",
3054  lsymbol_get_name(ls));
3055  value_free(value);
3056  value = NULL;
3057  goto errout;
3058  }
3059  value_set_strlen(value,strlen(value->buf) + 1);
3060  value_set_addr(value,addr);
3061 
3063  "symbol %s: autoloaded char * value with len %d\n",
3064  lsymbol_get_name(ls),value->bufsiz);
3065  }
3066  /*
3067  * If lsymbol_resolve_location returns an address
3068  * entirely contained inside of value->buf, we can just clone
3069  * the value from within the old value. Otherwise, we have to
3070  * load it from the final address.
3071  */
3072  /*
3073  * XXX: this stinks; if you change value_create_type, change
3074  * this size calculation too :(. We do it this way so we don't
3075  * create a value needlessly if the member value isn't fully
3076  * contained in the parent.
3077  */
3078  else if (addr >= oldaddr
3079  && ((addr + newlen) - oldaddr) < (unsigned)old_value->bufsiz) {
3080  if (flags & LOAD_FLAG_VALUE_FORCE_COPY) {
3081  value = value_create(tthread,range,ls,datatype);
3082  if (!value) {
3083  verror("symbol %s: could not create value: %s\n",
3084  lsymbol_get_name(ls),strerror(errno));
3085  goto errout;
3086  }
3087  memcpy(value->buf,old_value->buf + (addr - oldaddr),
3088  newlen);
3089  value_set_addr(value,addr);
3090 
3092  "symbol %s: forced member value copy with len %d\n",
3093  lsymbol_get_name(ls),value->bufsiz);
3094  }
3095  else {
3096  value = value_create_noalloc(tthread,range,ls,datatype);
3097  if (!value) {
3098  verror("symbol %s: could not create value: %s\n",
3099  lsymbol_get_name(ls),strerror(errno));
3100  goto errout;
3101  }
3102  value_set_child(value,old_value,addr);
3103 
3105  "symbol %s: loaded member value as child with len %d\n",
3106  lsymbol_get_name(ls),value->bufsiz);
3107  }
3108 
3109  goto out;
3110  }
3111  else {
3112  value = value_create(tthread,range,ls,tdatatype);
3113  if (!value) {
3114  verror("symbol %s: could not create value: %s\n",
3115  lsymbol_get_name(ls),strerror(errno));
3116  goto errout;
3117  }
3118 
3119  if (!__target_load_addr_real(target,range,addr,flags,
3120  (unsigned char *)value->buf,
3121  value->bufsiz)) {
3123  "symbol %s: failed to load value at 0x%"PRIxADDR"\n",
3124  lsymbol_get_name(ls),addr);
3125  value_free(value);
3126  value = NULL;
3127  goto errout;
3128  }
3129  else {
3130  value_set_addr(value,addr);
3131 
3133  "symbol %s: loaded value with len %d\n",
3134  lsymbol_get_name(ls),value->bufsiz);
3135  }
3136  }
3137  }
3138  else if (rc == LOCTYPE_REG) {
3139  reg = LOCATION_REG(&tloc);
3140 
3141  regval = target_read_reg(target,tid,reg);
3142  if (errno) {
3143  verror("symbol %s: could not read reg %d value in tid %"PRIiTID"\n",
3144  lsymbol_get_name(ls),reg,tid);
3145  goto errout;
3146  }
3147 
3148  datatype = symbol_get_datatype(symbol);
3149  rbuf = malloc(symbol_get_bytesize(datatype));
3150 
3151  if (target->arch->wordsize == 4 && __WORDSIZE == 64) {
3152  /* If the target is 32-bit on 64-bit host, we have to grab
3153  * the lower 32 bits of the regval.
3154  */
3155  memcpy(rbuf,((int32_t *)&regval),symbol_get_bytesize(datatype));
3156  }
3157  else if (__WORDSIZE == 32)
3158  memcpy(rbuf,&regval,(symbol_get_bytesize(datatype) < 4) \
3159  ? symbol_get_bytesize(datatype) : 4);
3160  else
3161  memcpy(rbuf,&regval,symbol_get_bytesize(datatype));
3162 
3163  /* Just create the value based on the register value. */
3164  value = value_create_noalloc(tthread,NULL,ls,datatype);
3165  if (!value) {
3166  verror("symbol %s: could not create value: %s\n",
3167  lsymbol_get_name(ls),strerror(errno));
3168  goto errout;
3169  }
3170  value->buf = rbuf;
3171  value->bufsiz = symbol_get_bytesize(datatype);
3172 
3173  value_set_reg(value,reg);
3174  }
3175  else if (rc == LOCTYPE_IMPLICIT_WORD) {
3176  word = LOCATION_WORD(&tloc);
3177  datatype = symbol_get_datatype(symbol);
3178  rbuf = malloc(symbol_get_bytesize(datatype));
3179 
3180  if (target->arch->wordsize == 4 && __WORDSIZE == 64) {
3181  /* If the target is 32-bit on 64-bit host, we have to grab
3182  * the lower 32 bits of the regval.
3183  */
3184  memcpy(rbuf,((int32_t *)&word),symbol_get_bytesize(datatype));
3185  }
3186  else if (__WORDSIZE == 32)
3187  memcpy(rbuf,&word,(symbol_get_bytesize(datatype) < 4) \
3188  ? symbol_get_bytesize(datatype) : 4);
3189  else
3190  memcpy(rbuf,&word,symbol_get_bytesize(datatype));
3191 
3192  /* Just create the value based on the register value. */
3193  value = value_create_noalloc(tthread,NULL,ls,datatype);
3194  if (!value) {
3195  verror("symbol %s: could not create value: %s\n",
3196  lsymbol_get_name(ls),strerror(errno));
3197  goto errout;
3198  }
3199  value->buf = rbuf;
3200  value->bufsiz = symbol_get_bytesize(datatype);
3201 
3202  value_set_const(value);
3203  }
3204  else if (rc <= LOCTYPE_UNKNOWN) {
3205  verror("symbol %s: failed to compute location (%d %s)\n",
3206  lsymbol_get_name(ls),rc,LOCTYPE(-rc));
3207  goto errout;
3208  }
3209  else {
3210  verror("symbol %s: computed location not register nor address (%d)"
3211  " -- BUG!\n",lsymbol_get_name(ls),rc);
3212  errno = EINVAL;
3213  goto errout;
3214  }
3215 
3216  out:
3217  if (created)
3218  target_location_ctxt_free(tlctxt);
3219  lsymbol_release(ls);
3220  return value;
3221 
3222  errout:
3223  if (created)
3224  target_location_ctxt_free(tlctxt);
3225  if (ls)
3226  lsymbol_release(ls);
3227  if (rbuf)
3228  free(rbuf);
3229  if (value)
3230  value_free(value);
3231  return NULL;
3232 }
3233 
3235  struct target_location_ctxt *tlctxt,
3236  struct bsymbol *bsymbol,load_flags_t flags) {
3237  ADDR addr;
3238  REG reg;
3239  struct lsymbol *lsymbol;
3240  struct symbol *symbol;
3241  struct symbol *datatype;
3242  struct memrange *range;
3243  struct value *value = NULL;
3244  REGVAL regval;
3245  char *rbuf;
3246  struct symbol *tdatatype;
3247  struct target_thread *tthread;
3248  int rc;
3249  ADDR word;
3250  struct location tloc;
3251  tid_t tid;
3252 
3253  if (!tlctxt) {
3254  errno = EINVAL;
3255  verror("must supply a context (tid,region) for bsymbol load!\n");
3256  return LOCTYPE_UNKNOWN;
3257  }
3258  tthread = tlctxt->thread;
3259  tid = tlctxt->thread->tid;
3260 
3261  lsymbol = bsymbol->lsymbol;
3262  symbol = lsymbol_last_symbol(lsymbol);
3263 
3264  if (!SYMBOL_IS_VAR(symbol)) {
3265  verror("symbol %s is not a variable (is %s)!\n",
3266  lsymbol_get_name(lsymbol),SYMBOL_TYPE(symbol->type));
3267  errno = EINVAL;
3268  return NULL;
3269  }
3270 
3271  /*
3272  * If the target backend can read a symbol directly, do it.
3273  */
3274  if (target->ops->read_symbol)
3275  return target->ops->read_symbol(target,tlctxt,bsymbol,flags);
3276 
3277  /*
3278  * If this symbol has a constant value, load that!
3279  */
3280  if (SYMBOLX_VAR(symbol) && SYMBOLX_VAR(symbol)->constval) {
3281  value = value_create_type(tthread,NULL,symbol_get_datatype(symbol));
3282  memcpy(value->buf,SYMBOLX_VAR(symbol)->constval,value->bufsiz);
3283 
3285  "symbol %s: loaded const value len %d\n",
3286  lsymbol_get_name(lsymbol),value->bufsiz);
3287 
3288  return value;
3289  }
3290 
3291  /*
3292  * Compute the symbol's location (reg or addr) and load that!
3293  */
3294  range = NULL;
3295  reg = -1;
3296  addr = 0;
3297  datatype = NULL;
3298  memset(&tloc,0,sizeof(tloc));
3299  rc = target_lsymbol_resolve_location(target,tlctxt,lsymbol,0,
3300  flags,&tloc,&datatype,&range);
3301  if (rc <= LOCTYPE_UNKNOWN) {
3302  vwarnopt(7,LA_TARGET,LF_SYMBOL,"symbol %s: failed to compute location\n",
3303  lsymbol_get_name(lsymbol));
3304  goto errout;
3305  }
3306  else if (rc == LOCTYPE_ADDR) {
3307  addr = LOCATION_ADDR(&tloc);
3308  tdatatype = symbol_type_skip_qualifiers(datatype);
3309  if (flags & LOAD_FLAG_AUTO_STRING
3310  && SYMBOL_IST_PTR(symbol_get_datatype(symbol))
3311  && symbol_type_is_char(tdatatype)) {
3312  value = value_create_noalloc(tthread,range,lsymbol,tdatatype);
3313  if (!value) {
3314  verror("symbol %s: could not create value: %s\n",
3315  lsymbol_get_name(lsymbol),strerror(errno));
3316  goto errout;
3317  }
3318 
3319  if (!(value->buf = (char *)__target_load_addr_real(target,range,
3320  addr,flags,
3321  NULL,0))) {
3323  "symbol %s: failed to autostring char pointer\n",
3324  lsymbol_get_name(lsymbol));
3325  value_free(value);
3326  value = NULL;
3327  goto errout;
3328  }
3329  value_set_strlen(value,strlen(value->buf) + 1);
3330  value_set_addr(value,addr);
3331 
3333  "symbol %s: autoloaded char * value with len %d\n",
3334  lsymbol_get_name(lsymbol),value->bufsiz);
3335  }
3336  else {
3337  value = value_create(tthread,range,bsymbol->lsymbol,tdatatype);
3338  if (!value) {
3339  verror("symbol %s: could not create value: %s\n",
3340  lsymbol_get_name(lsymbol),strerror(errno));
3341  goto errout;
3342  }
3343 
3344  if (!__target_load_addr_real(target,range,addr,flags,
3345  (unsigned char *)value->buf,
3346  value->bufsiz)) {
3348  "symbol %s: failed to load value at 0x%"PRIxADDR"\n",
3349  lsymbol_get_name(lsymbol),addr);
3350  value_free(value);
3351  value = NULL;
3352  goto out;
3353  }
3354  else {
3355  value_set_addr(value,addr);
3356 
3358  "symbol %s: loaded value with len %d\n",
3359  lsymbol_get_name(lsymbol),value->bufsiz);
3360  }
3361  }
3362  }
3363  else if (rc == LOCTYPE_REG) {
3364  reg = LOCATION_REG(&tloc);
3365 
3366  if (target_location_ctxt_read_reg(tlctxt,reg,&regval)) {
3368  "symbol %s: could not read reg %d value in tid %"PRIiTID"\n",
3369  lsymbol_get_name(lsymbol),reg,tid);
3370  goto errout;
3371  }
3372 
3374  rbuf = malloc(symbol_get_bytesize(datatype));
3375 
3376  if (target->arch->wordsize == 4 && __WORDSIZE == 64) {
3377  /* If the target is 32-bit on 64-bit host, we have to grab
3378  * the lower 32 bits of the regval.
3379  */
3380  memcpy(rbuf,((int32_t *)&regval),symbol_get_bytesize(datatype));
3381  }
3382  else if (__WORDSIZE == 32)
3383  memcpy(rbuf,&regval,(symbol_get_bytesize(datatype) < 4) \
3384  ? symbol_get_bytesize(datatype) : 4);
3385  else
3386  memcpy(rbuf,&regval,symbol_get_bytesize(datatype));
3387 
3388  /* Just create the value based on the register value. */
3389  value = value_create_noalloc(tthread,NULL,bsymbol->lsymbol,datatype);
3390  if (!value) {
3391  verror("symbol %s: could not create value: %s\n",
3392  lsymbol_get_name(lsymbol),strerror(errno));
3393  goto errout;
3394  }
3395  value->buf = rbuf;
3396  value->bufsiz = symbol_get_bytesize(datatype);
3397 
3398  value_set_reg(value,reg);
3399  }
3400  else if (rc == LOCTYPE_IMPLICIT_WORD) {
3401  word = LOCATION_WORD(&tloc);
3402 
3404  rbuf = malloc(symbol_get_bytesize(datatype));
3405 
3406  if (target->arch->wordsize == 4 && __WORDSIZE == 64) {
3407  /* If the target is 32-bit on 64-bit host, we have to grab
3408  * the lower 32 bits of the regval.
3409  */
3410  memcpy(rbuf,((int32_t *)&word),symbol_get_bytesize(datatype));
3411  }
3412  else if (__WORDSIZE == 32)
3413  memcpy(rbuf,&word,(symbol_get_bytesize(datatype) < 4) \
3414  ? symbol_get_bytesize(datatype) : 4);
3415  else
3416  memcpy(rbuf,&word,symbol_get_bytesize(datatype));
3417 
3418  /* Just create the value based on the register value. */
3419  value = value_create_noalloc(tthread,NULL,bsymbol->lsymbol,datatype);
3420  if (!value) {
3421  verror("symbol %s: could not create value: %s\n",
3422  lsymbol_get_name(lsymbol),strerror(errno));
3423  goto errout;
3424  }
3425  value->buf = rbuf;
3426  value->bufsiz = symbol_get_bytesize(datatype);
3427 
3428  value_set_const(value);
3429  }
3430  else {
3431  verror("symbol %s: computed location not register nor address (%d)"
3432  " -- BUG!\n",
3433  lsymbol_get_name(lsymbol),rc);
3434  errno = EINVAL;
3435  goto errout;
3436  }
3437 
3438  out:
3439  location_internal_free(&tloc);
3440  return value;
3441 
3442  errout:
3443  location_internal_free(&tloc);
3444  if (value)
3445  value_free(value);
3446  return NULL;
3447 }
3448 
3450  char *member,const char *delim) {
3451  return symbol_offsetof(bsymbol->lsymbol->symbol,member,delim);
3452 }
3453 
3455  struct target_location_ctxt *tlctxt,
3456  struct bsymbol *bsymbol,load_flags_t flags,
3457  struct memrange **o_range) {
3458  ADDR addr;
3459  struct lsymbol *lsymbol;
3460  loctype_t rc;
3461  struct location tloc;
3462 
3463  lsymbol = bsymbol->lsymbol;
3464 
3465  /*
3466  * Compute the symbol's location (reg or addr) and load that!
3467  */
3468  addr = 0;
3469  memset(&tloc,0,sizeof(tloc));
3470  rc = target_lsymbol_resolve_location(target,tlctxt,lsymbol,0,
3471  flags,&tloc,NULL,o_range);
3472  if (rc <= LOCTYPE_UNKNOWN) {
3473  verror("symbol %s: failed to compute location: %s (%d)\n",
3474  lsymbol_get_name(lsymbol),strerror(errno),rc);
3475  goto errout;
3476  }
3477  else if (rc == LOCTYPE_ADDR) {
3478  addr = LOCATION_ADDR(&tloc);
3479  location_internal_free(&tloc);
3480  return addr;
3481  }
3482  /*
3483  * XXX: technically, the register could still be in some address if
3484  * it was in a previous frame... we should handle that someday.
3485  */
3486  else if (rc == LOCTYPE_REG) {
3488  "symbol %s: computed location is register %"PRIiREG"\n",
3489  lsymbol_get_name(lsymbol),LOCATION_REG(&tloc));
3490  goto errout;
3491  }
3492  else if (rc == LOCTYPE_IMPLICIT_WORD) {
3494  "symbol %s: computed location is implicit value 0x%"PRIxADDR"\n",
3495  lsymbol_get_name(lsymbol),LOCATION_WORD(&tloc));
3496  goto errout;
3497  }
3498  else {
3499  verror("symbol %s: computed location not register nor address (%d)"
3500  " -- BUG!\n",
3501  lsymbol_get_name(lsymbol),rc);
3502  goto errout;
3503  }
3504 
3505  errout:
3506  location_internal_free(&tloc);
3507  if (!errno)
3508  errno = EINVAL;
3509  return 0;
3510 }
3511 
3513  /*
3514  * If the target backend can read a symbol directly, do it.
3515  */
3516  if (target->ops->write_symbol)
3517  return target->ops->write_symbol(target,value);
3518 
3519  /* mmap'd values were stored whenever they were value_update_*'d */
3520  if (value->ismmap)
3521  return 0;
3522  else if (value->isreg) {
3523  return target_write_reg(target,value->thread->tid,value->res.reg,
3524  *(REGVAL *)value->buf);
3525  }
3526  else if (target_write_addr(target,value->res.addr,
3527  (unsigned long)value->bufsiz,
3528  (unsigned char *)value->buf)
3529  != (unsigned long)value->bufsiz) {
3530  return -1;
3531  }
3532 
3533  return 0;
3534 }
3535 
3537  struct addrspace **space_saveptr,
3538  struct memregion **region_saveptr,
3539  struct memrange **range_saveptr) {
3540  GList *t1;
3541  struct addrspace *space;
3542 
3543  if (!target->spaces)
3544  return 0;
3545 
3546  v_g_list_foreach(target->spaces,t1,space) {
3547  if (addrspace_find_range_real(space,addr,
3548  region_saveptr,range_saveptr)) {
3549  if (space_saveptr)
3550  *space_saveptr = space;
3551  goto out;
3552  }
3553  }
3554  return 0;
3555 
3556  out:
3557  return 1;
3558 }
3559 
3561  GList *t1,*t2;
3562  struct addrspace *space;
3563  struct memregion *region;
3564 
3565  v_g_list_foreach(target->spaces,t1,space) {
3566  v_g_list_foreach(space->regions,t2,region) {
3567  if (memregion_contains_real(region,addr))
3568  return 1;
3569  }
3570  }
3571 
3572  return 0;
3573 }
3574 
3575 ADDR target_load_pointers(struct target *target,ADDR addr,int count,
3576  struct memrange **range_saveptr) {
3577  ADDR paddr = addr;
3578  struct memrange *range = NULL;
3579  int i;
3580 
3581  for (i = 0; i < count; ++i ) {
3582  if (paddr == 0) {
3583  verror("failed to follow NULL pointer #%d\n",i);
3584  errno = EFAULT;
3585  goto errout;
3586  }
3587 
3589  "loading ptr #%d at 0x%"PRIxADDR"\n",i,paddr);
3590 
3591  /*
3592  * The pointer may be in another region! We *have* to
3593  * switch regions -- and thus the memrange for the value we
3594  * return may not be in @addr's region/range!
3595  */
3596  if (!target_find_memory_real(target,paddr,NULL,NULL,&range)) {
3597  verror("could not find range for ptr 0x%"PRIxADDR"\n",paddr);
3598  errno = EFAULT;
3599  goto errout;
3600  }
3601 
3602  if (!__target_load_addr_real(target,range,paddr,LOAD_FLAG_NONE,
3603  (unsigned char *)&paddr,target->arch->ptrsize)) {
3604  verror("could not load ptr #%d at 0x%"PRIxADDR"\n",i,paddr);
3605  errno = EFAULT;
3606  goto errout;
3607  }
3608 
3610  "loaded next ptr value 0x%"PRIxADDR" (#%d)\n",
3611  paddr,i);
3612  }
3613 
3614  if (i == count && range) {
3615  if (range_saveptr)
3616  *range_saveptr = range;
3617  }
3618 
3619  errno = 0;
3620  return paddr;
3621 
3622  errout:
3623  return 0;
3624 }
3625 
3627  ADDR addr,load_flags_t flags,
3628  struct symbol **datatype_saveptr,
3629  struct memrange **range_saveptr) {
3630  load_flags_t ptrloadflags = flags;
3631  ADDR paddr = addr;
3632  struct memrange *range = NULL;
3633  int nptrs = 0;
3634 
3635  while (SYMBOL_IST_PTR(datatype)) {
3636  if (((flags & LOAD_FLAG_AUTO_DEREF) && SYMBOL_IST_PTR(datatype))
3637  || ((flags & LOAD_FLAG_AUTO_STRING)
3638  && SYMBOL_IST_PTR(datatype)
3639  && symbol_type_is_char(symbol_type_skip_ptrs(datatype)))) {
3640  if (paddr == 0) {
3641  verror("failed to follow NULL pointer #%d\n",nptrs);
3642  errno = EFAULT;
3643  goto errout;
3644  }
3645 
3647  "loading ptr at 0x%"PRIxADDR"\n",paddr);
3648 
3649  /*
3650  * The pointer may be in another region! We *have* to
3651  * switch regions -- and thus the memrange for the value we
3652  * return may not be in @addr's region/range!
3653  */
3654  if (!target_find_memory_real(target,paddr,NULL,NULL,&range)) {
3655  verror("could not find range for ptr 0x%"PRIxADDR"\n",paddr);
3656  errno = EFAULT;
3657  goto errout;
3658  }
3659 
3660  if (!__target_load_addr_real(target,range,paddr,ptrloadflags,
3661  (unsigned char *)&paddr,
3662  target->arch->ptrsize)) {
3663  verror("could not load ptr 0x%"PRIxADDR"\n",paddr);
3664  errno = EFAULT;
3665  goto errout;
3666  }
3667 
3668  ++nptrs;
3670  "loaded next ptr value 0x%"PRIxADDR" (#%d)\n",
3671  paddr,nptrs);
3672 
3673  /* Skip past the pointer we just loaded. */
3674  datatype = symbol_get_datatype(datatype);
3675  }
3676  else {
3677  break;
3678  }
3679  }
3680 
3681  if (range) {
3682  if (range_saveptr)
3683  *range_saveptr = range;
3684  if (datatype_saveptr)
3685  *datatype_saveptr = datatype;
3686  }
3687 
3688  errno = 0;
3689  return paddr;
3690 
3691  errout:
3692  return 0;
3693 }
3694 
3695 /*
3696  * Load a raw value (i.e., no symbol or type info) using an object
3697  * file-based location (i.e., a fixed object-relative address) and a
3698  * specific region.
3699  */
3700 struct value *target_load_addr_obj(struct target *target,struct memregion *region,
3701  ADDR obj_addr,load_flags_t flags,int len) {
3702  ADDR real;
3703  struct memrange *range;
3704 
3705  errno = 0;
3706  real = memregion_relocate(region,obj_addr,&range);
3707  if (errno)
3708  return NULL;
3709 
3710  return target_load_addr_real(target,real,flags,len);
3711 }
3712 
3713 /*
3714  * Load a raw value (i.e., no symbol or type info) using a real address.
3715  */
3717  load_flags_t flags,int len) {
3718  struct memrange *range;
3719  struct value *value;
3720 
3721  if (!target_find_memory_real(target,addr,NULL,NULL,&range)) {
3722  verror("could not find range containing addr 0x%"PRIxADDR"!\n",addr);
3723  errno = ERANGE;
3724  return NULL;
3725  }
3726 
3727  if (!(value = value_create_raw(target,NULL,range,len))) {
3728  verror("could not create raw value of len %d for addr 0x%"PRIxADDR"!\n",
3729  len,addr);
3730  return NULL;
3731  }
3732 
3733  if (!__target_load_addr_real(target,range,addr,flags,
3734  (unsigned char *)value->buf,value->bufsiz)) {
3735  value_free(value);
3736  return NULL;
3737  }
3738 
3739  value_set_addr(value,addr);
3740 
3741  return value;
3742 }
3743 
3745  load_flags_t flags,
3746  unsigned char *buf,int bufsiz) {
3747  struct memrange *range;
3748 
3749  if (!target_find_memory_real(target,addr,NULL,NULL,&range)) {
3750  verror("could not find range containing addr 0x%"PRIxADDR"!\n",addr);
3751  errno = ERANGE;
3752  return NULL;
3753  }
3754 
3755  return __target_load_addr_real(target,range,addr,flags,
3756  (unsigned char *)buf,bufsiz);
3757 }
3758 
3759 unsigned char *__target_load_addr_real(struct target *target,
3760  struct memrange *range,
3761  ADDR addr,load_flags_t flags,
3762  unsigned char *buf,int bufsiz) {
3763  if (!(flags & LOAD_FLAG_NO_CHECK_BOUNDS)) {
3764  if (!memrange_contains_real(range,addr)) {
3765  verror("addr 0x%"PRIxADDR" not in"
3766  " range(0x%"PRIxADDR",0x%"PRIxADDR")!\n",
3767  addr,range->start,range->end);
3768  errno = ERANGE;
3769  return NULL;
3770  }
3771  else if (!memrange_contains_real(range,addr+bufsiz-1)) {
3772  verror("addr 0x%"PRIxADDR" + bufsiz %d not in"
3773  " range(0x%"PRIxADDR",0x%"PRIxADDR")!\n",
3774  addr,bufsiz,range->start,range->end);
3775  errno = ERANGE;
3776  return NULL;
3777  }
3778  }
3779 
3780  return target_read_addr(target,addr,bufsiz,buf);
3781 }
3782 
3784  ADDR *start,ADDR *end,void **data) {
3785  GList *t1,*t2;
3786  struct addrspace *space;
3787  struct memregion *region;
3788  struct memrange *range = NULL;
3789  struct clf_range_data *crd;
3790 
3791  /* Find which region contains this address. */
3792  v_g_list_foreach(target->spaces,t1,space) {
3793  v_g_list_foreach(space->regions,t2,region) {
3794  if ((range = memregion_find_range_real(region,addr)))
3795  break;
3796  }
3797  }
3798 
3799  if (!range)
3800  return -1;
3801 
3802  if ((crd = clrange_find_loosest(&region->binfile->ranges,
3803  memrange_unrelocate(range,addr),
3804  NULL))) {
3805  if (start)
3806  *start = memrange_relocate(range,crd->start);
3807  if (end)
3808  *end = memrange_relocate(range,crd->end);
3809  if (data)
3810  *data = crd->data;
3811 
3812  return 0;
3813  }
3814 
3815  return -1;
3816 }
3817 
3819  ADDR *start,ADDR *end,void **data) {
3820  GList *t1,*t2;
3821  struct addrspace *space;
3822  struct memregion *region;
3823  struct memrange *range = NULL;
3824  struct clf_range_data *crd;
3825 
3826  /* Find which region contains this address. */
3827  v_g_list_foreach(target->spaces,t1,space) {
3828  v_g_list_foreach(space->regions,t2,region) {
3829  if ((range = memregion_find_range_real(region,addr)))
3830  break;
3831  }
3832  }
3833 
3834  if (!range)
3835  return -1;
3836 
3837  if ((crd = clrange_find_next_loosest(&region->binfile->ranges,
3838  memrange_unrelocate(range,addr),
3839  NULL))) {
3840  if (start)
3841  *start = memrange_relocate(range,crd->start);
3842  if (end)
3843  *end = memrange_relocate(range,crd->end);
3844  if (data)
3845  *data = crd->data;
3846 
3847  return 0;
3848  }
3849 
3850  return -1;
3851 }
3852 
3853 /*
3854  * CODE_CACHE_BUF_PAD -- distorm seems to have an off by one error decoding at
3855  * the end of a buffer supplied to it -- so we always pad our buffers we
3856  * pass to it with this many NUL bytes.
3857  */
3858 #define CODE_CACHE_BUF_PAD 5
3859 
3861  Word_t start;
3862  unsigned int len:31,
3863  isevictable:1;
3864  unsigned char *code;
3865 };
3866 
3867 unsigned char *target_load_code(struct target *target,
3868  ADDR start,unsigned int len,
3869  int nocache,int force_copy,int *caller_free) {
3870  unsigned char *buf = NULL;
3871  unsigned int llen = 0;
3872  struct code_cache_entry *ccd;
3873  ADDR nextaddr;
3874  ADDR cstart,cend;
3875  unsigned int tlen;
3876  unsigned char *tbuf;
3877 
3878  nextaddr = start;
3879 
3880  if (force_copy)
3881  buf = calloc(1,len + CODE_CACHE_BUF_PAD);
3882 
3883  while (llen < len) {
3884  /*
3885  * Check the cache first. If we find a hit, maybe we can fill
3886  * up at least part of our return buffer -- OR maybe even just
3887  * return a pointer.
3888  */
3889  checkcache:
3890  ccd = (struct code_cache_entry *)clrange_find(&target->code_ranges,
3891  nextaddr);
3892  if (ccd) {
3893  /* At least some of the code in this cache entry is
3894  * relevant; either plop it into our current buf; return a
3895  * pointer to it, or an offset of it.
3896  */
3897 
3898  /* If we don't have a buf (i.e., not forcing a copy, and
3899  * have not needed a buf because we're not needing to load
3900  * multiple segments), and if the code we need is entirely
3901  * in this buf, then just return a pointer to the right
3902  * place in this buf!
3903  */
3904  if (!buf && (nextaddr + len) <= (ccd->start + ccd->len)) {
3905  *caller_free = 0;
3906  return ccd->code + (nextaddr - ccd->start);
3907  }
3908  /* Otherwise, we have a buf (or we *must* create one because
3909  * we are loading more code than is in this one cache entry)
3910  * and we need to copy (at least some) of the data in this
3911  * cache entry into it.
3912  */
3913  else {
3914  if (!buf)
3915  buf = calloc(1,len + CODE_CACHE_BUF_PAD);
3916 
3917  tlen = ccd->len - (nextaddr - ccd->start);
3918  if ((len - llen) < tlen)
3919  tlen = len - llen;
3920 
3921  memcpy(buf + llen,ccd->code + (nextaddr - ccd->start),tlen);
3922  llen += tlen;
3923  }
3924  }
3925  else {
3926  /* If it's not in the cache, we need to load the next safe
3927  * disasm chunk --- OR FILL IN THE HOLE THAT CONTAINS
3928  * nextaddr.
3929  */
3930  if (target_lookup_safe_disasm_range(target,nextaddr,&cstart,&cend,
3931  NULL)) {
3932  verror("no safe disasm range contains 0x%"PRIxADDR"!\n",nextaddr);
3933  goto errout;
3934  }
3935 
3936  tbuf = target_load_raw_addr_real(target,cstart,
3937  LOAD_FLAG_NONE,NULL,cend - cstart);
3938  if (!tbuf) {
3939  verror("could not load code in safe disasm range"
3940  " 0x%"PRIxADDR",0x%"PRIxADDR"!\n",cstart,cend);
3941 
3942  tbuf = target_load_raw_addr_real(target,cstart,
3943  LOAD_FLAG_NONE,NULL,1);
3944  if (!tbuf) {
3945  verror("could not load even 1 byte of code in safe disasm range"
3946  " 0x%"PRIxADDR",0x%"PRIxADDR"!\n",cstart,cend);
3947  }
3948  else {
3949  verror("BUT could load 1 byte of code in safe disasm range"
3950  " 0x%"PRIxADDR",0x%"PRIxADDR"!\n",cstart,cend);
3951  }
3952  goto errout;
3953  }
3954 
3955  /* Save it in the cache! */
3956  ccd = (struct code_cache_entry *)calloc(1,sizeof(*ccd));
3957  ccd->start = cstart;
3958  ccd->len = cend - cstart;
3959  ccd->code = tbuf;
3960 
3961  clrange_add(&target->code_ranges,cstart,cend,ccd);
3962 
3963  /* Just hop back to the top of the loop and let the cache
3964  * check succeed this time!
3965  */
3966  goto checkcache;
3967  }
3968  }
3969 
3970  if (caller_free)
3971  *caller_free = 1;
3972  return buf;
3973 
3974  errout:
3975  if (buf)
3976  free(buf);
3977  return NULL;
3978 
3979 }
3980 
3982  vdebug(16,LA_TARGET,LF_THREAD,"thread %"PRIiTID"\n",tid);
3983  return (struct target_thread *)g_hash_table_lookup(target->threads,
3984  (gpointer)(ptr_t)tid);
3985 }
3986 
3988  vdebug(8,LA_TARGET,LF_TARGET,"target %s %s\n",
3989  target->name,TSTATUS(target->status));
3990  return target->status;
3991 }
3992 
3994  vdebug(8,LA_TARGET,LF_TARGET,"target %s %s -> %s\n",
3995  target->name,TSTATUS(target->status),TSTATUS(status));
3996  target->status = status;
3997 }
3998 
4001  vdebug(8,LA_TARGET,LF_THREAD | LF_TARGET,"target %s tid %d %s -> %s\n",
4002  tthread->target->name,tthread->tid,
4003  THREAD_STATUS(tthread->status),THREAD_STATUS(status));
4004  tthread->status = status;
4005 }
4006 
4009  struct target_thread *tthread = (struct target_thread *) \
4010  g_hash_table_lookup(target->threads,(gpointer)(ptr_t)tid);
4011  if (!tthread) {
4012  verror("could not set status for nonexistent tid %d -- BUG!\n",tid);
4013  return;
4014  }
4015  vdebug(8,LA_TARGET,LF_THREAD | LF_TARGET,"target %s tid %d %s -> %s\n",
4016  tthread->target->name,tthread->tid,
4017  THREAD_STATUS(tthread->status),THREAD_STATUS(status));
4018  tthread->status = status;
4019 }
4020 
4022  void *tstate,void *tpstate) {
4023  struct target_thread *t = (struct target_thread *)calloc(1,sizeof(*t));
4024 
4025  vdebug(3,LA_TARGET,LF_THREAD,"thread %"PRIiTID"\n",tid);
4026 
4027  t->tid = tid;
4028  t->state = tstate;
4029  t->personality_state = tpstate;
4030 
4031  /*
4032  * Don't *build* the regcaches yet -- just the per-thread_ctxt pointers.
4033  */
4034  t->regcaches = (struct regcache **) \
4035  calloc(target->max_thread_ctxt,sizeof(*t->regcaches));
4036 
4037  t->ptid = -1;
4038  t->tgid = -1;
4039  t->uid = -1;
4040  t->gid = -1;
4041 
4042  t->hard_probepoints = g_hash_table_new(g_direct_hash,g_direct_equal);
4043 
4044  t->tpc = NULL;
4045  t->tpc_stack = array_list_create(4);
4047 
4048  /* Keys are always copied; values get user-custom dtors */
4049  t->gkv_store = g_hash_table_new_full(g_str_hash,g_str_equal,free,NULL);
4050 
4051  if (target) {
4052  t->target = target;
4053  RHOLDW(target,t);
4054 
4055  /* This is basically what target_attach_thread would do if it existed */
4056  g_hash_table_insert(target->threads,(gpointer)(ptr_t)tid,t);
4057  RHOLD(t,target);
4058  }
4059 
4060  return t;
4061 }
4062 
4064  struct target_thread *thread) {
4065  vdebug(3,LA_TARGET,LF_THREAD,"thread %"PRIiTID" as global %"PRIiTID"\n",
4066  thread->tid,TID_GLOBAL);
4067  g_hash_table_insert(target->threads,(gpointer)TID_GLOBAL,thread);
4068  /* Hold a second ref to it! */
4069  RHOLD(thread,target);
4070  target->global_thread = thread;
4071 }
4072 
4073 void target_detach_thread(struct target *target,struct target_thread *tthread) {
4074  GHashTableIter iter;
4075  struct probepoint *probepoint;
4076  struct thread_action_context *tac,*ttac;
4077  REFCNT trefcnt;
4078 
4079  /*
4080  * If this thread has an overlay target, detach that first!
4081  */
4082  //zzz;
4083 
4084  if (!list_empty(&tthread->ss_actions)) {
4085  list_for_each_entry_safe(tac,ttac,&tthread->ss_actions,tac) {
4086  action_free(tac->action,0);
4087  free(tac);
4088  }
4089  }
4090 
4091  /* We have to free the probepoints manually, then remove all. We
4092  * can't remove an element during an iteration, but we *can* free
4093  * the data :).
4094  */
4095  g_hash_table_iter_init(&iter,tthread->hard_probepoints);
4096  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&probepoint)) {
4097  probepoint_free_ext(probepoint);
4098  }
4099 
4100  g_hash_table_remove_all(tthread->hard_probepoints);
4101 
4102  /*
4103  * Once we're done with the underlying target, tell it the overlay
4104  * is gone!
4105  */
4106  if (target->base)
4107  target_detach_overlay_thread(target->base,target,tthread->tid);
4108 
4109  /*
4110  * Remove it from our hashtable and drop the ref!
4111  */
4112  g_hash_table_remove(target->threads,(gpointer)(uintptr_t)tthread->tid);
4113  OBJSDEAD(tthread,target_thread);
4114  RPUT(tthread,target_thread,target,trefcnt);
4115 }
4116 
4118  obj_flags_t orf,obj_flags_t nandf) {
4119  return 0;
4120 }
4121 /*
4122  * target_delete_thread is for *internal* driver use; target_thread_free
4123  * is the RPUT destructor. That is because the target is the owner of
4124  * the thread. Hm, can we merge those things???
4125  */
4126 REFCNT target_thread_free(struct target_thread *tthread,int force) {
4127  REFCNT retval = tthread->refcnt;
4128  REFCNT trefcnt;
4129  unsigned int i;
4130  struct target *target = tthread->target;
4131 
4132  assert(tthread);
4133 
4134  if (tthread->refcnt) {
4135  if (!force) {
4136  verror("cannot free (%d refs) thread %"PRIiTID"\n",
4137  tthread->refcnt,tthread->tid);
4138  return tthread->refcnt;
4139  }
4140  else {
4141  vwarn("forcing free (%d refs) thread %"PRIiTID"\n",
4142  tthread->refcnt,tthread->tid);
4143  }
4144  }
4145 
4146  RWGUARD(tthread);
4147 
4148  vdebug(5,LA_TARGET,LF_TARGET,"freeing thread %"PRIiTID"\n",tthread->tid);
4149 
4150  /*
4151  * If this function is being called as a target being detached,
4152  * these probepoints must be freed *before* this function is called;
4153  * this is a last-minute check that works well because sometimes
4154  * this function is called during normal target runtime as threads
4155  * come and go.
4156  */
4157  if (target && OBJLIVE(tthread))
4158  target_detach_thread(target,tthread);
4159 
4160  /*
4161  * Threads don't own children yet; so the weak refcnt is pretty
4162  * meaningless. But still, support it.
4163  */
4164  if (tthread->refcntw) {
4165  if (!force) {
4166  verror("cannot free (%d wrefs) thread %"PRIiTID"\n",
4167  tthread->refcntw,tthread->tid);
4168  return tthread->refcntw;
4169  }
4170  else {
4171  vwarn("forced free (%d wrefs) thread %"PRIiTID"\n",
4172  tthread->refcntw,tthread->tid);
4173  }
4174 
4175  if (retval <= 0)
4176  retval = tthread->refcntw;
4177  }
4178 
4179  /*
4180  * Ok, delete it!
4181  */
4182 
4183  /*
4184  * Destroy any thread generic keys first.
4185  */
4186  if (target)
4187  target_thread_gkv_destroy(target,tthread);
4188 
4189  array_list_free(tthread->tpc_stack);
4190  tthread->tpc_stack = NULL;
4191 
4192  g_hash_table_destroy(tthread->hard_probepoints);
4193  tthread->hard_probepoints = NULL;
4194 
4195  if (target && tthread->personality_state) {
4196  if (target->personality_ops && target->personality_ops->free_thread_state)
4197  target->personality_ops->free_thread_state(target,
4198  tthread->personality_state);
4199  else
4200  free(tthread->personality_state);
4201 
4202  tthread->personality_state = NULL;
4203  }
4204 
4205  if (target) {
4206  for (i = 0; i < target->max_thread_ctxt; ++i) {
4207  if (tthread->regcaches[i]) {
4208  regcache_destroy(tthread->regcaches[i]);
4209  tthread->regcaches[i] = NULL;
4210  }
4211  }
4212  }
4213  free(tthread->regcaches);
4214  tthread->regcaches = NULL;
4215 
4216  if (target && tthread->state) {
4217  if (target->ops->free_thread_state)
4218  target->ops->free_thread_state(target,tthread->state);
4219  else
4220  free(tthread->state);
4221 
4222  tthread->state = NULL;
4223  }
4224 
4225  if (target) {
4226  RPUTW(target,target,tthread,trefcnt);
4227  target = NULL;
4228  }
4229 
4230  retval = tthread->refcnt + tthread->refcntw - 1;
4231 
4232  free(tthread);
4233 
4234  return retval;
4235 }
4236 
4237 /*
4238  * We recognize several keys:
4239  * tid -- the thread id
4240  * ptid -- the thread's parent thread id
4241  * tgid -- the thread group id
4242  * tidhier -- a common-separated list of tids starting with the
4243  * current tid, and then moving up the hierarchy to the root.
4244  * name -- the thread's name
4245  * namehier -- a comma-separated list of tid names starting with the
4246  * current tid, and then moving up the hierarchy to the root.
4247  * uid -- the thread's uid, if any
4248  * gid -- the thread's gid, if any.
4249  *
4250  * Eventually, we need to pass any other keys to the backend in question
4251  * for more powerful filtering. But this is enough for now.
4252  */
4254  struct target_nv_filter *tf) {
4255  struct target_thread *tthread,*tmpthread;
4256  char vstrbuf[1024];
4257  int rc;
4258  int i;
4259  GSList *gsltmp;
4260  struct target_nv_filter_regex *tfr;
4261 
4262  if (!tf)
4263  return 0;
4264 
4265  tthread = target_lookup_thread(target,tid);
4266  if (!tthread) {
4267  verror("tid %"PRIiTID" does not exist!\n",tid);
4268  errno = ESRCH;
4269  return 1;
4270  }
4271 
4272  /*
4273  * Check each filter by loading the value from @trigger.
4274  */
4275  v_g_slist_foreach(tf->value_regex_list,gsltmp,tfr) {
4276  /* NB: notice that longest matches have to be checked first;
4277  * else tid will match tidhier.
4278  */
4279  if (strncmp(tfr->value_name,"tidhier",strlen("tidhier")) == 0) {
4280  rc = 0;
4281  i = 0;
4282  tmpthread = tthread;
4283  do {
4284  if (likely(i > 0))
4285  rc += snprintf(vstrbuf + rc,sizeof(vstrbuf) - rc,
4286  ",%"PRIiTID,tmpthread->tid);
4287  else
4288  rc += snprintf(vstrbuf + rc,sizeof(vstrbuf) - rc,
4289  "%"PRIiTID,tmpthread->tid);
4290  ++i;
4291 
4292  if (tmpthread->ptid == -1)
4293  tmpthread = NULL;
4294  else {
4295  /* Don't need to load it; it would have been loaded
4296  * because the base child thread was loaded.
4297  */
4298  tmpthread = target_lookup_thread(target,tmpthread->ptid);
4299  }
4300  } while (tmpthread);
4301  }
4302  else if (strncmp(tfr->value_name,"tid",strlen("tid")) == 0) {
4303  rc = snprintf(vstrbuf,sizeof(vstrbuf),"%"PRIiTID,tthread->tid);
4304  }
4305  else if (strncmp(tfr->value_name,"tgid",strlen("tgid")) == 0) {
4306  rc = snprintf(vstrbuf,sizeof(vstrbuf),"%"PRIiTID,tthread->tgid);
4307  }
4308  else if (strncmp(tfr->value_name,"ptid",strlen("ptid")) == 0) {
4309  rc = snprintf(vstrbuf,sizeof(vstrbuf),"%"PRIiTID,tthread->ptid);
4310  }
4311  else if (strncmp(tfr->value_name,"namehier",strlen("namehier")) == 0) {
4312  rc = 0;
4313  i = 0;
4314  tmpthread = tthread;
4315  do {
4316  if (likely(i > 0))
4317  rc += snprintf(vstrbuf + rc,sizeof(vstrbuf) - rc,
4318  ",%s",tmpthread->name ? tmpthread->name : "");
4319  else
4320  rc += snprintf(vstrbuf + rc,sizeof(vstrbuf) - rc,
4321  "%s",tmpthread->name ? tmpthread->name : "");
4322  ++i;
4323 
4324  if (tmpthread->ptid == -1)
4325  tmpthread = NULL;
4326  else {
4327  /* Don't need to load it; it would have been loaded
4328  * because the base child thread was loaded.
4329  */
4330  tmpthread = target_lookup_thread(target,tmpthread->ptid);
4331  }
4332  } while (tmpthread);
4333  }
4334  else if (strncmp(tfr->value_name,"name",strlen("name")) == 0) {
4335  rc = snprintf(vstrbuf,sizeof(vstrbuf),"%s",
4336  tthread->name ? tthread->name : "");
4337  }
4338  else if (strncmp(tfr->value_name,"uid",strlen("uid")) == 0) {
4339  rc = snprintf(vstrbuf,sizeof(vstrbuf),"%d",tthread->uid);
4340  }
4341  else if (strncmp(tfr->value_name,"gid",strlen("gid")) == 0) {
4342  rc = snprintf(vstrbuf,sizeof(vstrbuf),"%d",tthread->gid);
4343  }
4344  else {
4345  vwarn("unrecognized thread filter key '%s'; skipping!\n",
4346  tfr->value_name);
4347  continue;
4348  }
4349 
4350  if (regexec(&tfr->regex,(const char *)vstrbuf,0,NULL,0) == REG_NOMATCH) {
4352  "failed to match name %s value '%s' with regex!\n",
4353  tfr->value_name,vstrbuf);
4354  return 1;
4355  }
4356  else {
4358  "matched name %s value '%s' with regex\n",
4359  tfr->value_name,vstrbuf);
4360  }
4361  }
4362 
4363  return 0;
4364 }
4365 
4367  struct target_thread *tthread) {
4368  unsigned int i;
4369 
4370  if (target->ops->invalidate_thread)
4371  target->ops->invalidate_thread(target,tthread);
4372  else if (target->personality_ops
4373  && target->personality_ops->invalidate_thread)
4374  target->personality_ops->invalidate_thread(target,tthread);
4375 
4376  /*
4377  * XXX: Invalidate any valid regcaches. Not sure we should do this
4378  * here...
4379  */
4380  for (i = 0; i < target->max_thread_ctxt; ++i) {
4381  if (tthread->regcaches[i]) {
4382  regcache_invalidate(tthread->regcaches[i]);
4383  }
4384  }
4385 
4386  OBJSINVALID(tthread);
4387 
4388  if (OBJDIRTY(tthread))
4389  vwarn("invalidated dirty thread %"PRIiTID"; BUG?\n",tthread->tid);
4390 
4391  return 0;
4392 }
4393 
4394 static int __target_invalidate_all_threads(struct target *target) {
4395  GHashTableIter iter;
4396  struct target_thread *tthread;
4397  unsigned int i;
4398 
4399  g_hash_table_iter_init(&iter,target->threads);
4400  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&tthread)) {
4401  if (target->ops->invalidate_thread)
4402  target->ops->invalidate_thread(target,tthread);
4403  else if (target->personality_ops
4404  && target->personality_ops->invalidate_thread)
4405  target->personality_ops->invalidate_thread(target,tthread);
4406 
4407  /*
4408  * XXX: Invalidate any valid regcaches. Not sure we should do this
4409  * here...
4410  */
4411  for (i = 0; i < target->max_thread_ctxt; ++i) {
4412  if (tthread->regcaches[i]) {
4413  regcache_invalidate(tthread->regcaches[i]);
4414  }
4415  }
4416 
4417  OBJSINVALID(tthread);
4418 
4419  if (OBJDIRTY(tthread))
4420  vwarn("invalidated dirty thread %"PRIiTID"; BUG?\n",tthread->tid);
4421  }
4422 
4423  return 0;
4424 }
4425 
4426 int target_invalidate_all_threads(struct target *target) {
4427  GHashTableIter iter;
4428  struct target *overlay;
4429  int rc;
4430 
4432  "invalidating all target(%s) threads\n",target->name);
4433 
4434  /*
4435  * Do it for all the overlays first.
4436  */
4437  g_hash_table_iter_init(&iter,target->overlays);
4438  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&overlay)) {
4440  "invalidating all overlay target(%s) threads\n",overlay->name);
4441  rc = target_invalidate_all_threads(overlay);
4443  "invalidating all overlay target(%s) threads (%d)\n",overlay->name,rc);
4444  }
4445 
4446  return __target_invalidate_all_threads(target);
4447 }
4448 
4451  tid_t tid,ADDR ipval,int *again) {
4452  return overlay->ops->handle_overlay_exception(overlay,flags,tid,ipval,again);
4453 }
4454 
4455 struct target *target_lookup_overlay(struct target *target,tid_t tid) {
4456  struct target *overlay;
4457 
4458  overlay = (struct target *) \
4459  g_hash_table_lookup(target->overlays,(gpointer)(uintptr_t)tid);
4460  if (!overlay)
4461  overlay = (struct target *) \
4462  g_hash_table_lookup(target->overlay_aliases,(gpointer)(uintptr_t)tid);
4463 
4464  return overlay;
4465 }
4466 
4467 void target_detach_overlay(struct target *base,tid_t overlaytid) {
4468  GHashTableIter iter;
4469  struct target *overlay;
4470  gpointer vp;
4471  REFCNT trefcnt;
4472 
4473  overlay = (struct target *) \
4474  g_hash_table_lookup(base->overlays,(gpointer)(uintptr_t)overlaytid);
4475  g_hash_table_remove(base->overlays,(gpointer)(uintptr_t)overlaytid);
4476 
4477  if (overlay) {
4478  g_hash_table_iter_init(&iter,base->overlay_aliases);
4479  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
4480  if (vp == overlay)
4481  g_hash_table_iter_remove(&iter);
4482  }
4483 
4484  RPUT(overlay,target,base,trefcnt);
4485  }
4486 }
4487 
4488 int target_attach_overlay_thread(struct target *base,struct target *overlay,
4489  tid_t newtid) {
4490  int rc;
4491 
4492  if (overlay->base != base || newtid == overlay->base_tid) {
4493  errno = EINVAL;
4494  return -1;
4495  }
4496 
4497  if (!base->ops->attach_overlay_thread) {
4498  errno = ENOTSUP;
4499  return -1;
4500  }
4501 
4502  if (target_lookup_overlay(base,newtid)) {
4503  errno = EADDRINUSE;
4504  return -1;
4505  }
4506 
4507  rc = base->ops->attach_overlay_thread(base,overlay,newtid);
4508  if (rc == 0) {
4509  g_hash_table_insert(base->overlay_aliases,(gpointer)(uintptr_t)newtid,
4510  overlay);
4511  }
4512 
4513  return rc;
4514 }
4515 
4516 int target_detach_overlay_thread(struct target *base,struct target *overlay,
4517  tid_t tid) {
4518  int rc;
4519  struct target_thread *tthread;
4520 
4521  if (tid == overlay->base_tid) {
4522  errno = EINVAL;
4523  return -1;
4524  }
4525 
4526  if (!base->ops->detach_overlay_thread) {
4527  errno = ENOTSUP;
4528  return -1;
4529  }
4530 
4531  tthread = (struct target_thread *) \
4532  g_hash_table_lookup(base->overlay_aliases,(gpointer)(uintptr_t)tid);
4533 
4534  /* May have already gone... */
4535  if (!tthread)
4536  return 0;
4537 
4538  rc = base->ops->detach_overlay_thread(base,overlay,tid);
4539  if (rc == 0) {
4540  g_hash_table_remove(base->overlay_aliases,(gpointer)(uintptr_t)tid);
4541  }
4542 
4543  return rc;
4544 }
4545 
4546 int target_attach_space(struct target *target,struct addrspace *space) {
4547  GList *t1;
4548  struct addrspace *lpc;
4549 
4550  /* make sure this space doesn't already exist: */
4551  v_g_list_foreach(target->spaces,t1,lpc) {
4552  if (((space->name && strcmp(space->name,lpc->name) == 0)
4553  || (space->name == NULL && lpc->name == NULL))
4554  && space->tag == lpc->tag) {
4555  verror("addrspace(%s:0x%"PRIxADDR") already attached to target %s!\n",
4556  space->name,space->tag,target->name);
4557  errno = EEXIST;
4558  return -1;
4559  }
4560  }
4561 
4562  target->spaces = g_list_append(target->spaces,space);
4563  RHOLD(space,target);
4564 
4565  return 0;
4566 }
4567 
4568 int target_detach_space(struct target *target,struct addrspace *space) {
4569  GList *t1;
4570  REFCNT trefcnt;
4571 
4572  if (!space->target || target != space->target) {
4573  verror("space(%s:0x%"PRIxADDR") not on target %s!\n",
4574  space->name,space->tag,target ? target->name : NULL);
4575  errno = EINVAL;
4576  return -1;
4577  }
4578 
4579  t1 = g_list_find(target->spaces,space);
4580  if (!t1) {
4581  verror("space(%s:0x%"PRIxADDR") not on target %s!\n",
4582  space->name,space->tag,target ? target->name : NULL);
4583  errno = ESRCH;
4584  return -1;
4585  }
4586 
4587  target->spaces = g_list_remove_link(target->spaces,t1);
4588 
4589  RPUT(space,addrspace,target,trefcnt);
4590 
4591  return 0;
4592 }
4593 
4594 struct probepoint *target_lookup_probepoint(struct target *target,
4595  struct target_thread *tthread,
4596  ADDR addr) {
4597  struct probepoint *retval;
4598 
4599  if (tthread
4600  && (retval = (struct probepoint *) \
4601  g_hash_table_lookup(tthread->hard_probepoints,(gpointer)addr))) {
4602  vdebug(9,LA_PROBE | LA_TARGET,LF_PROBEPOINT | LF_TARGET,"found hard ");
4604  retval);
4605  }
4606  else if ((retval = (struct probepoint *) \
4607  g_hash_table_lookup(target->soft_probepoints,(gpointer)addr))) {
4608  vdebug(9,LA_PROBE | LA_TARGET,LF_PROBEPOINT | LF_TARGET,"found soft ");
4610  retval);
4611  }
4612  else
4614  "no probepoint at 0x%"PRIxADDR"\n",addr);
4615 
4616  return retval;
4617 }
4618 
4619 int target_insert_probepoint(struct target *target,
4620  struct target_thread *tthread,
4621  struct probepoint *probepoint) {
4622  if (probepoint->style == PROBEPOINT_HW) {
4623  g_hash_table_insert(tthread->hard_probepoints,
4624  (gpointer)probepoint->addr,(gpointer)probepoint);
4625  probepoint->thread = tthread;
4626  }
4627  else if (probepoint->style == PROBEPOINT_SW) {
4628  g_hash_table_insert(target->soft_probepoints,
4629  (gpointer)probepoint->addr,(gpointer)probepoint);
4630  probepoint->thread = tthread;
4631  }
4632  else {
4633  verror("bad probepoint state %d; must be HW/SW!\n",probepoint->state);
4634  errno = EINVAL;
4635  return -1;
4636  }
4637 
4639  "inserted probepoint at 0x%"PRIxADDR" tid %"PRIiTID"\n",
4640  probepoint->addr,tthread->tid);
4641 
4642  return 0;
4643 }
4644 
4645 int target_remove_probepoint(struct target *target,
4646  struct target_thread *tthread,
4647  struct probepoint *probepoint) {
4648  if (probepoint->style == PROBEPOINT_HW) {
4649  g_hash_table_remove(tthread->hard_probepoints,(gpointer)probepoint->addr);
4650  probepoint->thread = NULL;
4651  }
4652  else if (probepoint->style == PROBEPOINT_SW) {
4653  g_hash_table_remove(target->soft_probepoints,(gpointer)probepoint->addr);
4654  probepoint->thread = NULL;
4655  }
4656  else {
4657  verror("bad probepoint state %d; must be HW/SW!\n",probepoint->state);
4658  errno = EINVAL;
4659  return -1;
4660  }
4661 
4663  "removed probepoint at 0x%"PRIxADDR" tid %"PRIiTID"\n",
4664  probepoint->addr,tthread->tid);
4665 
4666  return 0;
4667 }
4668 
4669 int target_attach_probe(struct target *target,struct target_thread *thread,
4670  struct probe *probe) {
4671  probe->id = target->probe_id_counter++;
4672  probe->target = target;
4673  probe->thread = thread;
4674 
4675  if (probe->tracked)
4676  g_hash_table_insert(target->probes,(gpointer)(uintptr_t)probe->id,probe);
4677 
4678  return probe->id;
4679 }
4680 
4681 int target_detach_probe(struct target *target,struct probe *probe) {
4682  if (probe->tracked)
4683  g_hash_table_remove(target->probes,(gpointer)(uintptr_t)probe->id);
4684 
4685  probe->id = -1;
4686  probe->target = NULL;
4687  probe->thread = NULL;
4688 
4689  return 0;
4690 }
4691 
4692 int target_attach_action(struct target *target,struct action *action) {
4693  action->id = target->action_id_counter++;
4694  action->target = target;
4695 
4696  g_hash_table_insert(target->actions,(gpointer)(uintptr_t)action->id,action);
4697 
4698  return action->id;
4699 }
4700 
4701 int target_detach_action(struct target *target,struct action *action) {
4702  g_hash_table_remove(target->actions,(gpointer)(uintptr_t)action->id);
4703 
4704  action->id = -1;
4705  action->target = NULL;
4706 
4707  return 0;
4708 }
4709 
4710 unsigned long target_memmod_length(struct target *target,
4711  struct target_memmod *mmod) {
4712  switch (mmod->state) {
4713  case MMS_SUBST:
4714  return mmod->mod_len;
4715  case MMS_ORIG:
4716  return 0;
4717  case MMS_TMP:
4718  return mmod->tmp_len;
4719  default:
4720  verror("unknown memmod state %d!\n",mmod->state);
4721  errno = EINVAL;
4722  return 0;
4723  }
4724 }
4725 
4726 struct target_memmod *target_memmod_create(struct target *target,tid_t tid,
4727  ADDR addr,int is_phys,
4729  unsigned char *code,
4730  unsigned int code_len,int nowrite) {
4731  struct target_memmod *mmod;
4732  unsigned char *ibuf = NULL;
4733  unsigned int ibuf_len;
4734  unsigned int rc;
4735  struct target_thread *tthread;
4736  unsigned char *rcc;
4737 
4738  tthread = target_lookup_thread(target,tid);
4739  if (!tthread) {
4740  verror("tid %"PRIiTID" does not exist!\n",tid);
4741  errno = ESRCH;
4742  return NULL;
4743  }
4744 
4745  mmod = calloc(1,sizeof(*mmod));
4746  mmod->state = MMS_SUBST;
4747  mmod->type = mmt;
4748  mmod->target = target;
4749  mmod->threads = array_list_create(1);
4750  mmod->addr = addr;
4751  mmod->is_phys = is_phys;
4752  mmod->no_write = nowrite;
4753 
4754  if (code) {
4755  /*
4756  * Backup the original memory. If debugging, read at least
4757  * 8 bytes so we can see what was there and dump it for debug
4758  * purposes. It is a bit wasteful in that case, but no big
4759  * deal.
4760  */
4761  if (code_len > 8)
4762  ibuf_len = code_len;
4763  else
4764  ibuf_len = 8;
4765  ibuf = calloc(1,ibuf_len);
4766 
4767  if (is_phys)
4768  rcc = target_read_physaddr(target,addr,ibuf_len,ibuf);
4769  else
4770  rcc = target_read_addr(target,addr,ibuf_len,ibuf);
4771 
4772  if (!rcc) {
4773  array_list_free(mmod->threads);
4774  free(ibuf);
4775  free(mmod);
4776  verror("could not read %u bytes at 0x%"PRIxADDR"!\n",
4777  ibuf_len,addr);
4778  return NULL;
4779  }
4780 
4781  mmod->orig_len = code_len;
4782  mmod->orig = calloc(1,mmod->orig_len);
4783 
4784  memcpy(mmod->orig,ibuf,mmod->orig_len);
4785 
4786  mmod->mod = malloc(code_len);
4787  mmod->mod_len = code_len;
4788  memcpy(mmod->mod,code,mmod->mod_len);
4789 
4790  if (nowrite)
4791  rc = mmod->mod_len;
4792  else if (is_phys)
4793  rc = target_write_physaddr(target,addr,mmod->mod_len,mmod->mod);
4794  else
4795  rc = target_write_addr(target,addr,mmod->mod_len,mmod->mod);
4796 
4797  if (rc != mmod->mod_len) {
4798  array_list_free(mmod->threads);
4799  free(mmod->mod);
4800  free(mmod->orig);
4801  free(mmod);
4802  verror("could not write %lu subst bytes at 0x%"PRIxADDR"!\n",
4803  mmod->orig_len,addr);
4804  return NULL;
4805  }
4806  }
4807 
4808  if (is_phys)
4809  g_hash_table_insert(target->phys_mmods,(gpointer)addr,mmod);
4810  else
4811  g_hash_table_insert(target->mmods,(gpointer)addr,mmod);
4812 
4813  array_list_append(mmod->threads,tthread);
4814 
4815  if (code) {
4817  "created memmod at 0x%"PRIxADDR" (is_phys=%d,no_write=%d) tid %"PRIiTID";"
4818  " inserted new bytes (orig mem: %02hhx %02hhx %02hhx %02hhx"
4819  " %02hhx %02hhx %02hhx %02hhx)\n",
4820  mmod->addr,is_phys,nowrite,tid,
4821  (int)ibuf[0],(int)ibuf[1],(int)ibuf[2],(int)ibuf[3],
4822  (int)ibuf[4],(int)ibuf[5],(int)ibuf[6],(int)ibuf[7]);
4823  }
4824  else {
4826  "created (fake) memmod at 0x%"PRIxADDR" (is_phys=%d) tid %"PRIiTID"\n",
4827  mmod->addr,is_phys,tid);
4828  }
4829 
4830  if (ibuf)
4831  free(ibuf);
4832 
4833  return mmod;
4834 }
4835 
4836 void target_memmod_set_writeable(struct target *target,
4837  struct target_memmod *mmod,int writeable) {
4838  mmod->no_write = !writeable;
4839 }
4840 
4841 struct target_memmod *target_memmod_lookup(struct target *target,tid_t tid,
4842  ADDR addr,int is_phys) {
4843  struct target_memmod *mmod;
4844  struct target_thread *tthread;
4845 
4846  tthread = target_lookup_thread(target,tid);
4847  if (!tthread) {
4848  verror("tid %"PRIiTID" does not exist!\n",tid);
4849  errno = ESRCH;
4850  return NULL;
4851  }
4852 
4853  /*
4854  * Eventually, the virt ->mmods hashtable will be per-thread.
4855  */
4856  if (is_phys)
4857  mmod = (struct target_memmod *) \
4858  g_hash_table_lookup(target->phys_mmods,(gpointer)addr);
4859  else
4860  mmod = (struct target_memmod *) \
4861  g_hash_table_lookup(target->mmods,(gpointer)addr);
4862 
4863  if (mmod)
4865  "found mmod 0x%"PRIxADDR" (phys=%d)\n",
4866  mmod->addr,mmod->is_phys);
4867  /*
4868  else
4869  vwarnopt(16,LA_TARGET,LF_TARGET,
4870  "did not find mmod for 0x%"PRIxADDR" (is_phys=%d)!\n",
4871  addr,is_phys);
4872  */
4873 
4874  return mmod;
4875 }
4876 
4877 int target_memmod_release(struct target *target,tid_t tid,
4878  struct target_memmod *mmod) {
4879  struct target_thread *tthread;
4880  ADDR addr;
4881 
4882  /*
4883  * Default implementation: just remove it if it is the last using
4884  * thread.
4885  */
4886  addr = mmod->addr;
4887 
4888  tthread = target_lookup_thread(target,tid);
4889  if (!tthread) {
4890  verror("tid %"PRIiTID" does not exist!\n",tid);
4891  errno = ESRCH;
4892  return -1;
4893  }
4894 
4895  if (array_list_remove_item(mmod->threads,tthread) != tthread) {
4896  vwarn("hm, tid %"PRIiTID" not on list for memmod at 0x%"PRIxADDR";"
4897  " BUG?!\n",tid,addr);
4898  errno = ESRCH;
4899  return -1;
4900  }
4901 
4903  "released memmod 0x%"PRIxADDR" (is_phys=%d) tid %"PRIiTID"\n",
4904  mmod->addr,mmod->is_phys,tid);
4905 
4906  /* If this is the last thread using it, be done now! */
4907  if (array_list_len(mmod->threads) == 0) {
4908  return target_memmod_free(target,tid,mmod,0);
4909  }
4910  else
4911  return array_list_len(mmod->threads);
4912 }
4913 
4914 int target_memmod_free(struct target *target,tid_t tid,
4915  struct target_memmod *mmod,int force) {
4916  unsigned int rc;
4917  int retval;
4918  ADDR addr;
4919  unsigned long (*writer)(struct target *target,ADDR paddr,
4920  unsigned long length,unsigned char *buf);
4921 
4922  if (mmod->is_phys)
4923  writer = target_write_physaddr;
4924  else
4925  writer = target_write_addr;
4926 
4927  retval = array_list_len(mmod->threads);
4928  addr = mmod->addr;
4929 
4930  /* If this is the last thread using it, be done now! */
4931  if (force || array_list_len(mmod->threads) == 0) {
4932  if (mmod->is_phys)
4933  g_hash_table_remove(target->phys_mmods,(gpointer)addr);
4934  else
4935  g_hash_table_remove(target->mmods,(gpointer)addr);
4936 
4937  if (mmod->tmp)
4938  free(mmod->tmp);
4939  if (mmod->mod)
4940  free(mmod->mod);
4941 
4942  if (!mmod->no_write && mmod->orig) {
4943  rc = writer(target,addr,mmod->orig_len,mmod->orig);
4944  if (rc != mmod->orig_len) {
4945  verror("could not restore orig memory at 0x%"PRIxADDR";"
4946  " but cannot do anything!\n",addr);
4947  retval = -1;
4948  }
4949  }
4950 
4952  "freed memmod 0x%"PRIxADDR" (is_phys=%d) tid %"PRIiTID"\n",
4953  mmod->addr,mmod->is_phys,tid);
4954 
4955  array_list_free(mmod->threads);
4956  free(mmod->orig);
4957  free(mmod);
4958 
4959  retval = 0;
4960  }
4961 
4962  return retval;
4963 }
4964 
4965 int target_memmod_set(struct target *target,tid_t tid,
4966  struct target_memmod *mmod) {
4967  ADDR addr;
4968  struct target_thread *tthread;
4969  unsigned int rc;
4970  unsigned long (*writer)(struct target *target,ADDR paddr,
4971  unsigned long length,unsigned char *buf);
4972 
4973  if (mmod->is_phys)
4974  writer = target_write_physaddr;
4975  else
4976  writer = target_write_addr;
4977 
4978  /*
4979  * Default implementation: enable it if necessary; swap mod bytes
4980  * into place, if state is not already SUBST.
4981  */
4982  addr = mmod->addr;
4983 
4984  tthread = target_lookup_thread(target,tid);
4985  if (!tthread) {
4986  vwarn("tid %"PRIiTID" does not exist!\n",tid);
4987  }
4988 
4989  if (mmod->owner && mmod->owner != tthread) {
4990  vwarn("memmod owned by tid %"PRIiTID", not tid %"PRIiTID"; ignoring!\n",
4991  mmod->owner->tid,tthread->tid);
4992  }
4993 
4994  switch (mmod->state) {
4995  case MMS_SUBST:
4997  "(was already) memmod 0x%"PRIxADDR" (is_phys=%d)"
4998  " tid %"PRIiTID"\n",
4999  mmod->addr,mmod->is_phys,tid);
5000  mmod->owner = NULL;
5001  return 0;
5002  case MMS_ORIG:
5003  if (mmod->no_write)
5004  rc = mmod->mod_len;
5005  else
5006  rc = writer(target,addr,mmod->mod_len,mmod->mod);
5007  if (rc != mmod->mod_len) {
5008  verror("could not insert subst memory at 0x%"PRIxADDR"!\n",addr);
5009  return -1;
5010  }
5011  mmod->state = MMS_SUBST;
5013  "(was orig) memmod 0x%"PRIxADDR" (is_phys=%d)"
5014  " tid %"PRIiTID"\n",
5015  mmod->addr,mmod->is_phys,tid);
5016  mmod->owner = NULL;
5017  return 0;
5018  case MMS_TMP:
5019  if (mmod->tmp) {
5020  free(mmod->tmp);
5021  mmod->tmp = NULL;
5022  mmod->tmp_len = 0;
5023  }
5024  if (mmod->no_write)
5025  rc = mmod->mod_len;
5026  else
5027  rc = writer(target,addr,mmod->mod_len,mmod->mod);
5028  if (rc != mmod->mod_len) {
5029  verror("could not insert subst memory at 0x%"PRIxADDR"!\n",addr);
5030  return -1;
5031  }
5032  mmod->state = MMS_SUBST;
5034  "(was tmp) memmod 0x%"PRIxADDR" (is_phys=%d)"
5035  " tid %"PRIiTID"\n",
5036  mmod->addr,mmod->is_phys,tid);
5037  mmod->owner = NULL;
5038  return 0;
5039  default:
5040  verror("unknown memmod state %d!\n",mmod->state);
5041  errno = EINVAL;
5042  return -1;
5043  }
5044 }
5045 
5046 int target_memmod_unset(struct target *target,tid_t tid,
5047  struct target_memmod *mmod) {
5048  ADDR addr;
5049  struct target_thread *tthread;
5050  unsigned int rc;
5051  unsigned long (*writer)(struct target *target,ADDR paddr,
5052  unsigned long length,unsigned char *buf);
5053 
5054  if (mmod->is_phys)
5055  writer = target_write_physaddr;
5056  else
5057  writer = target_write_addr;
5058 
5059  /*
5060  * Default implementation: disable it if necessary; swap orig bytes
5061  * into place, if state is not already ORIG.
5062  */
5063  addr = mmod->addr;
5064 
5065  tthread = target_lookup_thread(target,tid);
5066  if (!tthread) {
5067  vwarn("tid %"PRIiTID" does not exist!\n",tid);
5068  }
5069 
5070  if (mmod->owner && mmod->owner != tthread) {
5071  vwarn("memmod owned by tid %"PRIiTID", not tid %"PRIiTID"; ignoring!\n",
5072  mmod->owner->tid,tthread->tid);
5073  }
5074 
5075  switch (mmod->state) {
5076  case MMS_ORIG:
5078  "(was already) memmod 0x%"PRIxADDR" (is_phys=%d)"
5079  " tid %"PRIiTID"\n",
5080  mmod->addr,mmod->is_phys,tid);
5081  mmod->owner = tthread;
5082  return 0;
5083  case MMS_SUBST:
5084  if (mmod->no_write)
5085  rc = mmod->mod_len;
5086  else
5087  rc = writer(target,addr,mmod->orig_len,mmod->orig);
5088  if (rc != mmod->orig_len) {
5089  verror("could not restore orig memory at 0x%"PRIxADDR"!\n",addr);
5090  return -1;
5091  }
5092  mmod->state = MMS_ORIG;
5094  "(was set) memmod 0x%"PRIxADDR" (is_phys=%d)"
5095  " tid %"PRIiTID"\n",
5096  mmod->addr,mmod->is_phys,tid);
5097  mmod->owner = tthread;
5098  return 0;
5099  case MMS_TMP:
5100  if (mmod->tmp) {
5101  free(mmod->tmp);
5102  mmod->tmp = NULL;
5103  mmod->tmp_len = 0;
5104  }
5105  if (mmod->no_write)
5106  rc = mmod->mod_len;
5107  else
5108  rc = writer(target,addr,mmod->orig_len,mmod->orig);
5109  if (rc != mmod->orig_len) {
5110  verror("could not restore orig memory at 0x%"PRIxADDR"!\n",addr);
5111  return -1;
5112  }
5113  mmod->state = MMS_ORIG;
5114  mmod->owner = tthread;
5115  return 0;
5116  default:
5117  verror("unknown memmod state %d!\n",mmod->state);
5118  errno = EINVAL;
5119  return -1;
5120  }
5121 }
5122 
5123 int target_memmod_set_tmp(struct target *target,tid_t tid,
5124  struct target_memmod *mmod,
5125  unsigned char *code,unsigned long code_len) {
5126  ADDR addr;
5127  struct target_thread *tthread;
5128  unsigned int rc;
5129  unsigned char *new;
5130  unsigned int new_len;
5131  unsigned long (*writer)(struct target *target,ADDR paddr,
5132  unsigned long length,unsigned char *buf);
5133 
5134  if (mmod->is_phys)
5135  writer = target_write_physaddr;
5136  else
5137  writer = target_write_addr;
5138 
5139  /*
5140  * Default implementation: swap custom bytes into tmp, no matter
5141  * what state is. If the new @code_len is longer than our currently
5142  * saved orig_len, we need to extend the saved bytes in orig
5143  * correspondingly. Also, if @code_len is *shorter* than whatever
5144  * has currently been substituted in, we need to write the new
5145  * thing, plus put the "old" bytes back in. So, those two cases.
5146  */
5147  addr = mmod->addr;
5148 
5149  tthread = target_lookup_thread(target,tid);
5150  if (!tthread) {
5151  vwarn("tid %"PRIiTID" does not exist!\n",tid);
5152  }
5153 
5154  if (mmod->owner && mmod->owner != tthread) {
5155  vwarn("memmod owned by tid %"PRIiTID", not tid %"PRIiTID"; ignoring!\n",
5156  mmod->owner->tid,tthread->tid);
5157  }
5158 
5159  /*
5160  * If we are writing more stuff into the memmod than we wrote
5161  * initially, save more bytes!
5162  */
5163  if (code_len > mmod->orig_len) {
5164  mmod->orig = realloc(mmod->orig,code_len);
5165  if (!target_read_addr(target,mmod->addr,code_len - mmod->orig_len,
5166  mmod->orig + mmod->orig_len)) {
5167  verror("could not increase original saved bytes at 0x%"PRIxADDR"!\n",
5168  mmod->addr);
5169  return -1;
5170  }
5171  mmod->orig_len = code_len;
5172  }
5173 
5174  switch (mmod->state) {
5175  case MMS_TMP:
5176  if (code_len < mmod->tmp_len) {
5177  new = malloc(mmod->orig_len);
5178  new_len = mmod->orig_len;
5179  memcpy(new,mmod->orig,new_len);
5180  }
5181  else {
5182  new = malloc(code_len);
5183  new_len = code_len;
5184  memcpy(new,code,code_len);
5185  }
5186  free(mmod->tmp);
5187  mmod->tmp_len = 0;
5189  "(was tmp) memmod 0x%"PRIxADDR" (is_phys=%d)"
5190  " tid %"PRIiTID"\n",
5191  mmod->addr,mmod->is_phys,tid);
5192  break;
5193  case MMS_SUBST:
5194  if (code_len < mmod->mod_len) {
5195  new = malloc(mmod->orig_len);
5196  new_len = mmod->orig_len;
5197  memcpy(new,mmod->orig,new_len);
5198  }
5199  else {
5200  new = malloc(code_len);
5201  new_len = code_len;
5202  memcpy(new,code,code_len);
5203  }
5205  "(was set) memmod 0x%"PRIxADDR" (is_phys=%d)"
5206  " tid %"PRIiTID"\n",
5207  mmod->addr,mmod->is_phys,tid);
5208  break;
5209  case MMS_ORIG:
5210  new = malloc(code_len);
5211  new_len = code_len;
5212  memcpy(new,code,code_len);
5214  "(was orig) memmod 0x%"PRIxADDR" (is_phys=%d)"
5215  " tid %"PRIiTID"\n",
5216  mmod->addr,mmod->is_phys,tid);
5217  break;
5218  default:
5219  verror("unknown memmod state %d!\n",mmod->state);
5220  errno = EINVAL;
5221  return -1;
5222  }
5223 
5224  if (mmod->no_write)
5225  rc = mmod->mod_len;
5226  else
5227  rc = writer(target,addr,new_len,new);
5228  if (rc != new_len) {
5229  verror("could not write tmp memory at 0x%"PRIxADDR"!\n",addr);
5230  free(new);
5231  return -1;
5232  }
5233 
5234  mmod->tmp = new;
5235  mmod->tmp_len = new_len;
5236 
5237  mmod->state = MMS_TMP;
5238  mmod->owner = tthread;
5239 
5240  return 0;
5241 }
5242 
5243 struct target_location_ctxt *target_global_tlctxt(struct target *target) {
5244  return target->global_tlctxt;
5245 }
5246 
5247 struct target_location_ctxt *
5248 target_location_ctxt_create(struct target *target,tid_t tid,
5249  struct memregion *region) {
5250  struct target_location_ctxt *tlctxt;
5251 
5252  tlctxt = calloc(1,sizeof(*tlctxt));
5253  tlctxt->thread = target_lookup_thread(target,tid);
5254  if (!tlctxt->thread) {
5255  free(tlctxt);
5256  verror("could not lookup thread %"PRIiTID"!\n",tid);
5257  return NULL;
5258  }
5259  tlctxt->region = region;
5260  if (!target->location_ops)
5261  tlctxt->lctxt = location_ctxt_create(&target_location_ops,tlctxt);
5262  else
5263  tlctxt->lctxt = location_ctxt_create(target->location_ops,tlctxt);
5264 
5265  return tlctxt;
5266 }
5267 
5268 struct target_location_ctxt *
5270  struct bsymbol *bsymbol) {
5271  struct target_location_ctxt *tlctxt;
5272 
5273  tlctxt = calloc(1,sizeof(*tlctxt));
5274  tlctxt->thread = target_lookup_thread(target,tid);
5275  if (!tlctxt->thread) {
5276  free(tlctxt);
5277  verror("could not lookup thread %"PRIiTID"!\n",tid);
5278  return NULL;
5279  }
5280  tlctxt->region = bsymbol->region;
5281  tlctxt->lctxt = location_ctxt_create(&target_location_ops,tlctxt);
5282 
5283  return tlctxt;
5284 }
5285 
5286 void
5288  struct bsymbol *bsymbol) {
5289  tlctxt->region = bsymbol->region;
5290 }
5291 
5293  if (tlctxt->lctxt)
5294  location_ctxt_free(tlctxt->lctxt);
5295  free(tlctxt);
5296 }
5297 
5298 struct target_location_ctxt *target_unwind(struct target *target,tid_t tid) {
5299  struct target_location_ctxt *tlctxt;
5300  struct target_location_ctxt_frame *tlctxtf;
5301  struct target_thread *tthread;
5302  REGVAL ipval;
5303  struct bsymbol *bsymbol = NULL;
5304  struct bsymbol *alt_bsymbol = NULL;
5305  int rc;
5306 
5307  if (target->ops->unwind)
5308  return target->ops->unwind(target,tid);
5309 
5310  tthread = target_lookup_thread(target,tid);
5311  if (!tthread) {
5312  verror("tid %"PRIiTID" does not exist!\n",tid);
5313  errno = ESRCH;
5314  return NULL;
5315  }
5316 
5317  errno = 0;
5318  ipval = target_read_reg(target,tid,target->ipregno);
5319  if (errno) {
5320  verror("could not read IP in tid %"PRIiTID"!\n",tid);
5321  return NULL;
5322  }
5323 
5324  rc = target_lookup_sym_addr_alt(target,ipval,&bsymbol,&alt_bsymbol);
5325  if (rc) {
5326  verror("could not find symbol for IP addr 0x%"PRIxADDR"!\n",ipval);
5327  errno = EADDRNOTAVAIL;
5328  return NULL;
5329  }
5330 
5331  /* Ok, we have enough info to start unwinding. */
5332 
5333  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,
5334  bsymbol ? bsymbol : alt_bsymbol);
5335  tlctxt->frames = array_list_create(8);
5336 
5337  /*
5338  * Create the 0-th frame (current) (with a per-frame lops_priv).
5339  *
5340  * For each frame we create, its private target_location_ctxt->lctxt
5341  * is just a *ref* to unw->tlctxt->lctxt; this will get fixed
5342  * eventually; for now, see target_unwind_free() for our care in
5343  * handling this.
5344  */
5345  tlctxtf = calloc(1,sizeof(*tlctxtf));
5346  tlctxtf->tlctxt = tlctxt;
5347  tlctxtf->frame = 0;
5348  tlctxtf->bsymbol = bsymbol;
5349  tlctxtf->alt_bsymbol = alt_bsymbol;
5350  tlctxtf->registers = g_hash_table_new(g_direct_hash,g_direct_equal);
5351 
5352  g_hash_table_insert(tlctxtf->registers,
5353  (gpointer)(uintptr_t)tlctxt->thread->target->ipregno,
5354  (gpointer)(uintptr_t)ipval);
5355 
5356  array_list_append(tlctxt->frames,tlctxtf);
5357 
5358  return tlctxt;
5359 }
5360 
5362  struct target *target;
5363  tid_t tid;
5364  struct target_location_ctxt_frame *tlctxtf;
5365  REGVAL ipval;
5366  struct bsymbol *bsymbol = NULL;
5367  struct bsymbol *alt_bsymbol = NULL;
5368  int rc;
5369 
5370  if (tlctxt->frames) {
5371  errno = EALREADY;
5372  return -1;
5373  }
5374  if (!tlctxt->thread) {
5375  errno = EINVAL;
5376  return -1;
5377  }
5378  target = tlctxt->thread->target;
5379  tid = tlctxt->thread->tid;
5380 
5381  errno = 0;
5382  ipval = target_read_reg(target,tid,target->ipregno);
5383  if (errno) {
5384  verror("could not read IP in tid %"PRIiTID"!\n",tid);
5385  return -1;
5386  }
5387 
5388  rc = target_lookup_sym_addr_alt(target,ipval,&bsymbol,&alt_bsymbol);
5389  if (rc) {
5390  verror("could not find symbol for IP addr 0x%"PRIxADDR"!\n",ipval);
5391  errno = EADDRNOTAVAIL;
5392  return -1;
5393  }
5394 
5395  /* Ok, we have enough info to start unwinding. */
5396 
5397  tlctxt->region = bsymbol->region;
5398  tlctxt->frames = array_list_create(8);
5399 
5400  /*
5401  * Create the 0-th frame (current) (with a per-frame lops_priv).
5402  *
5403  * For each frame we create, its private target_location_ctxt->lctxt
5404  * is just a *ref* to unw->tlctxt->lctxt; this will get fixed
5405  * eventually; for now, see target_unwind_free() for our care in
5406  * handling this.
5407  */
5408  tlctxtf = calloc(1,sizeof(*tlctxtf));
5409  tlctxtf->tlctxt = tlctxt;
5410  tlctxtf->frame = 0;
5411  tlctxtf->bsymbol = bsymbol;
5412  tlctxtf->alt_bsymbol = alt_bsymbol;
5413  tlctxtf->registers = g_hash_table_new(g_direct_hash,g_direct_equal);
5414 
5415  g_hash_table_insert(tlctxtf->registers,
5416  (gpointer)(uintptr_t)tlctxt->thread->target->ipregno,
5417  (gpointer)(uintptr_t)ipval);
5418 
5419  array_list_append(tlctxt->frames,tlctxtf);
5420 
5421  return 0;
5422 }
5423 
5424 int target_unwind_snprintf(char *buf,int buflen,struct target *target,tid_t tid,
5425  target_unwind_style_t fstyle,
5426  char *frame_sep,char *ksep) {
5427  struct target_location_ctxt *tlctxt;
5428  struct target_location_ctxt_frame *tlctxtf;
5429  int i,j,k;
5430  int rc = 0;
5431  int retval;
5432  REG ipreg;
5433  REGVAL ipval;
5434  char *srcfile = NULL;
5435  int srcline;
5436  char *name;
5437  struct lsymbol *lsymbol = NULL;
5438  struct bsymbol *bsymbol = NULL;
5439  struct value *v;
5440  char vbuf[1024];
5441  GSList *args;
5442  GSList *gsltmp;
5443  struct symbol *argsym;
5444 
5445  if (!buf) {
5446  errno = EINVAL;
5447  return -1;
5448  }
5449 
5450  if (!frame_sep)
5451  frame_sep = "|";
5452  if (!ksep)
5453  ksep = ",";
5454 
5455  vdebug(16,LA_TARGET,LF_TARGET,"target(%s:%"PRIiTID") thread(%d)\n",
5456  target->name,tid);
5457 
5458  tlctxt = target_unwind(target,tid);
5459  if (!tlctxt)
5460  return -1;
5461 
5462  if (target_cregno(target,CREG_IP,&ipreg)) {
5463  verror("target(%s:%"PRIiTID") has no IP reg!\n",target->name,tid);
5464  return -1;
5465  }
5466 
5467  j = 0;
5468  while (1) {
5469  tlctxtf = target_location_ctxt_current_frame(tlctxt);
5470 
5471  ipval = 0;
5472  target_location_ctxt_read_reg(tlctxt,ipreg,&ipval);
5473 
5474  srcline = 0;
5475  srcfile = NULL;
5476  if (target_lookup_filename_line_addr(target,ipval,&srcfile,&srcline) > 0)
5477  ;
5478  else if (tlctxtf->bsymbol) {
5479  srcfile = symbol_get_srcfile(bsymbol_get_symbol(tlctxtf->bsymbol));
5480  srcline = symbol_get_srcline(bsymbol_get_symbol(tlctxtf->bsymbol));
5481  }
5482  else {
5483  srcfile = NULL;
5484  srcline = 0;
5485  }
5486 
5487  if (j > 0) {
5488  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,"%s",frame_sep);
5489  if (retval < 0) {
5491  "snprintf(frame_sep %d): %s\n",
5492  j,strerror(errno));
5493  goto err;
5494  }
5495  else
5496  rc += retval;
5497  }
5498 
5499  name = NULL;
5500  if (tlctxtf->bsymbol)
5501  name = bsymbol_get_name(tlctxtf->bsymbol);
5502  /* If this was a file symbol, try to find something better! */
5503  if ((!name
5504  || !tlctxtf->bsymbol
5506  && tlctxtf->alt_bsymbol)
5507  name = bsymbol_get_name(tlctxtf->alt_bsymbol);
5508  if (!name)
5509  name = "";
5510 
5511  if (fstyle == TARGET_UNWIND_STYLE_GDB)
5512  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,
5513  "#%d 0x%"PRIxFULLADDR" in %s (",
5514  j,ipval,name);
5515  else if (fstyle == TARGET_UNWIND_STYLE_PROG_KEYS)
5516  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,
5517  "frame=%d%sip=0x%"PRIxFULLADDR"%sfunction=%s%sargs=(",
5518  j,ksep,ipval,ksep,name,ksep);
5519  else
5520  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,
5521  "%d%s0x%"PRIxFULLADDR"%s%s%s(",
5522  j,ksep,ipval,ksep,name,ksep);
5523  if (retval < 0) {
5524  vwarnopt(3,LA_TARGET,LF_TARGET,"snprintf(frame header): %s\n",
5525  strerror(errno));
5526  goto err;
5527  }
5528  else
5529  rc += retval;
5530 
5531  if (tlctxtf->bsymbol) {
5534  i = 0;
5535  v_g_slist_foreach(args,gsltmp,argsym) {
5537  argsym);
5538 
5539  if (i > 0) {
5540  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,"%s",ksep);
5541  if (retval < 0) {
5543  "snprintf(ksep %d): %s\n",
5544  i,strerror(errno));
5545  goto err;
5546  }
5547  else
5548  rc += retval;
5549  }
5550 
5551  if (lsymbol)
5552  bsymbol = bsymbol_create(lsymbol,tlctxtf->bsymbol->region);
5553  else
5554  bsymbol = NULL;
5555  name = symbol_get_name(argsym);
5556  if (!name)
5557  name = "?";
5558 
5559  if (bsymbol)
5560  v = target_load_symbol(target,tlctxt,bsymbol,
5561  //LOAD_FLAG_AUTO_DEREF |
5563  else
5564  v = NULL;
5565 
5566  vbuf[0] = '\0';
5567  if (v) {
5568  if (value_snprintf(v,vbuf,sizeof(vbuf)) < 0) {
5569  vwarnopt(5,LA_TARGET,LF_TARGET,"<value_snprintf error>");
5570 
5571  snprintf(vbuf,sizeof(vbuf),"0x");
5572  for (k = 0; k < v->bufsiz && k < (int)sizeof(vbuf); ++k) {
5573  snprintf(vbuf + 2 + 2 * k,sizeof(vbuf) - 2 - 2 * k,
5574  "%02hhx",v->buf[k]);
5575  }
5576  }
5577  value_free(v);
5578  }
5579  else
5580  snprintf(vbuf,sizeof(vbuf),"?");
5581 
5582  if (fstyle == TARGET_UNWIND_STYLE_GDB
5583  || fstyle == TARGET_UNWIND_STYLE_PROG_KEYS)
5584  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,"%s=%s",name,vbuf);
5585  else
5586  retval = snprintf(buf + rc,((buflen - rc) > 0) ? buflen - rc : 0,"%s",vbuf);
5587  if (retval < 0) {
5588  vwarnopt(3,LA_TARGET,LF_TARGET,"snprintf(arg %d): %s\n",
5589  i,strerror(errno));
5590  goto err;
5591  }
5592  else
5593  rc += retval;
5594 
5595  ++i;
5596 
5597  if (bsymbol)
5598  bsymbol_release(bsymbol);
5599  bsymbol = NULL;
5600  if (lsymbol)
5601  lsymbol_release(lsymbol);
5602  lsymbol = NULL;
5603  }
5604  }
5605 
5606  if (fstyle == TARGET_UNWIND_STYLE_GDB)
5607  retval = snprintf(buf + rc, ((buflen - rc) > 0) ? buflen - rc : 0,
5608  ") at %s:%d",srcfile,srcline);
5609  else if (fstyle == TARGET_UNWIND_STYLE_PROG_KEYS)
5610  retval = snprintf(buf + rc, ((buflen - rc) > 0) ? buflen - rc : 0,
5611  ")%ssrcfile=%s%ssrcline=%d",
5612  ksep,srcfile,ksep,srcline);
5613  else
5614  retval = snprintf(buf + rc, ((buflen - rc) > 0) ? buflen - rc : 0,
5615  ")%s%s%s%d",
5616  ksep,srcfile,ksep,srcline);
5617  if (retval < 0) {
5618  vwarnopt(3,LA_TARGET,LF_TARGET,"snprintf(arg %d): %s\n",
5619  j,strerror(errno));
5620  goto err;
5621  }
5622  else
5623  rc += retval;
5624 
5625  tlctxtf = target_location_ctxt_prev(tlctxt);
5626  if (!tlctxtf)
5627  break;
5628 
5629  ++j;
5630  }
5631  target_location_ctxt_free(tlctxt);
5632 
5633  return rc;
5634 
5635  err:
5636  if (bsymbol)
5637  bsymbol_release(bsymbol);
5638  if (lsymbol)
5639  lsymbol_release(lsymbol);
5640 
5641  return retval;
5642 }
5643 
5646  return (struct target_location_ctxt_frame *) \
5647  array_list_item(tlctxt->frames,frame);
5648 }
5649 
5652 
5653  if (!tlctxt->frames)
5654  return NULL;
5655  return (struct target_location_ctxt_frame *) \
5656  array_list_item(tlctxt->frames,tlctxt->lctxt->current_frame);
5657 }
5658 
5660  REG reg,REGVAL *o_regval) {
5661  struct target_location_ctxt_frame *tlctxtf;
5662  REGVAL regval;
5663  gpointer v;
5664 
5665  if (tlctxt->thread->target->ops->unwind_read_reg)
5666  return tlctxt->thread->target->ops->unwind_read_reg(tlctxt,reg,o_regval);
5667 
5668  /*
5669  * Just use target_read_reg if this is frame 0.
5670  */
5671  if (tlctxt->lctxt->current_frame == 0) {
5672  errno = 0;
5673  regval = target_read_reg(tlctxt->thread->target,
5674  tlctxt->thread->tid,reg);
5675  if (errno)
5676  return -1;
5677  if (o_regval)
5678  *o_regval = regval;
5679  return 0;
5680  }
5681 
5682  tlctxtf = target_location_ctxt_current_frame(tlctxt);
5683 
5684  if (!tlctxtf->registers) {
5685  errno = EBADSLT;
5686  return -1;
5687  }
5688 
5689  /*
5690  * Check the cache first.
5691  */
5692  if (g_hash_table_lookup_extended(tlctxtf->registers,
5693  (gpointer)(uintptr_t)reg,NULL,&v) == TRUE) {
5694  if (o_regval)
5695  *o_regval = (REGVAL)v;
5696  return 0;
5697  }
5698 
5699  /*
5700  * Try to read it via location_ctxt_read_reg.
5701  */
5702  return location_ctxt_read_reg(tlctxtf->tlctxt->lctxt,reg,o_regval);
5703 }
5704 
5705 /*
5706  * What we want to do is read the current return address register; if it
5707  * doesn't exist there is no caller frame, this is it; if there is one,
5708  * "infer" the IP in @frame that called @frame - 1; create a new
5709  * location_ctxt_frame from the caller's symbol; fill the register cache
5710  * for @frame based on @frame - 1's CFA program (which determines its
5711  * return address and callee-saved registers within @frame -1's
5712  * activation).
5713  */
5716  struct target_location_ctxt_frame *tlctxtf;
5717  struct target_location_ctxt_frame *new;
5718  int rc;
5719  ADDR current_ip = 0;
5720  ADDR retaddr;
5721  struct bsymbol *bsymbol = NULL;
5722  struct bsymbol *alt_bsymbol = NULL;
5723  REG rbp;
5724  REG rsp = -1;
5725  ADDR bp = 0,sp = 0,old_bp = 0,old_sp = 0;
5726 
5727  if (!tlctxt->frames) {
5728  errno = EINVAL;
5729  return NULL;
5730  }
5731 
5732 #define __SWC 64
5733 
5734  if (tlctxt->thread->target->ops->unwind_prev)
5735  return tlctxt->thread->target->ops->unwind_prev(tlctxt);
5736 
5737  /* Just return it if it already exists. */
5738  new = (struct target_location_ctxt_frame *) \
5739  array_list_item(tlctxt->frames,tlctxt->lctxt->current_frame + 1);
5740  if (new)
5741  return new;
5742 
5743  tlctxtf = (struct target_location_ctxt_frame *) \
5744  array_list_item(tlctxt->frames,tlctxt->lctxt->current_frame);
5745 
5746  rsp = tlctxt->thread->target->spregno;
5747  errno = 0;
5748  rc = location_ctxt_read_reg(tlctxt->lctxt,rsp,&sp);
5749  errno = 0;
5750  rc = location_ctxt_read_reg(tlctxt->lctxt,tlctxt->thread->target->ipregno,
5751  &current_ip);
5752 
5753  if (vdebug_is_on(8,LA_TARGET,LF_TUNW)) {
5754  vdebug(8,LA_TARGET,LF_TUNW," current stack:\n");
5755  char *pp;
5756  char *tmp;
5757  tmp = malloc(__SWC * tlctxt->thread->target->arch->wordsize);
5758  target_read_addr(tlctxt->thread->target,sp,
5759  __SWC * tlctxt->thread->target->arch->wordsize,
5760  (unsigned char *)tmp);
5761  pp = tmp + (__SWC - 1) * tlctxt->thread->target->arch->wordsize;
5762  while (pp >= tmp) {
5763  if (tlctxt->thread->target->arch->wordsize == 8) {
5764  vdebug(8,LA_TARGET,LF_TUNW," 0x%"PRIxADDR" == %"PRIxADDR"\n",
5765  sp + (pp - tmp),*(uint64_t *)pp);
5766  }
5767  else {
5768  vdebug(8,LA_TARGET,LF_TUNW," 0x%"PRIxADDR" == %"PRIxADDR"\n",
5769  sp + (pp - tmp),(ADDR)*(uint32_t *)pp);
5770  }
5771  pp -= tlctxt->thread->target->arch->wordsize;
5772  }
5773  vdebug(8,LA_TARGET,LF_TUNW,"\n");
5774  free(tmp);
5775  }
5776  if (vdebug_is_on(8,LA_TARGET,LF_TUNW)) {
5777  vdebug(8,LA_TARGET,LF_TUNW," current (beyond) stack:\n");
5778  char *pp;
5779  char *tmp;
5780  tmp = malloc(__SWC * tlctxt->thread->target->arch->wordsize);
5781  target_read_addr(tlctxt->thread->target,
5782  sp - __SWC * tlctxt->thread->target->arch->wordsize,
5783  __SWC * tlctxt->thread->target->arch->wordsize,
5784  (unsigned char *)tmp);
5785  pp = tmp + (__SWC - 1) * tlctxt->thread->target->arch->wordsize;
5786  while (pp >= tmp) {
5787  if (tlctxt->thread->target->arch->wordsize == 8) {
5788  vdebug(8,LA_TARGET,LF_TUNW," 0x%"PRIxADDR" == %"PRIxADDR"\n",
5789  sp - __SWC * tlctxt->thread->target->arch->wordsize + (pp - tmp),*(uint64_t *)pp);
5790  }
5791  else {
5792  vdebug(8,LA_TARGET,LF_TUNW," 0x%"PRIxADDR" == %"PRIxADDR"\n",
5793  sp - __SWC * tlctxt->thread->target->arch->wordsize + (pp - tmp),(ADDR)*(uint32_t *)pp);
5794  }
5795  pp -= tlctxt->thread->target->arch->wordsize;
5796  }
5797  vdebug(8,LA_TARGET,LF_TUNW,"\n");
5798  free(tmp);
5799  }
5800 
5801  retaddr = 0;
5802  rc = 1;
5803  if (tlctxtf->bsymbol || tlctxtf->alt_bsymbol) {
5804  rc = location_ctxt_read_retaddr(tlctxt->lctxt,&retaddr);
5805  if (rc) {
5807  "could not read retaddr in current_frame %d from symbol;"
5808  " will try to infer it!!\n",tlctxt->lctxt->current_frame);
5809  }
5810  }
5811 
5812  if (rc) {
5814  "no symbol in current frame; will try to infer retaddr"
5815  " and next symbol!\n");
5816 
5817  /*
5818  * Just read *%bp to get the previous BP; and read *(%bp + 8)
5819  * to get the retaddr; then assume the sp in the previous frame
5820  * is *(%bp + 16). This assumes no -fomit-frame-pointer.
5821  */
5822  if (target_cregno(tlctxt->thread->target,CREG_BP,&rbp)) {
5823  verror("target %s has no frame pointer register!\n",
5824  tlctxt->thread->target->name);
5825  return NULL;
5826  }
5827  errno = 0;
5828  rc = location_ctxt_read_reg(tlctxt->lctxt,rbp,&bp);
5829  if (rc) {
5830  vwarn("could not read %%bp to manually unwind; halting!\n");
5831  return NULL;
5832  }
5833 
5834  /* Get the old bp and retaddr. */
5835  target_read_addr(tlctxt->thread->target,bp,
5836  tlctxt->thread->target->arch->wordsize,
5837  (unsigned char *)&old_bp);
5838  target_read_addr(tlctxt->thread->target,
5839  bp + tlctxt->thread->target->arch->wordsize,
5840  tlctxt->thread->target->arch->wordsize,
5841  (unsigned char *)&retaddr);
5842  /* Adjust the stack pointer. */
5843  old_sp = bp + 16;
5844 
5846  "current bp 0x%"PRIxADDR",sp=0x%"PRIxADDR
5847  " => retaddr 0x%"PRIxADDR
5848  ",old_bp 0x%"PRIxADDR",old_sp 0x%"PRIxADDR"\n",
5849  bp,sp,retaddr,old_bp,old_sp);
5850  }
5851 
5853  "retaddr of current frame %d is 0x%"PRIxADDR"\n",
5854  tlctxt->lctxt->current_frame,retaddr);
5855 
5856  if (current_ip == 0 && retaddr == 0) {
5857  verror("aborting stack trace; two 0x0 retaddrs in a row!\n");
5858  return NULL;
5859  }
5860 
5861  /*
5862  * Look up the new symbol.
5863  */
5864  rc = target_lookup_sym_addr_alt(tlctxt->thread->target,retaddr,
5865  &bsymbol,&alt_bsymbol);
5866  if (rc)
5867  vwarn("could not find symbol for IP addr 0x%"PRIxADDR"!\n",retaddr);
5868 
5869  /*
5870  * Create the i-th frame (current) (with a per-frame lops_priv).
5871  *
5872  * For each frame we create, its private target_location_ctxt->lctxt
5873  * is just a *ref* to tlctxt->tlctxt->lctxt; this will get fixed
5874  * eventually; for now, see target_unwind_free() for our care in
5875  * handling this.
5876  */
5877  new = calloc(1,sizeof(*new));
5878  new->tlctxt = tlctxt;
5879  new->frame = array_list_len(tlctxt->frames);
5880  new->bsymbol = bsymbol;
5881  new->alt_bsymbol = alt_bsymbol;
5882  new->registers = g_hash_table_new(g_direct_hash,g_direct_equal);
5883 
5884  g_hash_table_insert(new->registers,
5885  (gpointer)(uintptr_t)tlctxt->thread->target->ipregno,
5886  (gpointer)(uintptr_t)retaddr);
5887 
5888  if (!tlctxtf->bsymbol) {
5889  g_hash_table_insert(new->registers,
5890  (gpointer)(uintptr_t)rbp,
5891  (gpointer)(uintptr_t)old_bp);
5892  g_hash_table_insert(new->registers,
5893  (gpointer)(uintptr_t)rsp,
5894  (gpointer)(uintptr_t)old_sp);
5895  }
5896 
5897  array_list_append(tlctxt->frames,new);
5898 
5899  if (bsymbol)
5900  tlctxt->region = bsymbol->region;
5901  else {
5902  ; /* Don't change it! */
5903  }
5904 
5905  ++tlctxt->lctxt->current_frame;
5906 
5908  "created new previous frame %d with IP 0x%"PRIxADDR"\n",
5909  tlctxt->lctxt->current_frame,retaddr);
5910 
5911  return new;
5912 }
5913 
5917 int target_personality_load(char *filename) {
5918  unsigned int current_size;
5919  void *lib;
5920 
5921  current_size = g_hash_table_size(target_personality_tab);
5922 
5923  /*
5924  * NB: we want subsequent libraries to be able to reuse symbols from
5925  * this library if necessary... "overloading".
5926  */
5927  lib = dlopen(filename,RTLD_NOW | RTLD_GLOBAL);
5928  if (!lib) {
5929  verror("could not load '%s': %s (%s)\n",
5930  filename,dlerror(),strerror(errno));
5931  return -1;
5932  }
5933 
5934  /* Don't make this fatal, for now... */
5935  if (g_hash_table_size(target_personality_tab) == current_size) {
5936  vwarn("loaded library %s, but it did not add itself to the"
5937  " personality table! Duplicate personality ID?\n",filename);
5938  }
5939 
5940  return 0;
5941 }
5942 
5944  struct target_personality_ops *ptops,void *pops) {
5945  struct target_personality_info *tpi = NULL;
5946 
5947  if (g_hash_table_lookup(target_personality_tab,(gpointer)personality)) {
5948  verror("Personality %s already registered; cannot register.\n",
5949  personality);
5950  errno = EALREADY;
5951  return -1;
5952  }
5953 
5954  tpi = calloc(1,sizeof(*tpi));
5955  tpi->personality = strdup(personality);
5956  tpi->ptype = pt;
5957  tpi->ptops = ptops;
5958  tpi->pops = pops;
5959 
5960  g_hash_table_insert(target_personality_tab,(gpointer)tpi->personality,
5961  (gpointer)tpi);
5962  return 0;
5963 }
5964 
5965 int target_personality_attach(struct target *target,
5966  char *personality,char *personality_lib) {
5967  struct target_personality_info *tpi;
5968  char *buf;
5969  int bufsiz;
5970 
5971  if (!target_personality_tab) {
5972  verror("Target library improperly initialized -- call target_init!\n");
5973  errno = EINVAL;
5974  return -1;
5975  }
5976 
5977  /*
5978  * If this is specified, try to load it first!
5979  */
5980  if (personality_lib) {
5981  if (target_personality_load(personality_lib)) {
5982  vwarn("failed to load library '%s'; will try to find"
5983  " personality '%s' elsewhere!\n",personality_lib,personality);
5984  }
5985  }
5986 
5987  tpi = (struct target_personality_info *) \
5988  g_hash_table_lookup(target_personality_tab,(gpointer)personality);
5989  if (tpi)
5990  goto tpinit;
5991  else if (personality_lib) {
5992  vwarn("could not find personality '%s' after trying to load"
5993  " personality library '%s'\n",personality,personality_lib);
5994  }
5995 
5996  /*
5997  * Try to load it from a shared lib. The shared lib must either
5998  * provide _init() (or better yet, a routine with
5999  * __attribute__((constructor)) ); and this routine must register
6000  * the personality library with the target library.
6001  *
6002  * Try several strings. Just <personality>.so;
6003  * stackdb_<personality>.so; vmi_<personality>.so .
6004  */
6005  bufsiz = strlen(personality) + strlen(".so") + strlen("stackdb") + 1;
6006  buf = malloc(bufsiz);
6007  snprintf(buf,bufsiz,"%s.so",personality);
6008  if (target_personality_load(buf) == 0) {
6009  if ((tpi = (struct target_personality_info *) \
6010  g_hash_table_lookup(target_personality_tab,(gpointer)personality))) {
6011  free(buf);
6012  goto tpinit;
6013  }
6014  else {
6015  vwarn("loaded library '%s', but it did not provide personality '%s'!\n",
6016  buf,personality);
6017  }
6018  }
6019 
6020  snprintf(buf,bufsiz,"stackdb_%s.so",personality);
6021  if (target_personality_load(buf) == 0) {
6022  if ((tpi = (struct target_personality_info *) \
6023  g_hash_table_lookup(target_personality_tab,(gpointer)personality))) {
6024  free(buf);
6025  goto tpinit;
6026  }
6027  else {
6028  vwarn("loaded library '%s', but it did not provide personality '%s'!\n",
6029  buf,personality);
6030  }
6031  }
6032 
6033  snprintf(buf,bufsiz,"vmi_%s.so",personality);
6034  if (target_personality_load(buf) == 0) {
6035  if ((tpi = (struct target_personality_info *) \
6036  g_hash_table_lookup(target_personality_tab,(gpointer)personality))) {
6037  free(buf);
6038  goto tpinit;
6039  }
6040  else {
6041  vwarn("loaded library '%s', but it did not provide personality '%s'!\n",
6042  buf,personality);
6043  }
6044  }
6045 
6046  free(buf);
6047  verror("could not find personality '%s'!\n",personality);
6048  errno = ESRCH;
6049  return -1;
6050 
6051  tpinit:
6052  if (tpi->ptops->attach(target)) {
6053  vwarn("Failed to attach personality '%s' on target %d!\n",
6054  personality,target->id);
6055  return -1;
6056  }
6057  else {
6058  target->personality_ops = tpi->ptops;
6059  target->__personality_specific_ops = tpi->pops;
6060 
6062  "initialized personality '%s' for target %d!\n",
6063  personality,target->id);
6064 
6065  return 0;
6066  }
6067 }
6068 
6074 #define TARGET_REGCACHE_ALLOC(tctxt,errretval) \
6075  do { \
6076  if (tctxt > target->max_thread_ctxt) { \
6077  verror("target %d only has max thread ctxt %d (%d specified)!\n", \
6078  target->id,target->max_thread_ctxt,tctxt); \
6079  errno = EINVAL; \
6080  return errretval; \
6081  } \
6082  tthread = target_load_thread(target,tid,0); \
6083  if (!tthread) { \
6084  verror("target %d could not load thread %d!\n",target->id,tid); \
6085  errno = ESRCH; \
6086  return (errretval); \
6087  } \
6088  if (!tthread->regcaches[tctxt]) { \
6089  tthread->regcaches[tctxt] = regcache_create(target->arch); \
6090  } \
6091  regcache = tthread->regcaches[tctxt]; \
6092  } while(0)
6093 
6094 #define TARGET_REGCACHE_ALLOC_NT(tctxt,errretval) \
6095  do { \
6096  if (tctxt > target->max_thread_ctxt) { \
6097  verror("target %d only has max thread ctxt %d (%d specified)!\n", \
6098  target->id,target->max_thread_ctxt,tctxt); \
6099  errno = EINVAL; \
6100  return errretval; \
6101  } \
6102  if (!tthread->regcaches[tctxt]) { \
6103  tthread->regcaches[tctxt] = regcache_create(target->arch); \
6104  } \
6105  regcache = tthread->regcaches[tctxt]; \
6106  } while(0)
6107 
6108 #define TARGET_REGCACHE_GET(tctxt,errretval) \
6109  do { \
6110  if (tctxt > target->max_thread_ctxt) { \
6111  verror("target %d only has max thread ctxt %d (%d specified)!\n", \
6112  target->id,target->max_thread_ctxt,tctxt); \
6113  errno = EINVAL; \
6114  return errretval; \
6115  } \
6116  tthread = target_load_thread(target,tid,0); \
6117  if (!tthread) { \
6118  verror("target %d could not load thread %d!\n",target->id,tid); \
6119  errno = ESRCH; \
6120  return (errretval); \
6121  } \
6122  if (!tthread->regcaches[tctxt]) { \
6123  verror("target %d could not load thread %d!\n",target->id,tid); \
6124  errno = EADDRNOTAVAIL; \
6125  return (errretval); \
6126  } \
6127  regcache = tthread->regcaches[tctxt]; \
6128  } while(0)
6129 
6130 int target_regcache_init_reg_tidctxt(struct target *target,
6131  struct target_thread *tthread,
6132  thread_ctxt_t tctxt,
6133  REG reg,REGVAL regval) {
6134  struct regcache *regcache;
6135 
6137  "target %d init reg %s in thid %d ctxt %d 0x%"PRIxREGVAL"\n",
6138  target->id,target_regname(target,reg),tthread->tid,tctxt,regval);
6139 
6140  TARGET_REGCACHE_ALLOC_NT(tctxt,-1);
6141 
6142  if (regcache_init_reg(regcache,reg,regval)) {
6143  verror("target %d thread %d reg %d: could not init reg!\n",
6144  target->id,tthread->tid,reg);
6145  return -1;
6146  }
6147 
6148  return 0;
6149 }
6150 
6151 int target_regcache_init_done(struct target *target,
6152  tid_t tid,thread_ctxt_t tctxt) {
6153  struct target_thread *tthread;
6154  struct regcache *regcache;
6155 
6156  TARGET_REGCACHE_ALLOC(tctxt,-1);
6157 
6158  if (regcache_init_done(regcache)) {
6159  vwarn("failed -- target %d thid %d tctxt %d\n",target->id,tid,tctxt);
6160  return -1;
6161  }
6162  else {
6164  "target %d thid %d tctxt %d\n",target->id,tid,tctxt);
6165  return 0;
6166  }
6167 }
6168 
6169 int target_regcache_foreach_dirty(struct target *target,
6170  struct target_thread *tthread,
6171  thread_ctxt_t tctxt,
6174  void *priv) {
6175  int i;
6176  struct regcache *regcache;
6177 
6178  if (tctxt > target->max_thread_ctxt) {
6179  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6180  target->id,target->max_thread_ctxt,tctxt);
6181  errno = EINVAL;
6182  return 0;
6183  }
6184 
6185  if (!(regcache = tthread->regcaches[tctxt]))
6186  return 0;
6187 
6188  /*
6189  * XXX: too bad, but to make this efficient, this function has to
6190  * have direct knowledge of the regcache struct. Otherwise we'd
6191  * have two layers of callbacks, or some other inefficiency... so
6192  * just do this for now.
6193  */
6194  for (i = 0; i < regcache->arch->regcount; ++i) {
6195  if (!(regcache->flags[i] & REGCACHE_VALID)
6196  || !(regcache->flags[i] & REGCACHE_DIRTY))
6197  continue;
6198 
6199  if (regcache->flags[i] & REGCACHE_ALLOC)
6200  rawh(target,tthread,tctxt,i,(void *)regcache->values[i],
6201  arch_regsize(regcache->arch,i),priv);
6202  else
6203  regh(target,tthread,tctxt,i,regcache->values[i],priv);
6204  }
6205 
6206  return 0;
6207 }
6208 
6209 REGVAL target_regcache_readreg(struct target *target,tid_t tid,REG reg) {
6210  struct target_thread *tthread;
6211  struct regcache *regcache;
6212  REGVAL regval = 0;
6213 
6214  tthread = target_load_thread(target,tid,0);
6215  if (!tthread) {
6216  verror("target %d could not load thread %d!\n",target->id,tid);
6217  errno = ESRCH;
6218  return 0;
6219  }
6220 
6221  if (tthread->tidctxt > target->max_thread_ctxt) {
6222  verror("target %d only has max thread ctxt %d (thid %d currently %d)!\n",
6223  target->id,target->max_thread_ctxt,tid,tthread->tidctxt);
6224  errno = EINVAL;
6225  return 0;
6226  }
6227 
6229  "target %d reading reg %s in thid %d ctxt %d\n",
6230  target->id,target_regname(target,reg),tid,tthread->tidctxt);
6231 
6232  if (!tthread->regcaches[tthread->tidctxt]) {
6234  "target %d could not load thread %d!\n",target->id,tid);
6235  errno = EADDRNOTAVAIL;
6236  return 0;
6237  }
6238  regcache = tthread->regcaches[tthread->tidctxt];
6239 
6240  if (regcache_read_reg(regcache,reg,&regval)) {
6242  "target %d thread %d reg %d: could not read!\n",
6243  target->id,tid,reg);
6244  return 0;
6245  }
6246 
6247  return regval;
6248 }
6249 
6250 int target_regcache_writereg(struct target *target,tid_t tid,
6251  REG reg,REGVAL value) {
6252  struct target_thread *tthread;
6253  struct regcache *regcache;
6254 
6255  tthread = target_load_thread(target,tid,0);
6256  if (!tthread) {
6257  verror("target %d could not load thread %d!\n",target->id,tid);
6258  errno = ESRCH;
6259  return 0;
6260  }
6261 
6262  if (tthread->tidctxt > target->max_thread_ctxt) {
6263  verror("target %d only has max thread ctxt %d (thid %d currently %d)!\n",
6264  target->id,target->max_thread_ctxt,tid,tthread->tidctxt);
6265  errno = EINVAL;
6266  return 0;
6267  }
6268 
6270  "target %d reading reg %s in thid %d ctxt %d 0x%"PRIxREGVAL"\n",
6271  target->id,target_regname(target,reg),tid,tthread->tidctxt,value);
6272 
6273  if (!tthread->regcaches[tthread->tidctxt]) {
6274  verror("target %d could not load thread %d!\n",target->id,tid);
6275  errno = EADDRNOTAVAIL;
6276  return 0;
6277  }
6278  regcache = tthread->regcaches[tthread->tidctxt];
6279 
6280  if (regcache_write_reg(regcache,reg,value)) {
6281  verror("target %d thread %d reg %d: could not write!\n",
6282  target->id,tid,reg);
6283  return -1;
6284  }
6285 
6286  OBJSDIRTY(tthread);
6287 
6288  return 0;
6289 }
6290 
6291 int target_regcache_readreg_ifdirty(struct target *target,
6292  struct target_thread *tthread,
6293  thread_ctxt_t tctxt,REG reg,REGVAL *regval) {
6294  if (tctxt > target->max_thread_ctxt) {
6295  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6296  target->id,target->max_thread_ctxt,tctxt);
6297  errno = EINVAL;
6298  return 0;
6299  }
6300 
6301  if (!tthread->regcaches[tctxt])
6302  return 0;
6303  else
6304  return regcache_read_reg_ifdirty(tthread->regcaches[tctxt],reg,regval);
6305 }
6306 
6307 int target_regcache_isdirty(struct target *target,
6308  struct target_thread *tthread,
6309  thread_ctxt_t tctxt) {
6310  if (tctxt > target->max_thread_ctxt) {
6311  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6312  target->id,target->max_thread_ctxt,tctxt);
6313  errno = EINVAL;
6314  return 0;
6315  }
6316 
6317  if (!tthread->regcaches[tctxt])
6318  return 0;
6319  else
6320  return regcache_isdirty(tthread->regcaches[tctxt]);
6321 }
6322 
6323 int target_regcache_isdirty_reg(struct target *target,
6324  struct target_thread *tthread,
6325  thread_ctxt_t tctxt,REG reg) {
6326  if (tctxt > target->max_thread_ctxt) {
6327  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6328  target->id,target->max_thread_ctxt,tctxt);
6329  errno = EINVAL;
6330  return 0;
6331  }
6332 
6333  if (!tthread->regcaches[tctxt])
6334  return 0;
6335  else
6336  return regcache_isdirty_reg(tthread->regcaches[tctxt],reg);
6337 }
6338 
6339 int target_regcache_isdirty_reg_range(struct target *target,
6340  struct target_thread *tthread,
6341  thread_ctxt_t tctxt,REG start,REG end) {
6342  if (tctxt > target->max_thread_ctxt) {
6343  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6344  target->id,target->max_thread_ctxt,tctxt);
6345  errno = EINVAL;
6346  return 0;
6347  }
6348 
6349  if (!tthread->regcaches[tctxt])
6350  return 0;
6351  else
6352  return regcache_isdirty_reg_range(tthread->regcaches[tctxt],start,end);
6353 }
6354 
6355 struct regcache *target_regcache_get(struct target *target,
6356  struct target_thread *tthread,
6357  thread_ctxt_t tctxt) {
6358  if (tctxt > target->max_thread_ctxt) {
6359  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6360  target->id,target->max_thread_ctxt,tctxt);
6361  errno = EINVAL;
6362  return 0;
6363  }
6364 
6365  return tthread->regcaches[tctxt];
6366 }
6367 
6368 int target_regcache_snprintf(struct target *target,struct target_thread *tthread,
6369  thread_ctxt_t tctxt,char *buf,int bufsiz,
6370  int detail,char *sep,char *kvsep,int flags) {
6371  int rc;
6372  int nrc;
6373 
6374  if (tctxt > target->max_thread_ctxt) {
6375  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6376  target->id,target->max_thread_ctxt,tctxt);
6377  errno = EINVAL;
6378  return 0;
6379  }
6380 
6381  if (!tthread->regcaches[tctxt])
6382  return 0;
6383  else {
6384  rc = snprintf(buf,bufsiz,"%stctxt%s%d",sep,kvsep,tctxt);
6385  if (rc < 0)
6386  return rc;
6387  nrc = regcache_snprintf(tthread->regcaches[tctxt],
6388  (rc >= bufsiz) ? NULL : buf + rc,
6389  (rc >= bufsiz) ? 0 : bufsiz - rc,
6390  detail,sep,kvsep,flags);
6391  if (nrc < 0)
6392  return nrc;
6393  else
6394  return rc + nrc;
6395  }
6396 }
6397 
6398 int target_regcache_zero(struct target *target,struct target_thread *tthread,
6399  thread_ctxt_t tctxt) {
6400  if (tctxt > target->max_thread_ctxt) {
6401  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6402  target->id,target->max_thread_ctxt,tctxt);
6403  errno = EINVAL;
6404  return 0;
6405  }
6406 
6407  if (!tthread->regcaches[tctxt])
6408  return 0;
6409  else {
6410  regcache_zero(tthread->regcaches[tctxt]);
6411  return 0;
6412  }
6413 }
6414 
6415 int target_regcache_mark_flushed(struct target *target,
6416  struct target_thread *tthread,
6417  thread_ctxt_t tctxt) {
6418  if (tctxt > target->max_thread_ctxt) {
6419  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6420  target->id,target->max_thread_ctxt,tctxt);
6421  errno = EINVAL;
6422  return 0;
6423  }
6424 
6425  if (!tthread->regcaches[tctxt])
6426  return 0;
6427 
6428  regcache_mark_flushed(tthread->regcaches[tctxt]);
6429 
6430  return 0;
6431 }
6432 
6433 int target_regcache_invalidate(struct target *target,
6434  struct target_thread *tthread,
6435  thread_ctxt_t tctxt) {
6436  if (tctxt > target->max_thread_ctxt) {
6437  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6438  target->id,target->max_thread_ctxt,tctxt);
6439  errno = EINVAL;
6440  return 0;
6441  }
6442 
6443  if (!tthread->regcaches[tctxt])
6444  return 0;
6445 
6446  regcache_invalidate(tthread->regcaches[tctxt]);
6447 
6448  return 0;
6449 }
6450 
6452  thread_ctxt_t stidctxt,
6453  struct target_thread *dthread,
6454  thread_ctxt_t dtidctxt) {
6455  struct target *target = sthread->target;
6456 
6457  if (stidctxt > target->max_thread_ctxt
6458  || dtidctxt > target->max_thread_ctxt) {
6459  verror("target %d only has max thread ctxt %d (%d/%d specified)!\n",
6460  target->id,target->max_thread_ctxt,stidctxt,dtidctxt);
6461  errno = EINVAL;
6462  return 0;
6463  }
6464 
6466  "copying thid %d ctxt %d to thid %d ctxt %d\n",
6467  sthread->tid,stidctxt,dthread->tid,dtidctxt);
6468 
6469  if (!sthread->regcaches[stidctxt])
6470  return 0;
6471 
6472  if (!dthread->regcaches[dtidctxt])
6473  dthread->regcaches[dtidctxt] = regcache_create(dthread->target->arch);
6474 
6475  return regcache_copy_all(sthread->regcaches[stidctxt],
6476  dthread->regcaches[dtidctxt]);
6477 }
6478 
6480  thread_ctxt_t stidctxt,
6481  struct target_thread *dthread,
6482  thread_ctxt_t dtidctxt) {
6483  struct target *target = sthread->target;
6484 
6485  if (stidctxt > target->max_thread_ctxt
6486  || dtidctxt > target->max_thread_ctxt) {
6487  verror("target %d only has max thread ctxt %d (%d/%d specified)!\n",
6488  target->id,target->max_thread_ctxt,stidctxt,dtidctxt);
6489  errno = EINVAL;
6490  return 0;
6491  }
6492 
6493  if (dthread->regcaches[dtidctxt])
6494  regcache_zero(dthread->regcaches[dtidctxt]);
6495 
6496  return target_regcache_copy_all(sthread,stidctxt,dthread,dtidctxt);
6497 }
6498 
6500  thread_ctxt_t dtidctxt,
6501  struct regcache *sregcache) {
6502  struct target *target = dthread->target;
6503 
6504  if (dtidctxt > target->max_thread_ctxt) {
6505  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6506  target->id,target->max_thread_ctxt,dtidctxt);
6507  errno = EINVAL;
6508  return 0;
6509  }
6510 
6512  "copying regcache to thid %d ctxt %d\n",
6513  dthread->tid,dtidctxt);
6514 
6515  if (!dthread->regcaches[dtidctxt])
6516  dthread->regcaches[dtidctxt] = regcache_create(dthread->target->arch);
6517 
6518  return regcache_copy_all(sregcache,dthread->regcaches[dtidctxt]);
6519 }
6520 
6522  thread_ctxt_t stidctxt,
6523  struct regcache *dregcache) {
6524  struct target *target = sthread->target;
6525 
6526  if (stidctxt > target->max_thread_ctxt) {
6527  verror("target %d only has max thread ctxt %d (%d specified)!\n",
6528  target->id,target->max_thread_ctxt,stidctxt);
6529  errno = EINVAL;
6530  return 0;
6531  }
6532 
6534  "copying regcache to thid %d ctxt %d\n",
6535  sthread->tid,stidctxt);
6536 
6537  if (!sthread->regcaches[stidctxt])
6538  sthread->regcaches[stidctxt] = regcache_create(sthread->target->arch);
6539 
6540  return regcache_copy_dirty(sthread->regcaches[stidctxt],dregcache);
6541 }
6542 
6543 GHashTable *target_regcache_copy_registers(struct target *target,tid_t tid) {
6544  return target_regcache_copy_registers_tidctxt(target,tid,
6546 }
6547 
6548 GHashTable *target_regcache_copy_registers_tidctxt(struct target *target,
6549  tid_t tid,
6550  thread_ctxt_t tidctxt) {
6551  struct target_thread *tthread;
6552  struct regcache *regcache;
6553 
6555  "target %d copying in thid %d ctxt %d\n",
6556  target->id,tid,tidctxt);
6557 
6558  TARGET_REGCACHE_GET(tidctxt,0);
6559 
6560  if (!regcache)
6561  return NULL;
6562 
6563  return regcache_copy_registers(regcache);
6564 }
6565 
6567  tid_t tid,thread_ctxt_t tidctxt,
6568  REG reg) {
6569  struct target_thread *tthread;
6570  struct regcache *regcache;
6571  REGVAL regval = 0;
6572 
6574  "target %d reading reg %s in thid %d ctxt %d\n",
6575  target->id,target_regname(target,reg),tid,tidctxt);
6576 
6577  TARGET_REGCACHE_GET(tidctxt,0);
6578 
6579  if (regcache_read_reg(regcache,reg,&regval)) {
6580  verror("target %d thread %d reg %d ctxt %d: could not read!\n",
6581  target->id,tid,reg,tidctxt);
6582  return 0;
6583  }
6584 
6585  return regval;
6586 }
6587 
6588 int target_regcache_writereg_tidctxt(struct target *target,
6589  tid_t tid,thread_ctxt_t tidctxt,
6590  REG reg,REGVAL value) {
6591  struct target_thread *tthread;
6592  struct regcache *regcache;
6593 
6595  "target %d writing reg %s in thid %d ctxt %d 0x%"PRIxREGVAL"\n",
6596  target->id,target_regname(target,reg),tid,tidctxt,value);
6597 
6598  TARGET_REGCACHE_GET(tidctxt,0);
6599 
6600  if (regcache_write_reg(regcache,reg,value)) {
6601  verror("target %d thread %d reg %d ctxt %d: could not write!\n",
6602  target->id,tid,reg,tidctxt);
6603  return -1;
6604  }
6605 
6606  OBJSDIRTY(tthread);
6607 
6608  return 0;
6609 }
6610 
6611 /*
6612  * Util stuff.
6613  */
6614 char *TSTATUS_STRINGS[] = {
6615  "UNKNOWN",
6616  "RUNNING",
6617  "PAUSED",
6618  "ERROR",
6619  "DONE",
6620  "EXITING",
6621  NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
6622  "DEAD",
6623  "STOPPED",
6624 };
6625 
6627  "UNKNOWN",
6628  "RUNNING",
6629  "PAUSED",
6630  "ERROR",
6631  "DONE",
6632  "EXITING",
6633  NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
6634  "DEAD",
6635  "STOPPED",
6636 
6637  "SLEEPING",
6638  "ZOMBIE",
6639  "BLOCKEDIO",
6640  "PAGING",
6641  "RETURNING_USER",
6642  "RETURNING_KERNEL",
6643 };
6644 
6645 char *POLL_STRINGS[] = {
6646  "NOTHING",
6647  "ERROR",
6648  "SUCCESS",
6649  "UNKNOWN",
6650 };
6651 
6653  "unknown","heap","stack","vdso","vsyscall","anon","main","lib",
6654 };
struct bsymbol * bsymbol_create(struct lsymbol *lsymbol, struct memregion *region)
Definition: symbol.c:48
#define LOCATION_ADDR(loc)
Definition: dwdebug_priv.h:622
#define APF_ALL
Definition: target_api.h:463
int infd
Definition: target_api.h:2573
REFCNT target_thread_free(struct target_thread *tthread, int force)
Definition: target.c:4126
struct value * target_load_symbol(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, load_flags_t flags)
Definition: target.c:3234
int regcache_isdirty_reg_range(struct regcache *regcache, REG start, REG end)
Definition: regcache.c:212
struct arch * arch
Definition: regcache.h:36
#define RPUTW(x, objtype, hx, rc)
Definition: common.h:628
int memregion_contains_real(struct memregion *region, ADDR addr)
Definition: memory.c:327
#define RF_ACCEPT
Definition: rfilter.h:29
struct value * target_load_type(struct target *target, struct symbol *type, ADDR addr, load_flags_t flags)
Definition: target.c:2618
char * THREAD_STATUS_STRINGS[]
Definition: target.c:6626
REGVAL target_regcache_readreg_tidctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg)
Definition: target.c:6566
#define THREAD_STATUS(n)
Definition: target_api.h:288
OFFSET symbol_offsetof(struct symbol *symbol, const char *name, const char *delim)
Definition: debug.c:314
struct array_list * threads
Definition: target.h:374
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
char * TSTATUS_STRINGS[]
Definition: target.c:6614
struct value * value_create_noalloc(struct target_thread *thread, struct memrange *range, struct lsymbol *lsymbol, struct symbol *type)
Definition: value.c:153
GHashTable * config
Definition: target_api.h:2582
int(* fini)(struct target *target)
Definition: target_api.h:3102
unsigned int no_write
Definition: target.h:378
int(* fini)(struct target *target)
Definition: target_api.h:2775
GHashTable * regcache_copy_registers(struct regcache *regcache)
Definition: regcache.c:422
unsigned long target_memmod_length(struct target *target, struct target_memmod *mmod)
Definition: target.c:4710
struct argp_option target_argp_opts_only_one[]
Definition: target.c:402
#define TARGET_ARGP_CORE_OPTS
Definition: target.c:367
void location_ctxt_free(struct location_ctxt *lctxt)
Definition: location.c:812
Word_t start
Definition: clfit.h:37
struct target * base
Definition: target_api.h:2614
struct bsymbol * target_lookup_sym_line(struct target *target, char *filename, int line, SMOFFSET *offset, ADDR *addr)
Definition: target.c:2237
void * state
Definition: target_api.h:2488
void target_monitor_schedule_global_interrupt(void)
Definition: target.c:314
void regcache_mark_flushed(struct regcache *regcache)
Definition: regcache.c:118
struct lsymbol * debugfile_lookup_sym__int(struct debugfile *debugfile, char *name, const char *delim, struct rfilter *srcfile_filter, symbol_type_flag_t flags)
Definition: debug.c:677
char * linux_userproc_argp_header
int value_snprintf(struct value *value, char *buf, int buflen)
Definition: value.c:581
struct lsymbol * lsymbol_lookup_sym__int(struct lsymbol *lsymbol, const char *name, const char *delim)
Definition: debug.c:275
int action_id_counter
Definition: target_api.h:2742
void value_set_strlen(struct value *value, int len)
Definition: value.c:68
#define RHOLDW(x, hx)
Definition: common.h:623
target_status_t target_get_status(struct target *target)
Definition: target.c:3987
struct argp_option target_argp_opts[]
Definition: target.c:393
void * backend_spec
Definition: target_api.h:2252
thread_bpmode_t bpmode
Definition: target_api.h:2174
int(* target_regcache_regval_handler_t)(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, REGVAL regval, void *priv)
Definition: target.h:157
void target_default_sighandler(int signo, siginfo_t *siginfo, void *x)
Definition: target.c:167
int target_regcache_zero(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt)
Definition: target.c:6398
struct lsymbol * lsymbol
Definition: target.h:1006
int32_t tid_t
Definition: common.h:36
unsigned int ptrsize
Definition: arch.h:122
struct array_list * frames
Definition: target_api.h:2358
void * target_argp_driver_state(struct argp_state *state)
Definition: target.c:703
REFCNT lsymbol_release(struct lsymbol *lsymbol)
Definition: debug.c:4805
ADDR memregion_unrelocate(struct memregion *region, ADDR real_addr, struct memrange **range_saveptr)
Definition: memory.c:402
GSList * symbol_get_ordered_members(struct symbol *symbol, symbol_type_flag_t flags)
Definition: debug.c:3128
struct lsymbol * debugfile_lookup_addr__int(struct debugfile *debugfile, ADDR addr)
Definition: debug.c:503
target_gkv_dtor_t dtor
Definition: target.c:1388
int(* attach)(struct target *target)
Definition: target_api.h:3100
#define TARGET_TYPE_MASK_BASE
Definition: target_api.h:172
REFCNT action_free(struct action *action, int force)
Definition: probe.c:4598
target_status_t
Definition: target_api.h:197
int target_insert_probepoint(struct target *target, struct target_thread *tthread, struct probepoint *probepoint)
Definition: target.c:4619
struct value * target_load_type_reg(struct target *target, struct symbol *type, tid_t tid, REG reg, load_flags_t flags)
Definition: target.c:2875
struct argp xen_vm_argp
int target_unwind_snprintf(char *buf, int buflen, struct target *target, tid_t tid, target_unwind_style_t fstyle, char *frame_sep, char *ksep)
Definition: target.c:5424
int regcache_init_done(struct regcache *regcache)
Definition: regcache.c:189
int id
Definition: probe.h:396
#define TARGET_ARGP_OVERLAY
Definition: target.c:356
int target_personality_register(char *personality, target_personality_t pt, struct target_personality_ops *ptops, void *pops)
Definition: target.c:5943
void target_thread_gkv_remove(struct target *target, tid_t tid, char *key)
Definition: target.c:1564
uint8_t isreg
Definition: target_api.h:3260
struct symbol * symbol
Definition: dwdebug.h:1010
probepoint_style_t style
Definition: probe.h:223
struct memregion * region
Definition: target_api.h:2353
#define TARGET_TYPE_MASK_OVERLAY
Definition: target_api.h:174
unsigned int isevictable
Definition: target.c:3862
int gdb_spec_to_argv(struct target_spec *spec, int *argc, char ***argv)
Definition: target_gdb.c:328
struct target_location_ctxt * target_unwind(struct target *target, tid_t tid)
Definition: target.c:5298
char * DATATYPE(int n)
Definition: debug.c:5684
clrange_t ranges
Definition: binfile.h:279
int addrspace_find_range_real(struct addrspace *space, ADDR addr, struct memregion **region_saveptr, struct memrange **range_saveptr)
Definition: memory.c:141
GHashTable * overlays
Definition: target_api.h:2623
int target_detach_probe(struct target *target, struct probe *probe)
Definition: target.c:4681
Definition: probe.h:392
int target_regcache_copy_all(struct target_thread *sthread, thread_ctxt_t stidctxt, struct target_thread *dthread, thread_ctxt_t dtidctxt)
Definition: target.c:6451
struct scope * symbol_read_owned_scope(struct symbol *symbol)
Definition: debug.c:2674
int target_lsymbol_resolve_bounds(struct target *target, struct target_location_ctxt *tlctxt, struct lsymbol *lsymbol, ADDR base_addr, ADDR *start, ADDR *end, int *is_noncontiguous, ADDR *alt_start, ADDR *alt_end)
Definition: target.c:2387
int regcache_write_reg(struct regcache *regcache, REG reg, REGVAL regval)
Definition: regcache.c:240
struct linux_userproc_spec * linux_userproc_build_spec(void)
int target_regcache_copy_dirty_to(struct target_thread *sthread, thread_ctxt_t stidctxt, struct regcache *dregcache)
Definition: target.c:6521
struct target_location_ctxt_frame *(* unwind_prev)(struct target_location_ctxt *tlctxt)
Definition: target_api.h:3037
GHashTable * soft_probepoints
Definition: target_api.h:2695
Word_t end
Definition: clfit.h:38
sigset_t interrupt
Definition: spf.c:211
#define PRIiREG
Definition: common.h:94
struct bsymbol * target_lookup_sym(struct target *target, const char *name, const char *delim, char *srcfile, symbol_type_flag_t ftype)
Definition: target.c:2169
probepoint_state_t state
Definition: probe.h:220
struct target_personality_ops * personality_ops
Definition: target_api.h:2547
struct target_thread * owner
Definition: target.h:414
GHashTable * target_regcache_copy_registers(struct target *target, tid_t tid)
Definition: target.c:6543
OFFSET target_offsetof_symbol(struct target *target, struct bsymbol *bsymbol, char *member, const char *delim)
Definition: target.c:3449
char * POLL_STRINGS[]
Definition: target.c:6645
int symbol_get_srcline(struct symbol *symbol)
Definition: debug.c:2937
ADDR addr
Definition: probe.h:218
#define PRIxFULLADDR
Definition: common.h:68
GHashTable * actions
Definition: target_api.h:2736
void target_init(void)
Definition: target.c:67
Definition: arch.h:74
GList * targets
Definition: backtrace.c:47
struct probepoint * target_lookup_probepoint(struct target *target, struct target_thread *tthread, ADDR addr)
Definition: target.c:4594
int target_bsymbol_resolve_base(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, ADDR *o_addr, struct memrange **o_range)
Definition: target.c:2583
void vmi_inc_log_level(void)
Definition: log.c:38
#define v_g_slist_foreach(gslhead, gslcur, elm)
Definition: glib_wrapper.h:60
void location_internal_free(struct location *location)
Definition: location.c:347
ADDR end
Definition: target.h:984
#define v_g_list_foreach(glhead, glcur, elm)
Definition: glib_wrapper.h:34
struct target_location_ctxt * target_location_ctxt_create_from_bsymbol(struct target *target, tid_t tid, struct bsymbol *bsymbol)
Definition: target.c:5269
ADDR addr
Definition: dwdebug_priv.h:916
uint8_t kill_on_close
Definition: target_api.h:2176
unsigned int arch_regsize(struct arch *arch, REG reg)
Definition: arch.c:44
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
Definition: qemuhacks.c:77
ADDR target_addressof_symbol(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, load_flags_t flags, struct memrange **o_range)
Definition: target.c:3454
struct target_ops gdb_ops
Definition: target_gdb.c:193
struct target_thread * base_thread
Definition: target_api.h:2615
struct target * target
Definition: probe.h:241
int target_regcache_copy_from(struct target_thread *dthread, thread_ctxt_t dtidctxt, struct regcache *sregcache)
Definition: target.c:6499
struct os_process_spec * os_process_build_spec(void)
int target_regcache_init_done(struct target *target, tid_t tid, thread_ctxt_t tctxt)
Definition: target.c:6151
struct target_location_ctxt * tlctxt
Definition: target_api.h:2365
struct php_spec * php_build_spec(void)
Definition: target_php.c:938
#define __SWC
#define likely(expr)
Definition: debugpred.h:102
probepoint_style_t style
Definition: target_api.h:2175
REFCNT refcntw
Definition: target_api.h:2424
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
union value::@27 res
int vmi_add_log_area_flaglist(char *flaglist, char *separator)
Definition: log.c:103
int32_t SMOFFSET
Definition: common.h:100
#define TARGET_ARGP_PERSONALITY_LIB
Definition: target.c:358
int lsymbol_resolve_bounds(struct lsymbol *lsymbol, ADDR base_addr, struct location_ctxt *lctxt, ADDR *start, ADDR *end, int *is_noncontiguous, ADDR *alt_start, ADDR *alt_end)
Definition: location.c:1566
struct scope * target_lookup_addr(struct target *target, uint64_t addr)
Definition: target.c:2023
int target_cregno(struct target *target, common_reg_t creg, REG *reg)
Definition: target_api.c:1077
int(* unwind_read_reg)(struct target_location_ctxt *tlctxt, REG reg, REGVAL *o_regval)
Definition: target_api.h:3034
int regcache_init_reg(struct regcache *regcache, REG reg, REGVAL regval)
Definition: regcache.c:153
int target_detach_space(struct target *target, struct addrspace *space)
Definition: target.c:4568
struct target_thread * global_thread
Definition: target_api.h:2645
struct regcache * target_regcache_get(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt)
Definition: target.c:6355
struct target * target_create(char *type, struct target_spec *spec)
Definition: target.c:1849
void * target_gkv_steal(struct target *target, char *key)
Definition: target.c:1420
uint32_t monitorhandling
Definition: target_api.h:2427
#define TARGET_REGCACHE_ALLOC_NT(tctxt, errretval)
Definition: target.c:6094
target_memmod_state_t state
Definition: target.h:377
ADDR addr
Definition: target_api.h:3269
char * name
Definition: target.h:928
unsigned long mod_len
Definition: target.h:395
uint32_t symbol_get_bytesize(struct symbol *symbol)
Definition: debug.c:3065
struct debugfile * target_lookup_debugfile(struct target *target, ADDR addr)
Definition: target.c:1990
struct target * target
Definition: target.h:884
int target_regcache_writereg_tidctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt, REG reg, REGVAL value)
Definition: target.c:6588
char * bsymbol_get_name(struct bsymbol *bsymbol)
Definition: symbol.c:62
struct target_ops os_process_ops
#define ptr_t
Definition: common.h:79
int target_remove_probepoint(struct target *target, struct target_thread *tthread, struct probepoint *probepoint)
Definition: target.c:4645
#define CODE_CACHE_BUF_PAD
Definition: target.c:3858
int target_associate_debugfile(struct target *target, struct memregion *region, struct debugfile *debugfile)
Definition: target.c:1963
int32_t OFFSET
Definition: common.h:65
int target_close(struct target *target)
Definition: target_api.c:1446
ADDR start
Definition: target.h:983
uint8_t stay_paused
Definition: target_api.h:2176
struct bsymbol * alt_bsymbol
Definition: target_api.h:2378
int target_detach_action(struct target *target, struct action *action)
Definition: target.c:4701
int regcount
Definition: arch.h:128
struct list_head probe
Definition: probe.h:379
ADDR target_autoload_pointers(struct target *target, struct symbol *datatype, ADDR addr, load_flags_t flags, struct symbol **datatype_saveptr, struct memrange **range_saveptr)
Definition: target.c:3626
struct target_ops linux_userspace_process_ops
struct target_thread * thread
Definition: target_api.h:3237
#define verror(format,...)
Definition: log.h:30
target_personality_t ptype
Definition: target.h:235
uint8_t spec_was_overlay
Definition: target_api.h:2176
int base_target_id
Definition: target_api.h:2169
struct action * action
Definition: probe.h:198
int target_install_default_sighandlers(void(*sighandler)(int signo, siginfo_t *siginfo, void *x))
Definition: target.c:233
struct target_memmod * mmod
Definition: probe.h:275
unsigned char * __target_load_addr_real(struct target *target, struct memrange *range, ADDR addr, load_flags_t flags, unsigned char *buf, int bufsiz)
Definition: target.c:3759
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1014
int bufsiz
Definition: target_api.h:3257
int location_ctxt_read_retaddr(struct location_ctxt *lctxt, ADDR *o_retaddr)
Definition: location.c:576
int target_attach_space(struct target *target, struct addrspace *space)
Definition: target.c:4546
GHashTable * phys_mmods
Definition: target_api.h:2716
int target_install_custom_sighandlers(sigset_t *ignored, sigset_t *interrupt, sigset_t *exit, void(*sighandler)(int signo, siginfo_t *siginfo, void *x))
Definition: target.c:263
char * symbol_get_srcfile(struct symbol *symbol)
Definition: debug.c:2941
struct symbol * symbol_get_datatype(struct symbol *symbol)
Definition: debug.c:2989
void ** list
Definition: alist.h:34
int target_find_memory_real(struct target *target, ADDR addr, struct addrspace **space_saveptr, struct memregion **region_saveptr, struct memrange **range_saveptr)
Definition: target.c:3536
GHashTable * debugfiles
Definition: target.h:945
struct clf_range_data * clrange_find_loosest(clrange_t *clf, Word_t index, struct array_list **al_saveptr)
Definition: clfit.c:377
int linux_userproc_spec_to_argv(struct target_spec *spec, int *argc, char ***argv)
int regcache_copy_all(struct regcache *sregcache, struct regcache *dregcache)
Definition: regcache.c:58
#define LOGDUMPSYMBOL_NL(dl, lt, lf, s)
Definition: dwdebug_priv.h:30
void probepoint_free_ext(struct probepoint *probepoint)
Definition: probe.c:570
int location_ctxt_read_reg(struct location_ctxt *lctxt, REG reg, REGVAL *o_regval)
Definition: location.c:632
void target_detach_thread(struct target *target, struct target_thread *tthread)
Definition: target.c:4073
int target_regcache_isdirty_reg(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg)
Definition: target.c:6323
void target_location_ctxt_retarget_bsymbol(struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol)
Definition: target.c:5287
GHashTable * gkv_store
Definition: target_api.h:2593
int(* target_regcache_rawval_handler_t)(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, void *rawval, int rawlen, void *priv)
Definition: target.h:162
symbol_type_t type
Definition: dwdebug_priv.h:833
void * value
Definition: target.c:1387
#define OBJSINVALID(obj)
Definition: object.h:106
int symbol_resolve_bounds(struct symbol *symbol, struct location_ctxt *lctxt, ADDR *start, ADDR *end, int *is_noncontiguous, ADDR *o_alt_start, ADDR *o_alt_end)
Definition: location.c:1047
void target_fini(void)
Definition: target.c:84
GHashTable * mmods
Definition: target_api.h:2701
struct lsymbol * symbol_lookup_sym(struct symbol *symbol, const char *name, const char *delim)
Definition: debug.c:264
int target_invalidate_thread(struct target *target, struct target_thread *tthread)
Definition: target.c:4366
char * base_thread_name
Definition: target_api.h:2171
void vmi_set_log_level(int level)
Definition: log.c:34
ADDR base_phys_addr
Definition: target.h:966
int target_personality_attach(struct target *target, char *personality, char *personality_lib)
Definition: target.c:5965
void dwdebug_init(void)
Definition: debug.c:83
#define REGCACHE_ALLOC
Definition: regcache.h:33
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
struct target_thread * thread
Definition: probe.h:242
#define LOCATION_WORD(loc)
Definition: dwdebug_priv.h:626
int location_set_implicit_word(struct location *loc, ADDR word)
Definition: location.c:119
int target_lookup_sym_addr_alt(struct target *target, ADDR addr, struct bsymbol **primary, struct bsymbol **alt)
Definition: target.c:2105
int symbol_type_is_char(struct symbol *type)
Definition: debug.c:4224
REGVAL target_read_reg(struct target *target, tid_t tid, REG reg)
Definition: target_api.c:1083
struct target_location_ctxt_frame * target_location_ctxt_get_frame(struct target_location_ctxt *tlctxt, int frame)
Definition: target.c:5645
void regcache_invalidate(struct regcache *regcache)
Definition: regcache.c:127
int target_regcache_foreach_dirty(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, target_regcache_regval_handler_t regh, target_regcache_rawval_handler_t rawh, void *priv)
Definition: target.c:6169
struct lsymbol * lsymbol_create_from_member(struct lsymbol *parent, struct symbol *member)
Definition: debug.c:4646
char * gdb_argp_header
Definition: target_gdb.c:565
struct target_thread * target_load_thread(struct target *target, tid_t tid, int force)
Definition: target_api.c:1246
void regcache_zero(struct regcache *regcache)
Definition: regcache.c:101
struct clf_range_data * clrange_find_next_loosest(clrange_t *clf, Word_t index, struct array_list **al_saveptr)
Definition: clfit.c:420
struct regcache ** regcaches
Definition: target_api.h:2075
struct target * target
Definition: probe.h:452
#define OBJLIVE(obj)
Definition: object.h:84
void(* target_gkv_dtor_t)(struct target *target, char *key, void *value)
Definition: target.h:538
int(* write_symbol)(struct target *target, struct value *value)
Definition: target_api.h:2923
unsigned int len
Definition: target.c:3862
char * lsymbol_get_name(struct lsymbol *lsymbol)
Definition: debug.c:4732
int target_thread_gkv_insert(struct target *target, tid_t tid, char *key, void *value, target_thread_gkv_dtor_t dtor)
Definition: target.c:1491
int target_bsymbol_resolve_bounds(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, ADDR base_addr, ADDR *start, ADDR *end, int *is_noncontiguous, ADDR *alt_start, ADDR *alt_end)
Definition: target.c:2402
void target_monitor_clear_global_interrupt(void)
Definition: target.c:228
int outfd
Definition: target_api.h:2574
unsigned long tmp_len
Definition: target.h:400
void target_default_cleanup()
Definition: target.c:121
#define TARGET_ARGP_BASE
Definition: target.c:355
struct xen_vm_spec * xen_vm_build_spec(void)
int location_set_reg(struct location *l, REG reg)
Definition: location.c:55
void dwdebug_fini(void)
Definition: debug.c:143
int regcache_read_reg_ifdirty(struct regcache *regcache, REG reg, REGVAL *regval)
Definition: regcache.c:299
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
struct target_thread * current_thread
Definition: target_api.h:2640
datatype_code_t datatype_code
Definition: dwdebug_priv.h:827
#define OBJDIRTY(obj)
Definition: object.h:80
int target_argp_driver_parse(struct argp *driver_parser, void *driver_state, int argc, char **argv, target_type_t target_types, int filter_quoted, struct target_spec **primary_target_spec, GList **base_target_specs, GList **overlay_target_specs)
Definition: target.c:900
int target_monitor_was_interrupted(siginfo_t *last_siginfo)
Definition: target.c:219
struct value * value_create_raw(struct target *target, struct target_thread *thread, struct memrange *range, int len)
Definition: value.c:77
Word_t start
Definition: target.c:3861
struct target_memmod * target_memmod_lookup(struct target *target, tid_t tid, ADDR addr, int is_phys)
Definition: target.c:4841
void(* target_thread_gkv_dtor_t)(struct target *target, tid_t tid, char *key, void *value)
Definition: target.h:539
void target_memmod_set_writeable(struct target *target, struct target_memmod *mmod, int writeable)
Definition: target.c:4836
unsigned char * target_load_raw_addr_real(struct target *target, ADDR addr, load_flags_t flags, unsigned char *buf, int bufsiz)
Definition: target.c:3744
int target_location_ctxt_read_reg(struct target_location_ctxt *tlctxt, REG reg, REGVAL *o_regval)
Definition: target.c:5659
tid_t base_tid
Definition: target_api.h:2617
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
struct addrspace * space
Definition: target.h:926
struct target_location_ctxt_frame * target_location_ctxt_prev(struct target_location_ctxt *tlctxt)
Definition: target.c:5715
struct dt_argp_state opts
Definition: dumptarget.c:111
int target_attach_overlay_thread(struct target *base, struct target *overlay, tid_t newtid)
Definition: target.c:4488
struct memrange * memregion_find_range_real(struct memregion *region, ADDR real_addr)
Definition: memory.c:339
struct debugfile_load_opts * debugfile_load_opts_parse(char *optstr)
Definition: debug.c:1194
char * buf
Definition: target_api.h:3258
void target_free_spec(struct target_spec *spec)
Definition: target_api.c:436
target_memmod_type_t type
Definition: target.h:376
void(* free_thread_state)(struct target *target, void *state)
Definition: target_api.h:3134
#define TSTATUS(n)
Definition: target_api.h:252
struct target_location_ctxt * global_tlctxt
Definition: target_api.h:2667
clrange_t code_ranges
Definition: target_api.h:2754
int target_spec_to_argv(struct target_spec *spec, char *arg0, int *argc, char ***argv)
Definition: target.c:407
int value_set_child(struct value *value, struct value *parent_value, ADDR addr)
Definition: value.c:53
unsigned long target_write_physaddr(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1052
int target_symbol_resolve_bounds(struct target *target, struct target_location_ctxt *tlctxt, struct symbol *symbol, ADDR *start, ADDR *end, int *is_noncontiguous, ADDR *alt_start, ADDR *alt_end)
Definition: target.c:2372
#define SYMBOL_IST_PTR(sym)
int target_lookup_filename_line_addr(struct target *target, ADDR addr, char **filename, int *line)
Definition: target.c:2328
const char * target_regname(struct target *target, REG reg)
Definition: target_api.c:1065
struct memrange * range
Definition: target_api.h:3255
char * name
Definition: dwdebug_priv.h:788
GHashTable * threads
Definition: target_api.h:2632
#define TARGET_ARGP_PERSONALITY
Definition: target.c:357
struct list_head tac
Definition: probe.h:202
unsigned char * tmp
Definition: target.h:399
#define TARGET_ARGP_START_PAUSED
Definition: target.c:359
int target_memmod_unset(struct target *target, tid_t tid, struct target_memmod *mmod)
Definition: target.c:5046
uint8_t * flags
Definition: regcache.h:70
struct location_ctxt * location_ctxt_create(struct location_ops *ops, void *priv)
Definition: location.c:802
struct value * value_create_type(struct target_thread *thread, struct memrange *range, struct symbol *type)
Definition: value.c:102
void value_free(struct value *value)
Definition: value.c:224
struct target_location_ctxt * target_global_tlctxt(struct target *target)
Definition: target.c:5243
int target_regcache_copy_all_zero(struct target_thread *sthread, thread_ctxt_t stidctxt, struct target_thread *dthread, thread_ctxt_t dtidctxt)
Definition: target.c:6479
Definition: target.c:3860
struct target_spec * spec
Definition: target_api.h:2258
void vmi_set_warn_level(int level)
Definition: log.c:42
#define TARGET_REGCACHE_GET(tctxt, errretval)
Definition: target.c:6108
struct value * target_load_value_member(struct target *target, struct target_location_ctxt *tlctxt, struct value *old_value, const char *member, const char *delim, load_flags_t flags)
Definition: target.c:2907
unsigned char * orig
Definition: target.h:387
#define LOGDUMPPROBEPOINT_NL(dl, la, lt, p)
Definition: probe.h:50
ADDR tag
Definition: target.h:886
#define SYMBOLX_VAR(sym)
struct bsymbol * target_lookup_sym_addr(struct target *target, ADDR addr)
Definition: target.c:2063
int target_gkv_insert(struct target *target, char *key, void *value, target_gkv_dtor_t dtor)
Definition: target.c:1391
int target_location_ctxt_unwind(struct target_location_ctxt *tlctxt)
Definition: target.c:5361
char * REGION_TYPE_STRINGS[]
Definition: target.c:6652
int len
Definition: dumptarget.c:52
#define SYMBOL_IST_STUNC(sym)
struct value * target_load_type_regval(struct target *target, struct symbol *type, tid_t tid, REG reg, REGVAL regval, load_flags_t flags)
Definition: target.c:2727
#define RHOLD(x, hx)
Definition: common.h:622
#define RF_REJECT
Definition: rfilter.h:30
ADDR addr
Definition: target.h:381
void vmi_inc_warn_level(void)
Definition: log.c:46
error_t target_argp_parse_opt(int key, char *arg, struct argp_state *state)
Definition: target.c:1048
int target_regcache_snprintf(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, char *buf, int bufsiz, int detail, char *sep, char *kvsep, int flags)
Definition: target.c:6368
Definition: probe.h:308
target_type_t target_type
Definition: target_api.h:2166
GList * spaces
Definition: target_api.h:2603
target_unwind_style_t
Definition: target_api.h:2394
int location_set_addr(struct location *l, ADDR addr)
Definition: location.c:46
int target_store_value(struct target *target, struct value *value)
Definition: target.c:3512
struct target_thread * thread
Definition: probe.h:343
ADDR target_load_pointers(struct target *target, ADDR addr, int count, struct memrange **range_saveptr)
Definition: target.c:3575
struct binfile * binfile
Definition: target_api.h:2609
Definition: log.h:170
struct target_ops php_ops
Definition: target_php.c:1015
struct array_list * tpc_stack
Definition: target_api.h:2132
#define v_g_list_foreach_safe(glhead, glcur, glnext, elm)
Definition: glib_wrapper.h:46
int value_set_addr(struct value *value, ADDR addr)
Definition: value.c:28
int target_attach_probe(struct target *target, struct target_thread *thread, struct probe *probe)
Definition: target.c:4669
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
int(* attach_overlay_thread)(struct target *base, struct target *overlay, tid_t newtid)
Definition: target_api.h:2881
GHashTable * gkv_store
Definition: target_api.h:2162
REGVAL * values
Definition: regcache.h:63
int base_thread_id
Definition: target_api.h:2170
ADDR memrange_unrelocate(struct memrange *range, ADDR real)
Definition: memory.c:598
int target_regcache_readreg_ifdirty(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, REGVAL *regval)
Definition: target.c:6291
REFCNT target_free(struct target *target, int force)
Definition: target.c:1620
obj_flags_t
Definition: object.h:43
ADDR v_addr(struct value *v)
Definition: value.c:371
struct thread_probepoint_context * tpc
Definition: target_api.h:2131
void * data
Definition: clfit.h:39
struct symbol * symbol_type_skip_qualifiers(struct symbol *type)
Definition: debug.c:4191
int regcache_read_reg(struct regcache *regcache, REG reg, REGVAL *regval)
Definition: regcache.c:271
int target_regcache_init_reg_tidctxt(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG reg, REGVAL regval)
Definition: target.c:6130
int target_personality_load(char *filename)
Definition: target.c:5917
unsigned long orig_len
Definition: target.h:388
GSList * value_regex_list
Definition: target.h:674
struct memregion * region
Definition: target.h:981
#define vdebugc(devel, areas, flags, format,...)
Definition: log.h:303
#define SYMBOL_IS_TYPE(sym)
struct target_ops * target_get_ops(target_type_t target_type)
Definition: target.c:1832
struct target_location_ctxt_frame * target_location_ctxt_current_frame(struct target_location_ctxt *tlctxt)
Definition: target.c:5651
struct arch * arch
Definition: target_api.h:2563
#define OBJSDIRTY(obj)
Definition: object.h:111
unsigned int wordsize
Definition: arch.h:121
void target_detach_overlay(struct target *base, tid_t overlaytid)
Definition: target.c:4467
void(* free_thread_state)(struct target *target, void *state)
Definition: target_api.h:2952
struct value * value_create(struct target_thread *thread, struct memrange *range, struct lsymbol *lsymbol, struct symbol *type)
Definition: value.c:138
int target_detach_overlay_thread(struct target *base, struct target *overlay, tid_t tid)
Definition: target.c:4516
struct target_personality_ops * ptops
Definition: target.h:236
unsigned int is_phys
Definition: target.h:378
REFCNT refcnt
Definition: target_api.h:2423
struct array_list * debugfile_load_opts_list
Definition: target_api.h:2199
int value_set_reg(struct value *value, REG reg)
Definition: value.c:45
int target_regcache_mark_flushed(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt)
Definition: target.c:6415
unsigned char * code
Definition: target.c:3864
unsigned int thread_ctxt_t
Definition: target_api.h:300
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
#define list_for_each_entry_safe(pos, n, head, member)
Definition: list.h:387
GHashTable * overlay_aliases
Definition: target_api.h:2630
target_thread_gkv_dtor_t dtor
Definition: target.c:1488
struct lsymbol * debugfile_lookup_sym_line__int(struct debugfile *debugfile, char *filename, int line, SMOFFSET *offset, ADDR *addr)
Definition: debug.c:463
Definition: log.h:70
REFCNT refcntw
Definition: target_api.h:2052
void regcache_destroy(struct regcache *regcache)
Definition: regcache.c:42
void * target_thread_gkv_lookup(struct target *target, tid_t tid, char *key)
Definition: target.c:1519
uint32_t REGVAL
Definition: common.h:66
int probe_id_counter
Definition: target_api.h:2741
#define THREAD_CTXT_DEFAULT
Definition: target_api.h:301
struct list_head ss_actions
Definition: target_api.h:2156
REFCNT binfile_release(struct binfile *binfile)
Definition: binfile.c:352
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
void * personality_state
Definition: target_api.h:2069
uint32_t needmonitorinterrupt
Definition: target_api.h:2427
int target_attach_action(struct target *target, struct action *action)
Definition: target.c:4692
unsigned int symbol_type_full_bytesize(struct symbol *type)
Definition: debug.c:4267
int target_invalidate_all_threads(struct target *target)
Definition: target.c:4426
int(* invalidate_thread)(struct target *target, struct target_thread *tthread)
Definition: target_api.h:2965
#define PRIiTID
Definition: common.h:37
struct value * target_load_addr_obj(struct target *target, struct memregion *region, ADDR obj_addr, load_flags_t flags, int len)
Definition: target.c:3700
struct location_ops target_location_ops
Definition: location.c:310
sigset_t ignored
Definition: spf.c:211
int memrange_contains_real(struct memrange *range, ADDR real_addr)
Definition: memory.c:583
struct target_spec * target_build_spec(target_type_t type, target_mode_t mode)
Definition: target_api.c:394
struct target_ops xen_vm_ops
int target_regcache_isdirty(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt)
Definition: target.c:6307
struct symbol * symbol_type_skip_ptrs(struct symbol *type)
Definition: debug.c:4209
Definition: log.h:125
int regcache_isdirty_reg(struct regcache *regcache, REG reg)
Definition: regcache.c:202
void target_reuse_thread_as_global(struct target *target, struct target_thread *thread)
Definition: target.c:4063
#define TARGET_REGCACHE_ALLOC(tctxt, errretval)
Definition: target.c:6074
int8_t REG
Definition: common.h:93
target_type_t
Definition: target_api.h:163
int debugfile_lookup_line_addr(struct debugfile *debugfile, char *filename, ADDR addr)
Definition: debug.c:411
struct lsymbol * bsymbol_get_lsymbol(struct bsymbol *bsymbol)
Definition: symbol.c:70
uint32_t opened
Definition: target_api.h:2427
struct target_location_ctxt * target_location_ctxt_create(struct target *target, tid_t tid, struct memregion *region)
Definition: target.c:5248
void target_thread_gkv_destroy(struct target *target, struct target_thread *tthread)
Definition: target.c:1590
int target_finalize(struct target *target)
Definition: target.c:1925
GHashTable * hard_probepoints
Definition: target_api.h:2080
struct symbol * bsymbol_get_symbol(struct bsymbol *bsymbol)
Definition: symbol.c:66
struct target * target
Definition: probe.h:342
loctype_t lsymbol_resolve_location(struct lsymbol *lsymbol, ADDR base_addr, struct location_ctxt *lctxt, struct location *o_loc)
Definition: location.c:1266
struct list_head action
Definition: probe.h:449
target_personality_t
Definition: target_api.h:180
uint32_t ADDR
Definition: common.h:64
char * name
Definition: target_api.h:2483
struct target * target_lookup_overlay(struct target *target, tid_t tid)
Definition: target.c:4455
void * __personality_specific_ops
Definition: target_api.h:2554
struct target_ops * ops
Definition: target_api.h:2510
struct symbol * type
Definition: target_api.h:3247
Definition: log.h:162
char * infile
Definition: target_api.h:2248
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
struct value * target_load_addr_real(struct target *target, ADDR addr, load_flags_t flags, int len)
Definition: target.c:3716
char * name
Definition: target.h:887
target_status_t target_notify_overlay(struct target *overlay, target_exception_flags_t flags, tid_t tid, ADDR ipval, int *again)
Definition: target.c:4449
REG spregno
Definition: target_api.h:2469
struct scope * scope_lookup_addr(struct scope *scope, ADDR pc)
Definition: scope.c:528
int(* detach_overlay_thread)(struct target *base, struct target *overlay, tid_t tid)
Definition: target_api.h:2883
target_memmod_type_t
Definition: target.h:329
void os_linux_generic_register(void)
thread_ctxt_t tidctxt
Definition: target_api.h:2043
int(* invalidate_thread)(struct target *target, struct target_thread *tthread)
Definition: target_api.h:3145
ADDR memregion_relocate(struct memregion *region, ADDR obj_addr, struct memrange **range_saveptr)
Definition: memory.c:375
#define REGCACHE_DIRTY
Definition: regcache.h:31
thread_status_t
Definition: target_api.h:254
target_status_t status
Definition: target_api.h:2465
void target_gkv_destroy(struct target *target)
Definition: target.c:1456
int target_regcache_isdirty_reg_range(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt, REG start, REG end)
Definition: target.c:6339
int target_lookup_line_addr(struct target *target, char *srcfile, ADDR addr)
Definition: target.c:2289
char * filename
Definition: dwdebug.h:817
struct target_spec * target_argp_target_spec(struct argp_state *state)
Definition: target.c:696
struct target * target
Definition: target.h:368
int debugfile_lookup_filename_line_addr(struct debugfile *debugfile, ADDR addr, char **filename, int *line)
Definition: debug.c:437
struct value * target_load_symbol_member(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, const char *member, const char *delim, load_flags_t flags)
Definition: target.c:2885
char * personality
Definition: target_api.h:2190
int target_regcache_invalidate(struct target *target, struct target_thread *tthread, thread_ctxt_t tctxt)
Definition: target.c:6433
uint32_t REFCNT
Definition: common.h:124
int target_contains_real(struct target *target, ADDR addr)
Definition: target.c:3560
#define PRIxADDR
Definition: common.h:67
void target_location_ctxt_free(struct target_location_ctxt *tlctxt)
Definition: target.c:5292
#define SYMBOL_IS_ROOT(sym)
char * SYMBOL_TYPE(int n)
Definition: debug.c:5662
REGVAL target_regcache_readreg(struct target *target, tid_t tid, REG reg)
Definition: target.c:6209
void target_tid_set_status(struct target *target, tid_t tid, thread_status_t status)
Definition: target.c:4007
struct target_spec * spec
Definition: target_api.h:2565
int target_monitor_schedule_interrupt(struct target *target)
Definition: target.c:318
#define LOCATION_REG(loc)
Definition: dwdebug_priv.h:623
ADDR memrange_relocate(struct memrange *range, ADDR obj)
Definition: memory.c:602
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
load_flags_t
Definition: target_api.h:406
struct bsymbol * bsymbol
Definition: target_api.h:2377
struct target_location_ctxt *(* unwind)(struct target *target, tid_t tid)
Definition: target_api.h:3033
struct target_spec * target_argp_driver_parse_one(struct argp *driver_parser, void *driver_state, int argc, char **argv, target_type_t target_types, int filter_quoted)
Definition: target.c:789
char * symbol_get_name(struct symbol *symbol)
Definition: debug.c:2587
#define RPUT(x, objtype, hx, rc)
Definition: common.h:624
ADDR base_virt_addr
Definition: target.h:967
int id
Definition: probe.h:312
void debugfile_load_opts_free(struct debugfile_load_opts *opts)
Definition: debug.c:1275
struct location_ops * location_ops
Definition: target_api.h:2511
struct symbol_root * root
Definition: dwdebug_priv.h:973
unsigned char * mod
Definition: target.h:394
int id
Definition: target_api.h:2476
char * debugfile_root_prefix
Definition: target_api.h:2197
uint8_t ismmap
Definition: target_api.h:3260
struct regcache * regcache_create(struct arch *arch)
Definition: regcache.c:29
int regcache_snprintf(struct regcache *regcache, char *buf, int bufsiz, int detail, char *sep, char *kvsep, int flags)
Definition: regcache.c:459
unsigned int max_thread_ctxt
Definition: target_api.h:2467
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
void * clrange_find(clrange_t *clf, Word_t index)
Definition: clfit.c:312
GHashTable * probes
Definition: target_api.h:2725
struct target_thread * thread
Definition: target_api.h:2345
symbol_type_flag_t
Definition: dwdebug.h:190
target_type_t target_type(struct target *target)
Definition: target_api.c:484
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
char * errfile
Definition: target_api.h:2250
void value_set_const(struct value *value)
Definition: value.c:73
int target_lookup_safe_disasm_range(struct target *target, ADDR addr, ADDR *start, ADDR *end, void **data)
Definition: target.c:3783
target_status_t(* handle_overlay_exception)(struct target *overlay, target_exception_flags_t flags, tid_t tid, ADDR ipval, int *again)
Definition: target_api.h:2889
#define REGCACHE_VALID
Definition: regcache.h:32
REG reg
Definition: target_api.h:3270
int regcache_copy_dirty(struct regcache *sregcache, struct regcache *dregcache)
Definition: regcache.c:75
Definition: log.h:177
struct bsymbol * target_lookup_sym_member(struct target *target, struct bsymbol *bsymbol, const char *name, const char *delim)
Definition: target.c:2218
void target_gkv_remove(struct target *target, char *key)
Definition: target.c:1438
void * target_gkv_lookup(struct target *target, char *key)
Definition: target.c:1409
char * outfile
Definition: target_api.h:2249
int target_monitor_handling_exception(struct target *target)
Definition: target.c:310
GHashTable * target_regcache_copy_registers_tidctxt(struct target *target, tid_t tid, thread_ctxt_t tidctxt)
Definition: target.c:6548
int target_thread_filter_check(struct target *target, tid_t tid, struct target_nv_filter *tf)
Definition: target.c:4253
int target_lookup_next_safe_disasm_range(struct target *target, ADDR addr, ADDR *start, ADDR *end, void **data)
Definition: target.c:3818
#define INIT_LIST_HEAD(ptr)
Definition: list.h:60
struct argp linux_userproc_argp
int vdebug_is_on(int level, log_areas_t areas, log_flags_t flags)
Definition: log.c:335
uint8_t tracked
Definition: probe.h:376
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
uint8_t start_paused
Definition: target_api.h:2176
int clrange_add(clrange_t *clf, Word_t start, Word_t end, void *data)
Definition: clfit.c:104
int errfd
Definition: target_api.h:2575
int debugfile_lookup_addr_alt__int(struct debugfile *debugfile, ADDR addr, struct lsymbol **primary, struct lsymbol **alt)
Definition: debug.c:580
int target_regcache_writereg(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target.c:6250
REG ipregno
Definition: target_api.h:2470
int target_write_reg(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target_api.c:1092
void * target_thread_gkv_steal(struct target *target, tid_t tid, char *key)
Definition: target.c:1538
struct location_ctxt * lctxt
Definition: target_api.h:2339
loctype_t
Definition: dwdebug.h:234
struct symbol * datatype
Definition: dwdebug_priv.h:925
#define TID_GLOBAL
Definition: target_api.h:145
int regcache_isdirty(struct regcache *regcache)
Definition: regcache.c:236
int target_thread_obj_flags_propagate(struct target_thread *tthread, obj_flags_t orf, obj_flags_t nandf)
Definition: target.c:4117
int target_memmod_free(struct target *target, tid_t tid, struct target_memmod *mmod, int force)
Definition: target.c:4914
struct memregion * region
Definition: target.h:1009
void target_driver_argp_init_children(struct argp_state *state)
Definition: target.c:1044
#define LOGDUMPSYMBOL(dl, lt, lf, s)
Definition: dwdebug_priv.h:25
#define SYMBOL_IS_VAR(sym)
struct target * t
Definition: dumptarget.c:48
loctype_t target_lsymbol_resolve_location(struct target *target, struct target_location_ctxt *tlctxt, struct lsymbol *lsymbol, ADDR base_addr, load_flags_t flags, struct location *o_loc, struct symbol **o_datatype, struct memrange **o_range)
Definition: target.c:2421
Definition: arch.h:75
int xen_vm_spec_to_argv(struct target_spec *spec, int *argc, char ***argv)
clrange_t clrange_create(void)
Definition: clfit.c:27
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
#define PRIxREGVAL
Definition: common.h:72
char * xen_vm_argp_header
struct value *(* read_symbol)(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, load_flags_t flags)
Definition: target_api.h:2920
struct argp gdb_argp
Definition: target_gdb.c:562
char * personality_lib
Definition: target_api.h:2195
unsigned char * target_load_code(struct target *target, ADDR start, unsigned int len, int nocache, int force_copy, int *caller_free)
Definition: target.c:3867
#define RWGUARD(x)
Definition: common.h:220