1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _PERF_ANNOTATE_DATA_H
3 #define _PERF_ANNOTATE_DATA_H
4
5 #include <errno.h>
6 #include <linux/compiler.h>
7 #include <linux/rbtree.h>
8 #include <linux/types.h>
9 #include "dwarf-regs.h"
10 #include "annotate.h"
11
12 #ifdef HAVE_LIBDW_SUPPORT
13 #include "debuginfo.h"
14 #endif
15
16 struct annotated_op_loc;
17 struct debuginfo;
18 struct evsel;
19 struct hist_browser_timer;
20 struct hist_entry;
21 struct map_symbol;
22 struct thread;
23
24 #define pr_debug_dtp(fmt, ...) \
25 do { \
26 if (debug_type_profile) \
27 pr_info(fmt, ##__VA_ARGS__); \
28 else \
29 pr_debug3(fmt, ##__VA_ARGS__); \
30 } while (0)
31
32 enum type_state_kind {
33 TSR_KIND_INVALID = 0,
34 TSR_KIND_TYPE,
35 TSR_KIND_PERCPU_BASE,
36 TSR_KIND_CONST,
37 TSR_KIND_PERCPU_POINTER,
38 TSR_KIND_CANARY,
39 };
40
41 /**
42 * struct annotated_member - Type of member field
43 * @node: List entry in the parent list
44 * @children: List head for child nodes
45 * @type_name: Name of the member type
46 * @var_name: Name of the member variable
47 * @offset: Offset from the outer data type
48 * @size: Size of the member field
49 *
50 * This represents a member type in a data type.
51 */
52 struct annotated_member {
53 struct list_head node;
54 struct list_head children;
55 char *type_name;
56 char *var_name;
57 int offset;
58 int size;
59 };
60
61 /**
62 * struct type_hist_entry - Histogram entry per offset
63 * @nr_samples: Number of samples
64 * @period: Count of event
65 */
66 struct type_hist_entry {
67 int nr_samples;
68 u64 period;
69 };
70
71 /**
72 * struct type_hist - Type histogram for each event
73 * @nr_samples: Total number of samples in this data type
74 * @period: Total count of the event in this data type
75 * @offset: Array of histogram entry
76 */
77 struct type_hist {
78 u64 nr_samples;
79 u64 period;
80 struct type_hist_entry addr[];
81 };
82
83 /**
84 * struct annotated_data_type - Data type to profile
85 * @node: RB-tree node for dso->type_tree
86 * @self: Actual type information
87 * @nr_histogram: Number of histogram entries
88 * @histograms: An array of pointers to histograms
89 *
90 * This represents a data type accessed by samples in the profile data.
91 */
92 struct annotated_data_type {
93 struct rb_node node;
94 struct annotated_member self;
95 int nr_histograms;
96 struct type_hist **histograms;
97 };
98
99 extern struct annotated_data_type unknown_type;
100 extern struct annotated_data_type stackop_type;
101 extern struct annotated_data_type canary_type;
102
103 /**
104 * struct data_loc_info - Data location information
105 * @arch: CPU architecture info
106 * @thread: Thread info
107 * @ms: Map and Symbol info
108 * @ip: Instruction address
109 * @var_addr: Data address (for global variables)
110 * @cpumode: CPU execution mode
111 * @op: Instruction operand location (regs and offset)
112 * @di: Debug info
113 * @fbreg: Frame base register
114 * @fb_cfa: Whether the frame needs to check CFA
115 * @type_offset: Final offset in the type
116 */
117 struct data_loc_info {
118 /* These are input field, should be filled by caller */
119 struct arch *arch;
120 struct thread *thread;
121 struct map_symbol *ms;
122 u64 ip;
123 u64 var_addr;
124 u8 cpumode;
125 struct annotated_op_loc *op;
126 struct debuginfo *di;
127
128 /* These are used internally */
129 int fbreg;
130 bool fb_cfa;
131
132 /* This is for the result */
133 int type_offset;
134 };
135
136 /**
137 * struct annotated_data_stat - Debug statistics
138 * @total: Total number of entry
139 * @no_sym: No symbol or map found
140 * @no_insn: Failed to get disasm line
141 * @no_insn_ops: The instruction has no operands
142 * @no_mem_ops: The instruction has no memory operands
143 * @no_reg: Failed to extract a register from the operand
144 * @no_dbginfo: The binary has no debug information
145 * @no_cuinfo: Failed to find a compile_unit
146 * @no_var: Failed to find a matching variable
147 * @no_typeinfo: Failed to get a type info for the variable
148 * @invalid_size: Failed to get a size info of the type
149 * @bad_offset: The access offset is out of the type
150 */
151 struct annotated_data_stat {
152 int total;
153 int no_sym;
154 int no_insn;
155 int no_insn_ops;
156 int no_mem_ops;
157 int no_reg;
158 int no_dbginfo;
159 int no_cuinfo;
160 int no_var;
161 int no_typeinfo;
162 int invalid_size;
163 int bad_offset;
164 int insn_track;
165 };
166 extern struct annotated_data_stat ann_data_stat;
167
168 #ifdef HAVE_LIBDW_SUPPORT
169 /*
170 * Type information in a register, valid when @ok is true.
171 * The @caller_saved registers are invalidated after a function call.
172 */
173 struct type_state_reg {
174 Dwarf_Die type;
175 u32 imm_value;
176 bool ok;
177 bool caller_saved;
178 u8 kind;
179 u8 copied_from;
180 };
181
182 /* Type information in a stack location, dynamically allocated */
183 struct type_state_stack {
184 struct list_head list;
185 Dwarf_Die type;
186 int offset;
187 int size;
188 bool compound;
189 u8 kind;
190 };
191
192 /*
193 * Maximum number of registers tracked in type_state.
194 *
195 * This limit must cover all supported architectures, since perf
196 * may analyze perf.data files generated on systems with a different
197 * register set. Use 32 as a safe upper bound instead of relying on
198 * build-arch specific values.
199 */
200 #define TYPE_STATE_MAX_REGS 32
201
202 /*
203 * State table to maintain type info in each register and stack location.
204 * It'll be updated when new variable is allocated or type info is moved
205 * to a new location (register or stack). As it'd be used with the
206 * shortest path of basic blocks, it only maintains a single table.
207 */
208 struct type_state {
209 /* state of general purpose registers */
210 struct type_state_reg regs[TYPE_STATE_MAX_REGS];
211 /* state of stack location */
212 struct list_head stack_vars;
213 /* return value register */
214 int ret_reg;
215 /* stack pointer register */
216 int stack_reg;
217 };
218
219 /* Returns data type at the location (ip, reg, offset) */
220 struct annotated_data_type *find_data_type(struct data_loc_info *dloc);
221
222 /* Update type access histogram at the given offset */
223 int annotated_data_type__update_samples(struct annotated_data_type *adt,
224 struct evsel *evsel, int offset,
225 int nr_samples, u64 period);
226
227 /* Release all data type information in the tree */
228 void annotated_data_type__tree_delete(struct rb_root *root);
229
230 /* Release all global variable information in the tree */
231 void global_var_type__tree_delete(struct rb_root *root);
232
233 /* Print data type annotation (including members) on stdout */
234 int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evsel);
235
236 /* Get name of member field at the given offset in the data type */
237 int annotated_data_type__get_member_name(struct annotated_data_type *adt,
238 char *buf, size_t sz, int member_offset);
239
240 bool has_reg_type(struct type_state *state, int reg);
241 struct type_state_stack *findnew_stack_state(struct type_state *state,
242 int offset, u8 kind,
243 Dwarf_Die *type_die);
244 void set_stack_state(struct type_state_stack *stack, int offset, u8 kind,
245 Dwarf_Die *type_die);
246 struct type_state_stack *find_stack_state(struct type_state *state,
247 int offset);
248 bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
249 u64 ip, u64 var_addr, int *var_offset,
250 Dwarf_Die *type_die);
251 bool get_global_var_info(struct data_loc_info *dloc, u64 addr,
252 const char **var_name, int *var_offset);
253 void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind);
254
255 #else /* HAVE_LIBDW_SUPPORT */
256
257 static inline struct annotated_data_type *
find_data_type(struct data_loc_info * dloc __maybe_unused)258 find_data_type(struct data_loc_info *dloc __maybe_unused)
259 {
260 return NULL;
261 }
262
263 static inline int
annotated_data_type__update_samples(struct annotated_data_type * adt __maybe_unused,struct evsel * evsel __maybe_unused,int offset __maybe_unused,int nr_samples __maybe_unused,u64 period __maybe_unused)264 annotated_data_type__update_samples(struct annotated_data_type *adt __maybe_unused,
265 struct evsel *evsel __maybe_unused,
266 int offset __maybe_unused,
267 int nr_samples __maybe_unused,
268 u64 period __maybe_unused)
269 {
270 return -1;
271 }
272
annotated_data_type__tree_delete(struct rb_root * root __maybe_unused)273 static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe_unused)
274 {
275 }
276
global_var_type__tree_delete(struct rb_root * root __maybe_unused)277 static inline void global_var_type__tree_delete(struct rb_root *root __maybe_unused)
278 {
279 }
280
hist_entry__annotate_data_tty(struct hist_entry * he __maybe_unused,struct evsel * evsel __maybe_unused)281 static inline int hist_entry__annotate_data_tty(struct hist_entry *he __maybe_unused,
282 struct evsel *evsel __maybe_unused)
283 {
284 return -1;
285 }
286
annotated_data_type__get_member_name(struct annotated_data_type * adt __maybe_unused,char * buf __maybe_unused,size_t sz __maybe_unused,int member_offset __maybe_unused)287 static inline int annotated_data_type__get_member_name(struct annotated_data_type *adt __maybe_unused,
288 char *buf __maybe_unused,
289 size_t sz __maybe_unused,
290 int member_offset __maybe_unused)
291 {
292 return -1;
293 }
294
295 #endif /* HAVE_LIBDW_SUPPORT */
296
297 #ifdef HAVE_SLANG_SUPPORT
298 int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,
299 struct hist_browser_timer *hbt);
300 #else
hist_entry__annotate_data_tui(struct hist_entry * he __maybe_unused,struct evsel * evsel __maybe_unused,struct hist_browser_timer * hbt __maybe_unused)301 static inline int hist_entry__annotate_data_tui(struct hist_entry *he __maybe_unused,
302 struct evsel *evsel __maybe_unused,
303 struct hist_browser_timer *hbt __maybe_unused)
304 {
305 return -1;
306 }
307 #endif /* HAVE_SLANG_SUPPORT */
308
309 #endif /* _PERF_ANNOTATE_DATA_H */
310