Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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_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 */
 52struct 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 */
 66struct 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 */
 77struct 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 */
 92struct annotated_data_type {
 93	struct rb_node node;
 94	struct annotated_member self;
 95	int nr_histograms;
 96	struct type_hist **histograms;
 97};
 98
 99extern struct annotated_data_type unknown_type;
100extern struct annotated_data_type stackop_type;
101extern 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 */
117struct 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 */
151struct 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};
166extern 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 */
173struct 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 */
183struct 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 */
205struct 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) */
217struct annotated_data_type *find_data_type(struct data_loc_info *dloc);
218
219/* Update type access histogram at the given offset */
220int 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 */
225void annotated_data_type__tree_delete(struct rb_root *root);
226
227/* Release all global variable information in the tree */
228void global_var_type__tree_delete(struct rb_root *root);
229
230int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evsel);
231
232bool has_reg_type(struct type_state *state, int reg);
233struct type_state_stack *findnew_stack_state(struct type_state *state,
234						int offset, u8 kind,
235						Dwarf_Die *type_die);
236void set_stack_state(struct type_state_stack *stack, int offset, u8 kind,
237				Dwarf_Die *type_die);
238struct type_state_stack *find_stack_state(struct type_state *state,
239						int offset);
240bool 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);
243bool get_global_var_info(struct data_loc_info *dloc, u64 addr,
244				const char **var_name, int *var_offset);
245void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind);
246
247#else /* HAVE_LIBDW_SUPPORT */
248
249static inline struct annotated_data_type *
250find_data_type(struct data_loc_info *dloc __maybe_unused)
251{
252	return NULL;
253}
254
255static inline int
256annotated_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
265static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe_unused)
266{
267}
268
269static inline void global_var_type__tree_delete(struct rb_root *root __maybe_unused)
270{
271}
272
273static 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_LIBDW_SUPPORT */
280
281#ifdef HAVE_SLANG_SUPPORT
282int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,
283				  struct hist_browser_timer *hbt);
284#else
285static 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 */