1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
// 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 */
|