diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:17:52 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:17:52 +0000 |
commit | 3afb00d3f86d3d924f88b56fa8285d4e9db85852 (patch) | |
tree | 95a985d3019522cea546b7d8df621369bc44fc6c /tools/perf/util/print_insn.c | |
parent | Adding debian version 6.9.12-1. (diff) | |
download | linux-3afb00d3f86d3d924f88b56fa8285d4e9db85852.tar.xz linux-3afb00d3f86d3d924f88b56fa8285d4e9db85852.zip |
Merging upstream version 6.10.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tools/perf/util/print_insn.c')
-rw-r--r-- | tools/perf/util/print_insn.c | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c index 459e0e93d7..a950e9157d 100644 --- a/tools/perf/util/print_insn.c +++ b/tools/perf/util/print_insn.c @@ -4,6 +4,7 @@ * * Author(s): Changbin Du <changbin.du@huawei.com> */ +#include <inttypes.h> #include <string.h> #include <stdbool.h> #include "debug.h" @@ -12,6 +13,9 @@ #include "machine.h" #include "thread.h" #include "print_insn.h" +#include "dump-insn.h" +#include "map.h" +#include "dso.h" size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp) { @@ -28,12 +32,12 @@ size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp) #ifdef HAVE_LIBCAPSTONE_SUPPORT #include <capstone/capstone.h> -static int capstone_init(struct machine *machine, csh *cs_handle) +static int capstone_init(struct machine *machine, csh *cs_handle, bool is64) { cs_arch arch; cs_mode mode; - if (machine__is(machine, "x86_64")) { + if (machine__is(machine, "x86_64") && is64) { arch = CS_ARCH_X86; mode = CS_MODE_64; } else if (machine__normalized_is(machine, "x86")) { @@ -69,8 +73,8 @@ static int capstone_init(struct machine *machine, csh *cs_handle) return 0; } -static size_t print_insn_x86(struct perf_sample *sample, struct thread *thread, - cs_insn *insn, FILE *fp) +static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, + int print_opts, FILE *fp) { struct addr_location al; size_t printed = 0; @@ -80,9 +84,11 @@ static size_t print_insn_x86(struct perf_sample *sample, struct thread *thread, addr_location__init(&al); if (op->type == X86_OP_IMM && - thread__find_symbol(thread, sample->cpumode, op->imm, &al)) { + thread__find_symbol(thread, cpumode, op->imm, &al)) { printed += fprintf(fp, "%s ", insn[0].mnemonic); printed += symbol__fprintf_symname_offs(al.sym, &al, fp); + if (print_opts & PRINT_INSN_IMM_HEX) + printed += fprintf(fp, " [%#" PRIx64 "]", op->imm); addr_location__exit(&al); return printed; } @@ -93,42 +99,71 @@ static size_t print_insn_x86(struct perf_sample *sample, struct thread *thread, return printed; } -size_t sample__fprintf_insn_asm(struct perf_sample *sample, struct thread *thread, - struct machine *machine, FILE *fp) +static bool is64bitip(struct machine *machine, struct addr_location *al) { - csh cs_handle; + const struct dso *dso = al->map ? map__dso(al->map) : NULL; + + if (dso) + return dso__is_64_bit(dso); + + return machine__is(machine, "x86_64") || + machine__normalized_is(machine, "arm64") || + machine__normalized_is(machine, "s390"); +} + +ssize_t fprintf_insn_asm(struct machine *machine, struct thread *thread, u8 cpumode, + bool is64bit, const uint8_t *code, size_t code_size, + uint64_t ip, int *lenp, int print_opts, FILE *fp) +{ + size_t printed; cs_insn *insn; + csh cs_handle; size_t count; - size_t printed = 0; int ret; /* TODO: Try to initiate capstone only once but need a proper place. */ - ret = capstone_init(machine, &cs_handle); - if (ret < 0) { - /* fallback */ - return sample__fprintf_insn_raw(sample, fp); - } + ret = capstone_init(machine, &cs_handle, is64bit); + if (ret < 0) + return ret; - count = cs_disasm(cs_handle, (uint8_t *)sample->insn, sample->insn_len, - sample->ip, 1, &insn); + count = cs_disasm(cs_handle, code, code_size, ip, 1, &insn); if (count > 0) { if (machine__normalized_is(machine, "x86")) - printed += print_insn_x86(sample, thread, &insn[0], fp); + printed = print_insn_x86(thread, cpumode, &insn[0], print_opts, fp); else - printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); + printed = fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); + if (lenp) + *lenp = insn->size; cs_free(insn, count); } else { - printed += fprintf(fp, "illegal instruction"); + printed = -1; } cs_close(&cs_handle); return printed; } + +size_t sample__fprintf_insn_asm(struct perf_sample *sample, struct thread *thread, + struct machine *machine, FILE *fp, + struct addr_location *al) +{ + bool is64bit = is64bitip(machine, al); + ssize_t printed; + + printed = fprintf_insn_asm(machine, thread, sample->cpumode, is64bit, + (uint8_t *)sample->insn, sample->insn_len, + sample->ip, NULL, 0, fp); + if (printed < 0) + return sample__fprintf_insn_raw(sample, fp); + + return printed; +} #else size_t sample__fprintf_insn_asm(struct perf_sample *sample __maybe_unused, struct thread *thread __maybe_unused, struct machine *machine __maybe_unused, - FILE *fp __maybe_unused) + FILE *fp __maybe_unused, + struct addr_location *al __maybe_unused) { return 0; } |