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
dumptarget.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012, 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <string.h>
23 
24 #include <sys/user.h>
25 #include <sys/ptrace.h>
26 #include <inttypes.h>
27 
28 #include <signal.h>
29 
30 #include <argp.h>
31 
32 #include <glib.h>
33 #include "glib_wrapper.h"
34 
35 #include "log.h"
36 #include "dwdebug.h"
37 #include "target_api.h"
38 #include "target.h"
39 #include "target_linux_userproc.h"
40 #ifdef ENABLE_XEN
41 #include "target_xen_vm.h"
42 #endif
43 
44 #include "probe_api.h"
45 #include "probe.h"
46 #include "alist.h"
47 
48 struct target *t = NULL;
49 unsigned int ots_len = 0;
50 struct target **ots = NULL;
51 
52 int len = 0;
53 struct bsymbol **symbols = NULL;
54 GHashTable *probes = NULL;
55 GHashTable *disfuncs = NULL;
57 
58 int doit = 0;
59 
60 int at_symbol_hit = 0;
61 char *at_symbol = NULL;
62 struct bsymbol *at_bsymbol = NULL;
63 
65 char *until_symbol = NULL;
66 struct bsymbol *until_bsymbol = NULL;
67 struct probe *until_probe = NULL;
68 
70 
71 struct overlay_spec {
74  struct target_spec *spec;
75 };
76 
77 struct dt_argp_state {
78  char *at_symbol;
79  char *until_symbol;
80  int do_bts;
82  int raw;
83  int do_post;
84  int quiet;
85  int argc;
86  char **argv;
87  unsigned int ospecs_len;
88  struct overlay_spec **ospecs;
89 };
90 
91 error_t dt_argp_parse_opt(int key, char *arg,struct argp_state *state);
92 
93 #define __TARGET_OVERLAY 0x200000
94 
95 struct argp_option dt_argp_opts[] = {
96  { "overlay",__TARGET_OVERLAY,"[<target_id>:]<thread_name_or_id>:<spec_opts>",0,"Lookup name or id as an overlay target once the main target is instantiated, and try to open it. All dumptarget options then apply to the overlay.",0 },
97  { "at-symbol",'A',"SYMBOL",0,"Wait for a probe on this symbol/address to be hit before inserting all the other probes.",0 },
98  { "until-symbol",'U',"SYMBOL",0,"Remove all probes once a probe on this symbol/address is hit.",0 },
99  { "bts",'B',0,0,"Enable BTS (if XenTT) (starting at at-symbol if one was provided; otherwise, enable immediately).",0 },
100  { "stop-at-until",'S',0,0,"Stop probing once the until symbol/address is reached.",0 },
101  { "raw",'v',0,0,"Enable raw mode.",0 },
102  { "post",'P',0,0,"Enable post handlers.",0 },
103  { "quiet",'q',0,0,"Silent but deadly.",0 },
104  { 0,0,0,0,0,0 },
105 };
106 
107 struct argp dt_argp = {
108  dt_argp_opts,dt_argp_parse_opt,NULL,NULL,NULL,NULL,NULL,
109 };
110 
112 
114 
116  GHashTableIter iter;
117  gpointer key;
118  struct probe *probe;
119 
120  if (probes) {
121  g_hash_table_iter_init(&iter,probes);
122  while (g_hash_table_iter_next(&iter,
123  (gpointer)&key,
124  (gpointer)&probe)) {
125  probe_unregister(probe,1);
126  probe_free(probe,1);
127  g_hash_table_iter_remove(&iter);
128  }
129  g_hash_table_destroy(probes);
130  probes = NULL;
131  }
132 }
133 
134 void cleanup() {
135  static int cleaning = 0;
136  int j;
137 
138  if (cleaning)
139  return;
140  cleaning = 1;
141 
142  cleanup_probes();
143 
144  if (ots) {
145  for (j = ots_len - 1; j >= 0; --j) {
146  if (!ots[j])
147  continue;
148  target_close(ots[j]);
149  target_finalize(ots[j]);
150  ots[j] = NULL;
151  }
152  }
153 
154  target_close(t);
155  target_finalize(t);
156 
157  if (disfuncs)
158  g_hash_table_destroy(disfuncs);
159 
160  if (shadow_stack)
161  array_list_deep_free(shadow_stack);
162 
163  if (symbols)
164  free(symbols);
165 
166  target_free_spec(tspec);
167 
168  if (opts.argv)
169  free(opts.argv);
170 
171  target_fini();
172 
173 #ifdef REF_DEBUG
175 #endif
176 }
177 
178 void sigh(int signo) {
179 
180  if (t) {
181  target_pause(t);
182  fprintf(stderr,
183  "Ending trace (%d) (hits on probes not from root set: %d).\n",
184  signo,nonrootsethits);
185  cleanup();
186  fprintf(stderr,"Ended trace.\n");
187  }
188 
189  exit(0);
190 }
191 
192 #ifdef ENABLE_DISTORM
193 result_t retaddr_check(struct probe *probe,tid_t tid,void *handler_data,
194  struct probe *trigger,struct probe *base);
195 result_t retaddr_save(struct probe *probe,tid_t tid,void *handler_data,
196  struct probe *trigger,struct probe *base);
197 
198 ADDR instrument_func(struct bsymbol *bsymbol,int isroot) {
199  ADDR funcstart = 0;
200  struct target_location_ctxt *tlctxt;
201 
203  if (target_lsymbol_resolve_bounds(t,tlctxt,bsymbol->lsymbol,0,
204  &funcstart,NULL,NULL,NULL,NULL)) {
205  fprintf(stderr,
206  "Could not resolve base addr for function %s!\n",
207  bsymbol_get_name(bsymbol));
209  return 0;
210  }
212 
213  /* Disassemble the called function if we haven't already! */
214  if (!g_hash_table_lookup(disfuncs,(gpointer)funcstart)) {
215  /* Dissasemble the function and grab a list of
216  * RET instrs, and insert more child
217  * breakpoints.
218  */
219  int bufsiz = strlen(bsymbol_get_name(bsymbol))+1+4+1+2+1;
220  char *buf = malloc(bufsiz);
221  snprintf(buf,bufsiz,"call_in_%s",bsymbol_get_name(bsymbol));
222  struct probe *cprobe = probe_create(t,TID_GLOBAL,NULL,buf,
223  NULL,retaddr_save,NULL,0,1);
224  cprobe->handler_data = cprobe->name;
225  free(buf);
226  struct probe *rprobe;
227  if (!isroot) {
228  bufsiz = strlen(bsymbol_get_name(bsymbol))+1+3+1+2+1;
229  buf = malloc(bufsiz);
230  snprintf(buf,bufsiz,"ret_in_%s",bsymbol_get_name(bsymbol));
231  rprobe = probe_create(t,TID_GLOBAL,NULL,buf,retaddr_check,NULL,buf,0,1);
232  rprobe->handler_data = rprobe->name;
233  free(buf);
234  }
235  else
236  rprobe = NULL;
237 
238  if (isroot) {
239  if (!probe_register_function_instrs(bsymbol,PROBEPOINT_SW,1,
240  NULL,NULL,
241  INST_CALL,cprobe,
242  INST_NONE)) {
243  probe_free(cprobe,1);
244  return 0;
245  }
246  }
247  else {
248  if (!probe_register_function_instrs(bsymbol,PROBEPOINT_SW,1,
249  NULL,NULL,
250  INST_RET,rprobe,
251  INST_CALL,cprobe,
252  INST_NONE)) {
253  probe_free(cprobe,1);
254  probe_free(rprobe,1);
255  return 0;
256  }
257  }
258 
259  if (probe_num_sources(cprobe) == 0) {
260  probe_free(cprobe,1);
261  fprintf(stderr,
262  "No call sites in %s.\n",bsymbol_get_name(bsymbol));
263  }
264  else {
265  g_hash_table_insert(probes,(gpointer)cprobe,(gpointer)cprobe);
266  fprintf(stderr,
267  "Registered %d call probes in function %s.\n",
268  probe_num_sources(cprobe),bsymbol_get_name(bsymbol));
269  }
270 
271  if (!isroot) {
272  if (probe_num_sources(rprobe) == 0) {
273  probe_free(rprobe,1);
274  fprintf(stderr,
275  "No return sites in %s.\n",bsymbol_get_name(bsymbol));
276  }
277  else {
278  g_hash_table_insert(probes,(gpointer)rprobe,(gpointer)rprobe);
279  fprintf(stderr,
280  "Registered %d return probes in function %s.\n",
281  probe_num_sources(rprobe),bsymbol_get_name(bsymbol));
282  }
283  }
284 
285  g_hash_table_insert(disfuncs,(gpointer)funcstart,(gpointer)1);
286  }
287 
288  return funcstart;
289 }
290 
291 result_t retaddr_save(struct probe *probe,tid_t tid,void *handler_data,
292  struct probe *trigger,struct probe *base) {
293  struct target *t = probe->target;
294  REGVAL sp;
295  REGVAL ip;
296  ADDR *retaddr;
297  char buf[512];
298 
299  fflush(stderr);
300  fflush(stdout);
301 
302  errno = 0;
303  sp = target_read_reg(probe->target,tid,probe->target->spregno);
304  if (errno) {
305  fprintf(stderr,"Could not read SP in retaddr_save!\n");
306  return RESULT_SUCCESS;
307  }
308 
309  /* Grab the return address on the top of the stack */
310  retaddr = malloc(sizeof(*retaddr));
311  if (!target_read_addr(t,(ADDR)sp,sizeof(ADDR),
312  (unsigned char *)retaddr)) {
313  fprintf(stderr,"Could not read top of stack in retaddr_save!\n");
314  return RESULT_SUCCESS;
315  }
316 
317  /* Grab the current IP -- the post-call IP */
318  ip = target_read_reg(t,tid,t->ipregno);
319  if (errno) {
320  fprintf(stderr,"Could not read IP in retaddr_save!\n");
321  fflush(stderr);
322  fflush(stdout);
323  return RESULT_SUCCESS;
324  }
325 
326  struct bsymbol *bsymbol = target_lookup_sym_addr(t,ip);
327  if (!bsymbol) {
328  target_thread_snprintf(t,tid,buf,sizeof(buf),10,",","=");
329  fprintf(stdout,
330  "(SAVE) call 0x%"PRIxADDR" (<UNKNOWN>)"
331  " (from within %s): retaddr = 0x%"PRIxADDR
332  " (skipping unknown function!)"
333  " (handler_data = %s) (stack depth = %d) (thread = %s)\n",
334  ip,bsymbol_get_name(probe->bsymbol),*retaddr,
335  (char *)handler_data,array_list_len(shadow_stack),buf);
336  free(retaddr);
337  return RESULT_SUCCESS;
338  }
339  else {
340  target_thread_snprintf(t,tid,buf,sizeof(buf),10,",","=");
341  fprintf(stdout,
342  "(SAVE) call 0x%"PRIxADDR" (%s)"
343  " (from within %s): retaddr = 0x%"PRIxADDR
344  " (handler_data = %s) (stack depth = %d) (thread = %s)\n",
345  ip,bsymbol_get_name(bsymbol),
346  bsymbol_get_name(probe->bsymbol),
347  *retaddr,(char *)handler_data,array_list_len(shadow_stack),buf);
348  fflush(stderr);
349  fflush(stdout);
350  }
351 
352  fflush(stderr);
353  fflush(stdout);
354 
355  /* Since we know that the call is a known function that we can
356  * disasm and instrument return points for, push it onto the shadow
357  * stack!
358  */
359  array_list_add(shadow_stack,retaddr);
360 
361  instrument_func(bsymbol,0);
362  bsymbol_release(bsymbol);
363 
364  return RESULT_SUCCESS;
365 }
366 
367 result_t retaddr_check(struct probe *probe,tid_t tid,void *handler_data,
368  struct probe *trigger,struct probe *base) {
369  REGVAL sp;
370  ADDR newretaddr;
371  ADDR *oldretaddr = NULL;
372  char buf[512];
373 
374  fflush(stderr);
375  fflush(stdout);
376 
377  /* These are probably from functions we instrumented, but
378  * that were not called from our function root set.
379  */
380  if (array_list_len(shadow_stack) == 0) {
381  ++nonrootsethits;
382  return RESULT_SUCCESS;
383  }
384 
385  errno = 0;
386  sp = target_read_reg(probe->target,tid,probe->target->spregno);
387  if (errno) {
388  fprintf(stderr,"Could not read SP in retaddr_check!\n");
389  return RESULT_SUCCESS;
390  }
391 
392  oldretaddr = (ADDR *)array_list_remove(shadow_stack);
393 
394  if (!target_read_addr(probe->target,(ADDR)sp,sizeof(ADDR),
395  (unsigned char *)&newretaddr)) {
396  fprintf(stderr,"Could not read top of stack in retaddr_check!\n");
397  free(oldretaddr);
398  return RESULT_SUCCESS;
399  }
400 
401  if (newretaddr != *oldretaddr) {
402  target_thread_snprintf(probe->target,tid,buf,sizeof(buf),10,",","=");
403  fprintf(stdout,
404  "(CHECK) %s (0x%"PRIxADDR"): newretaddr = 0x%"PRIxADDR";"
405  " oldretaddr = 0x%"PRIxADDR
406  " (handler_data = %s) (stack depth = %d) (thread = %s)"
407  " ---- STACK CORRUPTION!\n",
408  bsymbol_get_name(probe->bsymbol),probe_addr(base),
409  newretaddr,*oldretaddr,
410  (char *)handler_data,array_list_len(shadow_stack),buf);
411  }
412  else {
413  target_thread_snprintf(probe->target,tid,buf,sizeof(buf),10,",","=");
414  fprintf(stdout,
415  "(CHECK) %s (0x%"PRIxADDR"): newretaddr = 0x%"PRIxADDR";"
416  " oldretaddr = 0x%"PRIxADDR
417  " (handler_data = %s) (stack depth = %d) (thread = %s)\n",
418  bsymbol_get_name(probe->bsymbol),probe_addr(base),
419  newretaddr,*oldretaddr,
420  (char *)handler_data,array_list_len(shadow_stack),buf);
421  }
422 
423  if (doit) {
424  if (!target_write_addr(probe->target,(ADDR)sp,sizeof(ADDR),
425  (unsigned char *)oldretaddr)) {
426  fprintf(stderr,"Could not reset top of stack in retaddr_check!\n");
427  free(oldretaddr);
428  return RESULT_SUCCESS;
429  }
430  else
431  fprintf(stdout,"Reset stack after corruption!\n");
432  }
433 
434  fflush(stderr);
435  fflush(stdout);
436 
437  free(oldretaddr);
438 
439  return RESULT_SUCCESS;
440 }
441 #endif /* ENABLE_DISTORM */
442 
443 result_t at_handler(struct probe *probe,tid_t tid,void *handler_data,
444  struct probe *trigger,struct probe *base) {
445  ADDR probeaddr;
446 
447  fflush(stderr);
448  fflush(stdout);
449 
450  if (!probe->probepoint)
451  probeaddr = probe_addr(base);
452  else
453  probeaddr = probe_addr(probe);
454 
455  fprintf(stdout,
456  "%s (0x%"PRIxADDR") (thread %"PRIiTID") (at_symbol hit)\n",
457  at_symbol,probeaddr,tid);
458  fflush(stdout);
459 
460  at_symbol_hit = 1;
461 
462  return RESULT_SUCCESS;
463 }
464 
465 result_t until_handler(struct probe *probe,tid_t tid,void *handler_data,
466  struct probe *trigger,struct probe *base) {
467  ADDR probeaddr;
468 
469  fflush(stderr);
470  fflush(stdout);
471 
472  if (!probe->probepoint && base)
473  probeaddr = probe_addr(base);
474  else
475  probeaddr = probe_addr(probe);
476 
477  fprintf(stdout,
478  "%s (0x%"PRIxADDR") (thread %"PRIiTID") (until_symbol hit)\n",
479  until_symbol,probeaddr,tid);
480  fflush(stdout);
481 
482  until_symbol_hit = 1;
483 
484  return RESULT_SUCCESS;
485 }
486 
487 result_t function_dump_args(struct probe *probe,tid_t tid,void *handler_data,
488  struct probe *trigger,struct probe *base) {
489  struct value *value;
490  int j;
491  ADDR probeaddr;
492  GSList *gsltmp;
493  struct target_location_ctxt *tlctxt;
494 
495  if (!opts.quiet) {
496  fflush(stderr);
497  fflush(stdout);
498  }
499 
500  if (!probe->probepoint && base)
501  probeaddr = probe_addr(base);
502  else
503  probeaddr = probe_addr(probe);
504 
505  //struct bsymbol *bsymbol = target_lookup_sym_addr(probe->target,probeaddr);
506  //ip = target_read_reg(probe->target,probe->target->ipregno);
507 
508  if (!opts.quiet)
509  fprintf(stdout,"%s (0x%"PRIxADDR") (thread %"PRIiTID") ",
510  bsymbol_get_name(probe->bsymbol),probeaddr,tid);
511 
512  GSList *args;
513  struct symbol *arg;
514  struct lsymbol *ls;
515  struct bsymbol *bs;
516  struct dump_info di = { .stream = stdout };
517 
518  args = symbol_get_members(probe->bsymbol->lsymbol->symbol,
520  if (args) {
521  gsltmp = NULL;
523  probe->bsymbol);
524  v_g_slist_foreach(args,gsltmp,arg) {
525  ls = lsymbol_create_from_symbol(arg);
526  bs = bsymbol_create(ls,probe->bsymbol->region);
527  lsymbol_release(ls);
528  if ((value = target_load_symbol(probe->target,tlctxt,bs,
533 
534  if (!opts.quiet) {
535  printf("%s = ",lsymbol_get_name(ls));
536  value_dump_simple(value,&di);
537  printf(" (0x");
538  for (j = 0; j < value->bufsiz; ++j) {
539  printf("%02hhx",value->buf[j]);
540  }
541  printf(")");
542  }
543  value_free(value);
544  }
545  bsymbol_free(bs,0);
546 
547  if (!opts.quiet)
548  printf(", ");
549  }
551  }
552 
553  if (!opts.quiet) {
554  fprintf(stdout," (handler_data = %s)\n",(char *)handler_data);
555 
556  fflush(stderr);
557  fflush(stdout);
558  }
559 
560  if (args) {
561  g_slist_free(args);
562  }
563 
564  return RESULT_SUCCESS;
565 }
566 
567 result_t function_post(struct probe *probe,tid_t tid,void *handler_data,
568  struct probe *trigger,struct probe *base) {
569  ADDR probeaddr;
570 
571  if (!probe->probepoint && base)
572  probeaddr = probe_addr(base);
573  else
574  probeaddr = probe_addr(probe);
575 
576  if (!opts.quiet) {
577  fflush(stderr);
578  fflush(stdout);
579 
580  fprintf(stdout,"%s (0x%"PRIxADDR") post handler (thread %"PRIiTID")",
581  bsymbol_get_name(probe->bsymbol),
582  probeaddr,tid);
583  fprintf(stdout," (handler_data = %s)\n",(char *)handler_data);
584 
585  fflush(stderr);
586  fflush(stdout);
587  }
588 
589  return RESULT_SUCCESS;
590 }
591 
592 result_t addr_code_pre(struct probe *probe,tid_t tid,void *handler_data,
593  struct probe *trigger,struct probe *base) {
594  fflush(stderr);
595  fflush(stdout);
596 
597  fprintf(stdout,"%s (0x%"PRIxADDR") (pre)\n",
598  probe_name(probe),probe_addr(probe));
599 
600  fflush(stderr);
601  fflush(stdout);
602 
603  return RESULT_SUCCESS;
604 }
605 
606 result_t addr_code_post(struct probe *probe,tid_t tid,void *handler_data,
607  struct probe *trigger,struct probe *base) {
608  fflush(stderr);
609  fflush(stdout);
610 
611  fprintf(stdout,"%s (0x%"PRIxADDR") (post)\n",
612  probe_name(probe),probe_addr(probe));
613 
614  fflush(stderr);
615  fflush(stdout);
616 
617  return RESULT_SUCCESS;
618 }
619 
620 result_t addr_var_pre(struct probe *probe,tid_t tid,void *handler_data,
621  struct probe *trigger,struct probe *base) {
622  uint32_t word;
623 
624  fflush(stderr);
625  fflush(stdout);
626 
627  target_read_addr(probe->target,probe_addr(probe),4,(unsigned char *)&word);
628 
629  fprintf(stdout,"%s (0x%"PRIxADDR") (pre): watched raw value: 0x%x\n",
630  probe_name(probe),probe_addr(probe),word);
631 
632  fflush(stderr);
633  fflush(stdout);
634 
635  return RESULT_SUCCESS;
636 }
637 
638 result_t addr_var_post(struct probe *probe,tid_t tid,void *handler_data,
639  struct probe *trigger,struct probe *base) {
640  uint32_t word;
641 
642  fflush(stderr);
643  fflush(stdout);
644 
645  target_read_addr(probe->target,probe_addr(probe),4,(unsigned char *)&word);
646 
647  fprintf(stdout,"%s (0x%"PRIxADDR") (post): watched raw value: 0x%x\n",
648  probe_name(probe),probe_addr(probe),word);
649 
650  fflush(stderr);
651  fflush(stdout);
652 
653  return RESULT_SUCCESS;
654 }
655 
656 result_t var_pre(struct probe *probe,tid_t tid,void *handler_data,
657  struct probe *trigger,struct probe *base) {
658  int j;
659  struct value *value;
660  struct bsymbol *bsymbol = probe->bsymbol;
661  struct dump_info di = { .stream = stdout };
662  struct target_location_ctxt *tlctxt;
663 
664  fflush(stderr);
665  fflush(stdout);
666 
667  tlctxt = target_location_ctxt_create_from_bsymbol(probe->target,tid,bsymbol);
668  if ((value = target_load_symbol(probe->target,tlctxt,bsymbol,
673  fprintf(stdout,"%s (0x%"PRIxADDR") (pre) = ",
674  bsymbol_get_name(probe->bsymbol),
675  probe_addr(probe));
676 
677  value_dump_simple(value,&di);
678  printf(" (0x");
679  for (j = 0; j < value->bufsiz; ++j) {
680  printf("%02hhx",value->buf[j]);
681  }
682  printf(")");
683  value_free(value);
684  }
685  else
686  fprintf(stdout,"%s (0x%"PRIxADDR") (pre): could not read value: %s",
687  bsymbol_get_name(probe->bsymbol),probe_addr(probe),
688  strerror(errno));
689  fprintf(stdout," (handler_data = %s)\n",(char *)handler_data);
690 
691  fflush(stderr);
692  fflush(stdout);
693 
695 
696  return RESULT_SUCCESS;
697 }
698 
699 result_t var_post(struct probe *probe,tid_t tid,void *handler_data,
700  struct probe *trigger,struct probe *base) {
701  int j;
702  struct value *value;
703  struct bsymbol *bsymbol = probe->bsymbol;
704  struct dump_info di = { .stream = stdout };
705  struct target_location_ctxt *tlctxt;
706 
707  fflush(stderr);
708  fflush(stdout);
709 
710  tlctxt = target_location_ctxt_create_from_bsymbol(probe->target,tid,bsymbol);
711  if ((value = target_load_symbol(probe->target,tlctxt,bsymbol,
716  fprintf(stdout,"%s (0x%"PRIxADDR") (post) = ",
717  bsymbol_get_name(probe->bsymbol),probe_addr(probe));
718 
719  value_dump_simple(value,&di);
720  printf(" (0x");
721  for (j = 0; j < value->bufsiz; ++j) {
722  printf("%02hhx",value->buf[j]);
723  }
724  printf(")");
725  value_free(value);
726  }
727  else
728  fprintf(stdout,"%s (0x%"PRIxADDR") (post): could not read value: %s",
729  bsymbol_get_name(probe->bsymbol),probe_addr(probe),
730  strerror(errno));
731  fprintf(stdout," (handler_data = %s)\n",(char *)handler_data);
732 
733  fflush(stderr);
734  fflush(stdout);
735 
737 
738  return RESULT_SUCCESS;
739 }
740 
742  struct probe *probe,struct probepoint *probepoint,
743  handler_msg_t msg,int msg_detail,void *handler_data) {
744  tid_t tid = target_gettid(probe->target);
745  REGVAL ipval = target_read_reg(probe->target,tid,probe->target->ipregno);
746  struct bsymbol *func = target_lookup_sym_addr(probe->target,ipval);
747  ADDR func_phys_base = 0;
748  struct target_location_ctxt *tlctxt;
749 
750  if (func) {
752  thread->tid,func);
753  target_lsymbol_resolve_bounds(probe->target,tlctxt,func->lsymbol,0,
754  &func_phys_base,NULL,NULL,NULL,NULL);
755  fprintf(stdout,"Single step %d (thread %"PRIiTID") (msg %d) 0x%"PRIxADDR" (%s:+%d)!\n",
756  msg_detail,tid,msg,ipval,bsymbol_get_name(func),
757  (int)(ipval - func_phys_base));
758  bsymbol_release(func);
760  }
761  else
762  fprintf(stdout,"Single step %d (thread %"PRIiTID") (msg %d) 0x%"PRIxADDR"!\n",
763  msg_detail,tid,msg,ipval);
764 
765  fflush(stderr);
766  fflush(stdout);
767 
768  return RESULT_SUCCESS;
769 }
770 
771 error_t dt_argp_parse_opt(int key, char *arg,struct argp_state *state) {
772  struct dt_argp_state *opts = \
773  (struct dt_argp_state *)target_argp_driver_state(state);
774  struct array_list *argv_list;
775  char *argptr,*argptr2;
776  char *nargptr;
777  char *vargptr;
778  int inesc;
779  int inquote;
780  int quotechar;
781  struct overlay_spec *ospec = NULL;
782 
783  switch (key) {
784  case ARGP_KEY_ARG:
785  /* We want to process all the remaining args, so bounce to the
786  * next case by returning this value.
787  */
788  return ARGP_ERR_UNKNOWN;
789  case ARGP_KEY_ARGS:
790  /* Eat all the remaining args. */
791  if (state->quoted > 0)
792  opts->argc = state->quoted - state->next;
793  else
794  opts->argc = state->argc - state->next;
795  if (opts->argc > 0) {
796  opts->argv = calloc(opts->argc,sizeof(char *));
797  memcpy(opts->argv,&state->argv[state->next],opts->argc*sizeof(char *));
798  state->next += opts->argc;
799  }
800  return 0;
801  case ARGP_KEY_INIT:
803  return 0;
804  case ARGP_KEY_END:
805  case ARGP_KEY_NO_ARGS:
806  case ARGP_KEY_SUCCESS:
807  return 0;
808  case ARGP_KEY_ERROR:
809  case ARGP_KEY_FINI:
810  return 0;
811 
812  case 'A':
813  opts->at_symbol = arg;
814  break;
815  case 'U':
816  opts->until_symbol = arg;
817  break;
818  case 'B':
819  opts->do_bts = 1;
820  break;
821  case 'S':
822  opts->until_stop_probing = 1;
823  break;
824  case 'v':
825  opts->raw = 1;
826  break;
827  case 'P':
828  opts->do_post = 1;
829  break;
830  case 'q':
831  opts->quiet = 1;
832  break;
833  case __TARGET_OVERLAY:
834  /*
835  * We need to split the <name_or_id>:<spec> part; then split
836  * <spec> into an argv. Simple rules: \ escapes the next char;
837  * space not in ' or " causes us to end the current argv[i] and
838  * start the next one.
839  */
840  argptr = index(arg,':');
841  if (!argptr) {
842  verror("bad overlay spec!\n");
843  return EINVAL;
844  }
845 
846  ospec = calloc(1,sizeof(*ospec));
847  ++opts->ospecs_len;
848  opts->ospecs =
849  realloc(opts->ospecs,opts->ospecs_len*sizeof(*opts->ospecs));
850  opts->ospecs[opts->ospecs_len - 1] = ospec;
851 
852  argv_list = array_list_create(32);
853  array_list_append(argv_list,"dumptarget_overlay");
854 
855  ospec->base_thread_name_or_id = arg;
856  *argptr = '\0';
857  ++argptr;
858 
859  argptr2 = index(argptr,':');
860  if (argptr2) {
861  ospec->base_target_id = ospec->base_thread_name_or_id;
862  ospec->base_thread_name_or_id = argptr;
863  *argptr2 = '\0';
864  argptr = ++argptr2;
865  }
866 
867  while (*argptr == ' ')
868  ++argptr;
869 
870  inesc = 0;
871  inquote = 0;
872  quotechar = 0;
873  nargptr = argptr;
874  vargptr = argptr;
875  while (*argptr != '\0') {
876  if (*argptr == '\\') {
877  if (inesc) {
878  inesc = 0;
879  *nargptr = '\\';
880  ++nargptr;
881  }
882  else {
883  /* Don't copy the escape char. */
884  inesc = 1;
885  ++argptr;
886  continue;
887  }
888  }
889  else if (inesc) {
890  inesc = 0;
891  /* Just copy it. */
892  *nargptr = *argptr;
893  ++nargptr;
894  }
895  else if (inquote && *argptr == quotechar) {
896  /* Ended the quoted sequence; don't copy quotes. */
897  inquote = 0;
898  quotechar = 0;
899  ++argptr;
900  continue;
901  }
902  else if (*argptr == '\'' || *argptr == '"') {
903  inquote = 1;
904  quotechar = *argptr;
905  ++argptr;
906  continue;
907  }
908  else if (!inquote && *argptr == ' ') {
909  *nargptr = *argptr = '\0';
910  if (vargptr) {
911  array_list_append(argv_list,vargptr);
912  //printf("vargptr (%p) = '%s'\n",vargptr,vargptr);
913  vargptr = NULL;
914  }
915  vargptr = NULL;
916  nargptr = ++argptr;
917  continue;
918  }
919  else {
920  if (!vargptr)
921  vargptr = nargptr;
922 
923  *nargptr = *argptr;
924  ++nargptr;
925  }
926 
927  /* Default increment. */
928  ++argptr;
929  }
930  if (vargptr) {
931  *nargptr = '\0';
932  array_list_append(argv_list,vargptr);
933  //printf("vargptr (%p) = '%s'\n",vargptr,vargptr);
934  }
935  array_list_append(argv_list,NULL);
936 
937  ospec->spec = target_argp_driver_parse_one(NULL,NULL,
938  array_list_len(argv_list) - 1,
939  (char **)argv_list->list,
941  if (!ospec->spec) {
942  verror("could not parse overlay spec %d!\n",opts->ospecs_len);
943  array_list_free(argv_list);
944  return EINVAL;
945  }
946 
947  array_list_free(argv_list);
948  break;
949 
950  default:
951  return ARGP_ERR_UNKNOWN;
952  }
953 
954  return 0;
955 }
956 
957 int main(int argc,char **argv) {
958  target_status_t tstat;
959  ADDR *addrs = NULL;
960  char *word;
961  int i;
962  unsigned int j;
963  struct probe *probe;
964  target_poll_outcome_t poutcome;
965  int pstatus;
966  ADDR paddr;
967  char *endptr;
968  char *targetstr;
969  char *tmp;
970  int oid;
971  tid_t base_tid;
972  struct target *base;
973  struct overlay_spec *ospec;
974  char namebuf[64];
975 
976  struct dump_info udn = {
977  .stream = stderr,
978  .prefix = "",
979  .detail = 1,
980  .meta = 1,
981  };
982 
983  memset(&opts,0,sizeof(opts));
984 
985  tspec = target_argp_driver_parse_one(&dt_argp,&opts,argc,argv,
987  | TARGET_TYPE_GDB,
988  1);
989 
990  if (!tspec) {
991  verror("could not parse target arguments!\n");
992  exit(-1);
993  }
994 
995  signal(SIGHUP,sigh);
996  signal(SIGINT,sigh);
997  signal(SIGQUIT,sigh);
998  signal(SIGABRT,sigh);
999  signal(SIGKILL,sigh);
1000  signal(SIGSEGV,sigh);
1001  signal(SIGPIPE,sigh);
1002  signal(SIGALRM,sigh);
1003  signal(SIGTERM,sigh);
1004  signal(SIGUSR1,sigh);
1005  signal(SIGUSR2,sigh);
1006 
1007  target_init();
1008  atexit(target_fini);
1009 
1010  t = target_instantiate(tspec,NULL);
1011  if (!t) {
1012  verror("could not instantiate target!\n");
1013  exit(-1);
1014  }
1015 
1016  if (target_open(t)) {
1017  fprintf(stderr,"could not open target!\n");
1018  exit(-4);
1019  }
1020 
1021  /*
1022  * Make a permanent copy so we can print useful messages after
1023  * target_free.
1024  */
1025  tmp = target_name(t);
1026  if (!tmp)
1027  targetstr = strdup("<UNNAMED_TARGET>");
1028  else
1029  targetstr = strdup(tmp);
1030  tmp = NULL;
1031 
1032  /*
1033  * Load the overlay targets, if any.
1034  */
1035  if (opts.ospecs)
1036  ots = calloc(opts.ospecs_len,sizeof(*ots));
1037  for (j = 0; j < opts.ospecs_len; ++j) {
1038  errno = 0;
1039  tmp = NULL;
1040  ospec = opts.ospecs[j];
1041 
1042  if (ospec->base_target_id) {
1043  base = target_lookup_target_id(atoi(ospec->base_target_id));
1044  if (!base) {
1045  verror("no existing target with id '%s'!\n",ospec->base_target_id);
1046  cleanup();
1047  exit(-113);
1048  }
1049  }
1050  else
1051  base = t;
1052 
1053  target_snprintf(base,namebuf,sizeof(namebuf));
1054 
1055  oid = (int)strtol(ospec->base_thread_name_or_id,&tmp,0);
1056  if (errno || tmp == ospec->base_thread_name_or_id)
1057  base_tid =
1059  else
1060  base_tid = target_lookup_overlay_thread_by_id(base,oid);
1061  if (base_tid < 0) {
1062  verror("could not find overlay thread '%s' in base target '%s',"
1063  " exiting!\n",
1064  ospec->base_thread_name_or_id,namebuf);
1065  cleanup();
1066  exit(-111);
1067  }
1068 
1069  ots[j] = target_instantiate_overlay(base,base_tid,ospec->spec);
1070  ++ots_len;
1071  if (!ots[j]) {
1072  verror("could not instantiate overlay on base '%s' thread '%s'!\n",
1073  namebuf,ospec->base_thread_name_or_id);
1074  cleanup();
1075  exit(-112);
1076  }
1077 
1078  if (target_open(ots[j])) {
1079  fprintf(stderr,"could not open overlay on base '%s' thread '%s'!\n",
1080  namebuf,ospec->base_thread_name_or_id);
1081  cleanup();
1082  exit(-114);
1083  }
1084  }
1085 
1086  /* Now that we have loaded any symbols we might need, process the
1087  * rest of our args.
1088  */
1089  if (opts.argc) {
1090  len = opts.argc;
1091  if (opts.raw) {
1092  addrs = (ADDR *)malloc(sizeof(ADDR)*opts.argc);
1093  memset(addrs,0,sizeof(ADDR)*opts.argc);
1094  }
1095  else {
1096  symbols = (struct bsymbol **)malloc(sizeof(struct bsymbol *)*opts.argc);
1097  memset(symbols,0,sizeof(struct bsymbol *)*opts.argc);
1098 
1099  shadow_stack = array_list_create(64);
1100 
1101  probes = g_hash_table_new(g_direct_hash,g_direct_equal);
1102  disfuncs = g_hash_table_new(g_direct_hash,g_direct_equal);
1103  }
1104  }
1105 
1108 
1109  if (opts.raw) {
1110  word = malloc(t->arch->wordsize);
1111  for (i = 0; i < opts.argc; ++i) {
1112  addrs[i] = strtoll(opts.argv[i],NULL,16);
1113  }
1114  }
1115  else {
1116  struct array_list *addrlist = array_list_create(0);
1117  struct array_list *symlist = array_list_create(0);
1118  struct bsymbol *bsymbol = NULL;
1119  int *retcodes = (int *)malloc(sizeof(int)*opts.argc);
1120  char **retcode_strs = (char **)malloc(sizeof(char *)*opts.argc);
1121 
1122  memset(retcodes,0,sizeof(int)*opts.argc);
1123  memset(retcode_strs,0,sizeof(char *)*opts.argc);
1124 
1125  word = NULL;
1126 
1127  char *srcfile = NULL;
1128  char *symname = NULL;
1129 
1130  for (i = 0; i < opts.argc; ++i) {
1131  /* Look for retval code */
1132  char *retcode_str = index(opts.argv[i],':');
1133  int line = -1;
1134  if (retcode_str) {
1135  if (*(retcode_str+1) == 'L') {
1136  /* line breakpoint, not retval */
1137  *retcode_str = '\0';
1138  ++retcode_str;
1139  line = retcodes[i] = atoi(retcode_str + 1);
1140  retcode_strs[i] = retcode_str;
1141  }
1142  else if (*(retcode_str+1) == 's') {
1143  *retcode_str = '\0';
1144  ++retcode_str;
1145  retcodes[i] = atoi(retcode_str + 1);
1146  retcode_strs[i] = retcode_str;
1147  }
1148  else if (*(retcode_str+1) == 'r') {
1149  *retcode_str = '\0';
1150  ++retcode_str;
1151  retcode_strs[i] = retcode_str;
1152  retcodes[i] = (REGVAL)atoi(retcode_str);
1153  }
1154  else if (*(retcode_str+1) == 'o') {
1155  *retcode_str = '\0';
1156  ++retcode_str;
1157  retcode_strs[i] = retcode_str;
1158  ++retcode_str;
1159  retcodes[i] = atoi(retcode_str);
1160  symname = opts.argv[i];
1161  }
1162  else {
1163  srcfile = opts.argv[i];
1164  *retcode_str = '\0';
1165  ++retcode_str;
1166  symname = retcode_str;
1167  }
1168  }
1169  else
1170  symname = opts.argv[i];
1171 
1172  if (strncmp(symname,"0x",2) == 0) {
1173  array_list_add(addrlist,opts.argv[i]);
1174  array_list_add(symlist,NULL);
1175  }
1176  else {
1177  if (line > 0) {
1178  bsymbol = target_lookup_sym_line(t,opts.argv[i],line,
1179  NULL,NULL);
1180  if (!bsymbol) {
1181  fprintf(stderr,"Could not find symbol %s!\n",opts.argv[i]);
1182  cleanup();
1183  exit(-1);
1184  }
1185  }
1186  else {
1187  if (ots) {
1188  for (j = ots_len - 1; (j + 1) > 0; --j) {
1189  bsymbol = target_lookup_sym(ots[j],symname,NULL,
1190  srcfile,
1192  if (bsymbol)
1193  break;
1194  }
1195  }
1196  if (!bsymbol) {
1197  bsymbol = target_lookup_sym(t,symname,NULL,srcfile,
1199  if (!bsymbol) {
1200  fprintf(stderr,"Could not find symbol %s!\n",
1201  symname);
1202  cleanup();
1203  exit(-1);
1204  }
1205  }
1206  }
1207 
1208  array_list_add(symlist,bsymbol);
1209  array_list_add(addrlist,NULL);
1210  bsymbol = NULL;
1211  }
1212  }
1213 
1214  if (at_symbol) {
1215  if (strncmp(at_symbol,"0x",2) == 0) {
1216  paddr = (ADDR)strtoll(at_symbol,&endptr,16);
1217  if (endptr == at_symbol) {
1218  fprintf(stderr,"Could not convert %s to address!\n",at_symbol);
1219  cleanup();
1220  exit(-1);
1221  }
1222 
1223  probe = probe_create(t,TID_GLOBAL,NULL,at_symbol,
1224  function_dump_args,at_handler,NULL,0,1);
1225  probe->handler_data = &at_symbol;
1226  if (!probe)
1227  goto err_unreg;
1228 
1229  if (!probe_register_addr(probe,paddr,PROBEPOINT_BREAK,t->spec->style,
1231  goto err_unreg;
1232  }
1233  }
1234  else {
1235  if (!(at_bsymbol = target_lookup_sym(t,at_symbol,".",NULL,
1237  fprintf(stderr,"Could not find symbol %s!\n",opts.argv[i]);
1238  cleanup();
1239  exit(-1);
1240  }
1241 
1242  if (!symbol_type_flags_match(at_bsymbol->lsymbol->symbol,
1244  fprintf(stderr,"pause at symbol %s is not a function!\n",
1245  opts.argv[i]);
1246  cleanup();
1247  exit(-1);
1248  }
1249 
1250  probe = probe_create(at_bsymbol->region->space->target,TID_GLOBAL,NULL,at_symbol,
1251  function_dump_args,at_handler,NULL,0,1);
1252  probe->handler_data = &at_symbol;
1253  if (!probe)
1254  goto err_unreg;
1255 
1256  if (!probe_register_symbol(probe,at_bsymbol,at_bsymbol->region->space->target->spec->style,
1258  goto err_unreg;
1259  }
1260  }
1261 
1262  target_resume(t);
1263 
1264  fprintf(stdout,"Starting looking for at_symbol %s!\n",
1265  at_symbol);
1266  fflush(stdout);
1267 
1268  while (!at_symbol_hit) {
1269  struct timeval tv;
1270 
1271  tv.tv_sec = 0;
1272  tv.tv_usec = 10000;
1273 
1274  tstat = target_poll(t,&tv,&poutcome,&pstatus);
1275  if (tstat != TSTATUS_PAUSED && tstat != TSTATUS_RUNNING) {
1276  fflush(stderr);
1277  fflush(stdout);
1278  cleanup();
1279  if (tstat == TSTATUS_DONE) {
1280  printf("%s finished (did not find pause point!\n",
1281  targetstr);
1282  exit(0);
1283  }
1284  else if (tstat == TSTATUS_ERROR) {
1285  printf("%s monitoring failed (did not find pause"
1286  " point)!\n",targetstr);
1287  exit(-9);
1288  }
1289  else {
1290  printf("%s monitoring failed with %d (did not find"
1291  " pause point)!\n",targetstr,tstat);
1292  exit(-10);
1293  }
1294  }
1295  if (!at_symbol_hit)
1296  target_resume(t);
1297  }
1298 
1299  printf("%s monitoring found at_symbol %s; removing "
1300  " pause probe and doing the real thing.\n",
1301  targetstr,at_symbol);
1302  fflush(stdout);
1303 
1304  /*
1305  * Yank out the at probe.
1306  */
1307  probe_free(probe,1);
1308  probe = NULL;
1309  }
1310 #if defined(ENABLE_XEN) && defined(CONFIG_DETERMINISTIC_TIMETRAVEL)
1311  if (target_type(t) == TARGET_TYPE_XEN && opts.do_bts) {
1312  printf("Enabling BTS!\n");
1313  fflush(stdout);
1315  verror("failed to enable BTS!\n");
1316  }
1317 #endif
1318 
1319  if (until_symbol) {
1320  /*
1321  * Insert the until probe.
1322  */
1323  if (strncmp(until_symbol,"0x",2) == 0) {
1324  paddr = (ADDR)strtoll(until_symbol,&endptr,16);
1325  if (endptr == until_symbol) {
1326  fprintf(stderr,"Could not convert %s to address!\n",until_symbol);
1327  cleanup();
1328  exit(-1);
1329  }
1330 
1331  probe = probe_create(until_bsymbol->region->space->target,TID_GLOBAL,NULL,until_symbol,
1333  probe->handler_data = &until_symbol;
1334  if (!probe)
1335  goto err_unreg;
1336 
1337  if (!probe_register_addr(probe,paddr,PROBEPOINT_BREAK,until_bsymbol->region->space->target->spec->style,
1339  goto err_unreg;
1340  }
1341  }
1342  else {
1343  if (!(until_bsymbol = target_lookup_sym(t,until_symbol,".",NULL,
1345  fprintf(stderr,"Could not find until_symbol %s!\n",opts.argv[i]);
1346  cleanup();
1347  exit(-1);
1348  }
1349 
1350  if (!symbol_type_flags_match(until_bsymbol->lsymbol->symbol,
1352  fprintf(stderr,"util_symbol %s is not a function!\n",
1353  opts.argv[i]);
1354  cleanup();
1355  exit(-1);
1356  }
1357 
1358  probe = probe_create(until_bsymbol->region->space->target,TID_GLOBAL,NULL,until_symbol,
1360  probe->handler_data = &until_symbol;
1361  if (!probe)
1362  goto err_unreg;
1363 
1364  if (!probe_register_symbol(probe,until_bsymbol,until_bsymbol->region->space->target->spec->style,
1366  goto err_unreg;
1367  }
1368  }
1369 
1370  until_probe = probe;
1371 
1372  fprintf(stdout,"Starting looking for until_symbol %s!\n",
1373  until_symbol);
1374  fflush(stdout);
1375  }
1376 
1377  /* Now move through symlist (we may add to it!) */
1378  for (i = 0; i < array_list_len(symlist); ++i) {
1379  bsymbol = (struct bsymbol *)array_list_item(symlist,i);
1380 
1381  if (!bsymbol)
1382  continue;
1383 
1384  bsymbol_dump(bsymbol,&udn);
1385 
1386  probepoint_whence_t whence;
1387  probe_handler_t pre;
1388  probe_handler_t post = NULL;
1389 
1390  if (symbol_type_flags_match(bsymbol->lsymbol->symbol,
1392  whence = PROBEPOINT_EXEC;
1393  pre = function_dump_args;
1394  if (opts.do_post)
1395  post = function_post;
1396  }
1397  else {
1398  pre = var_pre;
1399  if (opts.do_post)
1400  post = var_post;
1401  if (i < opts.argc && retcode_strs[i]
1402  && *retcode_strs[i] == 'w') {
1403  whence = PROBEPOINT_WRITE;
1404  }
1405  else
1406  whence = PROBEPOINT_READWRITE;
1407  }
1408 
1409  if (symbol_type_flags_match(bsymbol->lsymbol->symbol,
1411  && ((i < opts.argc && retcode_strs[i]
1412  && (*retcode_strs[i] == 'c'
1413  || *retcode_strs[i] == 'C')))) {
1414 #ifndef ENABLE_DISTORM
1415  fprintf(stderr,
1416  "Could not instrument function %s;"
1417  " DISTORM not configured in!\n",
1418  bsymbol_get_name(bsymbol));
1419  goto err_unreg;
1420 #else
1421  ADDR funcstart;
1422  if ((funcstart = instrument_func(bsymbol,1)) == 0) {
1423  fprintf(stderr,
1424  "Could not instrument function %s (0x%"PRIxADDR")!\n",
1425  bsymbol_get_name(bsymbol),funcstart);
1426  goto err_unreg;
1427  }
1428 #endif
1429  }
1430  else if (symbol_type_flags_match(bsymbol->lsymbol->symbol,
1432  && ((i < opts.argc && retcode_strs[i]
1433  && (*retcode_strs[i] == 'e'
1434  || *retcode_strs[i] == 'E')))) {
1435 #ifndef ENABLE_DISTORM
1436  fprintf(stderr,
1437  "Could not instrument function %s entry/returns;"
1438  " DISTORM not configured in!\n",
1439  bsymbol_get_name(bsymbol));
1440  goto err_unreg;
1441 #else
1442  probe = probe_create(bsymbol->region->space->target,TID_GLOBAL,NULL,bsymbol_get_name(bsymbol),
1443  pre,post,NULL,0,1);
1444  if (!probe)
1445  goto err_unreg;
1446  probe->handler_data = probe->name;
1447 
1448  if (!probe_register_function_ee(probe,PROBEPOINT_SW,bsymbol,0,1,1)) {
1449  fprintf(stderr,
1450  "Could not instrument function %s entry/returns!\n",
1451  bsymbol_get_name(bsymbol));
1452  goto err_unreg;
1453  }
1454 
1455  g_hash_table_insert(probes,(gpointer)probe,(gpointer)probe);
1456 #endif
1457  }
1458  else {
1459  probe = probe_create(bsymbol->region->space->target,TID_GLOBAL,NULL,bsymbol_get_name(bsymbol),
1460  pre,post,NULL,0,1);
1461  if (!probe)
1462  goto err_unreg;
1463  probe->handler_data = probe->name;
1464 
1465  if (i < opts.argc && retcode_strs[i] && *retcode_strs[i] == 'L') {
1466  if (!probe_register_line(probe,opts.argv[i],retcodes[i],
1467  bsymbol->region->space->target->spec->style,whence,PROBEPOINT_LAUTO)) {
1468  probe_free(probe,1);
1469  goto err_unreg;
1470  }
1471  }
1472  else if (symbol_is_inlined(bsymbol_get_symbol(bsymbol))) {
1473  if (!probe_register_inlined_symbol(probe,bsymbol,
1474  1,
1475  bsymbol->region->space->target->spec->style,whence,
1476  PROBEPOINT_LAUTO)) {
1477  probe_free(probe,1);
1478  goto err_unreg;
1479  }
1480  }
1481  else {
1482  if (!probe_register_symbol(probe,bsymbol,bsymbol->region->space->target->spec->style,whence,
1483  PROBEPOINT_LAUTO)) {
1484  probe_free(probe,1);
1485  goto err_unreg;
1486  }
1487  }
1488 
1489  g_hash_table_insert(probes,(gpointer)probe,(gpointer)probe);
1490 
1491  if (probe) {
1492  fprintf(stderr,
1493  "Registered probe %s at 0x%"PRIxADDR".\n",
1494  bsymbol_get_name(bsymbol),
1495  probe_addr(probe));
1496 
1497  /* Add the retcode action, if any! */
1498  if (symbol_type_flags_match(bsymbol->lsymbol->symbol,
1500  if (i < opts.argc && retcode_strs[i]
1501  && *retcode_strs[i] == 's') {
1502  struct action *action = action_singlestep(retcodes[i]);
1503  if (!action) {
1504  fprintf(stderr,"could not create action!\n");
1505  goto err_unreg;
1506  }
1507  if (action_sched(probe,action,ACTION_REPEATPRE,
1508  ss_handler,NULL)) {
1509  fprintf(stderr,"could not schedule action!\n");
1510  action_release(action);
1511  goto err_unreg;
1512  }
1513  else
1514  action_release(action);
1515  }
1516  else if (i < opts.argc && retcode_strs[i]) {
1517  struct action *action = action_return(retcodes[i]);
1518  if (!action) {
1519  fprintf(stderr,"could not create action!\n");
1520  goto err_unreg;
1521  }
1522  if (action_sched(probe,action,ACTION_REPEATPRE,
1523  NULL,NULL)) {
1524  fprintf(stderr,"could not schedule action!\n");
1525  action_release(action);
1526  goto err_unreg;
1527  }
1528  else
1529  action_release(action);
1530  }
1531  }
1532  }
1533  else {
1534  fprintf(stderr,
1535  "Failed to register probe on '%s'\n",
1536  bsymbol_get_name(bsymbol));
1537  --i;
1538  goto err_unreg;
1539  }
1540  }
1541 
1542  bsymbol_release(bsymbol);
1543 
1544  continue;
1545 
1546  err_unreg:
1547  if (at_bsymbol)
1548  bsymbol_release(at_bsymbol);
1549  if (until_bsymbol)
1550  bsymbol_release(until_bsymbol);
1551  if (bsymbol)
1552  bsymbol_release(bsymbol);
1553  array_list_free(symlist);
1554  array_list_free(addrlist);
1555  free(retcodes);
1556  free(retcode_strs);
1557  cleanup();
1558  exit(-1);
1559  }
1560 
1561  /* Now move through addrlist (we may add to it!) */
1562  for (i = 0; i < array_list_len(addrlist); ++i) {
1563  char *rawaddr = (char *)array_list_item(addrlist,i);
1564  struct target *tmpt = t;
1565 
1566  if (!rawaddr)
1567  continue;
1568 
1569  char *endptr = NULL;
1570  ADDR paddr = (ADDR)strtoull(rawaddr,&endptr,16);
1571 
1572  if (!endptr) {
1573  fprintf(stderr,"Bad address %s!\n",rawaddr);
1574  goto err_unreg;
1575  }
1576 
1577  if (!rawaddr)
1578  continue;
1579 
1580  probepoint_type_t type;
1581  probepoint_style_t rstyle;
1582  probepoint_whence_t whence;
1583  probe_handler_t pre;
1584  probe_handler_t post = NULL;
1585 
1586  if (i < opts.argc && retcode_strs[i] && *retcode_strs[i] == 'w') {
1587  pre = addr_var_pre;
1588  if (opts.do_post)
1589  post = addr_var_post;
1590  whence = PROBEPOINT_WRITE;
1591  type = PROBEPOINT_WATCH;
1592  rstyle = PROBEPOINT_HW;
1593  }
1594  else if (i < opts.argc && retcode_strs[i] && *retcode_strs[i] == 'r') {
1595  pre = addr_var_pre;
1596  if (opts.do_post)
1597  post = addr_var_post;
1598  whence = PROBEPOINT_READWRITE;
1599  type = PROBEPOINT_WATCH;
1600  rstyle = PROBEPOINT_HW;
1601  }
1602  else if (i < opts.argc && retcode_strs[i] && *retcode_strs[i] == 'o') {
1603  tmpt = target_lookup_target_id(retcodes[i]);
1604  if (!tmpt) {
1605  verror("No target with ID %d for addr 0x%"PRIxADDR";"
1606  " aborting!\n",retcodes[i],paddr);
1607  goto err_unreg2;
1608  }
1609  pre = addr_var_pre;
1610  if (opts.do_post)
1611  post = addr_var_post;
1612  whence = PROBEPOINT_WAUTO;
1613  type = PROBEPOINT_BREAK;
1614  rstyle = PROBEPOINT_SW;
1615  }
1616  else {
1617  whence = PROBEPOINT_EXEC;
1618  type = PROBEPOINT_BREAK;
1619  rstyle = PROBEPOINT_SW;
1620  pre = addr_code_pre;
1621  if (opts.do_post)
1622  post = addr_code_post;
1623  }
1624 
1625  probe = probe_create(tmpt,TID_GLOBAL,NULL,rawaddr,pre,post,NULL,0,1);
1626  probe->handler_data = rawaddr;
1627  if (!probe)
1628  goto err_unreg2;
1629 
1630  if (!probe_register_addr(probe,paddr,type,rstyle,whence,
1631  PROBEPOINT_LAUTO,NULL)) {
1632  probe_free(probe,1);
1633  goto err_unreg2;
1634  }
1635 
1636  g_hash_table_insert(probes,(gpointer)probe,(gpointer)probe);
1637 
1638  fprintf(stderr,
1639  "Registered probe %s at 0x%"PRIxADDR".\n",rawaddr,paddr);
1640 
1641  continue;
1642 
1643  err_unreg2:
1644  if (at_bsymbol)
1645  bsymbol_release(at_bsymbol);
1646  if (until_bsymbol)
1647  bsymbol_release(until_bsymbol);
1648  if (bsymbol)
1649  bsymbol_release(bsymbol);
1650  array_list_free(symlist);
1651  array_list_free(addrlist);
1652  free(retcodes);
1653  free(retcode_strs);
1654  cleanup();
1655  exit(-1);
1656  }
1657 
1658  array_list_free(symlist);
1659  array_list_free(addrlist);
1660  free(retcodes);
1661  free(retcode_strs);
1662  }
1663 
1664  /* The target is paused after the attach; we have to resume it now
1665  * that we've registered probes (or hit the at_symbol).
1666  */
1667  target_resume(t);
1668 
1669  fprintf(stdout,"Starting main debugging loop!\n");
1670  fflush(stdout);
1671 
1672  struct timeval poll_tv = { 0,0 };
1673  tid_t tid;
1674 
1675  while (1) {
1676  tid = 0;
1677 
1678  if (until_probe) {
1679  poll_tv.tv_usec = 10000;
1680  tstat = target_poll(t,&poll_tv,NULL,NULL);
1681  }
1682  else
1683  tstat = target_monitor(t);
1684 
1685  if (tstat == TSTATUS_RUNNING && until_probe)
1686  continue;
1687  else if (tstat == TSTATUS_PAUSED) {
1688  tid = target_gettid(t);
1689  if (until_probe && until_symbol_hit) {
1690  printf("%s monitoring found at_symbol %s; removing"
1691  " until probe.\n",
1692  targetstr,until_symbol);
1693  fflush(stdout);
1694 
1695  probe_free(until_probe,1);
1696  until_probe = NULL;
1697 
1698  /*
1699  * If we've hit our stopping point, do what we're
1700  * supposed to do -- maybe stop branch trace, maybe stop
1701  * all probes.
1702  */
1703 #if defined(ENABLE_XEN) && defined(CONFIG_DETERMINISTIC_TIMETRAVEL)
1704  if (target_type(t) == TARGET_TYPE_XEN && opts.do_bts) {
1705  printf("Disabling BTS at until probe.\n");
1706  fflush(stdout);
1708  verror("failed to disable BTS!\n");
1709  }
1710 #endif
1711  if (opts.until_stop_probing) {
1712  printf("Stopping monitoring at until probe.\n");
1713  fflush(stdout);
1714  tstat = TSTATUS_DONE;
1715  goto out;
1716  }
1717  }
1718  else if (until_probe)
1719  goto resume;
1720 
1722  goto resume;
1723 
1724  printf("%s thread %"PRIiTID" interrupted at 0x%" PRIxREGVAL "\n",
1725  targetstr,tid,target_read_reg(t,tid,CREG_IP));
1726 
1727  if (!opts.raw && target_type(t) == TARGET_TYPE_PTRACE)
1728  goto resume;
1729  else if (target_type(t) == TARGET_TYPE_XEN) { // && !opts.raw) {
1730  goto resume;
1731  //fprintf(stderr,"ERROR: unexpected Xen interrupt; trying to cleanup!\n");
1732  //goto exit;
1733  }
1734  else if (word) {
1735  for (i = 0; i < opts.argc; ++i) {
1736  if (target_read_addr(t,addrs[i],t->arch->wordsize,
1737  (unsigned char *)word) != NULL) {
1738  printf("0x%" PRIxADDR " = ",addrs[i]);
1739  for (j = 0; j < t->arch->wordsize; ++j) {
1740  printf("%02hhx",word[j]);
1741  }
1742  printf("\n");
1743  }
1744  else
1745  printf("0x%" PRIxADDR ": could not read value: %s\n",
1746  addrs[i],strerror(errno));
1747  }
1748  }
1749  resume:
1750  if (target_resume(t)) {
1751  fprintf(stderr,"could not resume target %s thread %"PRIiTID"\n",
1752  targetstr,tid);
1753 
1754  cleanup();
1755  exit(-16);
1756  }
1757  }
1758  else if (tstat == TSTATUS_EXITING) {
1759  tid = target_gettid(t);
1760  printf("%s exiting, removing probes safely...\n",targetstr);
1761  cleanup_probes();
1762  /* Let it resume to "finish" exiting! */
1763  if (target_resume(t)) {
1764  fprintf(stderr,"could not resume target %s thread %"PRIiTID"\n",
1765  targetstr,tid);
1766 
1767  cleanup();
1768  exit(-16);
1769  }
1770  }
1771  else {
1772  out:
1773  fflush(stderr);
1774  fflush(stdout);
1775  cleanup();
1776 
1777  if (tstat == TSTATUS_DONE) {
1778  printf("%s finished.\n",targetstr);
1779  free(targetstr);
1780  exit(0);
1781  }
1782  else if (tstat == TSTATUS_ERROR) {
1783  printf("%s monitoring failed!\n",targetstr);
1784  free(targetstr);
1785  exit(-9);
1786  }
1787  else {
1788  printf("%s monitoring failed with %d!\n",targetstr,tstat);
1789  free(targetstr);
1790  exit(-10);
1791  }
1792  }
1793  }
1794 
1795  exit(0);
1796 }
struct bsymbol * bsymbol_create(struct lsymbol *lsymbol, struct memregion *region)
Definition: symbol.c:48
struct target * target_instantiate_overlay(struct target *target, tid_t tid, struct target_spec *spec)
Definition: target_api.c:757
int target_thread_snprintf(struct target *target, tid_t tid, char *buf, int bufsiz, int detail, char *sep, char *kvsep)
Definition: target_api.c:1425
struct value * target_load_symbol(struct target *target, struct target_location_ctxt *tlctxt, struct bsymbol *bsymbol, load_flags_t flags)
Definition: target.c:3270
tid_t target_lookup_overlay_thread_by_name(struct target *target, char *name)
Definition: target_api.c:713
struct action * action_return(REGVAL retval)
Definition: probe.c:4457
struct target * base
Definition: target_api.h:2654
int probe_unregister(struct probe *probe, int force)
Definition: probe.c:1137
struct bsymbol * target_lookup_sym_line(struct target *target, char *filename, int line, SMOFFSET *offset, ADDR *addr)
Definition: target.c:2267
char * at_symbol
Definition: dumptarget.c:78
struct bsymbol * until_bsymbol
Definition: dumptarget.c:66
struct lsymbol * lsymbol
Definition: target.h:1017
int32_t tid_t
Definition: common.h:36
void * target_argp_driver_state(struct argp_state *state)
Definition: target.c:716
REFCNT lsymbol_release(struct lsymbol *lsymbol)
Definition: debug.c:4805
probepoint_type_t
Definition: probe_api.h:213
target_status_t
Definition: target_api.h:197
void value_dump_simple(struct value *value, struct dump_info *ud)
Definition: value.c:1289
tid_t target_lookup_overlay_thread_by_id(struct target *target, int id)
Definition: target_api.c:693
struct target_spec * tspec
Definition: dumptarget.c:113
struct symbol * symbol
Definition: dwdebug.h:1010
struct lsymbol * lsymbol_create_from_symbol(struct symbol *symbol)
Definition: debug.c:4722
#define __TARGET_OVERLAY
Definition: dumptarget.c:93
Definition: probe.h:392
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
char * name
Definition: probe.h:314
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
result_t ss_handler(struct action *action, struct target_thread *thread, struct probe *probe, struct probepoint *probepoint, handler_msg_t msg, int msg_detail, void *handler_data)
Definition: dumptarget.c:741
void target_init(void)
Definition: target.c:69
Definition: arch.h:74
REFCNT action_release(struct action *action)
Definition: probe.c:4576
struct array_list * shadow_stack
Definition: dumptarget.c:56
#define v_g_slist_foreach(gslhead, gslcur, elm)
Definition: glib_wrapper.h:60
int target_resume(struct target *target)
Definition: target_api.c:1012
int at_symbol_hit
Definition: dumptarget.c:60
struct target_location_ctxt * target_location_ctxt_create_from_bsymbol(struct target *target, tid_t tid, struct bsymbol *bsymbol)
Definition: target.c:5325
GHashTable * disfuncs
Definition: dumptarget.c:55
int target_disable_feature(struct target *target, int feature)
Definition: target_api.c:1957
probepoint_whence_t
Definition: probe_api.h:234
result_t function_dump_args(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:487
probepoint_style_t style
Definition: target_api.h:2212
int target_pause(struct target *target)
Definition: target_api.c:1027
result_t var_post(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:699
tid_t target_gettid(struct target *target)
Definition: target_api.c:1918
result_t addr_var_pre(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:620
struct target * target
Definition: target.h:895
struct target ** ots
Definition: dumptarget.c:50
char * bsymbol_get_name(struct bsymbol *bsymbol)
Definition: symbol.c:62
int target_close(struct target *target)
Definition: target_api.c:1511
struct list_head probe
Definition: probe.h:379
#define verror(format,...)
Definition: log.h:30
error_t dt_argp_parse_opt(int key, char *arg, struct argp_state *state)
Definition: dumptarget.c:771
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
struct probe * probe_register_addr(struct probe *probe, ADDR addr, probepoint_type_t type, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize, struct bsymbol *bsymbol)
Definition: probe.c:1393
void ** list
Definition: alist.h:34
result_t(* probe_handler_t)(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: probe_api.h:70
int symbol_is_inlined(struct symbol *symbol)
Definition: debug.c:3053
void target_fini(void)
Definition: target.c:91
int doit
Definition: dumptarget.c:58
int target_snprintf(struct target *target, char *buf, int bufsiz)
Definition: target_api.c:829
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
ADDR probe_addr(struct probe *probe)
Definition: probe.c:1959
tid_t tid
Definition: probe.h:344
char * lsymbol_get_name(struct lsymbol *lsymbol)
Definition: debug.c:4732
struct overlay_spec ** ospecs
Definition: dumptarget.c:88
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
REFCNT bsymbol_free(struct bsymbol *bsymbol, int force)
Definition: symbol.c:96
void cleanup()
Definition: dumptarget.c:134
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
struct addrspace * space
Definition: target.h:937
struct dt_argp_state opts
Definition: dumptarget.c:111
char * buf
Definition: target_api.h:3298
void target_free_spec(struct target_spec *spec)
Definition: target_api.c:453
int symbol_type_flags_match(struct symbol *symbol, symbol_type_flag_t flags)
Definition: debug.c:3102
char * target_name(struct target *target)
Definition: target_api.c:505
char * base_target_id
Definition: dumptarget.c:72
struct action * action_singlestep(int nsteps)
Definition: probe.c:4483
struct argp_option dt_argp_opts[]
Definition: dumptarget.c:95
void value_free(struct value *value)
Definition: value.c:282
int until_stop_probing
Definition: dumptarget.c:81
char ** argv
Definition: dumptarget.c:86
struct bsymbol * target_lookup_sym_addr(struct target *target, ADDR addr)
Definition: target.c:2093
int len
Definition: dumptarget.c:52
int probe_num_sources(struct probe *probe)
Definition: probe.c:1923
int target_enable_feature(struct target *target, int feature, void *arg)
Definition: target_api.c:1950
target_poll_outcome_t
Definition: target_api.h:394
Definition: probe.h:308
struct probe * probe_create(struct target *target, tid_t tid, struct probe_ops *pops, const char *name, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data, int autofree, int tracked)
Definition: probe.c:729
unsigned int ots_len
Definition: dumptarget.c:49
struct argp dt_argp
Definition: dumptarget.c:107
void * realloc(void *ptr, size_t size)
Definition: debugserver.c:221
FILE * stream
Definition: output.h:26
struct probe * probe_register_inlined_symbol(struct probe *probe, struct bsymbol *bsymbol, int do_primary, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe_lib.c:1089
handler_msg_t
Definition: probe_api.h:52
result_t var_pre(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:656
GHashTable * probes
Definition: dumptarget.c:54
char * at_symbol
Definition: dumptarget.c:61
struct arch * arch
Definition: target_api.h:2603
unsigned int wordsize
Definition: arch.h:121
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
struct target * target
Definition: target_api.h:2078
result_t addr_var_post(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:638
int main(int argc, char **argv)
Definition: dumptarget.c:957
result_t
Definition: common.h:25
uint32_t REGVAL
Definition: common.h:66
struct target * target_lookup_target_id(int id)
Definition: target.c:332
result_t function_post(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:567
char * until_symbol
Definition: dumptarget.c:79
#define PRIiTID
Definition: common.h:37
int until_symbol_hit
Definition: dumptarget.c:64
#define REF_DEBUG_REPORT_FINISH()
Definition: common.h:653
probepoint_style_t
Definition: probe_api.h:228
int target_finalize(struct target *target)
Definition: target.c:1955
struct symbol * bsymbol_get_symbol(struct bsymbol *bsymbol)
Definition: symbol.c:66
struct target * target
Definition: probe.h:342
uint32_t ADDR
Definition: common.h:64
char * base_thread_name_or_id
Definition: dumptarget.c:73
char * until_symbol
Definition: dumptarget.c:65
target_status_t target_poll(struct target *target, struct timeval *tv, target_poll_outcome_t *outcome, int *pstatus)
Definition: target_api.c:1001
GSList * symbol_get_members(struct symbol *symbol, symbol_type_flag_t flags)
Definition: debug.c:3146
REG spregno
Definition: target_api.h:2507
int target_open(struct target *target)
Definition: target_api.c:513
target_status_t target_monitor(struct target *target)
Definition: target_api.c:869
#define PRIxADDR
Definition: common.h:67
void target_location_ctxt_free(struct target_location_ctxt *tlctxt)
Definition: target.c:5348
struct target_spec * spec
Definition: target_api.h:2605
int linux_userproc_at_syscall(struct target *target, tid_t tid)
struct bsymbol * bsymbol
Definition: probe.h:389
unsigned int ospecs_len
Definition: dumptarget.c:87
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
struct target * target_instantiate(struct target_spec *spec, struct evloop *evloop)
Definition: target_api.c:55
struct probe * probe_register_line(struct probe *probe, char *filename, int line, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe.c:1403
struct bsymbol * at_bsymbol
Definition: dumptarget.c:62
void * malloc(size_t size)
Definition: debugserver.c:214
struct target_thread * thread
Definition: target_api.h:2383
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
void * handler_data
Definition: probe.h:359
result_t until_handler(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:465
char * probe_name(struct probe *probe)
Definition: probe.c:1935
struct probe * probe_register_symbol(struct probe *probe, struct bsymbol *bsymbol, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe.c:1470
struct probe * until_probe
Definition: dumptarget.c:67
int nonrootsethits
Definition: dumptarget.c:69
struct target_spec * spec
Definition: dumptarget.c:74
result_t addr_code_pre(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:592
result_t at_handler(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:443
int action_sched(struct probe *probe, struct action *action, action_whence_t whence, action_handler_t handler, void *handler_data)
Definition: probe.c:4119
void cleanup_probes()
Definition: dumptarget.c:115
REG ipregno
Definition: target_api.h:2508
#define TID_GLOBAL
Definition: target_api.h:145
struct memregion * region
Definition: target.h:1020
void target_driver_argp_init_children(struct argp_state *state)
Definition: target.c:1057
struct bsymbol ** symbols
Definition: dumptarget.c:53
struct probepoint * probepoint
Definition: probe.h:347
struct target * t
Definition: dumptarget.c:48
void bsymbol_dump(struct bsymbol *bsymbol, struct dump_info *ud)
Definition: symbol.c:120
result_t addr_code_post(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: dumptarget.c:606
#define PRIxREGVAL
Definition: common.h:72
void sigh(int signo)
Definition: dumptarget.c:178