1 // SPDX-License-Identifier: GPL-2.0 2 #ifndef __PERF_UTIL_DISASM_H 3 #define __PERF_UTIL_DISASM_H 4 5 #include "map_symbol.h" 6 7 #ifdef HAVE_LIBDW_SUPPORT 8 #include "dwarf-aux.h" 9 #endif 10 11 struct annotation_options; 12 struct disasm_line; 13 struct ins; 14 struct evsel; 15 struct symbol; 16 struct data_loc_info; 17 struct type_state; 18 struct disasm_line; 19 20 struct e_machine_and_e_flags { 21 uint32_t e_flags; 22 uint16_t e_machine; 23 }; 24 25 struct arch { 26 /** @name: name such as "x86" or "powerpc". */ 27 const char *name; 28 const struct ins *instructions; 29 size_t nr_instructions; 30 size_t nr_instructions_allocated; 31 const char *insn_suffix; 32 unsigned int model; 33 unsigned int family; 34 /** @id: ELF machine and flags associated with arch. */ 35 struct e_machine_and_e_flags id; 36 bool sorted_instructions; 37 struct { 38 char comment_char; 39 char skip_functions_char; 40 char register_char; 41 char memory_ref_char; 42 char imm_char; 43 } objdump; 44 bool (*ins_is_fused)(const struct arch *arch, const char *ins1, 45 const char *ins2); 46 const struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); 47 #ifdef HAVE_LIBDW_SUPPORT 48 void (*update_insn_state)(struct type_state *state, 49 struct data_loc_info *dloc, Dwarf_Die *cu_die, 50 struct disasm_line *dl); 51 #endif 52 }; 53 54 struct ins { 55 const char *name; 56 const struct ins_ops *ops; 57 }; 58 59 struct ins_operands { 60 char *raw; 61 struct { 62 char *raw; 63 char *name; 64 struct symbol *sym; 65 u64 addr; 66 s64 offset; 67 bool offset_avail; 68 bool outside; 69 bool multi_regs; 70 bool mem_ref; 71 } target; 72 union { 73 struct { 74 char *raw; 75 char *name; 76 u64 addr; 77 bool multi_regs; 78 bool mem_ref; 79 } source; 80 struct { 81 struct ins ins; 82 struct ins_operands *ops; 83 } locked; 84 struct { 85 char *raw_comment; 86 char *raw_func_start; 87 } jump; 88 }; 89 }; 90 91 struct ins_ops { 92 void (*free)(struct ins_operands *ops); 93 int (*parse)(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, 94 struct disasm_line *dl); 95 int (*scnprintf)(const struct ins *ins, char *bf, size_t size, 96 struct ins_operands *ops, int max_ins_name); 97 bool is_jump; 98 bool is_call; 99 }; 100 101 struct annotate_args { 102 const struct arch *arch; 103 struct map_symbol *ms; 104 struct annotation_options *options; 105 s64 offset; 106 char *line; 107 int line_nr; 108 char *fileloc; 109 }; 110 111 const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const char *cpuid); 112 bool arch__is_x86(const struct arch *arch); 113 bool arch__is_powerpc(const struct arch *arch); 114 115 extern const struct ins_ops call_ops; 116 extern const struct ins_ops dec_ops; 117 extern const struct ins_ops jump_ops; 118 extern const struct ins_ops mov_ops; 119 extern const struct ins_ops nop_ops; 120 extern const struct ins_ops lock_ops; 121 extern const struct ins_ops ret_ops; 122 123 int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops); 124 125 const struct arch *arch__new_arc(const struct e_machine_and_e_flags *id, const char *cpuid); 126 const struct arch *arch__new_arm(const struct e_machine_and_e_flags *id, const char *cpuid); 127 const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, const char *cpuid); 128 const struct arch *arch__new_csky(const struct e_machine_and_e_flags *id, const char *cpuid); 129 const struct arch *arch__new_loongarch(const struct e_machine_and_e_flags *id, const char *cpuid); 130 const struct arch *arch__new_mips(const struct e_machine_and_e_flags *id, const char *cpuid); 131 const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id, const char *cpuid); 132 const struct arch *arch__new_riscv64(const struct e_machine_and_e_flags *id, const char *cpuid); 133 const struct arch *arch__new_s390(const struct e_machine_and_e_flags *id, const char *cpuid); 134 const struct arch *arch__new_sparc(const struct e_machine_and_e_flags *id, const char *cpuid); 135 const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const char *cpuid); 136 137 const struct ins_ops *ins__find(const struct arch *arch, const char *name, struct disasm_line *dl); 138 139 bool ins__is_call(const struct ins *ins); 140 bool ins__is_jump(const struct ins *ins); 141 bool ins__is_fused(const struct arch *arch, const char *ins1, const char *ins2); 142 bool ins__is_ret(const struct ins *ins); 143 bool ins__is_lock(const struct ins *ins); 144 145 const struct ins_ops *check_ppc_insn(struct disasm_line *dl); 146 147 struct disasm_line *disasm_line__new(struct annotate_args *args); 148 void disasm_line__free(struct disasm_line *dl); 149 150 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, 151 bool raw, int max_ins_name); 152 153 int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size, 154 struct ins_operands *ops, int max_ins_name); 155 int ins__scnprintf(const struct ins *ins, char *bf, size_t size, 156 struct ins_operands *ops, int max_ins_name); 157 int call__scnprintf(const struct ins *ins, char *bf, size_t size, 158 struct ins_operands *ops, int max_ins_name); 159 int jump__scnprintf(const struct ins *ins, char *bf, size_t size, 160 struct ins_operands *ops, int max_ins_name); 161 int mov__scnprintf(const struct ins *ins, char *bf, size_t size, 162 struct ins_operands *ops, int max_ins_name); 163 164 int symbol__disassemble(struct symbol *sym, struct annotate_args *args); 165 166 char *expand_tabs(char *line, char **storage, size_t *storage_len); 167 168 #endif /* __PERF_UTIL_DISASM_H */ 169