projects/linux·blob master · refs

322 lines · 8.7 KiB

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
16struct annotated_op_loc;
17struct debuginfo;
18struct evsel;
19struct hist_browser_timer;
20struct hist_entry;
21struct map_symbol;
22struct thread;
23
24#define pr_debug_dtp(fmt, ...) \
25do { \
26 if (debug_type_profile) \
27 pr_info(fmt, ##__VA_ARGS__); \
28 else \
29 pr_debug3(fmt, ##__VA_ARGS__); \
30} while (0)
31
32enum 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 */
53struct 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 */
67struct 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 */
78struct 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 */
93struct annotated_data_type {
94 struct rb_node node;
95 struct annotated_member self;
96 int nr_histograms;
97 struct type_hist **histograms;
98};
99
100extern struct annotated_data_type unknown_type;
101extern struct annotated_data_type stackop_type;
102extern 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 */
118struct data_loc_info {
119 /* These are input field, should be filled by caller */
120 const 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 */
152struct 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};
167extern 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 */
174struct 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 /* DWARF location range tracking for register lifetime */
186 bool lifetime_active;
187 u64 lifetime_end;
188 u8 kind;
189 u8 copied_from;
190};
191
192/* Type information in a stack location, dynamically allocated */
193struct type_state_stack {
194 struct list_head list;
195 Dwarf_Die type;
196 int offset;
197 /* pointer offset, saves tsr->offset on the stack state */
198 int ptr_offset;
199 int size;
200 bool compound;
201 u8 kind;
202};
203
204/*
205 * Maximum number of registers tracked in type_state.
206 *
207 * This limit must cover all supported architectures, since perf
208 * may analyze perf.data files generated on systems with a different
209 * register set. Use 32 as a safe upper bound instead of relying on
210 * build-arch specific values.
211 */
212#define TYPE_STATE_MAX_REGS 32
213
214/*
215 * State table to maintain type info in each register and stack location.
216 * It'll be updated when new variable is allocated or type info is moved
217 * to a new location (register or stack). As it'd be used with the
218 * shortest path of basic blocks, it only maintains a single table.
219 */
220struct type_state {
221 /* state of general purpose registers */
222 struct type_state_reg regs[TYPE_STATE_MAX_REGS];
223 /* state of stack location */
224 struct list_head stack_vars;
225 /* return value register */
226 int ret_reg;
227 /* stack pointer register */
228 int stack_reg;
229};
230
231/* Returns data type at the location (ip, reg, offset) */
232struct annotated_data_type *find_data_type(struct data_loc_info *dloc);
233
234/* Update type access histogram at the given offset */
235int annotated_data_type__update_samples(struct annotated_data_type *adt,
236 struct evsel *evsel, int offset,
237 int nr_samples, u64 period);
238
239/* Release all data type information in the tree */
240void annotated_data_type__tree_delete(struct rb_root *root);
241
242/* Release all global variable information in the tree */
243void global_var_type__tree_delete(struct rb_root *root);
244
245/* Print data type annotation (including members) on stdout */
246int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evsel);
247
248/* Get name of member field at the given offset in the data type */
249int annotated_data_type__get_member_name(struct annotated_data_type *adt,
250 char *buf, size_t sz, int member_offset);
251
252bool has_reg_type(struct type_state *state, int reg);
253struct type_state_stack *findnew_stack_state(struct type_state *state,
254 int offset, u8 kind,
255 Dwarf_Die *type_die,
256 int ptr_offset);
257void set_stack_state(struct type_state_stack *stack, int offset, u8 kind,
258 Dwarf_Die *type_die, int ptr_offset);
259struct type_state_stack *find_stack_state(struct type_state *state,
260 int offset);
261bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
262 u64 ip, u64 var_addr, int *var_offset,
263 Dwarf_Die *type_die);
264bool get_global_var_info(struct data_loc_info *dloc, u64 addr,
265 const char **var_name, int *var_offset);
266void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind);
267
268#else /* HAVE_LIBDW_SUPPORT */
269
270static inline struct annotated_data_type *
271find_data_type(struct data_loc_info *dloc __maybe_unused)
272{
273 return NULL;
274}
275
276static inline int
277annotated_data_type__update_samples(struct annotated_data_type *adt __maybe_unused,
278 struct evsel *evsel __maybe_unused,
279 int offset __maybe_unused,
280 int nr_samples __maybe_unused,
281 u64 period __maybe_unused)
282{
283 return -1;
284}
285
286static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe_unused)
287{
288}
289
290static inline void global_var_type__tree_delete(struct rb_root *root __maybe_unused)
291{
292}
293
294static inline int hist_entry__annotate_data_tty(struct hist_entry *he __maybe_unused,
295 struct evsel *evsel __maybe_unused)
296{
297 return -1;
298}
299
300static inline int annotated_data_type__get_member_name(struct annotated_data_type *adt __maybe_unused,
301 char *buf __maybe_unused,
302 size_t sz __maybe_unused,
303 int member_offset __maybe_unused)
304{
305 return -1;
306}
307
308#endif /* HAVE_LIBDW_SUPPORT */
309
310#ifdef HAVE_SLANG_SUPPORT
311int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,
312 struct hist_browser_timer *hbt);
313#else
314static inline int hist_entry__annotate_data_tui(struct hist_entry *he __maybe_unused,
315 struct evsel *evsel __maybe_unused,
316 struct hist_browser_timer *hbt __maybe_unused)
317{
318 return -1;
319}
320#endif /* HAVE_SLANG_SUPPORT */
321
322#endif /* _PERF_ANNOTATE_DATA_H */