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