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
probe_lib.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 <stdlib.h>
20 #include <string.h>
21 #include <glib.h>
22 
23 #include "common.h"
24 #include "log.h"
25 #include "alist.h"
26 #include "glib_wrapper.h"
27 
28 #include "dwdebug.h"
29 #include "dwdebug_priv.h"
30 
31 #include "target_api.h"
32 #include "target.h"
33 
34 #include "probe_api.h"
35 #include "probe.h"
36 
37 struct probe *probe_simple(struct target *target,tid_t tid,char *name,
40  void *handler_data) {
41  struct probe *probe = probe_create(target,tid,NULL,name,pre_handler,
42  post_handler,handler_data,0,1);
43  if (!probe)
44  return NULL;
45 
49 }
50 
52  char *name,const char *delim,
53  probepoint_style_t style,
54  probepoint_whence_t whence,
55  probepoint_watchsize_t watchsize) {
56  struct bsymbol *bsymbol;
57  struct target *target = probe->target;
58 
59  if (!(bsymbol = target_lookup_sym(target,name,delim,NULL,
61  verror("could not find symbol %s!\n",name);
62  goto errout;
63  }
64 
65  return probe_register_symbol(probe,bsymbol,style,whence,watchsize);
66 
67  errout:
68  if (probe->autofree)
69  probe_free(probe,1);
70  return NULL;
71 }
72 
73 #ifdef ENABLE_DISTORM
74 struct probe *probe_register_function_ee(struct probe *probe,
75  probepoint_style_t style,
76  struct bsymbol *bsymbol,
77  int force_at_entry,int noabort,
78  int follow_jumps) {
79  struct target *target = probe->target;
80  struct memrange *range = NULL;
81  ADDR start = 0;
82  ADDR end = 0;
83  ADDR alt_start = 0;
84  ADDR probeaddr;
85  struct probe *source;
86  int j;
87  struct array_list *cflist = NULL;
88  unsigned char *funccode = NULL;
89  unsigned int funclen;
90  struct cf_inst_data *idata;
91  char buf[1024];
92  struct target_thread *tthread = probe->thread;
93  tid_t tid = tthread->tid;
94  int caller_free = 0;
95  inst_cf_flags_t cfflags = 0;
96  GHashTable *absolute_branch_targets = NULL;
97  GHashTableIter iter;
98  gpointer kp,vp;
99  ADDR jaddr,jlow,jhigh;
100  struct bsymbol *jbsymbol;
101  struct symbol *symbol;
102  struct target_location_ctxt *tlctxt = NULL;
103 
104  symbol = lsymbol_last_symbol(bsymbol->lsymbol);
105 
106  if (!SYMBOL_IS_FUNC(symbol)) {
107  verror("must supply a function symbol!\n");
108  goto errout;
109  }
110 
111  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,bsymbol);
112  if (target_lsymbol_resolve_bounds(target,tlctxt,bsymbol->lsymbol,0,
113  &start,&end,NULL,&alt_start,NULL)) {
114  verror("could not resolve entry PC for function %s!\n",
115  bsymbol->lsymbol->symbol->name);
116  goto errout;
117  }
118  else if (!force_at_entry && alt_start)
119  probeaddr = alt_start;
120  else
121  probeaddr = start;
122 
124  tlctxt = NULL;
125 
126  if (!target_find_memory_real(target,start,NULL,NULL,&range)) {
127  verror("could not find range for addr 0x%"PRIxADDR"\n",start);
128  goto errout;
129  }
130 
131  /*
132  * If we've got a post handler, we need to disasm this function
133  * before we insert a probe into it!!
134  */
135  funclen = end - start;
136  funccode = target_load_code(target,start,funclen,0,0,&caller_free);
137  if (!funccode) {
138  verror("could not load code for disasm of %s!\n",
139  bsymbol_get_name(bsymbol));
140  goto errout;
141  }
142 
143  /* Create and register the entry point probe if @probe has a
144  * pre_handler.
145  */
146  if (probe->pre_handler) {
147  snprintf(buf,sizeof(buf),"%s_entry",bsymbol_get_name(bsymbol));
148  source = probe_create(target,tid,NULL,buf,probe_do_sink_pre_handlers,
149  NULL,NULL,1,1);
150  if (!__probe_register_addr(source,probeaddr,range,
152  PROBEPOINT_LAUTO,bsymbol,start)) {
153  goto errout;
154  }
155 
156  if (!probe_register_source(probe,source)) {
157  probe_free(source,1);
158  goto errout;
159  }
160 
162  "registered entry addr probe at %s%+d\n",
163  bsymbol_get_name(bsymbol),(int)(probeaddr - start));
164  }
165 
166  /* If @probe has no post_handler, don't register for the return
167  * instructions.
168  */
169  if (!probe->post_handler)
170  return probe;
171 
172  /*
173  * Disassemble the function to find the return instructions.
174  *
175  * NB: also look for JMP/Jcc that go outside the function; if they
176  * do, we have to follow them and look for returns in them too.
177  * Otherwise we'll miss the "return". This happens with tail-call
178  * optimization. But the problem is, the probe on the ret in the
179  * jumped-to function will not be associated with the probe on the
180  * jumping function. So what do we do? Well, we lookup the
181  * jumped-to address, and create exit probes in it using its symbol,
182  * not the current one. Perhaps this is somewhat bad, but it's the
183  * best we can do.
184  */
185  cfflags = INST_CF_RET | INST_CF_IRET;
186  if (follow_jumps) {
187  cfflags |= INST_CF_JMP | INST_CF_JCC;
188  absolute_branch_targets =
189  g_hash_table_new(g_direct_hash,g_direct_equal);
190  }
191  if (disasm_get_control_flow_offsets(target,cfflags,funccode,funclen,
192  &cflist,start,noabort)) {
193  verror("could not disasm function %s!\n",bsymbol->lsymbol->symbol->name);
194  goto errout;
195  }
196 
197  if (caller_free)
198  free(funccode);
199  funccode = NULL;
200 
201  /* Now register probes for each return instruction! */
202  for (j = 0; j < array_list_len(cflist); ++j) {
203  idata = (struct cf_inst_data *)array_list_item(cflist,j);
204 
205  if (idata->type == INST_JMP || idata->type == INST_JCC) {
206  if (idata->cf.target_in_segment)
207  continue;
208  else if (idata->cf.target_is_valid) {
209  if (!g_hash_table_lookup(absolute_branch_targets,
210  (gpointer)(uintptr_t)idata->cf.target))
211  g_hash_table_insert(absolute_branch_targets,
212  (gpointer)(uintptr_t)idata->cf.target,
213  (gpointer)0x0UL);
214  continue;
215  }
216  }
217  else if (idata->type != INST_RET && idata->type != INST_IRET) {
218  verror("disasm instr was not RET/IRET!\n");
219  goto errout;
220  }
221 
222  /* Create the j-th exit probe. */
223  snprintf(buf,sizeof(buf),"%s_exit_%d",bsymbol->lsymbol->symbol->name,j);
224  source = probe_create(target,tid,NULL,buf,probe_do_sink_post_handlers,
225  NULL,NULL,1,1);
226 
227  /* Register the j-th exit probe. */
228  probeaddr = start + idata->offset;
229  if (!__probe_register_addr(source,probeaddr,range,
231  PROBEPOINT_LAUTO,bsymbol,start)) {
232  goto errout;
233  }
234 
235  if (!probe_register_source(probe,source)) {
236  probe_free(source,1);
237  goto errout;
238  }
239 
241  "registered return addr probe at %s%+d\n",
242  bsymbol->lsymbol->symbol->name,(int)idata->offset);
243  }
244 
245  if (cflist) {
246  array_list_deep_free(cflist);
247  cflist = NULL;
248  }
249 
250  /*
251  * If there were any JMPs outside this function, follow them (and
252  * any of theirs) for RET/IRETs.
253  */
254  while (1) {
255  if (!absolute_branch_targets
256  || !g_hash_table_size(absolute_branch_targets))
257  break;
258 
259  g_hash_table_iter_init(&iter,absolute_branch_targets);
260  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
261  /* If we already did this address, skip it. */
262  if (vp == (gpointer)0x1UL) {
263  vp = kp = NULL;
264  continue;
265  }
266  else
267  break;
268  }
269 
270  if (!kp)
271  /* Nothing left to do. */
272  break;
273 
274  /* Handle target addr kp; then mark as handled at end. */
275  jaddr = (ADDR)(uintptr_t)kp;
276  jbsymbol = target_lookup_sym_addr(target,(ADDR)(uintptr_t)kp);
277  if (!jbsymbol) {
278  vwarn("could not find symbol for jumped-to addr 0x%"PRIxADDR";"
279  " trying safe disasm range lookup\n",jaddr);
280  if (target_lookup_safe_disasm_range(target,jaddr,&jlow,&jhigh,
281  NULL)) {
282  verror("could not find safe disasm range for jumped-to"
283  " addr 0x%"PRIxADDR"!\n",jaddr);
284  goto errout;
285  }
286  }
287  else {
288  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,jbsymbol);
289  if (target_lsymbol_resolve_bounds(target,tlctxt,jbsymbol->lsymbol,0,
290  &jlow,&jhigh,NULL,NULL,NULL)) {
291  verror("could not resolve base addr function %s!\n",
292  bsymbol_get_name(jbsymbol));
293  goto errout;
294  }
295 
297  tlctxt = NULL;
298 
299  if (!target_find_memory_real(target,jlow,NULL,NULL,&range)) {
300  verror("could not find range for addr 0x%"PRIxADDR"\n",jlow);
301  goto errout;
302  }
303 
304  funclen = jhigh - jlow;
305  }
306 
307  caller_free = 0;
308  funccode = target_load_code(target,jlow,funclen,0,0,&caller_free);
309  if (!funccode) {
310  verror("could not load jumped-to code for disasm at 0x%"PRIxADDR
311  " (%s)!\n",jlow,jbsymbol ? bsymbol_get_name(jbsymbol) : "");
312  goto errout;
313  }
314 
315  if (disasm_get_control_flow_offsets(target,cfflags,funccode,funclen,
316  &cflist,jlow,noabort)) {
317  verror("could not disasm function %s!\n",bsymbol_get_name(jbsymbol));
318  goto errout;
319  }
320 
321  if (caller_free)
322  free(funccode);
323  funccode = NULL;
324 
325  /* Now register probes for each jumped-to segment's return instruction! */
326  for (j = 0; j < array_list_len(cflist); ++j) {
327  idata = (struct cf_inst_data *)array_list_item(cflist,j);
328 
329  if (idata->type == INST_JMP || idata->type == INST_JCC) {
330  if (idata->cf.target_in_segment)
331  continue;
332  else if (idata->cf.target_is_valid) {
333  if (!g_hash_table_lookup(absolute_branch_targets,
334  (gpointer)(uintptr_t)idata->cf.target))
335  /* Add a new one... we're an octopus! */
336  g_hash_table_insert(absolute_branch_targets,
337  (gpointer)(uintptr_t)idata->cf.target,
338  (gpointer)0x0UL);
339  continue;
340  }
341  }
342  else if (idata->type != INST_RET && idata->type != INST_IRET) {
343  verror("disasm instr was not RET/IRET!\n");
344  goto errout;
345  }
346 
347  /* Create the j-th exit probe. */
348  if (jbsymbol)
349  snprintf(buf,sizeof(buf),"%s_jmpto_exit_%d",
350  bsymbol_get_name(jbsymbol),j);
351  else
352  snprintf(buf,sizeof(buf),"0x%"PRIxADDR"_jmpto_exit_%d",
353  jlow,j);
354  source = probe_create(target,tid,NULL,buf,probe_do_sink_post_handlers,
355  NULL,NULL,1,1);
356 
357  /* Register the j-th exit probe. */
358  probeaddr = jlow + idata->offset;
359  if (!__probe_register_addr(source,probeaddr,range,
361  PROBEPOINT_LAUTO,jbsymbol,jlow)) {
362  goto errout;
363  }
364 
365  if (!probe_register_source(probe,source)) {
366  probe_free(source,1);
367  goto errout;
368  }
369 
370  if (jbsymbol)
372  "registered jumped-to return addr probe at %s+%d\n",
373  bsymbol->lsymbol->symbol->name,(int)idata->offset);
374  else
376  "registered jumped-to return addr probe at"
377  " 0x%"PRIxADDR"%d\n",
378  jlow,(int)idata->offset);
379  }
380 
381  if (cflist) {
382  array_list_deep_free(cflist);
383  cflist = NULL;
384  }
385 
386  /* Ok, mark target addr kp as handled. */
387  g_hash_table_insert(absolute_branch_targets,kp,(gpointer)0x1UL);
388  }
389 
390  if (absolute_branch_targets)
391  g_hash_table_destroy(absolute_branch_targets);
392 
393  return probe;
394 
395  errout:
396  if (tlctxt)
398  if (absolute_branch_targets)
399  g_hash_table_destroy(absolute_branch_targets);
400  if (funccode && caller_free)
401  free(funccode);
402  if (cflist) {
403  array_list_deep_free(cflist);
404  }
405  probe_unregister(probe,1);
406  if (probe->autofree)
407  probe_free(probe,1);
408  return NULL;
409 }
410 
411 struct probe *probe_register_function_invocations(struct probe *probe,
412  probepoint_style_t style,
413  struct bsymbol *caller,
414  struct bsymbol *callee,
415  int noabort) {
416  struct target *target;
417  struct target_thread *tthread;
418  tid_t tid;
419  struct memrange *range;
420  ADDR caller_start;
421  ADDR caller_end;
422  unsigned int caller_len;
423  unsigned char *funccode = NULL;
424  int caller_free = 0;
425  ADDR callee_start = 0;
426  ADDR callee_inlined_start;
427  ADDR callee_inlined_end;
428  GSList *callee_instances = NULL;
429  struct symbol *caller_symbol;
430  struct symbol *callee_symbol;
431  ADDR probeaddr;
432  struct probe *iprobe;
433  GSList *probes = NULL;
434  GSList *gsltmp;
435  int j;
436  struct array_list *cf_idata_list = NULL;
437  struct cf_inst_data *idata;
438  char namebuf[128];
439  struct symbol *isymbol;
440  struct target_location_ctxt *tlctxt = NULL;
441 
442  struct __iii {
443  struct bsymbol *bsymbol;
444  ADDR start;
445  ADDR end;
446  };
447  struct __iii *iii;
448 
449  target = probe->target;
450  tthread = probe->thread;
451  tid = tthread->tid;
452 
453  caller_symbol = bsymbol_get_symbol(caller);
454  callee_symbol = bsymbol_get_symbol(callee);
455 
456  if (!SYMBOL_IS_FUNC(caller_symbol)
457  || !SYMBOL_IS_FUNC(callee_symbol)) {
458  verror("caller and callee must be function symbols!\n");
459  goto errout;
460  }
461 
462  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,caller);
463  if (target_lsymbol_resolve_bounds(target,tlctxt,caller->lsymbol,0,
464  &caller_start,&caller_end,NULL,
465  NULL,NULL)) {
466  verror("could not resolve base addr for caller function %s!\n",
467  bsymbol_get_name(caller));
468  goto errout;
469  }
471  tlctxt = NULL;
472 
473  if (!target_find_memory_real(target,caller_start,NULL,NULL,&range)) {
474  verror("could not find range for addr 0x%"PRIxADDR"\n",caller_start);
475  goto errout;
476  }
477 
478  caller_len = caller_end - caller_start;
479 
480  /*
481  * Grab the base of the callee; there might not be one if it's only inlined.
482  */
483  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,callee);
484  if (target_lsymbol_resolve_bounds(target,tlctxt,callee->lsymbol,0,
485  &callee_start,NULL,NULL,NULL,NULL)) {
486  vwarn("could not resolve base addr for callee function %s!\n",
487  bsymbol_get_name(callee));
488  callee_start = 0;
489  }
491  tlctxt = NULL;
492  /*
493  * Find the inline instances within our caller, if any.
494  */
495  SYMBOL_RX_INLINE(callee_symbol,csii);
496  if (csii && csii->inline_instances) {
497  v_g_slist_foreach(csii->inline_instances,gsltmp,isymbol) {
498  /*
499  * Check and see if the instance is in our function; if so,
500  * add it to the list!
501  */
502  tlctxt = target_location_ctxt_create(target,tid,caller->region);
503  if (target_symbol_resolve_bounds(target,tlctxt,isymbol,
504  &callee_inlined_start,
505  &callee_inlined_end,NULL,NULL,NULL)) {
506  verror("could not resolve base addr for callee inline instance!\n");
507  goto errout;
508  }
510  tlctxt = NULL;
511 
512  if (!(caller_start <= callee_inlined_start
513  && callee_inlined_start <= caller_end
514  && caller_start <= callee_inlined_end
515  && callee_inlined_end <= caller_end))
516  continue;
517 
518  /* Use __int() version to not RHOLD(); bsymbol_create RHOLDS it. */
519  struct lsymbol *ilsymbol = lsymbol_create_from_symbol__int(isymbol);
520  if (!ilsymbol) {
521  verror("could not create lsymbol for inline instance symbol %s!\n",
522  symbol_get_name(isymbol));
523  goto errout;
524  }
525 
526  /* Ok, note this one down; we're going to place probes on it. */
527  iii = calloc(1,sizeof(*iii));
528  iii->bsymbol = bsymbol_create(ilsymbol,caller->region);
529  iii->start = callee_inlined_start;
530  iii->end = callee_inlined_end;
531 
532  callee_instances = g_slist_append(callee_instances,iii);
533  }
534  }
535 
536  /* If we didn't find any of these things for the callee, abort! */
537  if (!callee_start || !callee_instances) {
538  verror("callee function %s has no addr, and/or is not inlined in"
539  " caller function %s!\n",
540  symbol_get_name(callee_symbol),symbol_get_name(caller_symbol));
541  goto errout;
542  }
543 
544  /* If we found a callee addr, disasm to find the calls to it. */
545  funccode = target_load_code(target,caller_start,caller_len,0,0,&caller_free);
546  if (!funccode) {
547  verror("could not load code for disasm of %s!\n",
548  bsymbol_get_name(caller));
549  goto errout;
550  }
551 
552  /* Disassemble the function to find the call instructions. */
553  if (disasm_get_control_flow_offsets(target,INST_CF_CALL,funccode,caller_len,
554  &cf_idata_list,caller_start,noabort)) {
555  verror("could not disasm caller function %s!\n",
556  symbol_get_name(caller_symbol));
557  goto errout;
558  }
559 
560  if (caller_free)
561  free(funccode);
562  funccode = NULL;
563 
564  /* Now register probes for each call invocation instruction! */
565  for (j = 0; j < array_list_len(cf_idata_list); ++j) {
566  idata = (struct cf_inst_data *)array_list_item(cf_idata_list,j);
567 
568  if (idata->type != INST_CALL) {
569  verror("disasm instr was not CALL!\n");
570  goto errout;
571  }
572 
573  if (idata->cf.target != callee_start)
574  continue;
575 
576  if (probe->pre_handler) {
577  /* Create the j-th pre-callee-call probe. */
578  snprintf(namebuf,sizeof(namebuf),"%s__pre_invoke__%s__%i",
579  symbol_get_name(caller_symbol),
580  symbol_get_name(callee_symbol),j);
581  iprobe = probe_create(target,tid,NULL,namebuf,
582  probe_do_sink_pre_handlers,NULL,NULL,1,1);
583  probeaddr = caller_start + idata->offset;
584  if (!__probe_register_addr(iprobe,probeaddr,range,
586  PROBEPOINT_LAUTO,callee,0)) {
587  verror("failed to register probe %s at 0x%"PRIxADDR
588  " (call site %d)\n",
589  probe_name(iprobe),probeaddr,j);
590  probe_free(iprobe,0);
591  iprobe = NULL;
592  goto errout;
593  }
594  probes = g_slist_append(probes,iprobe);
595  }
596 
597  if (probe->post_handler) {
598  /* Create the j-th post-callee-call probe. */
599  snprintf(namebuf,sizeof(namebuf),"%s__post_invoke__%s__%i",
600  symbol_get_name(caller_symbol),
601  symbol_get_name(callee_symbol),j);
602  iprobe = probe_create(target,tid,NULL,namebuf,
603  probe_do_sink_post_handlers,NULL,NULL,1,1);
604  probeaddr = caller_start + idata->offset + idata->size;
605  if (!__probe_register_addr(iprobe,probeaddr,range,
607  PROBEPOINT_LAUTO,callee,0)) {
608  verror("failed to register probe %s at 0x%"PRIxADDR
609  " (call site %d)\n",
610  probe_name(iprobe),probeaddr,j);
611  probe_free(iprobe,0);
612  iprobe = NULL;
613  goto errout;
614  }
615  probes = g_slist_append(probes,iprobe);
616  }
617 
619  "registered invocation probes around call site 0x%"PRIxADDR"\n",
620  caller_start + idata->offset);
621  }
622 
623  if (cf_idata_list) {
624  array_list_deep_free(cf_idata_list);
625  cf_idata_list = NULL;
626  }
627 
628  /* Now register probes around each inline "invocation". */
629  if (callee_instances) {
630  j = 0;
631  v_g_slist_foreach(callee_instances,gsltmp,iii) {
632  if (probe->pre_handler) {
633  /* Create the j-th pre-callee-call probe. */
634  snprintf(namebuf,sizeof(namebuf),"%s__pre_inline_invoke__%s__%i",
635  symbol_get_name(caller_symbol),
636  symbol_get_name(callee_symbol),j);
637  iprobe = probe_create(target,tid,NULL,namebuf,
638  probe_do_sink_pre_handlers,NULL,NULL,1,1);
639  probeaddr = iii->start;
640  if (!__probe_register_addr(iprobe,probeaddr,range,
642  PROBEPOINT_LAUTO,iii->bsymbol,0)) {
643  verror("failed to register probe %s at 0x%"PRIxADDR
644  " (inline call site %d)\n",
645  probe_name(iprobe),probeaddr,j);
646  probe_free(iprobe,0);
647  iprobe = NULL;
648  goto errout;
649  }
650  probes = g_slist_append(probes,iprobe);
651  }
652 
653  if (probe->post_handler) {
654  /* Create the j-th post-callee-call probe. */
655  snprintf(namebuf,sizeof(namebuf),"%s__post_inline_invoke__%s__%i",
656  symbol_get_name(caller_symbol),
657  symbol_get_name(callee_symbol),j);
658  iprobe = probe_create(target,tid,NULL,namebuf,
659  probe_do_sink_post_handlers,NULL,NULL,1,1);
660  probeaddr = iii->end;
661  if (!__probe_register_addr(iprobe,probeaddr,range,
663  PROBEPOINT_LAUTO,iii->bsymbol,0)) {
664  verror("failed to register probe %s at 0x%"PRIxADDR
665  " (call site %d)\n",
666  probe_name(iprobe),probeaddr,j);
667  probe_free(iprobe,0);
668  iprobe = NULL;
669  goto errout;
670  }
671  probes = g_slist_append(probes,iprobe);
672  }
673 
675  "registered inline invocation probes around call site"
676  " 0x%"PRIxADDR"; return site 0x%"PRIxADDR"\n",
677  iii->start,iii->end);
678 
679  ++j;
680  }
681 
682  v_g_slist_foreach(callee_instances,gsltmp,iii) {
683  bsymbol_release(iii->bsymbol);
684  free(iii);
685  }
686  g_slist_free(callee_instances);
687  }
688 
689  /*
690  * Now register @probe on each probe in @probes! We CANNOT fail at
691  * this point, because we free would the whole probes list on errout
692  * below, and freeing a probe that we have registered @probe on is
693  * not desireable. Just free the source probe in question...
694  */
695  v_g_slist_foreach(probes,gsltmp,iprobe) {
696  if (!probe_register_source(probe,iprobe)) {
697  verror("could not register probe %s on source %s; cannot abort!\n",
698  probe_name(probe),probe_name(iprobe));
699  probe_free(iprobe,0);
700  }
701  }
702 
703  g_slist_free(probes);
704  probes = NULL;
705 
706  /* Whewph! */
707  return probe;
708 
709  errout:
710  if (tlctxt)
712  if (probes) {
713  v_g_slist_foreach(probes,gsltmp,iprobe) {
714  probe_free(iprobe,0);
715  }
716  g_slist_free(probes);
717  }
718  if (callee_instances) {
719  v_g_slist_foreach(callee_instances,gsltmp,iii) {
720  bsymbol_release(iii->bsymbol);
721  free(iii);
722  }
723  g_slist_free(callee_instances);
724  }
725  if (funccode && caller_free)
726  free(funccode);
727  if (cf_idata_list) {
728  array_list_deep_free(cf_idata_list);
729  }
730  probe_unregister(probe,1);
731  if (probe->autofree)
732  probe_free(probe,1);
733  return NULL;
734 }
735 
736 struct probe *probe_register_function_instrs(struct bsymbol *bsymbol,
737  probepoint_style_t style,
738  int noabort,
739  probe_register_disasm_handler_t handler,
740  void *handler_data,
741  inst_type_t inst,
742  struct probe *probe,...) {
743  va_list ap;
744  struct target *target = probe->target;
745  struct memrange *range;
746  struct memrange *newrange;
747  ADDR start = 0;
748  ADDR end = 0;
749  ADDR probeaddr;
750  struct probe *source;
751  int j;
752  struct array_list *cflist = NULL;
753  unsigned char *funccode = NULL;
754  unsigned int funclen;
755  struct cf_inst_data *idata;
756  size_t bufsiz;
757  char *buf;
758  GHashTable *itypes = NULL;
759  inst_cf_flags_t cfflags = INST_CF_ANY;
760  tid_t tid;
761  struct probe *probe_alt;
762  char *sname;
763  int sname_created = 0;
764  struct symbol *symbol;
765  struct target_location_ctxt *tlctxt = NULL;
766 
767  symbol = bsymbol_get_symbol(bsymbol);
768 
769  if (!SYMBOL_IS_FUNC(symbol)) {
770  verror("must supply a function symbol!\n");
771  goto errout;
772  }
773 
774  sname = symbol_get_name(symbol);
775  if (!sname) {
776  sname = malloc(sizeof("ref0x")+12);
777  snprintf(sname,sizeof("ref0x")+12,"ref0x%"PRIxSMOFFSET,
778  symbol->ref);
779  sname_created = 1;
780  }
781 
782  /* Resolve the base address of the function so that we can pass the
783  * best information to __probe_register_addr as possible to make
784  * debug output clearer.
785  */
786  tlctxt = target_location_ctxt_create_from_bsymbol(target,TID_GLOBAL,bsymbol);
787  if (target_lsymbol_resolve_bounds(target,tlctxt,bsymbol->lsymbol,0,
788  &start,&end,NULL,NULL,NULL)) {
789  verror("could not resolve base addr for function %s!\n",
790  bsymbol_get_name(bsymbol));
791  if (sname_created)
792  free(sname);
793  return NULL;
794  }
795  funclen = end - start;
797  tlctxt = NULL;
798 
799  if (!target_find_memory_real(target,start,NULL,NULL,&range)) {
800  verror("could not find range for addr 0x%"PRIxADDR"\n",start);
801  goto errout;
802  }
803 
804  /* Process our varargs list. There must be at least one
805  * inst_type_t,probe * tuple, as shown in the fucntion prototype.
806  * If inst_type_t is not INST_TYPE_NONE, we process another probe *;
807  * otherwise, we abort since it's the end of the list.
808  */
809  itypes = g_hash_table_new(g_direct_hash,g_direct_equal);
810  g_hash_table_insert(itypes,(gpointer)inst,probe);
811  cfflags |= INST_TO_CF_FLAG(inst);
812  va_start(ap,probe);
813  while ((inst = va_arg(ap,inst_type_t)) != INST_NONE) {
814  probe = va_arg(ap,struct probe *);
815  g_hash_table_insert(itypes,(gpointer)inst,probe);
816  cfflags |= INST_TO_CF_FLAG(inst);
817  }
818  va_end(ap);
819 
820  /* Disassemble the function to find the return instructions. */
821 
822  /* We allocate an extra NULL byte on the back side because distorm
823  * seems to have an off by one error (guessing, according to
824  * valgrind!
825  */
826  funccode = malloc(funclen + 1);
827 
828  if (!target_read_addr(target,start,funclen,funccode)) {
829  verror("could not read code before disasm of function %s!\n",sname);
830  goto errout;
831  }
832 
833  funccode[funclen] = 0;
834 
835  if (disasm_get_control_flow_offsets(target,cfflags,funccode,funclen,
836  &cflist,start,noabort)) {
837  verror("could not disasm function %s!\n",sname);
838  goto errout;
839  }
840 
841  free(funccode);
842  funccode = NULL;
843 
844  /* Now register probes for each instruction! */
845  for (j = 0; j < array_list_len(cflist); ++j) {
846  idata = (struct cf_inst_data *)array_list_item(cflist,j);
847 
848  /* We should be in the same range, of course; this should never
849  * happen!
850  */
851  if (0 && (!target_find_memory_real(target,start + idata->offset,
852  NULL,NULL,&newrange)
853  || range != newrange)) {
854  verror("could not find sane range!\n");
855  goto errout;
856  }
857  else {
858  newrange = range;
859  }
860 
861  /*
862  * Call the user callback to see if they REALLY want the instr
863  * probed. 1 means yes; 0 means no.
864  */
865  probe_alt = NULL;
866  if (handler && handler(idata,start + idata->offset,
867  handler_data,&probe_alt) == 0) {
868  vdebug(5,LA_PROBE,LF_PROBE,"user handler skipped this inst!\n");
869  continue;
870  }
871 
872  if (probe_alt) {
873  vdebug(5,LA_PROBE,LF_PROBE,"user customized the probe for inst!\n");
874  probe = probe_alt;
875  }
876  else
877  probe = (struct probe *) \
878  g_hash_table_lookup(itypes,(gpointer)idata->type);
879 
880  tid = probe->thread->tid;
881 
882  /* Create the j-th instruction probe. Assume that all
883  * instruction names fit in 16 bytes.
884  */
885  bufsiz = strlen(sname)+1+16+1+11+1;
886  bufsiz = strlen(sname)+1+16+1+11+1;
887  buf = malloc(bufsiz);
888  snprintf(buf,bufsiz,"%s_%s_%d",sname,disasm_get_inst_name(idata->type),j);
889  source = probe_create(target,tid,NULL,buf,probe_do_sink_pre_handlers,
890  probe_do_sink_post_handlers,NULL,1,1);
891  free(buf);
892 
893  /* Register the j-th exit probe. */
894  probeaddr = start + idata->offset;
895  if (!__probe_register_addr(source,probeaddr,newrange,
897  PROBEPOINT_LAUTO,bsymbol,start)) {
898  verror("could not register probe %s at 0x%"PRIxADDR"!\n",
899  source->name,probeaddr);
900  goto errout;
901  }
902 
903  if (!probe_register_source(probe,source)) {
904  verror("could not register probe %s on source %s!\n",
905  probe->name,source->name);
906  probe_free(source,1);
907  goto errout;
908  }
909 
911  "registered %s probe at %s%+d\n",
912  disasm_get_inst_name(idata->type),sname,(int)idata->offset);
913  }
914 
915  if (cflist) {
916  array_list_deep_free(cflist);
917  cflist = NULL;
918  }
919  if (itypes)
920  g_hash_table_destroy(itypes);
921  if (sname_created)
922  free(sname);
923 
924  return probe;
925 
926  errout:
927  if (tlctxt)
929  if (itypes)
930  g_hash_table_destroy(itypes);
931  if (funccode)
932  free(funccode);
933  if (cflist) {
934  array_list_deep_free(cflist);
935  }
936  probe_unregister(probe,1);
937  if (probe->autofree)
938  probe_free(probe,1);
939  if (sname_created)
940  free(sname);
941  return NULL;
942 
943 }
944 
945 struct probe *probe_register_block_instrs(struct target *target,
946  ADDR start,ADDR end,
947  probepoint_style_t style,
948  int noabort,
949  probe_register_disasm_handler_t handler,
950  void *handler_data,
951  inst_type_t inst,
952  struct probe *probe,...) {
953  va_list ap;
954  struct memrange *range;
955  ADDR probeaddr;
956  struct probe *source;
957  int j;
958  struct array_list *cflist = NULL;
959  unsigned char *funccode = NULL;
960  struct cf_inst_data *idata;
961  size_t bufsiz;
962  char *buf;
963  GHashTable *itypes = NULL;
964  inst_cf_flags_t cfflags = INST_CF_ANY;
965  tid_t tid;
966  struct probe *probe_alt;
967  char sname[sizeof(ADDR)*2 + 2 + 1];
968  int caller_free = 0;
969 
970  snprintf(sname,sizeof(sname),"0x%"PRIxADDR,start);
971 
972  if (!target_find_memory_real(target,start,NULL,NULL,&range)) {
973  verror("could not find range for addr 0x%"PRIxADDR"\n",start);
974  goto errout;
975  }
976 
977  /* Process our varargs list. There must be at least one
978  * inst_type_t,probe * tuple, as shown in the fucntion prototype.
979  * If inst_type_t is not INST_TYPE_NONE, we process another probe *;
980  * otherwise, we abort since it's the end of the list.
981  */
982  itypes = g_hash_table_new(g_direct_hash,g_direct_equal);
983  g_hash_table_insert(itypes,(gpointer)inst,probe);
984  cfflags |= INST_TO_CF_FLAG(inst);
985  va_start(ap,probe);
986  while ((inst = va_arg(ap,inst_type_t)) != INST_NONE) {
987  probe = va_arg(ap,struct probe *);
988  g_hash_table_insert(itypes,(gpointer)inst,probe);
989  cfflags |= INST_TO_CF_FLAG(inst);
990  }
991  va_end(ap);
992 
993  /* Disassemble the function to find the return instructions. */
994  funccode = target_load_code(target,start,end - start,0,0,&caller_free);
995 
996  if (disasm_get_control_flow_offsets(target,cfflags,funccode,end - start,
997  &cflist,start,noabort)) {
998  verror("could not disasm function %s!\n",sname);
999  goto errout;
1000  }
1001 
1002  if (caller_free)
1003  free(funccode);
1004  funccode = NULL;
1005 
1006  /* Now register probes for each instruction! */
1007  for (j = 0; j < array_list_len(cflist); ++j) {
1008  idata = (struct cf_inst_data *)array_list_item(cflist,j);
1009 
1010  /*
1011  * Call the user callback to see if they REALLY want the instr
1012  * probed. 1 means yes; 0 means no.
1013  */
1014  probe_alt = NULL;
1015  if (handler && handler(idata,start + idata->offset,
1016  handler_data,&probe_alt) == 0) {
1017  vdebug(5,LA_PROBE,LF_PROBE,"user handler skipped this inst!\n");
1018  continue;
1019  }
1020 
1021  if (probe_alt) {
1022  vdebug(5,LA_PROBE,LF_PROBE,"user customized the probe for inst!\n");
1023  probe = probe_alt;
1024  }
1025  else
1026  probe = (struct probe *) \
1027  g_hash_table_lookup(itypes,(gpointer)idata->type);
1028 
1029  tid = probe->thread->tid;
1030 
1031  /* Create the j-th instruction probe. Assume that all
1032  * instruction names fit in 16 bytes.
1033  */
1034  bufsiz = strlen(sname)+1+16+1+11+1;
1035  bufsiz = strlen(sname)+1+16+1+11+1;
1036  buf = malloc(bufsiz);
1037  snprintf(buf,bufsiz,"%s_%s_%d",sname,disasm_get_inst_name(idata->type),j);
1038  source = probe_create(target,tid,NULL,buf,probe_do_sink_pre_handlers,
1039  probe_do_sink_post_handlers,NULL,1,1);
1040  free(buf);
1041 
1042  /* Register the j-th exit probe. */
1043  probeaddr = start + idata->offset;
1044  if (!__probe_register_addr(source,probeaddr,range,
1046  PROBEPOINT_LAUTO,NULL,start)) {
1047  verror("could not register probe %s at 0x%"PRIxADDR"!\n",
1048  source->name,probeaddr);
1049  goto errout;
1050  }
1051 
1052  if (!probe_register_source(probe,source)) {
1053  verror("could not register probe %s on source %s!\n",
1054  probe->name,source->name);
1055  probe_free(source,1);
1056  goto errout;
1057  }
1058 
1060  "registered %s probe at %s%+d\n",
1061  disasm_get_inst_name(idata->type),sname,(int)idata->offset);
1062  }
1063 
1064  if (cflist) {
1065  array_list_deep_free(cflist);
1066  cflist = NULL;
1067  }
1068  if (itypes)
1069  g_hash_table_destroy(itypes);
1070 
1071  return probe;
1072 
1073  errout:
1074  if (itypes)
1075  g_hash_table_destroy(itypes);
1076  if (funccode)
1077  free(funccode);
1078  if (cflist) {
1079  array_list_deep_free(cflist);
1080  }
1081  probe_unregister(probe,1);
1082  if (probe->autofree)
1083  probe_free(probe,1);
1084  return NULL;
1085 
1086 }
1087 #endif /* ENABLE_DISTORM */
1088 
1089 struct probe *probe_register_inlined_symbol(struct probe *probe,
1090  struct bsymbol *bsymbol,
1091  int do_primary,
1092  probepoint_style_t style,
1093  probepoint_whence_t whence,
1094  probepoint_watchsize_t watchsize) {
1095  struct target *target = probe->target;
1096  struct symbol *symbol;
1097  struct probe *pcprobe = NULL;
1098  struct probe *cprobe;
1099  size_t bufsiz;
1100  char *buf;
1101  GSList *cprobes = NULL;
1102  GSList *gsltmp;
1103  struct symbol *isymbol;
1104  tid_t tid = probe->thread->tid;
1105  ADDR paddr;
1106  struct target_location_ctxt *tlctxt = NULL;
1107 
1108  symbol = bsymbol_get_symbol(bsymbol);
1109 
1110  if (!SYMBOL_IS_INSTANCE(symbol)) {
1111  verror("cannot probe a non-instance symbol!\n");
1112  return NULL;
1113  }
1114 
1115  /* We only try to register on the primary if it has an address
1116  * (i.e., is not ONLY inlined).
1117  */
1118  tlctxt = target_location_ctxt_create_from_bsymbol(target,tid,bsymbol);
1119  if (do_primary
1120  && !target_lsymbol_resolve_bounds(target,tlctxt,bsymbol->lsymbol,0,
1121  &paddr,NULL,NULL,NULL,NULL)) {
1122 
1123  bufsiz = strlen(bsymbol_get_name(bsymbol))+sizeof("_primary")+1;
1124  buf = malloc(bufsiz);
1125  snprintf(buf,bufsiz,"%s_primary",bsymbol_get_name(bsymbol));
1126 
1127  pcprobe = probe_create(target,tid,NULL,buf,probe_do_sink_pre_handlers,
1128  probe_do_sink_post_handlers,NULL,1,1);
1129  free(buf);
1130 
1131  /* Register the i-th instance probe. */
1132  if (!probe_register_symbol(pcprobe,bsymbol,style,whence,watchsize)) {
1133  verror("could not register probe %s!\n",pcprobe->name);
1134  /* Probe is autofree! */
1135  //probe_free(pcprobe,1);
1136  pcprobe = NULL;
1137  goto errout;
1138  }
1139 
1140  vdebug(3,LA_PROBE,LF_PROBE,"registered %s probe at 0x%"PRIxADDR"\n",
1141  pcprobe->name,probe_addr(pcprobe));
1142 
1143  if (!probe_register_source(probe,pcprobe)) {
1144  verror("could not register probe %s on source %s!\n",
1145  probe->name,pcprobe->name);
1146  probe_free(pcprobe,1);
1147  pcprobe = NULL;
1148  goto errout;
1149  }
1150 
1151  vdebug(3,LA_PROBE,LF_PROBE,"registered %s probe on source %s\n",
1152  probe->name,pcprobe->name);
1153  }
1154  target_location_ctxt_free(tlctxt);
1155  tlctxt = NULL;
1156 
1157  SYMBOL_RX_INLINE(symbol,sii);
1158  if (sii && sii->inline_instances) {
1159  v_g_slist_foreach(sii->inline_instances,gsltmp,isymbol) {
1160  /* Use __int() version to not RHOLD(); bsymbol_create RHOLDS it. */
1161  struct lsymbol *ilsymbol = lsymbol_create_from_symbol__int(isymbol);
1162  if (!ilsymbol) {
1163  verror("could not create lsymbol for inline instance symbol %s!\n",
1164  symbol_get_name(isymbol));
1165  goto errout;
1166  }
1167  struct bsymbol *ibsymbol = bsymbol_create(ilsymbol,bsymbol->region);
1168 
1169  cprobe = probe_create(target,tid,NULL,bsymbol_get_name(ibsymbol),
1171  probe_do_sink_post_handlers,NULL,1,1);
1172  /* Register the i-th instance probe. */
1173  if (!probe_register_symbol(cprobe,ibsymbol,style,whence,watchsize)) {
1174  verror("could not register probe %s!\n",cprobe->name);
1175  probe_free(cprobe,1);
1176  goto errout;
1177  }
1178 
1179  bufsiz = strlen(symbol_get_name(isymbol) ? : "?")+1+6+1+2+1+2+16+1;
1180  buf = malloc(bufsiz);
1181  snprintf(buf,bufsiz,"%s_inline_at_0x%"PRIxADDR,
1182  bsymbol_get_name(bsymbol),
1183  probe_addr(cprobe));
1184  probe_rename(probe,buf);
1185  free(buf);
1186 
1187  vdebug(3,LA_PROBE,LF_PROBE,"registered %s probe at 0x%"PRIxADDR"\n",
1188  cprobe->name,probe_addr(cprobe));
1189 
1190  if (!probe_register_source(probe,cprobe)) {
1191  verror("could not register probe %s on source %s!\n",
1192  probe->name,cprobe->name);
1193  probe_free(cprobe,1);
1194  goto errout;
1195  }
1196 
1197  vdebug(3,LA_PROBE,LF_PROBE,"registered %s probe on source %s\n",
1198  probe->name,cprobe->name);
1199 
1200  cprobes = g_slist_append(cprobes,cprobe);
1201  }
1202  }
1203 
1204  if (cprobes)
1205  g_slist_free(cprobes);
1206  return probe;
1207 
1208  errout:
1209  if (tlctxt)
1210  target_location_ctxt_free(tlctxt);
1211  /* If we can autofree the top-level parent probe, great, that will
1212  * free all the sources beneath it we might have created. But
1213  * otherwise, we have to free those source probes one by one.
1214  */
1215  if (probe->autofree)
1216  probe_free(probe,1);
1217  else {
1218  if (pcprobe)
1219  probe_free(pcprobe,1);
1220  if (cprobes) {
1221  v_g_slist_foreach(cprobes,gsltmp,cprobe) {
1222  probe_free(cprobe,1);
1223  }
1224  }
1225  }
1226  g_slist_free(cprobes);
1227 
1228  return NULL;
1229 }
struct bsymbol * bsymbol_create(struct lsymbol *lsymbol, struct memregion *region)
Definition: symbol.c:48
result_t pre_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:903
int probe_unregister(struct probe *probe, int force)
Definition: probe.c:1137
uint8_t size
Definition: disasm.h:101
probe_handler_t pre_handler
Definition: probe.h:350
struct lsymbol * lsymbol
Definition: target.h:1017
int32_t tid_t
Definition: common.h:36
#define INST_TO_CF_FLAG(inst)
Definition: disasm.h:84
struct probe * probe_simple(struct target *target, tid_t tid, char *name, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
Definition: probe_lib.c:37
OFFSET offset
Definition: disasm.h:100
struct probe * __probe_register_addr(struct probe *probe, ADDR addr, struct memrange *range, probepoint_type_t type, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize, struct bsymbol *bsymbol, ADDR symbol_addr)
Definition: probe.c:1250
struct symbol * symbol
Definition: dwdebug.h:1010
struct lsymbol * lsymbol_create_from_symbol__int(struct symbol *symbol)
Definition: debug.c:4657
Definition: log.h:190
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
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
inst_type_t type
Definition: disasm.h:99
#define v_g_slist_foreach(gslhead, gslcur, elm)
Definition: glib_wrapper.h:60
SMOFFSET ref
Definition: dwdebug_priv.h:868
ADDR end
Definition: target.h:995
struct target_location_ctxt * target_location_ctxt_create_from_bsymbol(struct target *target, tid_t tid, struct bsymbol *bsymbol)
Definition: target.c:5325
probepoint_whence_t
Definition: probe_api.h:234
#define SYMBOL_IS_INSTANCE(sym)
int target_in_segment
Definition: disasm.h:104
result_t probe_do_sink_post_handlers(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: probe.c:109
char * bsymbol_get_name(struct bsymbol *bsymbol)
Definition: symbol.c:62
ADDR start
Definition: target.h:994
struct list_head probe
Definition: probe.h:379
#define verror(format,...)
Definition: log.h:30
result_t probe_do_sink_pre_handlers(struct probe *probe, tid_t tid, void *handler_data, struct probe *trigger, struct probe *base)
Definition: probe.c:48
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1053
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
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
#define vwarn(format,...)
Definition: log.h:33
void free(void *ptr)
Definition: debugserver.c:207
int disasm_get_control_flow_offsets(struct target *target, inst_cf_flags_t flags, unsigned char *inst_buf, unsigned int buf_len, struct array_list **offset_list, ADDR base, int noabort)
Definition: disasm.c:131
ADDR probe_addr(struct probe *probe)
Definition: probe.c:1959
tid_t tid
Definition: probe.h:344
struct probe * probe_register_source(struct probe *sink, struct probe *src)
Definition: probe.c:1593
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
#define SYMBOL_RX_INLINE(sym, rvar)
probepoint_watchsize_t
Definition: probe_api.h:241
int probe_free(struct probe *probe, int force)
Definition: probe.c:777
int target_is_valid
Definition: disasm.h:104
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
char * name
Definition: dwdebug_priv.h:788
#define DWDEBUG_DEF_DELIM
Definition: dwdebug.h:50
#define PRIxSMOFFSET
Definition: common.h:102
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
struct bsymbol * target_lookup_sym_addr(struct target *target, ADDR addr)
Definition: target.c:2093
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
struct target_thread * thread
Definition: probe.h:343
inst_cf_flags_t
Definition: disasm.h:67
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
struct probe * probe_register_symbol_name(struct probe *probe, char *name, const char *delim, probepoint_style_t style, probepoint_whence_t whence, probepoint_watchsize_t watchsize)
Definition: probe_lib.c:51
const char * disasm_get_inst_name(inst_type_t type)
Definition: disasm.c:43
struct cf_inst_data::@12 cf
GHashTable * probes
Definition: dumptarget.c:54
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
result_t post_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: spf.c:908
ADDR target
Definition: disasm.h:132
Definition: log.h:71
uint8_t autofree
Definition: probe.h:364
probepoint_style_t
Definition: probe_api.h:228
struct target_location_ctxt * target_location_ctxt_create(struct target *target, tid_t tid, struct memregion *region)
Definition: target.c:5304
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
#define PRIxADDR
Definition: common.h:67
void target_location_ctxt_free(struct target_location_ctxt *tlctxt)
Definition: target.c:5348
inst_type_t
Definition: disasm.h:46
char * symbol_get_name(struct symbol *symbol)
Definition: debug.c:2587
void * malloc(size_t size)
Definition: debugserver.c:214
void probe_rename(struct probe *probe, const char *name)
Definition: probe.c:898
int target_lookup_safe_disasm_range(struct target *target, ADDR addr, ADDR *start, ADDR *end, void **data)
Definition: target.c:3825
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
#define SYMBOL_IS_FUNC(sym)
probe_handler_t post_handler
Definition: probe.h:354
#define TID_GLOBAL
Definition: target_api.h:145
struct memregion * region
Definition: target.h:1020
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