2024-01-16 11:35:27

by Changbin Du

[permalink] [raw]
Subject: [PATCH 2/3] perf: script: use capstone disasm engine to show assembly instructions

Currently, the instructions of samples are shown as raw hex strings
which are hard to read. x86 has a special option '--xed' to disassemble
the hex string via intel XED tool.

Here we use capstone as our disassembler engine to give more friendly
instructions. We select libcapstone because capstone can provide more
insn details. Perf will fallback to raw instructions if libcapstone is
not available.

The advantages compared to XED tool:
* Support arm, arm64, x86-32, x86_64 (more could be supported),
xed only for x86_64.
* Immediate address operands are shown as symbol+offs.

Before:
$ sudo perf record --event intel_pt//u -- ls
$ sudo perf script --insn-trace
perf 17423 [000] 423271.557970005: 7f2d95f16217 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.27.so) insn: 48 3d 01 f0 ff ff
perf 17423 [000] 423271.557970005: 7f2d95f1621d __GI___ioctl+0xd (/lib/x86_64-linux-gnu/libc-2.27.so) insn: 73 01
perf 17423 [000] 423271.557970338: 7f2d95f1621f __GI___ioctl+0xf (/lib/x86_64-linux-gnu/libc-2.27.so) insn: c3
perf 17423 [000] 423271.557970338: 5593ad3346d7 perf_evsel__enable_cpu+0x97 (/work/linux/tools/perf/perf) insn: 85 c0
perf 17423 [000] 423271.557970338: 5593ad3346d9 perf_evsel__enable_cpu+0x99 (/work/linux/tools/perf/perf) insn: 75 12
perf 17423 [000] 423271.557970338: 5593ad3346db perf_evsel__enable_cpu+0x9b (/work/linux/tools/perf/perf) insn: 49 8b 84 24 a8 00 00 00
perf 17423 [000] 423271.557970338: 5593ad3346e3 perf_evsel__enable_cpu+0xa3 (/work/linux/tools/perf/perf) insn: 48 8b 50 20

After:
$ sudo perf script --insn-trace
perf 17423 [000] 423271.557970005: 7f2d95f16217 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.27.so) insn: cmpq $-0xfff, %rax
perf 17423 [000] 423271.557970005: 7f2d95f1621d __GI___ioctl+0xd (/lib/x86_64-linux-gnu/libc-2.27.so) insn: jae __GI___ioctl+0x10
perf 17423 [000] 423271.557970338: 7f2d95f1621f __GI___ioctl+0xf (/lib/x86_64-linux-gnu/libc-2.27.so) insn: retq
perf 17423 [000] 423271.557970338: 5593ad3346d7 perf_evsel__enable_cpu+0x97 (/work/linux/tools/perf/perf) insn: testl %eax, %eax
perf 17423 [000] 423271.557970338: 5593ad3346d9 perf_evsel__enable_cpu+0x99 (/work/linux/tools/perf/perf) insn: jne perf_evsel__enable_cpu+0xad
perf 17423 [000] 423271.557970338: 5593ad3346db perf_evsel__enable_cpu+0x9b (/work/linux/tools/perf/perf) insn: movq 0xa8(%r12), %rax
perf 17423 [000] 423271.557970338: 5593ad3346e3 perf_evsel__enable_cpu+0xa3 (/work/linux/tools/perf/perf) insn: movq 0x20(%rax), %rdx
perf 17423 [000] 423271.557970338: 5593ad3346e7 perf_evsel__enable_cpu+0xa7 (/work/linux/tools/perf/perf) insn: cmpl %edx, %ebx
perf 17423 [000] 423271.557970338: 5593ad3346e9 perf_evsel__enable_cpu+0xa9 (/work/linux/tools/perf/perf) insn: jl perf_evsel__enable_cpu+0x60
perf 17423 [000] 423271.557970338: 5593ad3346eb perf_evsel__enable_cpu+0xab (/work/linux/tools/perf/perf) insn: xorl %eax, %eax

Signed-off-by: Changbin Du <[email protected]>
---
tools/perf/builtin-script.c | 8 +--
tools/perf/util/Build | 1 +
tools/perf/util/print_insn.c | 118 +++++++++++++++++++++++++++++++++++
tools/perf/util/print_insn.h | 14 +++++
4 files changed, 136 insertions(+), 5 deletions(-)
create mode 100644 tools/perf/util/print_insn.c
create mode 100644 tools/perf/util/print_insn.h

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index b1f57401ff23..c32a326e660f 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -34,6 +34,7 @@
#include "util/event.h"
#include "ui/ui.h"
#include "print_binary.h"
+#include "print_insn.h"
#include "archinsn.h"
#include <linux/bitmap.h>
#include <linux/kernel.h>
@@ -1511,11 +1512,8 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample,
if (PRINT_FIELD(INSNLEN))
printed += fprintf(fp, " ilen: %d", sample->insn_len);
if (PRINT_FIELD(INSN) && sample->insn_len) {
- int i;
-
- printed += fprintf(fp, " insn:");
- for (i = 0; i < sample->insn_len; i++)
- printed += fprintf(fp, " %02x", (unsigned char)sample->insn[i]);
+ printed += fprintf(fp, " insn: ");
+ printed += sample__fprintf_insn(sample, thread, machine, fp);
}
if (PRINT_FIELD(BRSTACKINSN) || PRINT_FIELD(BRSTACKINSNLEN))
printed += perf_sample__fprintf_brstackinsn(sample, thread, attr, machine, fp);
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 988473bf907a..c33aab53d8dd 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -32,6 +32,7 @@ perf-y += perf_regs.o
perf-y += perf-regs-arch/
perf-y += path.o
perf-y += print_binary.o
+perf-y += print_insn.o
perf-y += rlimit.o
perf-y += argv_split.o
perf-y += rbtree.o
diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c
new file mode 100644
index 000000000000..c8d9741748cd
--- /dev/null
+++ b/tools/perf/util/print_insn.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Instruction binary disassembler based on capstone.
+ *
+ * Author(s): Changbin Du <[email protected]>
+ */
+#include "print_insn.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "util/debug.h"
+#include "util/symbol.h"
+#include "machine.h"
+
+size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp)
+{
+ int printed = 0;
+
+ for (int i = 0; i < sample->insn_len; i++)
+ printed += fprintf(fp, "%02x ", (unsigned char)sample->insn[i]);
+ return printed;
+}
+
+#ifdef HAVE_LIBCAPSTONE_SUPPORT
+#include <capstone/capstone.h>
+
+static int capstone_init(struct machine *machine, csh *cs_handle)
+{
+ cs_arch arch;
+ cs_mode mode;
+
+ if (machine__is(machine, "x86_64")) {
+ arch = CS_ARCH_X86;
+ mode = CS_MODE_64;
+ } else if (machine__normalized_is(machine, "x86")) {
+ arch = CS_ARCH_X86;
+ mode = CS_MODE_32;
+ } else if (machine__normalized_is(machine, "arm64")) {
+ arch = CS_ARCH_ARM64;
+ mode = CS_MODE_ARM;
+ } else if (machine__normalized_is(machine, "arm")) {
+ arch = CS_ARCH_ARM;
+ mode = CS_MODE_ARM + CS_MODE_V8;
+ } else {
+ return -1;
+ }
+
+ if (cs_open(arch, mode, cs_handle) != CS_ERR_OK) {
+ pr_warning_once("cs_open failed\n");
+ return -1;
+ }
+
+ cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
+ if (machine__normalized_is(machine, "x86"))
+ cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON);
+
+ return 0;
+}
+
+static size_t print_insn_x86(struct perf_sample *sample, struct thread *thread,
+ cs_insn *insn, FILE *fp)
+{
+ struct addr_location al;
+ size_t printed = 0;
+
+ if (insn->detail && insn->detail->x86.op_count == 1) {
+ cs_x86_op *op = &insn->detail->x86.operands[0];
+
+ addr_location__init(&al);
+ if (op->type == X86_OP_IMM &&
+ thread__find_symbol(thread, sample->cpumode, op->imm, &al)) {
+ printed += fprintf(fp, "%s ", insn[0].mnemonic);
+ printed += symbol__fprintf_symname_offs(al.sym, &al, fp);
+ return printed;
+ }
+ }
+
+ printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str);
+ return printed;
+}
+
+size_t sample__fprintf_insn(struct perf_sample *sample, struct thread *thread,
+ struct machine *machine, FILE *fp)
+{
+ static csh cs_handle;
+ cs_insn *insn;
+ size_t count;
+ size_t printed = 0;
+ int ret;
+
+ ret = capstone_init(machine, &cs_handle);
+ if (ret < 0) {
+ /* fallback */
+ return sample__fprintf_insn_raw(sample, fp);
+ }
+
+ count = cs_disasm(cs_handle, (uint8_t *)sample->insn, sample->insn_len,
+ sample->ip, 1, &insn);
+ if (count > 0) {
+ if (machine__normalized_is(machine, "x86"))
+ printed += print_insn_x86(sample, thread, &insn[0], fp);
+ else
+ printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str);
+ cs_free(insn, count);
+ } else {
+ printed += fprintf(fp, "illegal instruction");
+ }
+
+ cs_close(&cs_handle);
+ return printed;
+}
+#else
+size_t sample__fprintf_insn(struct perf_sample *sample, struct thread *thread __maybe_unused,
+ struct machine *machine __maybe_unused, FILE *fp)
+{
+ return sample__fprintf_insn_raw(sample, fp);
+}
+#endif
diff --git a/tools/perf/util/print_insn.h b/tools/perf/util/print_insn.h
new file mode 100644
index 000000000000..af8fa5d01fb7
--- /dev/null
+++ b/tools/perf/util/print_insn.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef PERF_PRINT_ISNS_H
+#define PERF_PRINT_ISNS_H
+
+#include <stddef.h>
+#include <stdio.h>
+#include "event.h"
+#include "util/thread.h"
+
+size_t sample__fprintf_insn(struct perf_sample *sample, struct thread *thread,
+ struct machine *machine, FILE *fp);
+size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp);
+
+#endif /* PERF_PRINT_ISNS_H */
--
2.25.1



2024-01-16 14:27:30

by Thomas Richter

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf: script: use capstone disasm engine to show assembly instructions

On 1/16/24 12:34, Changbin Du wrote:
> Currently, the instructions of samples are shown as raw hex strings
> which are hard to read. x86 has a special option '--xed' to disassemble
> the hex string via intel XED tool.
>
> Here we use capstone as our disassembler engine to give more friendly
> instructions. We select libcapstone because capstone can provide more
> insn details. Perf will fallback to raw instructions if libcapstone is
> not available.
>
> The advantages compared to XED tool:
> * Support arm, arm64, x86-32, x86_64 (more could be supported),
> xed only for x86_64.
> * Immediate address operands are shown as symbol+offs.
>
> Before:
> $ sudo perf record --event intel_pt//u -- ls
> $ sudo perf script --insn-trace
> perf 17423 [000] 423271.557970005: 7f2d95f16217 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.27.so) insn: 48 3d 01 f0 ff ff
> perf 17423 [000] 423271.557970005: 7f2d95f1621d __GI___ioctl+0xd (/lib/x86_64-linux-gnu/libc-2.27.so) insn: 73 01
> perf 17423 [000] 423271.557970338: 7f2d95f1621f __GI___ioctl+0xf (/lib/x86_64-linux-gnu/libc-2.27.so) insn: c3
> perf 17423 [000] 423271.557970338: 5593ad3346d7 perf_evsel__enable_cpu+0x97 (/work/linux/tools/perf/perf) insn: 85 c0
> perf 17423 [000] 423271.557970338: 5593ad3346d9 perf_evsel__enable_cpu+0x99 (/work/linux/tools/perf/perf) insn: 75 12
> perf 17423 [000] 423271.557970338: 5593ad3346db perf_evsel__enable_cpu+0x9b (/work/linux/tools/perf/perf) insn: 49 8b 84 24 a8 00 00 00
> perf 17423 [000] 423271.557970338: 5593ad3346e3 perf_evsel__enable_cpu+0xa3 (/work/linux/tools/perf/perf) insn: 48 8b 50 20
>
> After:
> $ sudo perf script --insn-trace
> perf 17423 [000] 423271.557970005: 7f2d95f16217 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.27.so) insn: cmpq $-0xfff, %rax
> perf 17423 [000] 423271.557970005: 7f2d95f1621d __GI___ioctl+0xd (/lib/x86_64-linux-gnu/libc-2.27.so) insn: jae __GI___ioctl+0x10
> perf 17423 [000] 423271.557970338: 7f2d95f1621f __GI___ioctl+0xf (/lib/x86_64-linux-gnu/libc-2.27.so) insn: retq
> perf 17423 [000] 423271.557970338: 5593ad3346d7 perf_evsel__enable_cpu+0x97 (/work/linux/tools/perf/perf) insn: testl %eax, %eax
> perf 17423 [000] 423271.557970338: 5593ad3346d9 perf_evsel__enable_cpu+0x99 (/work/linux/tools/perf/perf) insn: jne perf_evsel__enable_cpu+0xad
> perf 17423 [000] 423271.557970338: 5593ad3346db perf_evsel__enable_cpu+0x9b (/work/linux/tools/perf/perf) insn: movq 0xa8(%r12), %rax
> perf 17423 [000] 423271.557970338: 5593ad3346e3 perf_evsel__enable_cpu+0xa3 (/work/linux/tools/perf/perf) insn: movq 0x20(%rax), %rdx
> perf 17423 [000] 423271.557970338: 5593ad3346e7 perf_evsel__enable_cpu+0xa7 (/work/linux/tools/perf/perf) insn: cmpl %edx, %ebx
> perf 17423 [000] 423271.557970338: 5593ad3346e9 perf_evsel__enable_cpu+0xa9 (/work/linux/tools/perf/perf) insn: jl perf_evsel__enable_cpu+0x60
> perf 17423 [000] 423271.557970338: 5593ad3346eb perf_evsel__enable_cpu+0xab (/work/linux/tools/perf/perf) insn: xorl %eax, %eax
>
> Signed-off-by: Changbin Du <[email protected]>
> ---

...

> diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c
> new file mode 100644
> index 000000000000..c8d9741748cd
> --- /dev/null
> +++ b/tools/perf/util/print_insn.c
> @@ -0,0 +1,118 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Instruction binary disassembler based on capstone.
> + *
> + * Author(s): Changbin Du <[email protected]>
> + */
> +#include "print_insn.h"
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdbool.h>
> +#include "util/debug.h"
> +#include "util/symbol.h"
> +#include "machine.h"
> +
> +size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp)
> +{
> + int printed = 0;
> +
> + for (int i = 0; i < sample->insn_len; i++)
> + printed += fprintf(fp, "%02x ", (unsigned char)sample->insn[i]);
> + return printed;
> +}
> +
> +#ifdef HAVE_LIBCAPSTONE_SUPPORT
> +#include <capstone/capstone.h>
> +
> +static int capstone_init(struct machine *machine, csh *cs_handle)
> +{
> + cs_arch arch;
> + cs_mode mode;
> +
> + if (machine__is(machine, "x86_64")) {
> + arch = CS_ARCH_X86;
> + mode = CS_MODE_64;
> + } else if (machine__normalized_is(machine, "x86")) {
> + arch = CS_ARCH_X86;
> + mode = CS_MODE_32;
> + } else if (machine__normalized_is(machine, "arm64")) {
> + arch = CS_ARCH_ARM64;
> + mode = CS_MODE_ARM;
> + } else if (machine__normalized_is(machine, "arm")) {
> + arch = CS_ARCH_ARM;
> + mode = CS_MODE_ARM + CS_MODE_V8;
> + } else {
> + return -1;
> + }
> ...

Did you forgot to support s390? Or was it omitted on intention?
Something along the lines will support s390:

# git diff util/print_insn.c
diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c
index c8d9741748cd..c5127910c75b 100644
--- a/tools/perf/util/print_insn.c
+++ b/tools/perf/util/print_insn.c
@@ -41,6 +41,9 @@ static int capstone_init(struct machine *machine, csh *cs_handle)
} else if (machine__normalized_is(machine, "arm")) {
arch = CS_ARCH_ARM;
mode = CS_MODE_ARM + CS_MODE_V8;
+ } else if (machine__normalized_is(machine, "s390x")) {
+ arch = CS_ARCH_SYSZ;
+ mode = CS_MODE_BIG_ENDIAN;
} else {
return -1;
}
#

Thanks a lot for including these line in your next version.

--
Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany
--
IBM Deutschland Research & Development GmbH

Vorsitzender des Aufsichtsrats: Wolfgang Wendt

Geschäftsführung: David Faller

Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294


2024-01-17 02:17:50

by Changbin Du

[permalink] [raw]
Subject: Re: [PATCH 2/3] perf: script: use capstone disasm engine to show assembly instructions

On Tue, Jan 16, 2024 at 03:26:52PM +0100, Thomas Richter wrote:
> On 1/16/24 12:34, Changbin Du wrote:
> > Currently, the instructions of samples are shown as raw hex strings
> > which are hard to read. x86 has a special option '--xed' to disassemble
> > the hex string via intel XED tool.
> >
> > Here we use capstone as our disassembler engine to give more friendly
> > instructions. We select libcapstone because capstone can provide more
> > insn details. Perf will fallback to raw instructions if libcapstone is
> > not available.
> >
> > The advantages compared to XED tool:
> > * Support arm, arm64, x86-32, x86_64 (more could be supported),
> > xed only for x86_64.
> > * Immediate address operands are shown as symbol+offs.
> >
> > Before:
> > $ sudo perf record --event intel_pt//u -- ls
> > $ sudo perf script --insn-trace
> > perf 17423 [000] 423271.557970005: 7f2d95f16217 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.27.so) insn: 48 3d 01 f0 ff ff
> > perf 17423 [000] 423271.557970005: 7f2d95f1621d __GI___ioctl+0xd (/lib/x86_64-linux-gnu/libc-2.27.so) insn: 73 01
> > perf 17423 [000] 423271.557970338: 7f2d95f1621f __GI___ioctl+0xf (/lib/x86_64-linux-gnu/libc-2.27.so) insn: c3
> > perf 17423 [000] 423271.557970338: 5593ad3346d7 perf_evsel__enable_cpu+0x97 (/work/linux/tools/perf/perf) insn: 85 c0
> > perf 17423 [000] 423271.557970338: 5593ad3346d9 perf_evsel__enable_cpu+0x99 (/work/linux/tools/perf/perf) insn: 75 12
> > perf 17423 [000] 423271.557970338: 5593ad3346db perf_evsel__enable_cpu+0x9b (/work/linux/tools/perf/perf) insn: 49 8b 84 24 a8 00 00 00
> > perf 17423 [000] 423271.557970338: 5593ad3346e3 perf_evsel__enable_cpu+0xa3 (/work/linux/tools/perf/perf) insn: 48 8b 50 20
> >
> > After:
> > $ sudo perf script --insn-trace
> > perf 17423 [000] 423271.557970005: 7f2d95f16217 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.27.so) insn: cmpq $-0xfff, %rax
> > perf 17423 [000] 423271.557970005: 7f2d95f1621d __GI___ioctl+0xd (/lib/x86_64-linux-gnu/libc-2.27.so) insn: jae __GI___ioctl+0x10
> > perf 17423 [000] 423271.557970338: 7f2d95f1621f __GI___ioctl+0xf (/lib/x86_64-linux-gnu/libc-2.27.so) insn: retq
> > perf 17423 [000] 423271.557970338: 5593ad3346d7 perf_evsel__enable_cpu+0x97 (/work/linux/tools/perf/perf) insn: testl %eax, %eax
> > perf 17423 [000] 423271.557970338: 5593ad3346d9 perf_evsel__enable_cpu+0x99 (/work/linux/tools/perf/perf) insn: jne perf_evsel__enable_cpu+0xad
> > perf 17423 [000] 423271.557970338: 5593ad3346db perf_evsel__enable_cpu+0x9b (/work/linux/tools/perf/perf) insn: movq 0xa8(%r12), %rax
> > perf 17423 [000] 423271.557970338: 5593ad3346e3 perf_evsel__enable_cpu+0xa3 (/work/linux/tools/perf/perf) insn: movq 0x20(%rax), %rdx
> > perf 17423 [000] 423271.557970338: 5593ad3346e7 perf_evsel__enable_cpu+0xa7 (/work/linux/tools/perf/perf) insn: cmpl %edx, %ebx
> > perf 17423 [000] 423271.557970338: 5593ad3346e9 perf_evsel__enable_cpu+0xa9 (/work/linux/tools/perf/perf) insn: jl perf_evsel__enable_cpu+0x60
> > perf 17423 [000] 423271.557970338: 5593ad3346eb perf_evsel__enable_cpu+0xab (/work/linux/tools/perf/perf) insn: xorl %eax, %eax
> >
> > Signed-off-by: Changbin Du <[email protected]>
> > ---
>
> ....
>
> > diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c
> > new file mode 100644
> > index 000000000000..c8d9741748cd
> > --- /dev/null
> > +++ b/tools/perf/util/print_insn.c
> > @@ -0,0 +1,118 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Instruction binary disassembler based on capstone.
> > + *
> > + * Author(s): Changbin Du <[email protected]>
> > + */
> > +#include "print_insn.h"
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <stdbool.h>
> > +#include "util/debug.h"
> > +#include "util/symbol.h"
> > +#include "machine.h"
> > +
> > +size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp)
> > +{
> > + int printed = 0;
> > +
> > + for (int i = 0; i < sample->insn_len; i++)
> > + printed += fprintf(fp, "%02x ", (unsigned char)sample->insn[i]);
> > + return printed;
> > +}
> > +
> > +#ifdef HAVE_LIBCAPSTONE_SUPPORT
> > +#include <capstone/capstone.h>
> > +
> > +static int capstone_init(struct machine *machine, csh *cs_handle)
> > +{
> > + cs_arch arch;
> > + cs_mode mode;
> > +
> > + if (machine__is(machine, "x86_64")) {
> > + arch = CS_ARCH_X86;
> > + mode = CS_MODE_64;
> > + } else if (machine__normalized_is(machine, "x86")) {
> > + arch = CS_ARCH_X86;
> > + mode = CS_MODE_32;
> > + } else if (machine__normalized_is(machine, "arm64")) {
> > + arch = CS_ARCH_ARM64;
> > + mode = CS_MODE_ARM;
> > + } else if (machine__normalized_is(machine, "arm")) {
> > + arch = CS_ARCH_ARM;
> > + mode = CS_MODE_ARM + CS_MODE_V8;
> > + } else {
> > + return -1;
> > + }
> > ...
>
> Did you forgot to support s390? Or was it omitted on intention?
> Something along the lines will support s390:
>
> # git diff util/print_insn.c
> diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c
> index c8d9741748cd..c5127910c75b 100644
> --- a/tools/perf/util/print_insn.c
> +++ b/tools/perf/util/print_insn.c
> @@ -41,6 +41,9 @@ static int capstone_init(struct machine *machine, csh *cs_handle)
> } else if (machine__normalized_is(machine, "arm")) {
> arch = CS_ARCH_ARM;
> mode = CS_MODE_ARM + CS_MODE_V8;
> + } else if (machine__normalized_is(machine, "s390x")) {
> + arch = CS_ARCH_SYSZ;
> + mode = CS_MODE_BIG_ENDIAN;
> } else {
> return -1;
> }
> #
>
> Thanks a lot for including these line in your next version.
>
No problem, thanks.

> --
> Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany
> --
> IBM Deutschland Research & Development GmbH
>
> Vorsitzender des Aufsichtsrats: Wolfgang Wendt
>
> Geschäftsführung: David Faller
>
> Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294
>

--
Cheers,
Changbin Du