aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index de9fe906f3be..1ce2cb9845b6 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -383,6 +383,51 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
383 return ret; 383 return ret;
384} 384}
385 385
386static struct ref_reloc_sym *__kernel_get_ref_reloc_sym(void)
387{
388 /* kmap->ref_reloc_sym should be set if host_machine is initialized */
389 struct kmap *kmap;
390
391 kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]);
392 return kmap->ref_reloc_sym;
393}
394
395/* Post processing the probe events */
396static int post_process_probe_trace_events(struct probe_trace_event *tevs,
397 int ntevs, const char *module,
398 bool uprobe)
399{
400 struct ref_reloc_sym *reloc_sym;
401 char *tmp;
402 int i;
403
404 if (uprobe)
405 return add_exec_to_probe_trace_events(tevs, ntevs, module);
406
407 /* Note that currently ref_reloc_sym based probe is not for drivers */
408 if (module)
409 return add_module_to_probe_trace_events(tevs, ntevs, module);
410
411 reloc_sym = __kernel_get_ref_reloc_sym();
412 if (!reloc_sym) {
413 pr_warning("Relocated base symbol is not found!\n");
414 return -EINVAL;
415 }
416
417 for (i = 0; i < ntevs; i++) {
418 if (tevs[i].point.address) {
419 tmp = strdup(reloc_sym->name);
420 if (!tmp)
421 return -ENOMEM;
422 free(tevs[i].point.symbol);
423 tevs[i].point.symbol = tmp;
424 tevs[i].point.offset = tevs[i].point.address -
425 reloc_sym->unrelocated_addr;
426 }
427 }
428 return 0;
429}
430
386static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) 431static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
387{ 432{
388 int i; 433 int i;
@@ -411,21 +456,16 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
411 return 0; 456 return 0;
412 } 457 }
413 458
459 pr_debug("Try to find probe point from debuginfo.\n");
414 /* Searching trace events corresponding to a probe event */ 460 /* Searching trace events corresponding to a probe event */
415 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs); 461 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
416 462
417 debuginfo__delete(dinfo); 463 debuginfo__delete(dinfo);
418 464
419 if (ntevs > 0) { /* Succeeded to find trace events */ 465 if (ntevs > 0) { /* Succeeded to find trace events */
420 pr_debug("find %d probe_trace_events.\n", ntevs); 466 pr_debug("Found %d probe_trace_events.\n", ntevs);
421 if (target) { 467 ret = post_process_probe_trace_events(*tevs, ntevs,
422 if (pev->uprobes) 468 target, pev->uprobes);
423 ret = add_exec_to_probe_trace_events(*tevs,
424 ntevs, target);
425 else
426 ret = add_module_to_probe_trace_events(*tevs,
427 ntevs, target);
428 }
429 if (ret < 0) { 469 if (ret < 0) {
430 clear_probe_trace_events(*tevs, ntevs); 470 clear_probe_trace_events(*tevs, ntevs);
431 zfree(tevs); 471 zfree(tevs);