]> asedeno.scripts.mit.edu Git - linux.git/blob - tools/perf/util/annotate.h
perf annotate: Find 'call' instruction target symbol at parsing time
[linux.git] / tools / perf / util / annotate.h
1 /* SPDX-License-Identifier: GPL-2.0 */
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
15 struct ins_ops;
16
17 struct ins {
18         const char     *name;
19         struct ins_ops *ops;
20 };
21
22 struct ins_operands {
23         char    *raw;
24         struct {
25                 char    *raw;
26                 char    *name;
27                 struct symbol *sym;
28                 u64     addr;
29                 s64     offset;
30                 bool    offset_avail;
31         } target;
32         union {
33                 struct {
34                         char    *raw;
35                         char    *name;
36                         u64     addr;
37                 } source;
38                 struct {
39                         struct ins          ins;
40                         struct ins_operands *ops;
41                 } locked;
42         };
43 };
44
45 struct arch;
46
47 struct ins_ops {
48         void (*free)(struct ins_operands *ops);
49         int (*parse)(struct arch *arch, struct ins_operands *ops, struct map *map);
50         int (*scnprintf)(struct ins *ins, char *bf, size_t size,
51                          struct ins_operands *ops);
52 };
53
54 bool ins__is_jump(const struct ins *ins);
55 bool ins__is_call(const struct ins *ins);
56 bool ins__is_ret(const struct ins *ins);
57 bool ins__is_lock(const struct ins *ins);
58 int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops);
59 bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2);
60
61 struct annotation;
62
63 struct sym_hist_entry {
64         u64             nr_samples;
65         u64             period;
66 };
67
68 struct annotation_data {
69         double                   percent;
70         double                   percent_sum;
71         struct sym_hist_entry    he;
72 };
73
74 struct annotation_line {
75         struct list_head         node;
76         struct rb_node           rb_node;
77         s64                      offset;
78         char                    *line;
79         int                      line_nr;
80         float                    ipc;
81         u64                      cycles;
82         size_t                   privsize;
83         char                    *path;
84         int                      samples_nr;
85         struct annotation_data   samples[0];
86 };
87
88 struct disasm_line {
89         struct ins               ins;
90         struct ins_operands      ops;
91
92         /* This needs to be at the end. */
93         struct annotation_line   al;
94 };
95
96 static inline struct disasm_line *disasm_line(struct annotation_line *al)
97 {
98         return al ? container_of(al, struct disasm_line, al) : NULL;
99 }
100
101 static inline bool disasm_line__has_offset(const struct disasm_line *dl)
102 {
103         return dl->ops.target.offset_avail;
104 }
105
106 void disasm_line__free(struct disasm_line *dl);
107 struct annotation_line *
108 annotation_line__next(struct annotation_line *pos, struct list_head *head);
109 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
110 size_t disasm__fprintf(struct list_head *head, FILE *fp);
111 void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel);
112
113 struct sym_hist {
114         u64                   nr_samples;
115         u64                   period;
116         struct sym_hist_entry addr[0];
117 };
118
119 struct cyc_hist {
120         u64     start;
121         u64     cycles;
122         u64     cycles_aggr;
123         u32     num;
124         u32     num_aggr;
125         u8      have_start;
126         /* 1 byte padding */
127         u16     reset;
128 };
129
130 /** struct annotated_source - symbols with hits have this attached as in sannotation
131  *
132  * @histogram: Array of addr hit histograms per event being monitored
133  * @lines: If 'print_lines' is specified, per source code line percentages
134  * @source: source parsed from a disassembler like objdump -dS
135  * @cyc_hist: Average cycles per basic block
136  *
137  * lines is allocated, percentages calculated and all sorted by percentage
138  * when the annotation is about to be presented, so the percentages are for
139  * one of the entries in the histogram array, i.e. for the event/counter being
140  * presented. It is deallocated right after symbol__{tui,tty,etc}_annotate
141  * returns.
142  */
143 struct annotated_source {
144         struct list_head   source;
145         int                nr_histograms;
146         size_t             sizeof_sym_hist;
147         struct cyc_hist    *cycles_hist;
148         struct sym_hist    histograms[0];
149 };
150
151 struct annotation {
152         pthread_mutex_t         lock;
153         u64                     max_coverage;
154         struct annotated_source *src;
155 };
156
157 static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx)
158 {
159         return (((void *)&notes->src->histograms) +
160                 (notes->src->sizeof_sym_hist * idx));
161 }
162
163 static inline struct annotation *symbol__annotation(struct symbol *sym)
164 {
165         return (void *)sym - symbol_conf.priv_size;
166 }
167
168 int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample,
169                                  int evidx);
170
171 int addr_map_symbol__account_cycles(struct addr_map_symbol *ams,
172                                     struct addr_map_symbol *start,
173                                     unsigned cycles);
174
175 int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample,
176                                  int evidx, u64 addr);
177
178 int symbol__alloc_hist(struct symbol *sym);
179 void symbol__annotate_zero_histograms(struct symbol *sym);
180
181 int symbol__annotate(struct symbol *sym, struct map *map,
182                      struct perf_evsel *evsel, size_t privsize,
183                      struct arch **parch);
184
185 enum symbol_disassemble_errno {
186         SYMBOL_ANNOTATE_ERRNO__SUCCESS          = 0,
187
188         /*
189          * Choose an arbitrary negative big number not to clash with standard
190          * errno since SUS requires the errno has distinct positive values.
191          * See 'Issue 6' in the link below.
192          *
193          * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
194          */
195         __SYMBOL_ANNOTATE_ERRNO__START          = -10000,
196
197         SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX       = __SYMBOL_ANNOTATE_ERRNO__START,
198
199         __SYMBOL_ANNOTATE_ERRNO__END,
200 };
201
202 int symbol__strerror_disassemble(struct symbol *sym, struct map *map,
203                                  int errnum, char *buf, size_t buflen);
204
205 int symbol__annotate_printf(struct symbol *sym, struct map *map,
206                             struct perf_evsel *evsel, bool full_paths,
207                             int min_pcnt, int max_lines, int context);
208 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
209 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
210 void annotated_source__purge(struct annotated_source *as);
211
212 bool ui__has_annotation(void);
213
214 int symbol__tty_annotate(struct symbol *sym, struct map *map,
215                          struct perf_evsel *evsel, bool print_lines,
216                          bool full_paths, int min_pcnt, int max_lines);
217
218 #ifdef HAVE_SLANG_SUPPORT
219 int symbol__tui_annotate(struct symbol *sym, struct map *map,
220                          struct perf_evsel *evsel,
221                          struct hist_browser_timer *hbt);
222 #else
223 static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
224                                 struct map *map __maybe_unused,
225                                 struct perf_evsel *evsel  __maybe_unused,
226                                 struct hist_browser_timer *hbt
227                                 __maybe_unused)
228 {
229         return 0;
230 }
231 #endif
232
233 extern const char       *disassembler_style;
234
235 #endif  /* __PERF_ANNOTATE_H */