brintos

brintos / linux-shallow public Read only

0
0
Text · 7.6 KiB · 8ac0fd9 Raw
294 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _PERF_ANNOTATE_DATA_H3#define _PERF_ANNOTATE_DATA_H4 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_SUPPORT13#include "debuginfo.h"14#endif15 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 field43 * @node: List entry in the parent list44 * @children: List head for child nodes45 * @type_name: Name of the member type46 * @var_name: Name of the member variable47 * @offset: Offset from the outer data type48 * @size: Size of the member field49 *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 offset63 * @nr_samples: Number of samples64 * @period: Count of event65 */66struct type_hist_entry {67	int nr_samples;68	u64 period;69};70 71/**72 * struct type_hist - Type histogram for each event73 * @nr_samples: Total number of samples in this data type74 * @period: Total count of the event in this data type75 * @offset: Array of histogram entry76 */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 profile85 * @node: RB-tree node for dso->type_tree86 * @self: Actual type information87 * @nr_histogram: Number of histogram entries88 * @histograms: An array of pointers to histograms89 *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 information105 * @arch: CPU architecture info106 * @thread: Thread info107 * @ms: Map and Symbol info108 * @ip: Instruction address109 * @var_addr: Data address (for global variables)110 * @cpumode: CPU execution mode111 * @op: Instruction operand location (regs and offset)112 * @di: Debug info113 * @fbreg: Frame base register114 * @fb_cfa: Whether the frame needs to check CFA115 * @type_offset: Final offset in the type116 */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 statistics138 * @total: Total number of entry139 * @no_sym: No symbol or map found140 * @no_insn: Failed to get disasm line141 * @no_insn_ops: The instruction has no operands142 * @no_mem_ops: The instruction has no memory operands143 * @no_reg: Failed to extract a register from the operand144 * @no_dbginfo: The binary has no debug information145 * @no_cuinfo: Failed to find a compile_unit146 * @no_var: Failed to find a matching variable147 * @no_typeinfo: Failed to get a type info for the variable148 * @invalid_size: Failed to get a size info of the type149 * @bad_offset: The access offset is out of the type150 */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_DWARF_SUPPORT169/*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  32195#else196#define TYPE_STATE_MAX_REGS  16197#endif198 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 moved202 * to a new location (register or stack).  As it'd be used with the203 * 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_DWARF_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 int256annotated_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_DWARF_SUPPORT */280 281#ifdef HAVE_SLANG_SUPPORT282int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,283				  struct hist_browser_timer *hbt);284#else285static 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