diff options
-rw-r--r-- | tools/perf/util/probe-event.c | 58 |
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 | ||
386 | static 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 */ | ||
396 | static 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 | |||
386 | static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) | 431 | static 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); |