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