162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __PERF_SYMBOL
362306a36Sopenharmony_ci#define __PERF_SYMBOL 1
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/types.h>
662306a36Sopenharmony_ci#include <linux/refcount.h>
762306a36Sopenharmony_ci#include <stdbool.h>
862306a36Sopenharmony_ci#include <stdint.h>
962306a36Sopenharmony_ci#include <linux/list.h>
1062306a36Sopenharmony_ci#include <linux/rbtree.h>
1162306a36Sopenharmony_ci#include <stdio.h>
1262306a36Sopenharmony_ci#include "addr_location.h"
1362306a36Sopenharmony_ci#include "path.h"
1462306a36Sopenharmony_ci#include "symbol_conf.h"
1562306a36Sopenharmony_ci#include "spark.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#ifdef HAVE_LIBELF_SUPPORT
1862306a36Sopenharmony_ci#include <libelf.h>
1962306a36Sopenharmony_ci#include <gelf.h>
2062306a36Sopenharmony_ci#endif
2162306a36Sopenharmony_ci#include <elf.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistruct dso;
2462306a36Sopenharmony_cistruct map;
2562306a36Sopenharmony_cistruct maps;
2662306a36Sopenharmony_cistruct option;
2762306a36Sopenharmony_cistruct build_id;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/*
3062306a36Sopenharmony_ci * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
3162306a36Sopenharmony_ci * for newer versions we can use mmap to reduce memory usage:
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci#ifdef ELF_C_READ_MMAP
3462306a36Sopenharmony_ci# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
3562306a36Sopenharmony_ci#else
3662306a36Sopenharmony_ci# define PERF_ELF_C_READ_MMAP ELF_C_READ
3762306a36Sopenharmony_ci#endif
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#ifdef HAVE_LIBELF_SUPPORT
4062306a36Sopenharmony_ciElf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
4162306a36Sopenharmony_ci			     GElf_Shdr *shp, const char *name, size_t *idx);
4262306a36Sopenharmony_ci#endif
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/**
4562306a36Sopenharmony_ci * A symtab entry. When allocated this may be preceded by an annotation (see
4662306a36Sopenharmony_ci * symbol__annotation) and/or a browser_index (see symbol__browser_index).
4762306a36Sopenharmony_ci */
4862306a36Sopenharmony_cistruct symbol {
4962306a36Sopenharmony_ci	struct rb_node	rb_node;
5062306a36Sopenharmony_ci	/** Range of symbol [start, end). */
5162306a36Sopenharmony_ci	u64		start;
5262306a36Sopenharmony_ci	u64		end;
5362306a36Sopenharmony_ci	/** Length of the string name. */
5462306a36Sopenharmony_ci	u16		namelen;
5562306a36Sopenharmony_ci	/** ELF symbol type as defined for st_info. E.g STT_OBJECT or STT_FUNC. */
5662306a36Sopenharmony_ci	u8		type:4;
5762306a36Sopenharmony_ci	/** ELF binding type as defined for st_info. E.g. STB_WEAK or STB_GLOBAL. */
5862306a36Sopenharmony_ci	u8		binding:4;
5962306a36Sopenharmony_ci	/** Set true for kernel symbols of idle routines. */
6062306a36Sopenharmony_ci	u8		idle:1;
6162306a36Sopenharmony_ci	/** Resolvable but tools ignore it (e.g. idle routines). */
6262306a36Sopenharmony_ci	u8		ignore:1;
6362306a36Sopenharmony_ci	/** Symbol for an inlined function. */
6462306a36Sopenharmony_ci	u8		inlined:1;
6562306a36Sopenharmony_ci	/** Has symbol__annotate2 been performed. */
6662306a36Sopenharmony_ci	u8		annotate2:1;
6762306a36Sopenharmony_ci	/** Symbol is an alias of an STT_GNU_IFUNC */
6862306a36Sopenharmony_ci	u8		ifunc_alias:1;
6962306a36Sopenharmony_ci	/** Architecture specific. Unused except on PPC where it holds st_other. */
7062306a36Sopenharmony_ci	u8		arch_sym;
7162306a36Sopenharmony_ci	/** The name of length namelen associated with the symbol. */
7262306a36Sopenharmony_ci	char		name[];
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_civoid symbol__delete(struct symbol *sym);
7662306a36Sopenharmony_civoid symbols__delete(struct rb_root_cached *symbols);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* symbols__for_each_entry - iterate over symbols (rb_root)
7962306a36Sopenharmony_ci *
8062306a36Sopenharmony_ci * @symbols: the rb_root of symbols
8162306a36Sopenharmony_ci * @pos: the 'struct symbol *' to use as a loop cursor
8262306a36Sopenharmony_ci * @nd: the 'struct rb_node *' to use as a temporary storage
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ci#define symbols__for_each_entry(symbols, pos, nd)			\
8562306a36Sopenharmony_ci	for (nd = rb_first_cached(symbols);					\
8662306a36Sopenharmony_ci	     nd && (pos = rb_entry(nd, struct symbol, rb_node));	\
8762306a36Sopenharmony_ci	     nd = rb_next(nd))
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic inline size_t symbol__size(const struct symbol *sym)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	return sym->end - sym->start;
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistruct strlist;
9562306a36Sopenharmony_cistruct intlist;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	return path__join(bf, size, symbol_conf.symfs, path);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci#define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), path)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciextern int vmlinux_path__nr_entries;
10562306a36Sopenharmony_ciextern char **vmlinux_path;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic inline void *symbol__priv(struct symbol *sym)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	return ((void *)sym) - symbol_conf.priv_size;
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistruct ref_reloc_sym {
11362306a36Sopenharmony_ci	const char	*name;
11462306a36Sopenharmony_ci	u64		addr;
11562306a36Sopenharmony_ci	u64		unrelocated_addr;
11662306a36Sopenharmony_ci};
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciint dso__load(struct dso *dso, struct map *map);
11962306a36Sopenharmony_ciint dso__load_vmlinux(struct dso *dso, struct map *map,
12062306a36Sopenharmony_ci		      const char *vmlinux, bool vmlinux_allocated);
12162306a36Sopenharmony_ciint dso__load_vmlinux_path(struct dso *dso, struct map *map);
12262306a36Sopenharmony_ciint __dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
12362306a36Sopenharmony_ci			 bool no_kcore);
12462306a36Sopenharmony_ciint dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map);
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_civoid dso__insert_symbol(struct dso *dso,
12762306a36Sopenharmony_ci			struct symbol *sym);
12862306a36Sopenharmony_civoid dso__delete_symbol(struct dso *dso,
12962306a36Sopenharmony_ci			struct symbol *sym);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cistruct symbol *dso__find_symbol(struct dso *dso, u64 addr);
13262306a36Sopenharmony_cistruct symbol *dso__find_symbol_nocache(struct dso *dso, u64 addr);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistruct symbol *dso__next_symbol_by_name(struct dso *dso, size_t *idx);
13562306a36Sopenharmony_cistruct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name, size_t *idx);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistruct symbol *dso__first_symbol(struct dso *dso);
13862306a36Sopenharmony_cistruct symbol *dso__last_symbol(struct dso *dso);
13962306a36Sopenharmony_cistruct symbol *dso__next_symbol(struct symbol *sym);
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cienum dso_type dso__type_fd(int fd);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ciint filename__read_build_id(const char *filename, struct build_id *id);
14462306a36Sopenharmony_ciint sysfs__read_build_id(const char *filename, struct build_id *bid);
14562306a36Sopenharmony_ciint modules__parse(const char *filename, void *arg,
14662306a36Sopenharmony_ci		   int (*process_module)(void *arg, const char *name,
14762306a36Sopenharmony_ci					 u64 start, u64 size));
14862306a36Sopenharmony_ciint filename__read_debuglink(const char *filename, char *debuglink,
14962306a36Sopenharmony_ci			     size_t size);
15062306a36Sopenharmony_cibool filename__has_section(const char *filename, const char *sec);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_cistruct perf_env;
15362306a36Sopenharmony_ciint symbol__init(struct perf_env *env);
15462306a36Sopenharmony_civoid symbol__exit(void);
15562306a36Sopenharmony_civoid symbol__elf_init(void);
15662306a36Sopenharmony_ciint symbol__annotation_init(void);
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistruct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name);
15962306a36Sopenharmony_cisize_t __symbol__fprintf_symname_offs(const struct symbol *sym,
16062306a36Sopenharmony_ci				      const struct addr_location *al,
16162306a36Sopenharmony_ci				      bool unknown_as_addr,
16262306a36Sopenharmony_ci				      bool print_offsets, FILE *fp);
16362306a36Sopenharmony_cisize_t symbol__fprintf_symname_offs(const struct symbol *sym,
16462306a36Sopenharmony_ci				    const struct addr_location *al, FILE *fp);
16562306a36Sopenharmony_cisize_t __symbol__fprintf_symname(const struct symbol *sym,
16662306a36Sopenharmony_ci				 const struct addr_location *al,
16762306a36Sopenharmony_ci				 bool unknown_as_addr, FILE *fp);
16862306a36Sopenharmony_cisize_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
16962306a36Sopenharmony_cisize_t symbol__fprintf(struct symbol *sym, FILE *fp);
17062306a36Sopenharmony_cibool symbol__restricted_filename(const char *filename,
17162306a36Sopenharmony_ci				 const char *restricted_filename);
17262306a36Sopenharmony_ciint symbol__config_symfs(const struct option *opt __maybe_unused,
17362306a36Sopenharmony_ci			 const char *dir, int unset __maybe_unused);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cistruct symsrc;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#ifdef HAVE_LIBBFD_SUPPORT
17862306a36Sopenharmony_ciint dso__load_bfd_symbols(struct dso *dso, const char *debugfile);
17962306a36Sopenharmony_ci#endif
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ciint dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
18262306a36Sopenharmony_ci		  struct symsrc *runtime_ss, int kmodule);
18362306a36Sopenharmony_ciint dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss);
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cichar *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name);
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_civoid __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym,
18862306a36Sopenharmony_ci		       bool kernel);
18962306a36Sopenharmony_civoid symbols__insert(struct rb_root_cached *symbols, struct symbol *sym);
19062306a36Sopenharmony_civoid symbols__fixup_duplicate(struct rb_root_cached *symbols);
19162306a36Sopenharmony_civoid symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms);
19262306a36Sopenharmony_civoid maps__fixup_end(struct maps *maps);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_citypedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
19562306a36Sopenharmony_ciint file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
19662306a36Sopenharmony_ci		    bool *is_64_bit);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci#define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX"
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistruct kcore_extract {
20162306a36Sopenharmony_ci	char *kcore_filename;
20262306a36Sopenharmony_ci	u64 addr;
20362306a36Sopenharmony_ci	u64 offs;
20462306a36Sopenharmony_ci	u64 len;
20562306a36Sopenharmony_ci	char extract_filename[sizeof(PERF_KCORE_EXTRACT)];
20662306a36Sopenharmony_ci	int fd;
20762306a36Sopenharmony_ci};
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ciint kcore_extract__create(struct kcore_extract *kce);
21062306a36Sopenharmony_civoid kcore_extract__delete(struct kcore_extract *kce);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ciint kcore_copy(const char *from_dir, const char *to_dir);
21362306a36Sopenharmony_ciint compare_proc_modules(const char *from, const char *to);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ciint setup_list(struct strlist **list, const char *list_str,
21662306a36Sopenharmony_ci	       const char *list_name);
21762306a36Sopenharmony_ciint setup_intlist(struct intlist **list, const char *list_str,
21862306a36Sopenharmony_ci		  const char *list_name);
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci#ifdef HAVE_LIBELF_SUPPORT
22162306a36Sopenharmony_cibool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
22262306a36Sopenharmony_civoid arch__sym_update(struct symbol *s, GElf_Sym *sym);
22362306a36Sopenharmony_ci#endif
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciconst char *arch__normalize_symbol_name(const char *name);
22662306a36Sopenharmony_ci#define SYMBOL_A 0
22762306a36Sopenharmony_ci#define SYMBOL_B 1
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ciint arch__compare_symbol_names(const char *namea, const char *nameb);
23062306a36Sopenharmony_ciint arch__compare_symbol_names_n(const char *namea, const char *nameb,
23162306a36Sopenharmony_ci				 unsigned int n);
23262306a36Sopenharmony_ciint arch__choose_best_symbol(struct symbol *syma, struct symbol *symb);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_cienum symbol_tag_include {
23562306a36Sopenharmony_ci	SYMBOL_TAG_INCLUDE__NONE = 0,
23662306a36Sopenharmony_ci	SYMBOL_TAG_INCLUDE__DEFAULT_ONLY
23762306a36Sopenharmony_ci};
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ciint symbol__match_symbol_name(const char *namea, const char *nameb,
24062306a36Sopenharmony_ci			      enum symbol_tag_include includes);
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci/* structure containing an SDT note's info */
24362306a36Sopenharmony_cistruct sdt_note {
24462306a36Sopenharmony_ci	char *name;			/* name of the note*/
24562306a36Sopenharmony_ci	char *provider;			/* provider name */
24662306a36Sopenharmony_ci	char *args;
24762306a36Sopenharmony_ci	bool bit32;			/* whether the location is 32 bits? */
24862306a36Sopenharmony_ci	union {				/* location, base and semaphore addrs */
24962306a36Sopenharmony_ci		Elf64_Addr a64[3];
25062306a36Sopenharmony_ci		Elf32_Addr a32[3];
25162306a36Sopenharmony_ci	} addr;
25262306a36Sopenharmony_ci	struct list_head note_list;	/* SDT notes' list */
25362306a36Sopenharmony_ci};
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ciint get_sdt_note_list(struct list_head *head, const char *target);
25662306a36Sopenharmony_ciint cleanup_sdt_note_list(struct list_head *sdt_notes);
25762306a36Sopenharmony_ciint sdt_notes__get_count(struct list_head *start);
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci#define SDT_PROBES_SCN ".probes"
26062306a36Sopenharmony_ci#define SDT_BASE_SCN ".stapsdt.base"
26162306a36Sopenharmony_ci#define SDT_NOTE_SCN  ".note.stapsdt"
26262306a36Sopenharmony_ci#define SDT_NOTE_TYPE 3
26362306a36Sopenharmony_ci#define SDT_NOTE_NAME "stapsdt"
26462306a36Sopenharmony_ci#define NR_ADDR 3
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cienum {
26762306a36Sopenharmony_ci	SDT_NOTE_IDX_LOC = 0,
26862306a36Sopenharmony_ci	SDT_NOTE_IDX_BASE,
26962306a36Sopenharmony_ci	SDT_NOTE_IDX_REFCTR,
27062306a36Sopenharmony_ci};
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_cistruct mem_info *mem_info__new(void);
27362306a36Sopenharmony_cistruct mem_info *mem_info__get(struct mem_info *mi);
27462306a36Sopenharmony_civoid   mem_info__put(struct mem_info *mi);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistatic inline void __mem_info__zput(struct mem_info **mi)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	mem_info__put(*mi);
27962306a36Sopenharmony_ci	*mi = NULL;
28062306a36Sopenharmony_ci}
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci#define mem_info__zput(mi) __mem_info__zput(&mi)
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ciint symbol__validate_sym_arguments(void);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci#endif /* __PERF_SYMBOL */
287