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