xref: /linux/tools/perf/util/symbol.h (revision 044462f6f64d16e9f51a695719a3248e277c1d4e)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __PERF_SYMBOL
3 #define __PERF_SYMBOL 1
4 
5 #include <linux/types.h>
6 #include <linux/refcount.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <stdatomic.h>
10 #include <linux/list.h>
11 #include <linux/rbtree.h>
12 #include <stdio.h>
13 #include <errno.h>
14 #include "addr_location.h"
15 #include "path.h"
16 #include "symbol_conf.h"
17 #include "spark.h"
18 #include "util.h"
19 
20 #ifdef HAVE_LIBELF_SUPPORT
21 #include <libelf.h>
22 #include <gelf.h>
23 #endif
24 #include <elf.h>
25 
26 struct dso;
27 struct map;
28 struct maps;
29 struct option;
30 struct build_id;
31 struct perf_env;
32 
33 /*
34  * Ignore kernel mapping symbols, matching kernel is_mapping_symbol() logic.
35  * This checks for '$' prefix (used by ARM, AArch64, RISC-V) and
36  * x86 local symbol prefixes (.L* and L0*).
37  * Only use this for kernel symbols (kallsyms, ksymbol events, kernel ELF DSOs).
38  */
39 static inline bool is_ignored_kernel_symbol(const char *str)
40 {
41 	if (str[0] == '.' && str[1] == 'L')
42 		return true;
43 	if (str[0] == 'L' && str[1] == '0')
44 		return true;
45 	return str[0] == '$';
46 }
47 
48 /*
49  * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
50  * for newer versions we can use mmap to reduce memory usage:
51  */
52 #ifdef ELF_C_READ_MMAP
53 # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
54 #else
55 # define PERF_ELF_C_READ_MMAP ELF_C_READ
56 #endif
57 
58 #ifdef HAVE_LIBELF_SUPPORT
59 Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
60 			     GElf_Shdr *shp, const char *name, size_t *idx);
61 #endif
62 
63 enum symbol_idle_kind {
64 	SYMBOL_IDLE__UNKNOWN = 0,
65 	SYMBOL_IDLE__NOT_IDLE = 1,
66 	SYMBOL_IDLE__IDLE = 2,
67 };
68 
69 #define SYMBOL_FLAG_TYPE_SHIFT      0
70 #define SYMBOL_FLAG_TYPE_MASK       (0xF << SYMBOL_FLAG_TYPE_SHIFT)
71 #define SYMBOL_FLAG_BINDING_SHIFT   4
72 #define SYMBOL_FLAG_BINDING_MASK    (0xF << SYMBOL_FLAG_BINDING_SHIFT)
73 #define SYMBOL_FLAG_IDLE_SHIFT      8
74 #define SYMBOL_FLAG_IDLE_MASK       (0x3 << SYMBOL_FLAG_IDLE_SHIFT)
75 #define SYMBOL_FLAG_IGNORE          (1 << 10)
76 #define SYMBOL_FLAG_INLINED         (1 << 11)
77 #define SYMBOL_FLAG_ANNOTATE2       (1 << 12)
78 #define SYMBOL_FLAG_IFUNC_ALIAS     (1 << 13)
79 /**
80  * A symtab entry. When allocated this may be preceded by an annotation (see
81  * symbol__annotation) and/or a browser_index (see symbol__browser_index).
82  */
83 struct symbol {
84 	struct rb_node	rb_node;
85 	/** Range of symbol [start, end). */
86 	u64		start;
87 	u64		end;
88 	/** Length of the string name. */
89 	u16		namelen;
90 	_Atomic uint16_t flags;
91 	/** Architecture specific. Unused except on PPC where it holds st_other. */
92 	u8		arch_sym;
93 	/** The name of length namelen associated with the symbol. */
94 	char		name[];
95 };
96 
97 void symbol__delete(struct symbol *sym);
98 void symbols__delete(struct rb_root_cached *symbols);
99 
100 static inline u8 symbol__type(const struct symbol *sym)
101 {
102 	return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
103 		SYMBOL_FLAG_TYPE_MASK) >> SYMBOL_FLAG_TYPE_SHIFT;
104 }
105 
106 static inline u8 symbol__binding(const struct symbol *sym)
107 {
108 	return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
109 		SYMBOL_FLAG_BINDING_MASK) >> SYMBOL_FLAG_BINDING_SHIFT;
110 }
111 
112 static inline bool symbol__ignore(const struct symbol *sym)
113 {
114 	return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
115 		SYMBOL_FLAG_IGNORE) != 0;
116 }
117 
118 static inline bool symbol__inlined(const struct symbol *sym)
119 {
120 	return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
121 		SYMBOL_FLAG_INLINED) != 0;
122 }
123 
124 static inline bool symbol__is_annotate2(const struct symbol *sym)
125 {
126 	return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
127 		SYMBOL_FLAG_ANNOTATE2) != 0;
128 }
129 
130 static inline bool symbol__ifunc_alias(const struct symbol *sym)
131 {
132 	return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
133 		SYMBOL_FLAG_IFUNC_ALIAS) != 0;
134 }
135 
136 bool symbol__is_idle(struct symbol *sym, const struct dso *dso, struct perf_env *env);
137 
138 void symbol__set_ignore(struct symbol *sym, bool ignore);
139 void symbol__set_annotate2(struct symbol *sym, bool annotate2);
140 void symbol__set_inlined(struct symbol *sym, bool inlined);
141 void symbol__set_ifunc_alias(struct symbol *sym, bool ifunc_alias);
142 
143 /* symbols__for_each_entry - iterate over symbols (rb_root)
144  *
145  * @symbols: the rb_root of symbols
146  * @pos: the 'struct symbol *' to use as a loop cursor
147  * @nd: the 'struct rb_node *' to use as a temporary storage
148  */
149 #define symbols__for_each_entry(symbols, pos, nd)			\
150 	for (nd = rb_first_cached(symbols);					\
151 	     nd && (pos = rb_entry(nd, struct symbol, rb_node));	\
152 	     nd = rb_next(nd))
153 
154 static inline size_t symbol__size(const struct symbol *sym)
155 {
156 	return sym->end - sym->start;
157 }
158 
159 struct strlist;
160 struct intlist;
161 
162 static inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
163 {
164 	if (symbol_conf.symfs_layout_flat)
165 		return path__join(bf, size, symbol_conf.symfs, perf_basename(path));
166 
167 	return path__join(bf, size, symbol_conf.symfs, path);
168 }
169 
170 #define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), path)
171 
172 extern int vmlinux_path__nr_entries;
173 extern char **vmlinux_path;
174 
175 static inline void *symbol__priv(struct symbol *sym)
176 {
177 	return ((void *)sym) - symbol_conf.priv_size;
178 }
179 
180 struct ref_reloc_sym {
181 	const char	*name;
182 	u64		addr;
183 	u64		unrelocated_addr;
184 };
185 
186 int dso__load(struct dso *dso, struct map *map);
187 int dso__load_vmlinux(struct dso *dso, struct map *map,
188 		      const char *vmlinux, bool vmlinux_allocated);
189 int dso__load_vmlinux_path(struct dso *dso, struct map *map);
190 int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
191 			 bool no_kcore);
192 int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map);
193 
194 void dso__insert_symbol(struct dso *dso,
195 			struct symbol *sym);
196 void dso__delete_symbol(struct dso *dso,
197 			struct symbol *sym);
198 
199 struct symbol *dso__find_symbol(struct dso *dso, u64 addr);
200 struct symbol *dso__find_symbol_nocache(struct dso *dso, u64 addr);
201 
202 struct symbol *dso__next_symbol_by_name(struct dso *dso, size_t *idx);
203 struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name, size_t *idx);
204 
205 struct symbol *dso__first_symbol(struct dso *dso);
206 struct symbol *dso__last_symbol(struct dso *dso);
207 struct symbol *dso__next_symbol(struct symbol *sym);
208 
209 enum dso_type dso__type_fd(int fd);
210 
211 int filename__read_build_id(const char *filename, struct build_id *id);
212 int sysfs__read_build_id(const char *filename, struct build_id *bid);
213 int modules__parse(const char *filename, void *arg,
214 		   int (*process_module)(void *arg, const char *name,
215 					 u64 start, u64 size));
216 int filename__read_debuglink(const char *filename, char *debuglink,
217 			     size_t size);
218 bool filename__has_section(const char *filename, const char *sec);
219 
220 int symbol__init(struct perf_env *env);
221 void symbol__exit(void);
222 void symbol__elf_init(void);
223 int symbol__annotation_init(void);
224 
225 struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name);
226 size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
227 				      const struct addr_location *al,
228 				      bool unknown_as_addr,
229 				      bool print_offsets, FILE *fp);
230 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
231 				    const struct addr_location *al, FILE *fp);
232 size_t __symbol__fprintf_symname(const struct symbol *sym,
233 				 const struct addr_location *al,
234 				 bool unknown_as_addr, FILE *fp);
235 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
236 size_t symbol__fprintf(struct symbol *sym, FILE *fp);
237 bool symbol__restricted_filename(const char *filename,
238 				 const char *restricted_filename);
239 
240 #define SYMFS_HELP "setup root directory which contains debug files:\n" \
241 	"\t\t\t\t" "directory:\tLook for files with symbols relative to this directory.\n" \
242 	"\t\t\t\t" "layout:   \tLayout of files, 'hierarchy' matches full path (default), 'flat' only matches base name.\n"
243 
244 int symbol__config_symfs(const struct option *opt __maybe_unused,
245 			 const char *dir, int unset __maybe_unused);
246 
247 struct symsrc;
248 
249 #ifdef HAVE_LIBBFD_SUPPORT
250 int dso__load_bfd_symbols(struct dso *dso, const char *debugfile);
251 #endif
252 
253 int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
254 		  struct symsrc *runtime_ss, int kmodule);
255 int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss);
256 
257 char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name);
258 
259 void __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym);
260 void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym);
261 void symbols__fixup_duplicate(struct rb_root_cached *symbols);
262 void symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms);
263 
264 typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
265 int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
266 		    bool *is_64_bit);
267 
268 #define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX"
269 
270 struct kcore_extract {
271 	char *kcore_filename;
272 	u64 addr;
273 	u64 offs;
274 	u64 len;
275 	char extract_filename[sizeof(PERF_KCORE_EXTRACT)];
276 	int fd;
277 };
278 
279 int kcore_extract__create(struct kcore_extract *kce);
280 void kcore_extract__delete(struct kcore_extract *kce);
281 
282 int kcore_copy(const char *from_dir, const char *to_dir);
283 int compare_proc_modules(const char *from, const char *to);
284 
285 int setup_list(struct strlist **list, const char *list_str,
286 	       const char *list_name);
287 int setup_intlist(struct intlist **list, const char *list_str,
288 		  const char *list_name);
289 
290 #ifdef HAVE_LIBELF_SUPPORT
291 void arch__sym_update(struct symbol *s, GElf_Sym *sym);
292 #endif
293 
294 const char *arch__normalize_symbol_name(const char *name);
295 #define SYMBOL_A 0
296 #define SYMBOL_B 1
297 
298 int arch__compare_symbol_names(const char *namea, const char *nameb);
299 int arch__compare_symbol_names_n(const char *namea, const char *nameb,
300 				 unsigned int n);
301 int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb);
302 
303 enum symbol_tag_include {
304 	SYMBOL_TAG_INCLUDE__NONE = 0,
305 	SYMBOL_TAG_INCLUDE__DEFAULT_ONLY
306 };
307 
308 int symbol__match_symbol_name(const char *namea, const char *nameb,
309 			      enum symbol_tag_include includes);
310 
311 /* structure containing an SDT note's info */
312 struct sdt_note {
313 	char *name;			/* name of the note*/
314 	char *provider;			/* provider name */
315 	char *args;
316 	bool bit32;			/* whether the location is 32 bits? */
317 	union {				/* location, base and semaphore addrs */
318 		Elf64_Addr a64[3];
319 		Elf32_Addr a32[3];
320 	} addr;
321 	struct list_head note_list;	/* SDT notes' list */
322 };
323 
324 int get_sdt_note_list(struct list_head *head, const char *target);
325 int cleanup_sdt_note_list(struct list_head *sdt_notes);
326 int sdt_notes__get_count(struct list_head *start);
327 
328 #define SDT_PROBES_SCN ".probes"
329 #define SDT_BASE_SCN ".stapsdt.base"
330 #define SDT_NOTE_SCN  ".note.stapsdt"
331 #define SDT_NOTE_TYPE 3
332 #define SDT_NOTE_NAME "stapsdt"
333 #define NR_ADDR 3
334 
335 enum {
336 	SDT_NOTE_IDX_LOC = 0,
337 	SDT_NOTE_IDX_BASE,
338 	SDT_NOTE_IDX_REFCTR,
339 };
340 
341 int symbol__validate_sym_arguments(void);
342 
343 #endif /* __PERF_SYMBOL */
344