[PATCH 19/19] perf annotate: AArch64 support

From: Arnaldo Carvalho de Melo
Date: Thu Dec 01 2016 - 13:04:40 EST


From: Kim Phillips <kim.phillips@xxxxxxx>

This is a regex converted version from the original:

https://lkml.org/lkml/2016/5/19/461

Add basic support to recognise AArch64 assembly. This allows perf to
identify AArch64 instructions that branch to other parts within the
same function, thereby properly annotating them.

Rebased onto new cross-arch annotation bits:

https://lkml.org/lkml/2016/11/25/546

Sample output:

security_file_permission vmlinux
5.80 â â ret â
â70: ldr w0, [x21,#68] â
4.44 â â tbnz d0 â
â mov w0, #0x24 // #36 â
1.37 â ands w0, w22, w0 â
â â b.eq 60 â
1.37 â â tbnz e4 â
â mov w19, #0x20000 // #131072 â
1.02 â â tbz ec â
â90:âââldr x3, [x21,#24] â
1.37 â â add x21, x21, #0x10 â
â â mov w2, w19 â
1.02 â â mov x0, x21 â
â â mov x1, x3 â
1.71 â â ldr x20, [x3,#48] â
â ââ bl __fsnotify_parent â
0.68 â ââ cbnz 60 â
â â mov x2, x21 â
1.37 â â mov w1, w19 â
â â mov x0, x20 â
0.68 â â mov w5, #0x0 // #0 â
â â mov x4, #0x0 // #0 â
1.71 â â mov w3, #0x1 // #1 â
â ââ bl fsnotify â
1.37 â ââ b 60 â
âd0:â mov w0, #0x0 // #0 â
â â ldp x19, x20, [sp,#16] â
â â ldp x21, x22, [sp,#32] â
â â ldp x29, x30, [sp],#48 â
â ââ ret â
âe4:â mov w19, #0x10000 // #65536 â
â âââb 90 â
âec: brk #0x800 â
Press 'h' for help on key bindings

Signed-off-by: Kim Phillips <kim.phillips@xxxxxxx>
Signed-off-by: Chris Ryder <chris.ryder@xxxxxxx>
Cc: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>
Cc: Mark Rutland <mark.rutland@xxxxxxx>
Cc: Pawel Moll <pawel.moll@xxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Will Deacon <will.deacon@xxxxxxx>
Link: http://lkml.kernel.org/r/20161130092344.012e18e3e623bea395162f95@xxxxxxx
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/arch/arm64/annotate/instructions.c | 62 +++++++++++++++++++++++++++
tools/perf/util/annotate.c | 5 +++
2 files changed, 67 insertions(+)
create mode 100644 tools/perf/arch/arm64/annotate/instructions.c

diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c
new file mode 100644
index 000000000000..44eafd6f2d50
--- /dev/null
+++ b/tools/perf/arch/arm64/annotate/instructions.c
@@ -0,0 +1,62 @@
+#include <sys/types.h>
+#include <regex.h>
+
+struct arm64_annotate {
+ regex_t call_insn,
+ jump_insn;
+};
+
+static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name)
+{
+ struct arm64_annotate *arm = arch->priv;
+ struct ins_ops *ops;
+ regmatch_t match[2];
+
+ if (!regexec(&arm->jump_insn, name, 2, match, 0))
+ ops = &jump_ops;
+ else if (!regexec(&arm->call_insn, name, 2, match, 0))
+ ops = &call_ops;
+ else if (!strcmp(name, "ret"))
+ ops = &ret_ops;
+ else
+ return NULL;
+
+ arch__associate_ins_ops(arch, name, ops);
+ return ops;
+}
+
+static int arm64__annotate_init(struct arch *arch)
+{
+ struct arm64_annotate *arm;
+ int err;
+
+ if (arch->initialized)
+ return 0;
+
+ arm = zalloc(sizeof(*arm));
+ if (!arm)
+ return -1;
+
+ /* bl, blr */
+ err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED);
+ if (err)
+ goto out_free_arm;
+ /* b, b.cond, br, cbz/cbnz, tbz/tbnz */
+ err = regcomp(&arm->jump_insn, "^[ct]?br?\\.?(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl)?n?z?$",
+ REG_EXTENDED);
+ if (err)
+ goto out_free_call;
+
+ arch->initialized = true;
+ arch->priv = arm;
+ arch->associate_instruction_ops = arm64__associate_instruction_ops;
+ arch->objdump.comment_char = ';';
+ arch->objdump.skip_functions_char = '+';
+ return 0;
+
+out_free_call:
+ regfree(&arm->call_insn);
+out_free_arm:
+ free(arm);
+ return -1;
+}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 191599eca807..4012b1de2813 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -105,6 +105,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i
}

#include "arch/arm/annotate/instructions.c"
+#include "arch/arm64/annotate/instructions.c"
#include "arch/x86/annotate/instructions.c"
#include "arch/powerpc/annotate/instructions.c"

@@ -114,6 +115,10 @@ static struct arch architectures[] = {
.init = arm__annotate_init,
},
{
+ .name = "arm64",
+ .init = arm64__annotate_init,
+ },
+ {
.name = "x86",
.instructions = x86__instructions,
.nr_instructions = ARRAY_SIZE(x86__instructions),
--
2.9.3