1
2#ifndef __PERF_ANNOTATE_H
3#define __PERF_ANNOTATE_H
4
5#include <stdbool.h>
6#include <stdint.h>
7#include <linux/types.h>
8#include "symbol.h"
9#include "hist.h"
10#include "sort.h"
11#include <linux/list.h>
12#include <linux/rbtree.h>
13#include <pthread.h>
14
15struct ins_ops;
16
17struct ins {
18 const char *name;
19 struct ins_ops *ops;
20};
21
22struct ins_operands {
23 char *raw;
24 struct {
25 char *raw;
26 char *name;
27 u64 addr;
28 s64 offset;
29 bool offset_avail;
30 } target;
31 union {
32 struct {
33 char *raw;
34 char *name;
35 u64 addr;
36 } source;
37 struct {
38 struct ins ins;
39 struct ins_operands *ops;
40 } locked;
41 };
42};
43
44struct arch;
45
46struct ins_ops {
47 void (*free)(struct ins_operands *ops);
48 int (*parse)(struct arch *arch, struct ins_operands *ops, struct map *map);
49 int (*scnprintf)(struct ins *ins, char *bf, size_t size,
50 struct ins_operands *ops);
51};
52
53bool ins__is_jump(const struct ins *ins);
54bool ins__is_call(const struct ins *ins);
55bool ins__is_ret(const struct ins *ins);
56bool ins__is_lock(const struct ins *ins);
57int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops);
58bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2);
59
60struct annotation;
61
62struct sym_hist_entry {
63 u64 nr_samples;
64 u64 period;
65};
66
67struct annotation_data {
68 double percent;
69 double percent_sum;
70 struct sym_hist_entry he;
71};
72
73struct annotation_line {
74 struct list_head node;
75 struct rb_node rb_node;
76 s64 offset;
77 char *line;
78 int line_nr;
79 float ipc;
80 u64 cycles;
81 size_t privsize;
82 char *path;
83 int samples_nr;
84 struct annotation_data samples[0];
85};
86
87struct disasm_line {
88 struct ins ins;
89 struct ins_operands ops;
90
91
92 struct annotation_line al;
93};
94
95static inline struct disasm_line *disasm_line(struct annotation_line *al)
96{
97 return al ? container_of(al, struct disasm_line, al) : NULL;
98}
99
100static inline bool disasm_line__has_offset(const struct disasm_line *dl)
101{
102 return dl->ops.target.offset_avail;
103}
104
105void disasm_line__free(struct disasm_line *dl);
106struct annotation_line *
107annotation_line__next(struct annotation_line *pos, struct list_head *head);
108int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
109size_t disasm__fprintf(struct list_head *head, FILE *fp);
110void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel);
111
112struct sym_hist {
113 u64 nr_samples;
114 u64 period;
115 struct sym_hist_entry addr[0];
116};
117
118struct cyc_hist {
119 u64 start;
120 u64 cycles;
121 u64 cycles_aggr;
122 u32 num;
123 u32 num_aggr;
124 u8 have_start;
125
126 u16 reset;
127};
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142struct annotated_source {
143 struct list_head source;
144 int nr_histograms;
145 size_t sizeof_sym_hist;
146 struct cyc_hist *cycles_hist;
147 struct sym_hist histograms[0];
148};
149
150struct annotation {
151 pthread_mutex_t lock;
152 u64 max_coverage;
153 struct annotated_source *src;
154};
155
156static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx)
157{
158 return (((void *)¬es->src->histograms) +
159 (notes->src->sizeof_sym_hist * idx));
160}
161
162static inline struct annotation *symbol__annotation(struct symbol *sym)
163{
164 return (void *)sym - symbol_conf.priv_size;
165}
166
167int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample,
168 int evidx);
169
170int addr_map_symbol__account_cycles(struct addr_map_symbol *ams,
171 struct addr_map_symbol *start,
172 unsigned cycles);
173
174int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample,
175 int evidx, u64 addr);
176
177int symbol__alloc_hist(struct symbol *sym);
178void symbol__annotate_zero_histograms(struct symbol *sym);
179
180int symbol__annotate(struct symbol *sym, struct map *map,
181 struct perf_evsel *evsel, size_t privsize,
182 struct arch **parch);
183
184enum symbol_disassemble_errno {
185 SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
186
187
188
189
190
191
192
193
194 __SYMBOL_ANNOTATE_ERRNO__START = -10000,
195
196 SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START,
197
198 __SYMBOL_ANNOTATE_ERRNO__END,
199};
200
201int symbol__strerror_disassemble(struct symbol *sym, struct map *map,
202 int errnum, char *buf, size_t buflen);
203
204int symbol__annotate_printf(struct symbol *sym, struct map *map,
205 struct perf_evsel *evsel, bool full_paths,
206 int min_pcnt, int max_lines, int context);
207void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
208void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
209void annotated_source__purge(struct annotated_source *as);
210
211bool ui__has_annotation(void);
212
213int symbol__tty_annotate(struct symbol *sym, struct map *map,
214 struct perf_evsel *evsel, bool print_lines,
215 bool full_paths, int min_pcnt, int max_lines);
216
217#ifdef HAVE_SLANG_SUPPORT
218int symbol__tui_annotate(struct symbol *sym, struct map *map,
219 struct perf_evsel *evsel,
220 struct hist_browser_timer *hbt);
221#else
222static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
223 struct map *map __maybe_unused,
224 struct perf_evsel *evsel __maybe_unused,
225 struct hist_browser_timer *hbt
226 __maybe_unused)
227{
228 return 0;
229}
230#endif
231
232extern const char *disassembler_style;
233
234#endif
235