[PATCH -tip v3 09/11] perf-probe: Show source-level or symbol-level info for uprobes

2014-02-05 Thread Masami Hiramatsu
Show source-level or symbol-level information for uprobe events.

Without this change;
  # ./perf probe -l
probe_perf:dso__load_vmlinux (on 0x0006d110 in 
/kbuild/ksrc/linux-3/tools/perf/perf)

With this change;
  # ./perf probe -l
probe_perf:dso__load_vmlinux (on dso__load_vmlinux@util/symbol.c in 
/kbuild/ksrc/linux-3/tools/perf/perf)

Changes from v2:
 - Update according to previous patches.

Changes from v1:
 - Rewrite the code based on new series.

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/probe-event.c |  227 ++---
 1 file changed, 144 insertions(+), 83 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f86820c..3c35b7a 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -249,34 +249,6 @@ out:
return ret;
 }
 
-static int convert_to_perf_probe_point(struct probe_trace_point *tp,
-   struct perf_probe_point *pp)
-{
-   struct symbol *sym;
-   struct map *map;
-   u64 addr = kernel_get_symbol_address_by_name(tp->symbol, true);
-
-   if (addr) {
-   addr += tp->offset;
-   sym = __find_kernel_function(addr, );
-   if (!sym)
-   goto failed;
-   pp->function = strdup(sym->name);
-   pp->offset = addr - map->unmap_ip(map, sym->start);
-   } else {
-failed:
-   pp->function = strdup(tp->symbol);
-   pp->offset = tp->offset;
-   }
-
-   if (pp->function == NULL)
-   return -ENOMEM;
-
-   pp->retprobe = tp->retprobe;
-
-   return 0;
-}
-
 #ifdef HAVE_DWARF_SUPPORT
 /* Open new debuginfo of given module */
 static struct debuginfo *open_debuginfo(const char *module)
@@ -298,44 +270,6 @@ static struct debuginfo *open_debuginfo(const char *module)
return debuginfo__new(path);
 }
 
-/*
- * Convert trace point to probe point with debuginfo
- * Currently only handles kprobes.
- */
-static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
-   struct perf_probe_point *pp)
-{
-   u64 addr = 0;
-   int ret = -ENOENT;
-   struct debuginfo *dinfo;
-
-   addr = kernel_get_symbol_address_by_name(tp->symbol, false);
-   if (addr) {
-   addr += tp->offset;
-   pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
-tp->offset, addr);
-
-   dinfo = open_debuginfo(tp->module);
-   if (dinfo) {
-   ret = debuginfo__find_probe_point(dinfo,
-(unsigned long)addr, pp);
-   debuginfo__delete(dinfo);
-   } else {
-   pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n",
-addr);
-   ret = -ENOENT;
-   }
-   }
-   if (ret <= 0) {
-   pr_debug("Failed to find corresponding probes from "
-"debuginfo. Use kprobe event information.\n");
-   return convert_to_perf_probe_point(tp, pp);
-   }
-   pp->retprobe = tp->retprobe;
-
-   return 0;
-}
-
 static int get_text_start_address(const char *exec, unsigned long *address)
 {
Elf *elf;
@@ -364,6 +298,57 @@ out:
return ret;
 }
 
+/*
+ * Convert trace point to probe point with debuginfo
+ */
+static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
+   struct perf_probe_point *pp,
+   bool is_kprobe)
+{
+   struct debuginfo *dinfo = NULL;
+   unsigned long stext = 0;
+   u64 addr = tp->address;
+   int ret = -ENOENT;
+
+   /* convert the address to dwarf address */
+   if (!is_kprobe) {
+   if (!addr) {
+   ret = -EINVAL;
+   goto error;
+   }
+   ret = get_text_start_address(tp->module, );
+   if (ret < 0)
+   goto error;
+   addr += stext;
+   } else {
+   addr = kernel_get_symbol_address_by_name(tp->symbol, false);
+   if (addr == 0)
+   goto error;
+   addr += tp->offset;
+   }
+
+   pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
+tp->module ? : "kernel");
+
+   dinfo = open_debuginfo(tp->module);
+   if (dinfo) {
+   ret = debuginfo__find_probe_point(dinfo,
+(unsigned long)addr, pp);
+   debuginfo__delete(dinfo);
+   } else {
+   pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n", addr);
+   ret = -ENOENT;
+   }
+
+   if (ret > 0) {
+   pp->retprobe = tp->retprobe;
+   

[PATCH -tip v3 09/11] perf-probe: Show source-level or symbol-level info for uprobes

2014-02-05 Thread Masami Hiramatsu
Show source-level or symbol-level information for uprobe events.

Without this change;
  # ./perf probe -l
probe_perf:dso__load_vmlinux (on 0x0006d110 in 
/kbuild/ksrc/linux-3/tools/perf/perf)

With this change;
  # ./perf probe -l
probe_perf:dso__load_vmlinux (on dso__load_vmlinux@util/symbol.c in 
/kbuild/ksrc/linux-3/tools/perf/perf)

Changes from v2:
 - Update according to previous patches.

Changes from v1:
 - Rewrite the code based on new series.

Signed-off-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
---
 tools/perf/util/probe-event.c |  227 ++---
 1 file changed, 144 insertions(+), 83 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f86820c..3c35b7a 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -249,34 +249,6 @@ out:
return ret;
 }
 
-static int convert_to_perf_probe_point(struct probe_trace_point *tp,
-   struct perf_probe_point *pp)
-{
-   struct symbol *sym;
-   struct map *map;
-   u64 addr = kernel_get_symbol_address_by_name(tp-symbol, true);
-
-   if (addr) {
-   addr += tp-offset;
-   sym = __find_kernel_function(addr, map);
-   if (!sym)
-   goto failed;
-   pp-function = strdup(sym-name);
-   pp-offset = addr - map-unmap_ip(map, sym-start);
-   } else {
-failed:
-   pp-function = strdup(tp-symbol);
-   pp-offset = tp-offset;
-   }
-
-   if (pp-function == NULL)
-   return -ENOMEM;
-
-   pp-retprobe = tp-retprobe;
-
-   return 0;
-}
-
 #ifdef HAVE_DWARF_SUPPORT
 /* Open new debuginfo of given module */
 static struct debuginfo *open_debuginfo(const char *module)
@@ -298,44 +270,6 @@ static struct debuginfo *open_debuginfo(const char *module)
return debuginfo__new(path);
 }
 
-/*
- * Convert trace point to probe point with debuginfo
- * Currently only handles kprobes.
- */
-static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
-   struct perf_probe_point *pp)
-{
-   u64 addr = 0;
-   int ret = -ENOENT;
-   struct debuginfo *dinfo;
-
-   addr = kernel_get_symbol_address_by_name(tp-symbol, false);
-   if (addr) {
-   addr += tp-offset;
-   pr_debug(try to find %s+%ld@% PRIx64 \n, tp-symbol,
-tp-offset, addr);
-
-   dinfo = open_debuginfo(tp-module);
-   if (dinfo) {
-   ret = debuginfo__find_probe_point(dinfo,
-(unsigned long)addr, pp);
-   debuginfo__delete(dinfo);
-   } else {
-   pr_debug(Failed to open debuginfo at 0x% PRIx64 \n,
-addr);
-   ret = -ENOENT;
-   }
-   }
-   if (ret = 0) {
-   pr_debug(Failed to find corresponding probes from 
-debuginfo. Use kprobe event information.\n);
-   return convert_to_perf_probe_point(tp, pp);
-   }
-   pp-retprobe = tp-retprobe;
-
-   return 0;
-}
-
 static int get_text_start_address(const char *exec, unsigned long *address)
 {
Elf *elf;
@@ -364,6 +298,57 @@ out:
return ret;
 }
 
+/*
+ * Convert trace point to probe point with debuginfo
+ */
+static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
+   struct perf_probe_point *pp,
+   bool is_kprobe)
+{
+   struct debuginfo *dinfo = NULL;
+   unsigned long stext = 0;
+   u64 addr = tp-address;
+   int ret = -ENOENT;
+
+   /* convert the address to dwarf address */
+   if (!is_kprobe) {
+   if (!addr) {
+   ret = -EINVAL;
+   goto error;
+   }
+   ret = get_text_start_address(tp-module, stext);
+   if (ret  0)
+   goto error;
+   addr += stext;
+   } else {
+   addr = kernel_get_symbol_address_by_name(tp-symbol, false);
+   if (addr == 0)
+   goto error;
+   addr += tp-offset;
+   }
+
+   pr_debug(try to find information at % PRIx64  in %s\n, addr,
+tp-module ? : kernel);
+
+   dinfo = open_debuginfo(tp-module);
+   if (dinfo) {
+   ret = debuginfo__find_probe_point(dinfo,
+(unsigned long)addr, pp);
+   debuginfo__delete(dinfo);
+   } else {
+   pr_debug(Failed to open debuginfo at 0x% PRIx64 \n, addr);
+   ret = -ENOENT;
+   }
+
+   if (ret  0) {
+   pp-retprobe = tp-retprobe;
+   return 0;
+