4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Masami Hiramatsu <mhiramat@xxxxxxxxxx> commit 3e96dac7c956089d3f23aca98c4dfca57b6aaf8a upstream. Add error check codes on post processing and improve it for offline probe events as: - post processing fails if no matched symbol found in map(-ENOENT) or strdup() failed(-ENOMEM). - Even if the symbol name is the same, it updates symbol address and offset. Signed-off-by: Masami Hiramatsu <mhiramat@xxxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: Namhyung Kim <namhyung@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Link: http://lkml.kernel.org/r/148411443738.9978.4617979132625405545.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> Cc: Krister Johansen <kjlx@xxxxxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- tools/perf/util/probe-event.c | 50 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 17 deletions(-) --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -618,6 +618,33 @@ error: return ret ? : -ENOENT; } +/* Adjust symbol name and address */ +static int post_process_probe_trace_point(struct probe_trace_point *tp, + struct map *map, unsigned long offs) +{ + struct symbol *sym; + u64 addr = tp->address + tp->offset - offs; + + sym = map__find_symbol(map, addr); + if (!sym) + return -ENOENT; + + if (strcmp(sym->name, tp->symbol)) { + /* If we have no realname, use symbol for it */ + if (!tp->realname) + tp->realname = tp->symbol; + else + free(tp->symbol); + tp->symbol = strdup(sym->name); + if (!tp->symbol) + return -ENOMEM; + } + tp->offset = addr - sym->start; + tp->address -= offs; + + return 0; +} + /* * Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions * and generate new symbols with suffixes such as .constprop.N or .isra.N @@ -630,11 +657,9 @@ static int post_process_offline_probe_trace_events(struct probe_trace_event *tevs, int ntevs, const char *pathname) { - struct symbol *sym; struct map *map; unsigned long stext = 0; - u64 addr; - int i; + int i, ret = 0; /* Prepare a map for offline binary */ map = dso__new_map(pathname); @@ -644,23 +669,14 @@ post_process_offline_probe_trace_events( } for (i = 0; i < ntevs; i++) { - addr = tevs[i].point.address + tevs[i].point.offset - stext; - sym = map__find_symbol(map, addr); - if (!sym) - continue; - if (!strcmp(sym->name, tevs[i].point.symbol)) - continue; - /* If we have no realname, use symbol for it */ - if (!tevs[i].point.realname) - tevs[i].point.realname = tevs[i].point.symbol; - else - free(tevs[i].point.symbol); - tevs[i].point.symbol = strdup(sym->name); - tevs[i].point.offset = addr - sym->start; + ret = post_process_probe_trace_point(&tevs[i].point, + map, stext); + if (ret < 0) + break; } map__put(map); - return 0; + return ret; } static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,