1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Instruction binary disassembler based on capstone. 4 * 5 * Author(s): Changbin Du <changbin.du@huawei.com> 6 */ 7 #include "print_insn.h" 8 9 #include <inttypes.h> 10 #include <stdbool.h> 11 #include <string.h> 12 13 #include <dwarf-regs.h> 14 15 #include "capstone.h" 16 #include "debug.h" 17 #include "dso.h" 18 #include "dump-insn.h" 19 #include "env.h" 20 #include "machine.h" 21 #include "map.h" 22 #include "sample.h" 23 #include "symbol.h" 24 #include "thread.h" 25 26 size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp) 27 { 28 int printed = 0; 29 30 for (int i = 0; i < sample->insn_len; i++) { 31 printed += fprintf(fp, "%02x", (unsigned char)sample->insn[i]); 32 if (sample->insn_len - i > 1) 33 printed += fprintf(fp, " "); 34 } 35 return printed; 36 } 37 38 static bool is64bitip(struct machine *machine, struct addr_location *al) 39 { 40 const struct dso *dso = al->map ? map__dso(al->map) : NULL; 41 uint16_t e_machine; 42 43 if (dso) 44 return dso__is_64_bit(dso); 45 46 e_machine = perf_env__e_machine(machine->env, /*e_flags=*/NULL); 47 return e_machine == EM_X86_64 || e_machine == EM_AARCH64 || e_machine == EM_S390; 48 } 49 50 ssize_t fprintf_insn_asm(struct machine *machine, struct thread *thread, u8 cpumode, 51 bool is64bit, const uint8_t *code, size_t code_size, 52 uint64_t ip, int *lenp, int print_opts, FILE *fp) 53 { 54 return capstone__fprintf_insn_asm(machine, thread, cpumode, is64bit, code, code_size, 55 ip, lenp, print_opts, fp); 56 } 57 58 size_t sample__fprintf_insn_asm(struct perf_sample *sample, struct thread *thread, 59 struct machine *machine, FILE *fp, 60 struct addr_location *al) 61 { 62 bool is64bit = is64bitip(machine, al); 63 ssize_t printed; 64 65 printed = fprintf_insn_asm(machine, thread, sample->cpumode, is64bit, 66 (uint8_t *)sample->insn, sample->insn_len, 67 sample->ip, NULL, 0, fp); 68 if (printed < 0) 69 return sample__fprintf_insn_raw(sample, fp); 70 71 return printed; 72 } 73