summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-02-06 05:32:18 +0000
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-02-18 09:34:51 -0300
commitf90acac75713cc6f18a4b2f1b9162bc1cd893c20 (patch)
tree5a845a8cac58ed20e28fa7c00e2cb798b52bf7ee /tools/perf/util/probe-event.c
parentdfef99cd0b2c8abafb571e5992ce954135be5f40 (diff)
downloadop-kernel-dev-f90acac75713cc6f18a4b2f1b9162bc1cd893c20.zip
op-kernel-dev-f90acac75713cc6f18a4b2f1b9162bc1cd893c20.tar.gz
perf probe: Find given address from offline dwarf
Find the given address from offline dwarfs instead of online kernel dwarfs. On the KASLR enabled kernel, the kernel text section is loaded with random offset, and the debuginfo__new_online_kernel can't handle it. So let's move to the offline dwarf loader instead of using the online dwarf loader. As a result, since we don't need debuginfo__new_online_kernel any more, this also removes the functions related to that. Without this change; # ./perf probe -l probe:t_show (on _stext+901288 with m v) probe:t_show_1 (on _stext+939624 with m v t) probe:t_show_2 (on _stext+980296 with m v fmt) probe:t_show_3 (on _stext+1014392 with m v file) With this change; # ./perf probe -l probe:t_show (on t_show@linux-3/kernel/trace/ftrace.c with m v) probe:t_show_1 (on t_show@linux-3/kernel/trace/trace.c with m v t) probe:t_show_2 (on t_show@kernel/trace/trace_printk.c with m v fmt) probe:t_show_3 (on t_show@kernel/trace/trace_events.c with m v file) Changes from v2: - Instead of retrying, directly opens offline dwarf. - Remove debuginfo__new_online_kernel and related functions. - Refer map->reloc to get the correct address of a symbol. - Add a special case for handling ref_reloc_sym based address. Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: David Ahern <dsahern@gmail.com> Cc: "David A. Long" <dave.long@linaro.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: yrl.pp-manager.tt@hitachi.com Link: http://lkml.kernel.org/r/20140206053218.29635.74821.stgit@kbuild-fedora.yrl.intra.hitachi.co.jp Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 1ce2cb9..8e34c8d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -248,6 +248,18 @@ static struct debuginfo *open_debuginfo(const char *module)
return debuginfo__new(path);
}
+static struct ref_reloc_sym *__kernel_get_ref_reloc_sym(void)
+{
+ /* kmap->ref_reloc_sym should be set if host_machine is initialized */
+ struct kmap *kmap;
+
+ if (map__load(host_machine->vmlinux_maps[MAP__FUNCTION], NULL) < 0)
+ return NULL;
+
+ kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]);
+ return kmap->ref_reloc_sym;
+}
+
/*
* Convert trace point to probe point with debuginfo
* Currently only handles kprobes.
@@ -256,18 +268,27 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
struct perf_probe_point *pp)
{
struct symbol *sym;
+ struct ref_reloc_sym *reloc_sym;
struct map *map;
- u64 addr;
+ u64 addr = 0;
int ret = -ENOENT;
struct debuginfo *dinfo;
- sym = __find_kernel_function_by_name(tp->symbol, &map);
- if (sym) {
- addr = map->unmap_ip(map, sym->start + tp->offset);
+ /* ref_reloc_sym is just a label. Need a special fix*/
+ reloc_sym = __kernel_get_ref_reloc_sym();
+ if (reloc_sym && strcmp(tp->symbol, reloc_sym->name) == 0)
+ addr = reloc_sym->unrelocated_addr + tp->offset;
+ else {
+ sym = __find_kernel_function_by_name(tp->symbol, &map);
+ if (sym)
+ addr = map->unmap_ip(map, sym->start + tp->offset) -
+ map->reloc;
+ }
+ if (addr) {
pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
tp->offset, addr);
- dinfo = debuginfo__new_online_kernel(addr);
+ dinfo = open_debuginfo(tp->module);
if (dinfo) {
ret = debuginfo__find_probe_point(dinfo,
(unsigned long)addr, pp);
@@ -383,15 +404,6 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
return ret;
}
-static struct ref_reloc_sym *__kernel_get_ref_reloc_sym(void)
-{
- /* kmap->ref_reloc_sym should be set if host_machine is initialized */
- struct kmap *kmap;
-
- kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]);
- return kmap->ref_reloc_sym;
-}
-
/* Post processing the probe events */
static int post_process_probe_trace_events(struct probe_trace_event *tevs,
int ntevs, const char *module,
OpenPOWER on IntegriCloud