| // SPDX-License-Identifier: GPL-2.0 |
| #ifndef __PERF_UTIL_DISASM_H |
| #define __PERF_UTIL_DISASM_H |
| |
| #include "map_symbol.h" |
| |
| #ifdef HAVE_LIBDW_SUPPORT |
| #include "dwarf-aux.h" |
| #endif |
| |
| struct annotation_options; |
| struct disasm_line; |
| struct ins; |
| struct evsel; |
| struct symbol; |
| struct data_loc_info; |
| struct type_state; |
| struct disasm_line; |
| |
| struct e_machine_and_e_flags { |
| uint32_t e_flags; |
| uint16_t e_machine; |
| }; |
| |
| struct arch { |
| /** @name: name such as "x86" or "powerpc". */ |
| const char *name; |
| const struct ins *instructions; |
| size_t nr_instructions; |
| size_t nr_instructions_allocated; |
| const char *insn_suffix; |
| unsigned int model; |
| unsigned int family; |
| /** @id: ELF machine and flags associated with arch. */ |
| struct e_machine_and_e_flags id; |
| bool sorted_instructions; |
| struct { |
| char comment_char; |
| char skip_functions_char; |
| char register_char; |
| char memory_ref_char; |
| char imm_char; |
| } objdump; |
| bool (*ins_is_fused)(const struct arch *arch, const char *ins1, |
| const char *ins2); |
| const struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); |
| #ifdef HAVE_LIBDW_SUPPORT |
| void (*update_insn_state)(struct type_state *state, |
| struct data_loc_info *dloc, Dwarf_Die *cu_die, |
| struct disasm_line *dl); |
| #endif |
| }; |
| |
| struct ins { |
| const char *name; |
| const struct ins_ops *ops; |
| }; |
| |
| struct ins_operands { |
| char *raw; |
| struct { |
| char *raw; |
| char *name; |
| struct symbol *sym; |
| u64 addr; |
| s64 offset; |
| bool offset_avail; |
| bool outside; |
| bool multi_regs; |
| bool mem_ref; |
| } target; |
| union { |
| struct { |
| char *raw; |
| char *name; |
| u64 addr; |
| bool multi_regs; |
| bool mem_ref; |
| } source; |
| struct { |
| struct ins ins; |
| struct ins_operands *ops; |
| } locked; |
| struct { |
| char *raw_comment; |
| char *raw_func_start; |
| } jump; |
| }; |
| }; |
| |
| struct ins_ops { |
| void (*free)(struct ins_operands *ops); |
| int (*parse)(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, |
| struct disasm_line *dl); |
| int (*scnprintf)(const struct ins *ins, char *bf, size_t size, |
| struct ins_operands *ops, int max_ins_name); |
| bool is_jump; |
| bool is_call; |
| }; |
| |
| struct annotate_args { |
| const struct arch *arch; |
| struct map_symbol *ms; |
| struct annotation_options *options; |
| s64 offset; |
| char *line; |
| int line_nr; |
| char *fileloc; |
| }; |
| |
| const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const char *cpuid); |
| bool arch__is_x86(const struct arch *arch); |
| bool arch__is_powerpc(const struct arch *arch); |
| |
| extern const struct ins_ops call_ops; |
| extern const struct ins_ops dec_ops; |
| extern const struct ins_ops jump_ops; |
| extern const struct ins_ops mov_ops; |
| extern const struct ins_ops nop_ops; |
| extern const struct ins_ops lock_ops; |
| extern const struct ins_ops ret_ops; |
| |
| int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops); |
| |
| const struct arch *arch__new_arc(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_arm(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_csky(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_loongarch(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_mips(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_riscv64(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_s390(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_sparc(const struct e_machine_and_e_flags *id, const char *cpuid); |
| const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const char *cpuid); |
| |
| const struct ins_ops *ins__find(const struct arch *arch, const char *name, struct disasm_line *dl); |
| |
| bool ins__is_call(const struct ins *ins); |
| bool ins__is_jump(const struct ins *ins); |
| bool ins__is_fused(const struct arch *arch, const char *ins1, const char *ins2); |
| bool ins__is_ret(const struct ins *ins); |
| bool ins__is_lock(const struct ins *ins); |
| |
| const struct ins_ops *check_ppc_insn(struct disasm_line *dl); |
| |
| struct disasm_line *disasm_line__new(struct annotate_args *args); |
| void disasm_line__free(struct disasm_line *dl); |
| |
| int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, |
| bool raw, int max_ins_name); |
| |
| int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size, |
| struct ins_operands *ops, int max_ins_name); |
| int ins__scnprintf(const struct ins *ins, char *bf, size_t size, |
| struct ins_operands *ops, int max_ins_name); |
| int call__scnprintf(const struct ins *ins, char *bf, size_t size, |
| struct ins_operands *ops, int max_ins_name); |
| int jump__scnprintf(const struct ins *ins, char *bf, size_t size, |
| struct ins_operands *ops, int max_ins_name); |
| int mov__scnprintf(const struct ins *ins, char *bf, size_t size, |
| struct ins_operands *ops, int max_ins_name); |
| |
| int symbol__disassemble(struct symbol *sym, struct annotate_args *args); |
| |
| char *expand_tabs(char *line, char **storage, size_t *storage_len); |
| |
| #endif /* __PERF_UTIL_DISASM_H */ |