diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-03-20 15:19:08 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-03-21 15:19:41 -0400 |
commit | 85a84e4f813912ab77d872ff6882dd7b435fbf4e (patch) | |
tree | 9398213418866ee06bb94a64b8d6a8e961b72912 | |
parent | 425859ff0de33a2362bec2a2c7ca486f87c13100 (diff) |
perf annotate: Pass function descriptor to its instruction parsing routines
We need that to figure out if jumps have targets in a different
function.
E.g. _cpp_lex_token(), in /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/cc1
has a line like this:
jne c469be <cpp_named_operator2name@@Base+0xa72>
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-ris0ioziyp469pofpzix2atb@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/arch/s390/annotate/instructions.c | 5 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 30 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 2 |
3 files changed, 21 insertions, 16 deletions
diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c index 46c21831f2ac..cee4e2f7c057 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c | |||
@@ -2,9 +2,10 @@ | |||
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | 3 | ||
4 | static int s390_call__parse(struct arch *arch, struct ins_operands *ops, | 4 | static int s390_call__parse(struct arch *arch, struct ins_operands *ops, |
5 | struct map *map) | 5 | struct map_symbol *ms) |
6 | { | 6 | { |
7 | char *endptr, *tok, *name; | 7 | char *endptr, *tok, *name; |
8 | struct map *map = ms->map; | ||
8 | struct addr_map_symbol target = { | 9 | struct addr_map_symbol target = { |
9 | .map = map, | 10 | .map = map, |
10 | }; | 11 | }; |
@@ -54,7 +55,7 @@ static struct ins_ops s390_call_ops = { | |||
54 | 55 | ||
55 | static int s390_mov__parse(struct arch *arch __maybe_unused, | 56 | static int s390_mov__parse(struct arch *arch __maybe_unused, |
56 | struct ins_operands *ops, | 57 | struct ins_operands *ops, |
57 | struct map *map __maybe_unused) | 58 | struct map_symbol *ms __maybe_unused) |
58 | { | 59 | { |
59 | char *s = strchr(ops->raw, ','), *target, *endptr; | 60 | char *s = strchr(ops->raw, ','), *target, *endptr; |
60 | 61 | ||
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 666f62c58e1a..3ff829d89178 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -202,9 +202,10 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) | |||
202 | return arch->ins_is_fused(arch, ins1, ins2); | 202 | return arch->ins_is_fused(arch, ins1, ins2); |
203 | } | 203 | } |
204 | 204 | ||
205 | static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) | 205 | static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) |
206 | { | 206 | { |
207 | char *endptr, *tok, *name; | 207 | char *endptr, *tok, *name; |
208 | struct map *map = ms->map; | ||
208 | struct addr_map_symbol target = { | 209 | struct addr_map_symbol target = { |
209 | .map = map, | 210 | .map = map, |
210 | }; | 211 | }; |
@@ -272,7 +273,7 @@ bool ins__is_call(const struct ins *ins) | |||
272 | return ins->ops == &call_ops || ins->ops == &s390_call_ops; | 273 | return ins->ops == &call_ops || ins->ops == &s390_call_ops; |
273 | } | 274 | } |
274 | 275 | ||
275 | static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused) | 276 | static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) |
276 | { | 277 | { |
277 | const char *s = strchr(ops->raw, '+'); | 278 | const char *s = strchr(ops->raw, '+'); |
278 | const char *c = strchr(ops->raw, ','); | 279 | const char *c = strchr(ops->raw, ','); |
@@ -365,7 +366,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) | |||
365 | return 0; | 366 | return 0; |
366 | } | 367 | } |
367 | 368 | ||
368 | static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map) | 369 | static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms) |
369 | { | 370 | { |
370 | ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); | 371 | ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); |
371 | if (ops->locked.ops == NULL) | 372 | if (ops->locked.ops == NULL) |
@@ -380,7 +381,7 @@ static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map * | |||
380 | goto out_free_ops; | 381 | goto out_free_ops; |
381 | 382 | ||
382 | if (ops->locked.ins.ops->parse && | 383 | if (ops->locked.ins.ops->parse && |
383 | ops->locked.ins.ops->parse(arch, ops->locked.ops, map) < 0) | 384 | ops->locked.ins.ops->parse(arch, ops->locked.ops, ms) < 0) |
384 | goto out_free_ops; | 385 | goto out_free_ops; |
385 | 386 | ||
386 | return 0; | 387 | return 0; |
@@ -423,7 +424,7 @@ static struct ins_ops lock_ops = { | |||
423 | .scnprintf = lock__scnprintf, | 424 | .scnprintf = lock__scnprintf, |
424 | }; | 425 | }; |
425 | 426 | ||
426 | static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map *map __maybe_unused) | 427 | static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) |
427 | { | 428 | { |
428 | char *s = strchr(ops->raw, ','), *target, *comment, prev; | 429 | char *s = strchr(ops->raw, ','), *target, *comment, prev; |
429 | 430 | ||
@@ -484,7 +485,7 @@ static struct ins_ops mov_ops = { | |||
484 | .scnprintf = mov__scnprintf, | 485 | .scnprintf = mov__scnprintf, |
485 | }; | 486 | }; |
486 | 487 | ||
487 | static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused) | 488 | static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused) |
488 | { | 489 | { |
489 | char *target, *comment, *s, prev; | 490 | char *target, *comment, *s, prev; |
490 | 491 | ||
@@ -923,14 +924,14 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *samp | |||
923 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); | 924 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); |
924 | } | 925 | } |
925 | 926 | ||
926 | static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) | 927 | static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms) |
927 | { | 928 | { |
928 | dl->ins.ops = ins__find(arch, dl->ins.name); | 929 | dl->ins.ops = ins__find(arch, dl->ins.name); |
929 | 930 | ||
930 | if (!dl->ins.ops) | 931 | if (!dl->ins.ops) |
931 | return; | 932 | return; |
932 | 933 | ||
933 | if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, map) < 0) | 934 | if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, ms) < 0) |
934 | dl->ins.ops = NULL; | 935 | dl->ins.ops = NULL; |
935 | } | 936 | } |
936 | 937 | ||
@@ -967,7 +968,7 @@ out_free_name: | |||
967 | struct annotate_args { | 968 | struct annotate_args { |
968 | size_t privsize; | 969 | size_t privsize; |
969 | struct arch *arch; | 970 | struct arch *arch; |
970 | struct map *map; | 971 | struct map_symbol ms; |
971 | struct perf_evsel *evsel; | 972 | struct perf_evsel *evsel; |
972 | s64 offset; | 973 | s64 offset; |
973 | char *line; | 974 | char *line; |
@@ -1049,7 +1050,7 @@ static struct disasm_line *disasm_line__new(struct annotate_args *args) | |||
1049 | if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) | 1050 | if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) |
1050 | goto out_free_line; | 1051 | goto out_free_line; |
1051 | 1052 | ||
1052 | disasm_line__init_ins(dl, args->arch, args->map); | 1053 | disasm_line__init_ins(dl, args->arch, &args->ms); |
1053 | } | 1054 | } |
1054 | } | 1055 | } |
1055 | 1056 | ||
@@ -1307,7 +1308,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, | |||
1307 | struct annotate_args *args, | 1308 | struct annotate_args *args, |
1308 | int *line_nr) | 1309 | int *line_nr) |
1309 | { | 1310 | { |
1310 | struct map *map = args->map; | 1311 | struct map *map = args->ms.map; |
1311 | struct annotation *notes = symbol__annotation(sym); | 1312 | struct annotation *notes = symbol__annotation(sym); |
1312 | struct disasm_line *dl; | 1313 | struct disasm_line *dl; |
1313 | char *line = NULL, *parsed_line, *tmp, *tmp2; | 1314 | char *line = NULL, *parsed_line, *tmp, *tmp2; |
@@ -1354,6 +1355,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, | |||
1354 | args->offset = offset; | 1355 | args->offset = offset; |
1355 | args->line = parsed_line; | 1356 | args->line = parsed_line; |
1356 | args->line_nr = *line_nr; | 1357 | args->line_nr = *line_nr; |
1358 | args->ms.sym = sym; | ||
1357 | 1359 | ||
1358 | dl = disasm_line__new(args); | 1360 | dl = disasm_line__new(args); |
1359 | free(line); | 1361 | free(line); |
@@ -1506,7 +1508,7 @@ fallback: | |||
1506 | 1508 | ||
1507 | static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) | 1509 | static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) |
1508 | { | 1510 | { |
1509 | struct map *map = args->map; | 1511 | struct map *map = args->ms.map; |
1510 | struct dso *dso = map->dso; | 1512 | struct dso *dso = map->dso; |
1511 | char *command; | 1513 | char *command; |
1512 | FILE *file; | 1514 | FILE *file; |
@@ -1705,7 +1707,6 @@ int symbol__annotate(struct symbol *sym, struct map *map, | |||
1705 | { | 1707 | { |
1706 | struct annotate_args args = { | 1708 | struct annotate_args args = { |
1707 | .privsize = privsize, | 1709 | .privsize = privsize, |
1708 | .map = map, | ||
1709 | .evsel = evsel, | 1710 | .evsel = evsel, |
1710 | }; | 1711 | }; |
1711 | struct perf_env *env = perf_evsel__env(evsel); | 1712 | struct perf_env *env = perf_evsel__env(evsel); |
@@ -1731,6 +1732,9 @@ int symbol__annotate(struct symbol *sym, struct map *map, | |||
1731 | } | 1732 | } |
1732 | } | 1733 | } |
1733 | 1734 | ||
1735 | args.ms.map = map; | ||
1736 | args.ms.sym = sym; | ||
1737 | |||
1734 | return symbol__disassemble(sym, &args); | 1738 | return symbol__disassemble(sym, &args); |
1735 | } | 1739 | } |
1736 | 1740 | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 365e9df888cf..c0bf0554a9ea 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -46,7 +46,7 @@ struct arch; | |||
46 | 46 | ||
47 | struct ins_ops { | 47 | struct ins_ops { |
48 | void (*free)(struct ins_operands *ops); | 48 | void (*free)(struct ins_operands *ops); |
49 | int (*parse)(struct arch *arch, struct ins_operands *ops, struct map *map); | 49 | int (*parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms); |
50 | int (*scnprintf)(struct ins *ins, char *bf, size_t size, | 50 | int (*scnprintf)(struct ins *ins, char *bf, size_t size, |
51 | struct ins_operands *ops); | 51 | struct ins_operands *ops); |
52 | }; | 52 | }; |