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_DWARF_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_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_DWARF_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  /* FIXME: This should be arch-dependent */
193  #ifdef __powerpc__
194  #define TYPE_STATE_MAX_REGS  32
195  #else
196  #define TYPE_STATE_MAX_REGS  16
197  #endif
198  
199  /*
200   * State table to maintain type info in each register and stack location.
201   * It'll be updated when new variable is allocated or type info is moved
202   * to a new location (register or stack).  As it'd be used with the
203   * shortest path of basic blocks, it only maintains a single table.
204   */
205  struct type_state {
206  	/* state of general purpose registers */
207  	struct type_state_reg regs[TYPE_STATE_MAX_REGS];
208  	/* state of stack location */
209  	struct list_head stack_vars;
210  	/* return value register */
211  	int ret_reg;
212  	/* stack pointer register */
213  	int stack_reg;
214  };
215  
216  /* Returns data type at the location (ip, reg, offset) */
217  struct annotated_data_type *find_data_type(struct data_loc_info *dloc);
218  
219  /* Update type access histogram at the given offset */
220  int annotated_data_type__update_samples(struct annotated_data_type *adt,
221  					struct evsel *evsel, int offset,
222  					int nr_samples, u64 period);
223  
224  /* Release all data type information in the tree */
225  void annotated_data_type__tree_delete(struct rb_root *root);
226  
227  /* Release all global variable information in the tree */
228  void global_var_type__tree_delete(struct rb_root *root);
229  
230  int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evsel);
231  
232  bool has_reg_type(struct type_state *state, int reg);
233  struct type_state_stack *findnew_stack_state(struct type_state *state,
234  						int offset, u8 kind,
235  						Dwarf_Die *type_die);
236  void set_stack_state(struct type_state_stack *stack, int offset, u8 kind,
237  				Dwarf_Die *type_die);
238  struct type_state_stack *find_stack_state(struct type_state *state,
239  						int offset);
240  bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
241  				u64 ip, u64 var_addr, int *var_offset,
242  				Dwarf_Die *type_die);
243  bool get_global_var_info(struct data_loc_info *dloc, u64 addr,
244  				const char **var_name, int *var_offset);
245  void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind);
246  
247  #else /* HAVE_DWARF_SUPPORT */
248  
249  static inline struct annotated_data_type *
find_data_type(struct data_loc_info * dloc __maybe_unused)250  find_data_type(struct data_loc_info *dloc __maybe_unused)
251  {
252  	return NULL;
253  }
254  
255  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)256  annotated_data_type__update_samples(struct annotated_data_type *adt __maybe_unused,
257  				    struct evsel *evsel __maybe_unused,
258  				    int offset __maybe_unused,
259  				    int nr_samples __maybe_unused,
260  				    u64 period __maybe_unused)
261  {
262  	return -1;
263  }
264  
annotated_data_type__tree_delete(struct rb_root * root __maybe_unused)265  static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe_unused)
266  {
267  }
268  
global_var_type__tree_delete(struct rb_root * root __maybe_unused)269  static inline void global_var_type__tree_delete(struct rb_root *root __maybe_unused)
270  {
271  }
272  
hist_entry__annotate_data_tty(struct hist_entry * he __maybe_unused,struct evsel * evsel __maybe_unused)273  static inline int hist_entry__annotate_data_tty(struct hist_entry *he __maybe_unused,
274  						struct evsel *evsel __maybe_unused)
275  {
276  	return -1;
277  }
278  
279  #endif /* HAVE_DWARF_SUPPORT */
280  
281  #ifdef HAVE_SLANG_SUPPORT
282  int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,
283  				  struct hist_browser_timer *hbt);
284  #else
hist_entry__annotate_data_tui(struct hist_entry * he __maybe_unused,struct evsel * evsel __maybe_unused,struct hist_browser_timer * hbt __maybe_unused)285  static inline int hist_entry__annotate_data_tui(struct hist_entry *he __maybe_unused,
286  						struct evsel *evsel __maybe_unused,
287  						struct hist_browser_timer *hbt __maybe_unused)
288  {
289  	return -1;
290  }
291  #endif /* HAVE_SLANG_SUPPORT */
292  
293  #endif /* _PERF_ANNOTATE_DATA_H */
294