diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-03-02 11:59:36 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-03-05 09:58:45 -0300 |
commit | 696703af37a28892db89ff6a6d0cdfde6fb803ab (patch) | |
tree | 2085b7c0ac98337176cd65424c601a7dcf50fffc /tools/perf/util | |
parent | b09c2364a4dc2a67e640c2b839d936302815693f (diff) |
perf annotate: Find 'call' instruction target symbol at parsing time
So that we do it just once, not everytime we press enter or -> on a
'call' instruction line.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: https://lkml.kernel.org/n/tip-uysyojl1e6nm94amzzzs08tf@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/annotate.c | 38 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 1 |
2 files changed, 22 insertions, 17 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 28b233c3dcbe..49ff825f745c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -187,6 +187,9 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) { char *endptr, *tok, *name; + struct addr_map_symbol target = { + .map = map, + }; ops->target.addr = strtoull(ops->raw, &endptr, 16); @@ -208,28 +211,29 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map * ops->target.name = strdup(name); *tok = '>'; - return ops->target.name == NULL ? -1 : 0; + if (ops->target.name == NULL) + return -1; +find_target: + target.addr = map__objdump_2mem(map, ops->target.addr); -indirect_call: - tok = strchr(endptr, '*'); - if (tok == NULL) { - struct symbol *sym = map__find_symbol(map, map->map_ip(map, ops->target.addr)); - if (sym != NULL) - ops->target.name = strdup(sym->name); - else - ops->target.addr = 0; - return 0; - } + if (map_groups__find_ams(&target) == 0 && + map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr) + ops->target.sym = target.sym; - ops->target.addr = strtoull(tok + 1, NULL, 16); return 0; + +indirect_call: + tok = strchr(endptr, '*'); + if (tok != NULL) + ops->target.addr = strtoull(tok + 1, NULL, 16); + goto find_target; } static int call__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops) { - if (ops->target.name) - return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.name); + if (ops->target.sym) + return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name); if (ops->target.addr == 0) return ins__raw_scnprintf(ins, bf, size, ops); @@ -1283,8 +1287,8 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, dl->ops.target.offset_avail = true; } - /* kcore has no symbols, so add the call target name */ - if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) { + /* kcore has no symbols, so add the call target symbol */ + if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) { struct addr_map_symbol target = { .map = map, .addr = dl->ops.target.addr, @@ -1292,7 +1296,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, if (!map_groups__find_ams(&target) && target.sym->start == target.al_addr) - dl->ops.target.name = strdup(target.sym->name); + dl->ops.target.sym = target.sym; } annotation_line__add(&dl->al, ¬es->src->source); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index ce427445671f..7e914e834101 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -24,6 +24,7 @@ struct ins_operands { struct { char *raw; char *name; + struct symbol *sym; u64 addr; s64 offset; bool offset_avail; |