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