[PATCH -tip v3 09/11] perf-probe: Show source-level or symbol-level info for uprobes
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
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; +