diff options
| author | Kim Phillips <kim.phillips@arm.com> | 2018-08-27 16:08:07 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-08-30 14:52:25 -0400 |
| commit | 58094c48f4079cfc784f53a73caaa446db436389 (patch) | |
| tree | 604c5649b67b3c667b3ff97f98b51a54fdc9d3b3 | |
| parent | 3de3e8bbf302545ef9acebb9f900939ac5c3820f (diff) | |
perf annotate: Handle arm64 move instructions
Add default handler for non-jump instructions. This really only has an
effect on instructions that compute a PC-relative address, such as
'adrp,' as seen in these couple of examples:
BEFORE: adrp x0, ffff20000aa11000 <kallsyms_token_index+0xce000>
AFTER: adrp x0, kallsyms_token_index+0xce000
BEFORE: adrp x23, ffff20000ae94000 <__per_cpu_load>
AFTER: adrp x23, __per_cpu_load
The implementation is identical to that of s390, but with a slight
adjustment for objdump whitespace propagation (arm64 objdump puts spaces
after commas, whereas s390's presumably doesn't).
The mov__scnprintf() declaration is moved from s390's to arm64's
instructions.c because arm64's gets included before s390's.
Committer testing:
Ran 'perf annotate --stdio2 > /tmp/{before,after}' no diff.
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Link: http://lkml.kernel.org/r/20180827150807.304110d2e9919a17c832ca48@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/perf/arch/arm64/annotate/instructions.c | 59 | ||||
| -rw-r--r-- | tools/perf/arch/s390/annotate/instructions.c | 2 |
2 files changed, 58 insertions, 3 deletions
diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c index 6688977e4ac7..76c6345a57d5 100644 --- a/tools/perf/arch/arm64/annotate/instructions.c +++ b/tools/perf/arch/arm64/annotate/instructions.c | |||
| @@ -8,6 +8,63 @@ struct arm64_annotate { | |||
| 8 | jump_insn; | 8 | jump_insn; |
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | static int arm64_mov__parse(struct arch *arch __maybe_unused, | ||
| 12 | struct ins_operands *ops, | ||
| 13 | struct map_symbol *ms __maybe_unused) | ||
| 14 | { | ||
| 15 | char *s = strchr(ops->raw, ','), *target, *endptr; | ||
| 16 | |||
| 17 | if (s == NULL) | ||
| 18 | return -1; | ||
| 19 | |||
| 20 | *s = '\0'; | ||
| 21 | ops->source.raw = strdup(ops->raw); | ||
| 22 | *s = ','; | ||
| 23 | |||
| 24 | if (ops->source.raw == NULL) | ||
| 25 | return -1; | ||
| 26 | |||
| 27 | target = ++s; | ||
| 28 | ops->target.raw = strdup(target); | ||
| 29 | if (ops->target.raw == NULL) | ||
| 30 | goto out_free_source; | ||
| 31 | |||
| 32 | ops->target.addr = strtoull(target, &endptr, 16); | ||
| 33 | if (endptr == target) | ||
| 34 | goto out_free_target; | ||
| 35 | |||
| 36 | s = strchr(endptr, '<'); | ||
| 37 | if (s == NULL) | ||
| 38 | goto out_free_target; | ||
| 39 | endptr = strchr(s + 1, '>'); | ||
| 40 | if (endptr == NULL) | ||
| 41 | goto out_free_target; | ||
| 42 | |||
| 43 | *endptr = '\0'; | ||
| 44 | *s = ' '; | ||
| 45 | ops->target.name = strdup(s); | ||
| 46 | *s = '<'; | ||
| 47 | *endptr = '>'; | ||
| 48 | if (ops->target.name == NULL) | ||
| 49 | goto out_free_target; | ||
| 50 | |||
| 51 | return 0; | ||
| 52 | |||
| 53 | out_free_target: | ||
| 54 | zfree(&ops->target.raw); | ||
| 55 | out_free_source: | ||
| 56 | zfree(&ops->source.raw); | ||
| 57 | return -1; | ||
| 58 | } | ||
| 59 | |||
| 60 | static int mov__scnprintf(struct ins *ins, char *bf, size_t size, | ||
| 61 | struct ins_operands *ops); | ||
| 62 | |||
| 63 | static struct ins_ops arm64_mov_ops = { | ||
| 64 | .parse = arm64_mov__parse, | ||
| 65 | .scnprintf = mov__scnprintf, | ||
| 66 | }; | ||
| 67 | |||
| 11 | static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name) | 68 | static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name) |
| 12 | { | 69 | { |
| 13 | struct arm64_annotate *arm = arch->priv; | 70 | struct arm64_annotate *arm = arch->priv; |
| @@ -21,7 +78,7 @@ static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const | |||
| 21 | else if (!strcmp(name, "ret")) | 78 | else if (!strcmp(name, "ret")) |
| 22 | ops = &ret_ops; | 79 | ops = &ret_ops; |
| 23 | else | 80 | else |
| 24 | return NULL; | 81 | ops = &arm64_mov_ops; |
| 25 | 82 | ||
| 26 | arch__associate_ins_ops(arch, name, ops); | 83 | arch__associate_ins_ops(arch, name, ops); |
| 27 | return ops; | 84 | return ops; |
diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c index cee4e2f7c057..de0dd66dbb48 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c | |||
| @@ -100,8 +100,6 @@ out_free_source: | |||
| 100 | return -1; | 100 | return -1; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static int mov__scnprintf(struct ins *ins, char *bf, size_t size, | ||
| 104 | struct ins_operands *ops); | ||
| 105 | 103 | ||
| 106 | static struct ins_ops s390_mov_ops = { | 104 | static struct ins_ops s390_mov_ops = { |
| 107 | .parse = s390_mov__parse, | 105 | .parse = s390_mov__parse, |
