xref: /openbmc/linux/tools/perf/util/symbol.h (revision b181f7029bd71238ac2754ce7052dffd69432085)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
28b40f521SJohn Kacur #ifndef __PERF_SYMBOL
38b40f521SJohn Kacur #define __PERF_SYMBOL 1
486470930SIngo Molnar 
586470930SIngo Molnar #include <linux/types.h>
6c38fa94dSArnaldo Carvalho de Melo #include <linux/refcount.h>
7e4204992SArnaldo Carvalho de Melo #include <stdbool.h>
85aab621bSArnaldo Carvalho de Melo #include <stdint.h>
95da50258SArnaldo Carvalho de Melo #include <linux/list.h>
1043cbcd8aSArnaldo Carvalho de Melo #include <linux/rbtree.h>
115aab621bSArnaldo Carvalho de Melo #include <stdio.h>
12620be847SIan Rogers #include "addr_location.h"
139a3993d4SArnaldo Carvalho de Melo #include "path.h"
1419ea1b6fSArnaldo Carvalho de Melo #include "symbol_conf.h"
15cebf7d51SJin Yao #include "spark.h"
1686470930SIngo Molnar 
1789fe808aSIngo Molnar #ifdef HAVE_LIBELF_SUPPORT
18b68e2f91SCody P Schafer #include <libelf.h>
19b68e2f91SCody P Schafer #include <gelf.h>
20b68e2f91SCody P Schafer #endif
21eec185abSNamhyung Kim #include <elf.h>
22b68e2f91SCody P Schafer 
23b1d1b094SArnaldo Carvalho de Melo struct dso;
2468c0188eSArnaldo Carvalho de Melo struct map;
2579b6bb73SArnaldo Carvalho de Melo struct maps;
2668c0188eSArnaldo Carvalho de Melo struct option;
27f766819cSJiri Olsa struct build_id;
2868c0188eSArnaldo Carvalho de Melo 
2984087126SMarti Raudsepp /*
3084087126SMarti Raudsepp  * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
3184087126SMarti Raudsepp  * for newer versions we can use mmap to reduce memory usage:
3284087126SMarti Raudsepp  */
3322dd1ac9SAndrii Nakryiko #ifdef ELF_C_READ_MMAP
3484087126SMarti Raudsepp # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
3529a0fc9bSNamhyung Kim #else
3629a0fc9bSNamhyung Kim # define PERF_ELF_C_READ_MMAP ELF_C_READ
3784087126SMarti Raudsepp #endif
3884087126SMarti Raudsepp 
3999ca4233SMasami Hiramatsu #ifdef HAVE_LIBELF_SUPPORT
403938bad4SArnaldo Carvalho de Melo Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
4199ca4233SMasami Hiramatsu 			     GElf_Shdr *shp, const char *name, size_t *idx);
4299ca4233SMasami Hiramatsu #endif
4399ca4233SMasami Hiramatsu 
44bd9acd9cSIan Rogers /**
45bd9acd9cSIan Rogers  * A symtab entry. When allocated this may be preceded by an annotation (see
46*259dce91SIan Rogers  * symbol__annotation) and/or a browser_index (see symbol__browser_index).
47171b3be9SArnaldo Carvalho de Melo  */
4886470930SIngo Molnar struct symbol {
4986470930SIngo Molnar 	struct rb_node	rb_node;
50bd9acd9cSIan Rogers 	/** Range of symbol [start, end). */
519cffa8d5SPaul Mackerras 	u64		start;
529cffa8d5SPaul Mackerras 	u64		end;
53bd9acd9cSIan Rogers 	/** Length of the string name. */
54fefb0b94SArnaldo Carvalho de Melo 	u16		namelen;
55bd9acd9cSIan Rogers 	/** ELF symbol type as defined for st_info. E.g STT_OBJECT or STT_FUNC. */
56af30bffaSArnaldo Carvalho de Melo 	u8		type:4;
57bd9acd9cSIan Rogers 	/** ELF binding type as defined for st_info. E.g. STB_WEAK or STB_GLOBAL. */
58af30bffaSArnaldo Carvalho de Melo 	u8		binding:4;
59bd9acd9cSIan Rogers 	/** Set true for kernel symbols of idle routines. */
60b55cc4edSArnaldo Carvalho de Melo 	u8		idle:1;
61bd9acd9cSIan Rogers 	/** Resolvable but tools ignore it (e.g. idle routines). */
62cdeb01bfSNamhyung Kim 	u8		ignore:1;
63bd9acd9cSIan Rogers 	/** Symbol for an inlined function. */
64fea0cf84SMilian Wolff 	u8		inlined:1;
6542704567SIan Rogers 	/** Has symbol__annotate2 been performed. */
6642704567SIan Rogers 	u8		annotate2:1;
6705963491SAdrian Hunter 	/** Symbol is an alias of an STT_GNU_IFUNC */
6805963491SAdrian Hunter 	u8		ifunc_alias:1;
69bd9acd9cSIan Rogers 	/** Architecture specific. Unused except on PPC where it holds st_other. */
700b3c2264SNaveen N. Rao 	u8		arch_sym;
71bd9acd9cSIan Rogers 	/** The name of length namelen associated with the symbol. */
726549a8c0SGustavo A. R. Silva 	char		name[];
7386470930SIngo Molnar };
7486470930SIngo Molnar 
75aeafcbafSArnaldo Carvalho de Melo void symbol__delete(struct symbol *sym);
767137ff50SDavidlohr Bueso void symbols__delete(struct rb_root_cached *symbols);
77628ada0cSArnaldo Carvalho de Melo 
78eb948e50SMasami Hiramatsu /* symbols__for_each_entry - iterate over symbols (rb_root)
79eb948e50SMasami Hiramatsu  *
80eb948e50SMasami Hiramatsu  * @symbols: the rb_root of symbols
81eb948e50SMasami Hiramatsu  * @pos: the 'struct symbol *' to use as a loop cursor
82eb948e50SMasami Hiramatsu  * @nd: the 'struct rb_node *' to use as a temporary storage
83eb948e50SMasami Hiramatsu  */
84eb948e50SMasami Hiramatsu #define symbols__for_each_entry(symbols, pos, nd)			\
857137ff50SDavidlohr Bueso 	for (nd = rb_first_cached(symbols);					\
86eb948e50SMasami Hiramatsu 	     nd && (pos = rb_entry(nd, struct symbol, rb_node));	\
87eb948e50SMasami Hiramatsu 	     nd = rb_next(nd))
88eb948e50SMasami Hiramatsu 
symbol__size(const struct symbol * sym)891b2e2df4SArnaldo Carvalho de Melo static inline size_t symbol__size(const struct symbol *sym)
901b2e2df4SArnaldo Carvalho de Melo {
912c241bd3SArnaldo Carvalho de Melo 	return sym->end - sym->start;
921b2e2df4SArnaldo Carvalho de Melo }
931b2e2df4SArnaldo Carvalho de Melo 
94655000e7SArnaldo Carvalho de Melo struct strlist;
95e03eaa40SDavid Ahern struct intlist;
96655000e7SArnaldo Carvalho de Melo 
__symbol__join_symfs(char * bf,size_t size,const char * path)97972f393bSArnaldo Carvalho de Melo static inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
98972f393bSArnaldo Carvalho de Melo {
99972f393bSArnaldo Carvalho de Melo 	return path__join(bf, size, symbol_conf.symfs, path);
100972f393bSArnaldo Carvalho de Melo }
101972f393bSArnaldo Carvalho de Melo 
102972f393bSArnaldo Carvalho de Melo #define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), path)
103972f393bSArnaldo Carvalho de Melo 
1043f067dcaSArnaldo Carvalho de Melo extern int vmlinux_path__nr_entries;
1053f067dcaSArnaldo Carvalho de Melo extern char **vmlinux_path;
10600a192b3SArnaldo Carvalho de Melo 
symbol__priv(struct symbol * sym)107aeafcbafSArnaldo Carvalho de Melo static inline void *symbol__priv(struct symbol *sym)
10800a192b3SArnaldo Carvalho de Melo {
109aeafcbafSArnaldo Carvalho de Melo 	return ((void *)sym) - symbol_conf.priv_size;
11000a192b3SArnaldo Carvalho de Melo }
11100a192b3SArnaldo Carvalho de Melo 
1129de89fe7SArnaldo Carvalho de Melo struct ref_reloc_sym {
1139de89fe7SArnaldo Carvalho de Melo 	const char	*name;
1149de89fe7SArnaldo Carvalho de Melo 	u64		addr;
1159de89fe7SArnaldo Carvalho de Melo 	u64		unrelocated_addr;
1169de89fe7SArnaldo Carvalho de Melo };
1179de89fe7SArnaldo Carvalho de Melo 
118be39db9fSArnaldo Carvalho de Melo int dso__load(struct dso *dso, struct map *map);
119aeafcbafSArnaldo Carvalho de Melo int dso__load_vmlinux(struct dso *dso, struct map *map,
120be39db9fSArnaldo Carvalho de Melo 		      const char *vmlinux, bool vmlinux_allocated);
121be39db9fSArnaldo Carvalho de Melo int dso__load_vmlinux_path(struct dso *dso, struct map *map);
122e02092b9SArnaldo Carvalho de Melo int __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
123be39db9fSArnaldo Carvalho de Melo 			 bool no_kcore);
124be39db9fSArnaldo Carvalho de Melo int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map);
125b0a9ab62SArnaldo Carvalho de Melo 
1263183f8caSArnaldo Carvalho de Melo void dso__insert_symbol(struct dso *dso,
127ae93a6c7SChris Phlipot 			struct symbol *sym);
128ab8bf5f2STommi Rantala void dso__delete_symbol(struct dso *dso,
129ab8bf5f2STommi Rantala 			struct symbol *sym);
130ae93a6c7SChris Phlipot 
1313183f8caSArnaldo Carvalho de Melo struct symbol *dso__find_symbol(struct dso *dso, u64 addr);
132a2db72c5SAdrian Hunter struct symbol *dso__find_symbol_nocache(struct dso *dso, u64 addr);
133af07eeb0SArnaldo Carvalho de Melo 
134*259dce91SIan Rogers struct symbol *dso__next_symbol_by_name(struct dso *dso, size_t *idx);
135*259dce91SIan Rogers struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name, size_t *idx);
13686470930SIngo Molnar 
1375cf88a63SArnaldo Carvalho de Melo struct symbol *dso__first_symbol(struct dso *dso);
1385cf88a63SArnaldo Carvalho de Melo struct symbol *dso__last_symbol(struct dso *dso);
1399c00a81bSAdrian Hunter struct symbol *dso__next_symbol(struct symbol *sym);
1409c00a81bSAdrian Hunter 
1412b5b8bb2SAdrian Hunter enum dso_type dso__type_fd(int fd);
1422b5b8bb2SAdrian Hunter 
143f766819cSJiri Olsa int filename__read_build_id(const char *filename, struct build_id *id);
1443ff1b8c8SJiri Olsa int sysfs__read_build_id(const char *filename, struct build_id *bid);
145316d70d6SAdrian Hunter int modules__parse(const char *filename, void *arg,
146316d70d6SAdrian Hunter 		   int (*process_module)(void *arg, const char *name,
1479ad4652bSThomas Richter 					 u64 start, u64 size));
148e5a1845fSNamhyung Kim int filename__read_debuglink(const char *filename, char *debuglink,
149e5a1845fSNamhyung Kim 			     size_t size);
15006ea72a4SNamhyung Kim bool filename__has_section(const char *filename, const char *sec);
1512643ce11SArnaldo Carvalho de Melo 
152ce80d3beSKan Liang struct perf_env;
153ce80d3beSKan Liang int symbol__init(struct perf_env *env);
154d65a458bSArnaldo Carvalho de Melo void symbol__exit(void);
155166ccc9cSNamhyung Kim void symbol__elf_init(void);
156b01141f4SArnaldo Carvalho de Melo int symbol__annotation_init(void);
157b01141f4SArnaldo Carvalho de Melo 
158af30bffaSArnaldo Carvalho de Melo struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name);
159fd4be130SArnaldo Carvalho de Melo size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
160fd4be130SArnaldo Carvalho de Melo 				      const struct addr_location *al,
161a8763445SNamhyung Kim 				      bool unknown_as_addr,
162a8763445SNamhyung Kim 				      bool print_offsets, FILE *fp);
163a978f2abSAkihiro Nagai size_t symbol__fprintf_symname_offs(const struct symbol *sym,
164a978f2abSAkihiro Nagai 				    const struct addr_location *al, FILE *fp);
165fd4be130SArnaldo Carvalho de Melo size_t __symbol__fprintf_symname(const struct symbol *sym,
166fd4be130SArnaldo Carvalho de Melo 				 const struct addr_location *al,
167fd4be130SArnaldo Carvalho de Melo 				 bool unknown_as_addr, FILE *fp);
168547a92e0SAkihiro Nagai size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
169cdd059d7SJiri Olsa size_t symbol__fprintf(struct symbol *sym, FILE *fp);
1703f067dcaSArnaldo Carvalho de Melo bool symbol__restricted_filename(const char *filename,
1713f067dcaSArnaldo Carvalho de Melo 				 const char *restricted_filename);
172a7066709SHe Kuang int symbol__config_symfs(const struct option *opt __maybe_unused,
173a7066709SHe Kuang 			 const char *dir, int unset __maybe_unused);
17436a3e646SArnaldo Carvalho de Melo 
175b1d1b094SArnaldo Carvalho de Melo struct symsrc;
176b1d1b094SArnaldo Carvalho de Melo 
177eac9a434SRemi Bernon #ifdef HAVE_LIBBFD_SUPPORT
178eac9a434SRemi Bernon int dso__load_bfd_symbols(struct dso *dso, const char *debugfile);
179eac9a434SRemi Bernon #endif
180eac9a434SRemi Bernon 
181261360b6SCody P Schafer int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
182be39db9fSArnaldo Carvalho de Melo 		  struct symsrc *runtime_ss, int kmodule);
1833183f8caSArnaldo Carvalho de Melo int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss);
184e5a1845fSNamhyung Kim 
18580c345b2SMilian Wolff char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name);
186a64489c5SJin Yao 
1877137ff50SDavidlohr Bueso void __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym,
1887137ff50SDavidlohr Bueso 		       bool kernel);
1897137ff50SDavidlohr Bueso void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym);
1907137ff50SDavidlohr Bueso void symbols__fixup_duplicate(struct rb_root_cached *symbols);
191838425f2SNamhyung Kim void symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms);
192e5a1845fSNamhyung Kim 
1938e0cf965SAdrian Hunter typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
1948e0cf965SAdrian Hunter int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
1958e0cf965SAdrian Hunter 		    bool *is_64_bit);
1968e0cf965SAdrian Hunter 
197afba19d9SAdrian Hunter #define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX"
198afba19d9SAdrian Hunter 
199afba19d9SAdrian Hunter struct kcore_extract {
200afba19d9SAdrian Hunter 	char *kcore_filename;
201afba19d9SAdrian Hunter 	u64 addr;
202afba19d9SAdrian Hunter 	u64 offs;
203afba19d9SAdrian Hunter 	u64 len;
204afba19d9SAdrian Hunter 	char extract_filename[sizeof(PERF_KCORE_EXTRACT)];
205afba19d9SAdrian Hunter 	int fd;
206afba19d9SAdrian Hunter };
207afba19d9SAdrian Hunter 
208afba19d9SAdrian Hunter int kcore_extract__create(struct kcore_extract *kce);
209afba19d9SAdrian Hunter void kcore_extract__delete(struct kcore_extract *kce);
210afba19d9SAdrian Hunter 
211fc1b691dSAdrian Hunter int kcore_copy(const char *from_dir, const char *to_dir);
212fc1b691dSAdrian Hunter int compare_proc_modules(const char *from, const char *to);
213fc1b691dSAdrian Hunter 
2143bfe5f81SDavid Ahern int setup_list(struct strlist **list, const char *list_str,
2153bfe5f81SDavid Ahern 	       const char *list_name);
216e03eaa40SDavid Ahern int setup_intlist(struct intlist **list, const char *list_str,
217e03eaa40SDavid Ahern 		  const char *list_name);
2183bfe5f81SDavid Ahern 
219d2332098SNaveen N. Rao #ifdef HAVE_LIBELF_SUPPORT
220d2332098SNaveen N. Rao bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
2210b3c2264SNaveen N. Rao void arch__sym_update(struct symbol *s, GElf_Sym *sym);
222d2332098SNaveen N. Rao #endif
223d2332098SNaveen N. Rao 
2244b3a2716SMasami Hiramatsu const char *arch__normalize_symbol_name(const char *name);
225fb6d5942SNaveen N. Rao #define SYMBOL_A 0
226fb6d5942SNaveen N. Rao #define SYMBOL_B 1
227fb6d5942SNaveen N. Rao 
228d8040645SPaul Clarke int arch__compare_symbol_names(const char *namea, const char *nameb);
229d8040645SPaul Clarke int arch__compare_symbol_names_n(const char *namea, const char *nameb,
230d8040645SPaul Clarke 				 unsigned int n);
231fb6d5942SNaveen N. Rao int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb);
232fb6d5942SNaveen N. Rao 
233d8040645SPaul Clarke enum symbol_tag_include {
234d8040645SPaul Clarke 	SYMBOL_TAG_INCLUDE__NONE = 0,
235d8040645SPaul Clarke 	SYMBOL_TAG_INCLUDE__DEFAULT_ONLY
236d8040645SPaul Clarke };
237d8040645SPaul Clarke 
238d8040645SPaul Clarke int symbol__match_symbol_name(const char *namea, const char *nameb,
239d8040645SPaul Clarke 			      enum symbol_tag_include includes);
240d8040645SPaul Clarke 
241060fa0c7SHemant Kumar /* structure containing an SDT note's info */
242060fa0c7SHemant Kumar struct sdt_note {
243060fa0c7SHemant Kumar 	char *name;			/* name of the note*/
244060fa0c7SHemant Kumar 	char *provider;			/* provider name */
245be88184bSAlexis Berlemont 	char *args;
246060fa0c7SHemant Kumar 	bool bit32;			/* whether the location is 32 bits? */
247060fa0c7SHemant Kumar 	union {				/* location, base and semaphore addrs */
248060fa0c7SHemant Kumar 		Elf64_Addr a64[3];
249060fa0c7SHemant Kumar 		Elf32_Addr a32[3];
250060fa0c7SHemant Kumar 	} addr;
251060fa0c7SHemant Kumar 	struct list_head note_list;	/* SDT notes' list */
252060fa0c7SHemant Kumar };
253060fa0c7SHemant Kumar 
254060fa0c7SHemant Kumar int get_sdt_note_list(struct list_head *head, const char *target);
255060fa0c7SHemant Kumar int cleanup_sdt_note_list(struct list_head *sdt_notes);
256060fa0c7SHemant Kumar int sdt_notes__get_count(struct list_head *start);
257060fa0c7SHemant Kumar 
2585a5e3d3cSRavi Bangoria #define SDT_PROBES_SCN ".probes"
259060fa0c7SHemant Kumar #define SDT_BASE_SCN ".stapsdt.base"
260060fa0c7SHemant Kumar #define SDT_NOTE_SCN  ".note.stapsdt"
261060fa0c7SHemant Kumar #define SDT_NOTE_TYPE 3
262060fa0c7SHemant Kumar #define SDT_NOTE_NAME "stapsdt"
263060fa0c7SHemant Kumar #define NR_ADDR 3
264060fa0c7SHemant Kumar 
2655a5e3d3cSRavi Bangoria enum {
2665a5e3d3cSRavi Bangoria 	SDT_NOTE_IDX_LOC = 0,
2675a5e3d3cSRavi Bangoria 	SDT_NOTE_IDX_BASE,
2685a5e3d3cSRavi Bangoria 	SDT_NOTE_IDX_REFCTR,
2695a5e3d3cSRavi Bangoria };
2705a5e3d3cSRavi Bangoria 
2719f87498fSJiri Olsa struct mem_info *mem_info__new(void);
2729f87498fSJiri Olsa struct mem_info *mem_info__get(struct mem_info *mi);
2739f87498fSJiri Olsa void   mem_info__put(struct mem_info *mi);
2749f87498fSJiri Olsa 
__mem_info__zput(struct mem_info ** mi)2759f87498fSJiri Olsa static inline void __mem_info__zput(struct mem_info **mi)
2769f87498fSJiri Olsa {
2779f87498fSJiri Olsa 	mem_info__put(*mi);
2789f87498fSJiri Olsa 	*mi = NULL;
2799f87498fSJiri Olsa }
2809f87498fSJiri Olsa 
2819f87498fSJiri Olsa #define mem_info__zput(mi) __mem_info__zput(&mi)
2829f87498fSJiri Olsa 
283a3df50abSJames Clark int symbol__validate_sym_arguments(void);
284a3df50abSJames Clark 
2858b40f521SJohn Kacur #endif /* __PERF_SYMBOL */
286