Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) #include <dirent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <sys/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "annotate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "cap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "util.h" // lsdir()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include "map_symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include "mem-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include "symsrc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include "strlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include "intlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "header.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include "path.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <symbol/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <sys/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) static int dso__load_kernel_sym(struct dso *dso, struct map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) static bool symbol__is_idle(const char *name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) int vmlinux_path__nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) char **vmlinux_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) struct symbol_conf symbol_conf = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	.nanosecs		= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	.use_modules		= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	.try_vmlinux_path	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	.demangle		= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	.demangle_kernel	= false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	.cumulate_callchain	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	.time_quantum		= 100 * NSEC_PER_MSEC, /* 100ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	.show_hist_headers	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	.symfs			= "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	.event_group		= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	.inline_name		= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	.res_sample		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static enum dso_binary_type binary_type_symtab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	DSO_BINARY_TYPE__KALLSYMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	DSO_BINARY_TYPE__GUEST_KALLSYMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	DSO_BINARY_TYPE__JAVA_JIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	DSO_BINARY_TYPE__DEBUGLINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	DSO_BINARY_TYPE__BUILD_ID_CACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	DSO_BINARY_TYPE__GUEST_KMODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	DSO_BINARY_TYPE__NOT_FOUND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) static bool symbol_type__filter(char symbol_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	symbol_type = toupper(symbol_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	return symbol_type == 'T' || symbol_type == 'W' || symbol_type == 'D' || symbol_type == 'B';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static int prefix_underscores_count(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	const char *tail = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	while (*tail == '_')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		tail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	return tail - str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) void __weak arch__symbols__fixup_end(struct symbol *p, struct symbol *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	p->end = c->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) const char * __weak arch__normalize_symbol_name(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	return name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) int __weak arch__compare_symbol_names(const char *namea, const char *nameb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	return strcmp(namea, nameb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) int __weak arch__compare_symbol_names_n(const char *namea, const char *nameb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 					unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	return strncmp(namea, nameb, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) int __weak arch__choose_best_symbol(struct symbol *syma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 				    struct symbol *symb __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	/* Avoid "SyS" kernel syscall aliases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	if (strlen(syma->name) >= 3 && !strncmp(syma->name, "SyS", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	if (strlen(syma->name) >= 10 && !strncmp(syma->name, "compat_SyS", 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	return SYMBOL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) static int choose_best_symbol(struct symbol *syma, struct symbol *symb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	s64 a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	s64 b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	size_t na, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	/* Prefer a symbol with non zero length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	a = syma->end - syma->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	b = symb->end - symb->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	if ((b == 0) && (a > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		return SYMBOL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	else if ((a == 0) && (b > 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	/* Prefer a non weak symbol over a weak one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	a = syma->binding == STB_WEAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	b = symb->binding == STB_WEAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	if (b && !a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		return SYMBOL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	if (a && !b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	/* Prefer a global symbol over a non global one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	a = syma->binding == STB_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	b = symb->binding == STB_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	if (a && !b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		return SYMBOL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	if (b && !a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	/* Prefer a symbol with less underscores */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	a = prefix_underscores_count(syma->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	b = prefix_underscores_count(symb->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	if (b > a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		return SYMBOL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	else if (a > b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	/* Choose the symbol with the longest name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	na = strlen(syma->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	nb = strlen(symb->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	if (na > nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		return SYMBOL_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	else if (na < nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		return SYMBOL_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	return arch__choose_best_symbol(syma, symb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) void symbols__fixup_duplicate(struct rb_root_cached *symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	struct symbol *curr, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	if (symbol_conf.allow_aliases)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	nd = rb_first_cached(symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	while (nd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		curr = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		nd = rb_next(&curr->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		next = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		if (!nd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		if (curr->start != next->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		if (choose_best_symbol(curr, next) == SYMBOL_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 			rb_erase_cached(&next->rb_node, symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 			symbol__delete(next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 			goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			nd = rb_next(&curr->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 			rb_erase_cached(&curr->rb_node, symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			symbol__delete(curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) void symbols__fixup_end(struct rb_root_cached *symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	struct rb_node *nd, *prevnd = rb_first_cached(symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	struct symbol *curr, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	if (prevnd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	curr = rb_entry(prevnd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		prev = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		curr = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		if (prev->end == prev->start || prev->end != curr->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			arch__symbols__fixup_end(prev, curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	/* Last entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	if (curr->end == curr->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		curr->end = roundup(curr->start, 4096) + 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) void maps__fixup_end(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	struct map *prev = NULL, *curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	down_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	maps__for_each_entry(maps, curr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		if (prev != NULL && !prev->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 			prev->end = curr->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		prev = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	 * We still haven't the actual symbols, so guess the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	 * last map final address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	if (curr && !curr->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		curr->end = ~0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	up_write(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	size_t namelen = strlen(name) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	struct symbol *sym = calloc(1, (symbol_conf.priv_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 					sizeof(*sym) + namelen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	if (sym == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (symbol_conf.priv_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		if (symbol_conf.init_annotation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			struct annotation *notes = (void *)sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			pthread_mutex_init(&notes->lock, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		sym = ((void *)sym) + symbol_conf.priv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	sym->start   = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	sym->end     = len ? start + len : start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	sym->type    = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	sym->binding = binding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	sym->namelen = namelen - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		  __func__, name, start, sym->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	memcpy(sym->name, name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) void symbol__delete(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	free(((void *)sym) - symbol_conf.priv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) void symbols__delete(struct rb_root_cached *symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	struct symbol *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	struct rb_node *next = rb_first_cached(symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		pos = rb_entry(next, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		next = rb_next(&pos->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		rb_erase_cached(&pos->rb_node, symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		symbol__delete(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) void __symbols__insert(struct rb_root_cached *symbols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		       struct symbol *sym, bool kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	struct rb_node **p = &symbols->rb_root.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	const u64 ip = sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	struct symbol *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	bool leftmost = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	if (kernel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		const char *name = sym->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		 * ppc64 uses function descriptors and appends a '.' to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		 * start of every instruction address. Remove it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (name[0] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		sym->idle = symbol__is_idle(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		s = rb_entry(parent, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		if (ip < s->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 			p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 			p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			leftmost = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	rb_link_node(&sym->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	rb_insert_color_cached(&sym->rb_node, symbols, leftmost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	__symbols__insert(symbols, sym, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) static struct symbol *symbols__find(struct rb_root_cached *symbols, u64 ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	if (symbols == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	n = symbols->rb_root.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		struct symbol *s = rb_entry(n, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		if (ip < s->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 			n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		else if (ip > s->end || (ip == s->end && ip != s->start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) static struct symbol *symbols__first(struct rb_root_cached *symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	struct rb_node *n = rb_first_cached(symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	if (n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		return rb_entry(n, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) static struct symbol *symbols__last(struct rb_root_cached *symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	struct rb_node *n = rb_last(&symbols->rb_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	if (n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		return rb_entry(n, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) static struct symbol *symbols__next(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	struct rb_node *n = rb_next(&sym->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		return rb_entry(n, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) static void symbols__insert_by_name(struct rb_root_cached *symbols, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	struct rb_node **p = &symbols->rb_root.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	struct symbol_name_rb_node *symn, *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	bool leftmost = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	symn = container_of(sym, struct symbol_name_rb_node, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		if (strcmp(sym->name, s->sym.name) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 			p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 			p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			leftmost = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	rb_link_node(&symn->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	rb_insert_color_cached(&symn->rb_node, symbols, leftmost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static void symbols__sort_by_name(struct rb_root_cached *symbols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				  struct rb_root_cached *source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	for (nd = rb_first_cached(source); nd; nd = rb_next(nd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		symbols__insert_by_name(symbols, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) int symbol__match_symbol_name(const char *name, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			      enum symbol_tag_include includes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	const char *versioning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	if (includes == SYMBOL_TAG_INCLUDE__DEFAULT_ONLY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	    (versioning = strstr(name, "@@"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		int len = strlen(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		if (len < versioning - name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			len = versioning - name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		return arch__compare_symbol_names_n(name, str, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		return arch__compare_symbol_names(name, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) static struct symbol *symbols__find_by_name(struct rb_root_cached *symbols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 					    const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 					    enum symbol_tag_include includes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	struct symbol_name_rb_node *s = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	if (symbols == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	n = symbols->rb_root.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		int cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		s = rb_entry(n, struct symbol_name_rb_node, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		cmp = symbol__match_symbol_name(s->sym.name, name, includes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		if (cmp > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		else if (cmp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	if (n == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	if (includes != SYMBOL_TAG_INCLUDE__DEFAULT_ONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		/* return first symbol that has same name (if any) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		for (n = rb_prev(n); n; n = rb_prev(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			struct symbol_name_rb_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			tmp = rb_entry(n, struct symbol_name_rb_node, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			if (arch__compare_symbol_names(tmp->sym.name, s->sym.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 			s = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	return &s->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) void dso__reset_find_symbol_cache(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	dso->last_find_result.addr   = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	dso->last_find_result.symbol = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) void dso__insert_symbol(struct dso *dso, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	__symbols__insert(&dso->symbols, sym, dso->kernel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	/* update the symbol cache if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	if (dso->last_find_result.addr >= sym->start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	    (dso->last_find_result.addr < sym->end ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	    sym->start == sym->end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		dso->last_find_result.symbol = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) void dso__delete_symbol(struct dso *dso, struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	rb_erase_cached(&sym->rb_node, &dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	symbol__delete(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	dso__reset_find_symbol_cache(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) struct symbol *dso__find_symbol(struct dso *dso, u64 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	if (dso->last_find_result.addr != addr || dso->last_find_result.symbol == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		dso->last_find_result.addr   = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		dso->last_find_result.symbol = symbols__find(&dso->symbols, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	return dso->last_find_result.symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) struct symbol *dso__first_symbol(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	return symbols__first(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) struct symbol *dso__last_symbol(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	return symbols__last(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) struct symbol *dso__next_symbol(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	return symbols__next(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) struct symbol *symbol__next_by_name(struct symbol *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	struct rb_node *n = rb_next(&s->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558)  /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559)   * Returns first symbol that matched with @name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560)   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	struct symbol *s = symbols__find_by_name(&dso->symbol_names, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 						 SYMBOL_TAG_INCLUDE__NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		s = symbols__find_by_name(&dso->symbol_names, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 					  SYMBOL_TAG_INCLUDE__DEFAULT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) void dso__sort_by_name(struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	dso__set_sorted_by_name(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	return symbols__sort_by_name(&dso->symbol_names, &dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  * While we find nice hex chars, build a long_val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  * Return number of chars processed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) static int hex2u64(const char *ptr, u64 *long_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	*long_val = strtoull(ptr, &p, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	return p - ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) int modules__parse(const char *filename, void *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		   int (*process_module)(void *arg, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 					 u64 start, u64 size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	char *line = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	size_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	FILE *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	file = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (file == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		char name[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		u64 start, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		char *sep, *endptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		ssize_t line_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		line_len = getline(&line, &n, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		if (line_len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			if (feof(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 			err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		if (!line) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		line[--line_len] = '\0'; /* \n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		sep = strrchr(line, 'x');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		if (sep == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		hex2u64(sep + 1, &start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		sep = strchr(line, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		if (sep == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		*sep = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		scnprintf(name, sizeof(name), "[%s]", line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		size = strtoul(sep + 1, &endptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		if (*endptr != ' ' && *endptr != '\t')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		err = process_module(arg, name, start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	free(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	fclose(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)  * These are symbols in the kernel image, so make sure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * sym is from a kernel DSO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static bool symbol__is_idle(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	const char * const idle_symbols[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		"acpi_idle_do_entry",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		"acpi_processor_ffh_cstate_enter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		"arch_cpu_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		"cpu_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		"cpu_startup_entry",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		"idle_cpu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		"intel_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		"default_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		"native_safe_halt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		"enter_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		"exit_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		"mwait_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		"mwait_idle_with_hints",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		"mwait_idle_with_hints.constprop.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		"poll_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		"ppc64_runlatch_off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		"pseries_dedicated_idle_sleep",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		"psw_idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		"psw_idle_exit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	static struct strlist *idle_symbols_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if (idle_symbols_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		return strlist__has_entry(idle_symbols_list, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	idle_symbols_list = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	for (i = 0; idle_symbols[i]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		strlist__add(idle_symbols_list, idle_symbols[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	return strlist__has_entry(idle_symbols_list, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) static int map__process_kallsym_symbol(void *arg, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 				       char type, u64 start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	struct dso *dso = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	struct rb_root_cached *root = &dso->symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	if (!symbol_type__filter(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	 * module symbols are not sorted so we add all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	 * symbols, setting length to 0, and rely on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	 * symbols__fixup_end() to fix it up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	sym = symbol__new(start, 0, kallsyms2elf_binding(type), kallsyms2elf_type(type), name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	if (sym == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	 * We will pass the symbols to the filter later, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	 * map__split_kallsyms, when we have split the maps per module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	__symbols__insert(root, sym, !strchr(name, '['));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723)  * Loads the function entries in /proc/kallsyms into kernel_map->dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724)  * so that we can in the next step set the symbol ->end address and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)  * call kernel_maps__split_kallsyms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) static int dso__load_all_kallsyms(struct dso *dso, const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	return kallsyms__parse(filename, dso, map__process_kallsym_symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	struct map *curr_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	struct symbol *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	struct rb_root_cached old_root = dso->symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	struct rb_root_cached *root = &dso->symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	struct rb_node *next = rb_first_cached(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (!kmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	*root = RB_ROOT_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		char *module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		pos = rb_entry(next, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		next = rb_next(&pos->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		rb_erase_cached(&pos->rb_node, &old_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		RB_CLEAR_NODE(&pos->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		module = strchr(pos->name, '\t');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		if (module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			*module = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		curr_map = maps__find(kmaps, pos->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		if (!curr_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			symbol__delete(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		pos->start -= curr_map->start - curr_map->pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		if (pos->end > curr_map->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			pos->end = curr_map->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		if (pos->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 			pos->end -= curr_map->start - curr_map->pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		symbols__insert(&curr_map->dso->symbols, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		++count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	/* Symbols have been adjusted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	dso->adjust_symbols = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781)  * Split the symbols into maps, making sure there are no overlaps, i.e. the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782)  * kernel range is broken in several maps, named [kernel].N, as we don't have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783)  * the original ELF section names vmlinux have.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 				struct map *initial_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	struct machine *machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	struct map *curr_map = initial_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	struct symbol *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	int count = 0, moved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	struct rb_root_cached *root = &dso->symbols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	struct rb_node *next = rb_first_cached(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	int kernel_range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	bool x86_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	if (!kmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	machine = kmaps->machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	x86_64 = machine__is(machine, "x86_64");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		char *module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		pos = rb_entry(next, struct symbol, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		next = rb_next(&pos->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		module = strchr(pos->name, '\t');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		if (module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			if (!symbol_conf.use_modules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 				goto discard_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			*module++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			if (strcmp(curr_map->dso->short_name, module)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 				if (curr_map != initial_map &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 				    dso->kernel == DSO_SPACE__KERNEL_GUEST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 				    machine__is_default_guest(machine)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 					 * We assume all symbols of a module are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 					 * continuous in * kallsyms, so curr_map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 					 * points to a module and all its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 					 * symbols are in its kmap. Mark it as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 					 * loaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 					dso__set_loaded(curr_map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				curr_map = maps__find_by_name(kmaps, module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 				if (curr_map == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 					pr_debug("%s/proc/{kallsyms,modules} "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 					         "inconsistency while looking "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 						 "for \"%s\" module!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 						 machine->root_dir, module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 					curr_map = initial_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 					goto discard_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 				if (curr_map->dso->loaded &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 				    !machine__is_default_guest(machine))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 					goto discard_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			 * So that we look just like we get from .ko files,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			 * i.e. not prelinked, relative to initial_map->start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			pos->start = curr_map->map_ip(curr_map, pos->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			pos->end   = curr_map->map_ip(curr_map, pos->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		} else if (x86_64 && is_entry_trampoline(pos->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			 * These symbols are not needed anymore since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			 * trampoline maps refer to the text section and it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 			 * symbols instead. Avoid having to deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			 * relocations, and the assumption that the first symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			 * is the start of kernel text, by simply removing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			 * symbols at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			goto discard_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		} else if (curr_map != initial_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			char dso_name[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			struct dso *ndso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			if (delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 				/* Kernel was relocated at boot time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 				pos->start -= delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 				pos->end -= delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 				curr_map = initial_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 				goto add_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				snprintf(dso_name, sizeof(dso_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 					"[guest.kernel].%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 					kernel_range++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 				snprintf(dso_name, sizeof(dso_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 					"[kernel].%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 					kernel_range++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			ndso = dso__new(dso_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			if (ndso == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 			ndso->kernel = dso->kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			curr_map = map__new2(pos->start, ndso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			if (curr_map == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 				dso__put(ndso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 				return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			maps__insert(kmaps, curr_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			++kernel_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		} else if (delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 			/* Kernel was relocated at boot time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			pos->start -= delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			pos->end -= delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) add_symbol:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		if (curr_map != initial_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			rb_erase_cached(&pos->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			symbols__insert(&curr_map->dso->symbols, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 			++moved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 			++count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) discard_symbol:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		rb_erase_cached(&pos->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		symbol__delete(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	if (curr_map != initial_map &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	    dso->kernel == DSO_SPACE__KERNEL_GUEST &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	    machine__is_default_guest(kmaps->machine)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		dso__set_loaded(curr_map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	return count + moved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) bool symbol__restricted_filename(const char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 				 const char *restricted_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	bool restricted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	if (symbol_conf.kptr_restrict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		char *r = realpath(filename, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		if (r != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			restricted = strcmp(r, restricted_filename) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 			free(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			return restricted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	return restricted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) struct module_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct rb_node rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	u64 start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) static void add_module(struct module_info *mi, struct rb_root *modules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct rb_node **p = &modules->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	struct module_info *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		m = rb_entry(parent, struct module_info, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		if (strcmp(mi->name, m->name) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 			p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	rb_link_node(&mi->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	rb_insert_color(&mi->rb_node, modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) static void delete_modules(struct rb_root *modules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	struct module_info *mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	struct rb_node *next = rb_first(modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		mi = rb_entry(next, struct module_info, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		next = rb_next(&mi->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		rb_erase(&mi->rb_node, modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		zfree(&mi->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		free(mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) static struct module_info *find_module(const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 				       struct rb_root *modules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	struct rb_node *n = modules->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		struct module_info *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		int cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		m = rb_entry(n, struct module_info, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		cmp = strcmp(name, m->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		if (cmp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		else if (cmp > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 			n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			return m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static int __read_proc_modules(void *arg, const char *name, u64 start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			       u64 size __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	struct rb_root *modules = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	struct module_info *mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	mi = zalloc(sizeof(struct module_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	if (!mi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	mi->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	mi->start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (!mi->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		free(mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	add_module(mi, modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static int read_proc_modules(const char *filename, struct rb_root *modules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	if (symbol__restricted_filename(filename, "/proc/modules"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (modules__parse(filename, modules, __read_proc_modules)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		delete_modules(modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) int compare_proc_modules(const char *from, const char *to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	struct rb_root from_modules = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	struct rb_root to_modules = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	struct rb_node *from_node, *to_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct module_info *from_m, *to_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	if (read_proc_modules(from, &from_modules))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	if (read_proc_modules(to, &to_modules))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		goto out_delete_from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	from_node = rb_first(&from_modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	to_node = rb_first(&to_modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	while (from_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		if (!to_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		from_m = rb_entry(from_node, struct module_info, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		to_m = rb_entry(to_node, struct module_info, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		if (from_m->start != to_m->start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		    strcmp(from_m->name, to_m->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		from_node = rb_next(from_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		to_node = rb_next(to_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	if (!from_node && !to_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	delete_modules(&to_modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) out_delete_from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	delete_modules(&from_modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static int do_validate_kcore_modules(const char *filename, struct maps *kmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	struct rb_root modules = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	struct map *old_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	err = read_proc_modules(filename, &modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	maps__for_each_entry(kmaps, old_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		struct module_info *mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		if (!__map__is_kmodule(old_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		/* Module must be in memory at the same address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		mi = find_module(old_map->dso->short_name, &modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		if (!mi || mi->start != old_map->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	delete_modules(&modules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)  * If kallsyms is referenced by name then we look for filename in the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)  * directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static bool filename_from_kallsyms_filename(char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 					    const char *base_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 					    const char *kallsyms_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	strcpy(filename, kallsyms_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	name = strrchr(filename, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	name += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	if (!strcmp(name, "kallsyms")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		strcpy(name, base_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int validate_kcore_modules(const char *kallsyms_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 				  struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	struct maps *kmaps = map__kmaps(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	char modules_filename[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	if (!kmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	if (!filename_from_kallsyms_filename(modules_filename, "modules",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 					     kallsyms_filename))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	if (do_validate_kcore_modules(modules_filename, kmaps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static int validate_kcore_addresses(const char *kallsyms_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 				    struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	struct kmap *kmap = map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	if (!kmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		u64 start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		if (kallsyms__get_function_start(kallsyms_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 						 kmap->ref_reloc_sym->name, &start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		if (start != kmap->ref_reloc_sym->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	return validate_kcore_modules(kallsyms_filename, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct kcore_mapfn_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	struct dso *dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	struct list_head maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	struct kcore_mapfn_data *md = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	map = map__new2(start, md->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (map == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	map->end = map->start + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	map->pgoff = pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	list_add(&map->node, &md->maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)  * Merges map into maps by splitting the new map within the existing map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)  * regions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) int maps__merge_in(struct maps *kmaps, struct map *new_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	struct map *old_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	LIST_HEAD(merged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	maps__for_each_entry(kmaps, old_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		/* no overload with this one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		if (new_map->end < old_map->start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		    new_map->start >= old_map->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		if (new_map->start < old_map->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			 * |new......
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			 *       |old....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 			if (new_map->end < old_map->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 				 * |new......|     -> |new..|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 				 *       |old....| ->       |old....|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 				new_map->end = old_map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 				 * |new.............| -> |new..|       |new..|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 				 *       |old....|    ->       |old....|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 				struct map *m = map__clone(new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 				if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 				m->end = old_map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 				list_add_tail(&m->node, &merged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 				new_map->pgoff += old_map->end - new_map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 				new_map->start = old_map->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 			 *      |new......
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 			 * |old....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 			if (new_map->end < old_map->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 				 *      |new..|   -> x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 				 * |old.........| -> |old.........|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 				map__put(new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 				new_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 				 *      |new......| ->         |new...|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 				 * |old....|        -> |old....|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 				new_map->pgoff += old_map->end - new_map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 				new_map->start = old_map->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	while (!list_empty(&merged)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		old_map = list_entry(merged.next, struct map, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		list_del_init(&old_map->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		maps__insert(kmaps, old_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		map__put(old_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	if (new_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 		maps__insert(kmaps, new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		map__put(new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static int dso__load_kcore(struct dso *dso, struct map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			   const char *kallsyms_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	struct maps *kmaps = map__kmaps(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	struct kcore_mapfn_data md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	struct map *old_map, *new_map, *replacement_map = NULL, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	struct machine *machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	bool is_64_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	int err, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	char kcore_filename[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	u64 stext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	if (!kmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	machine = kmaps->machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	/* This function requires that the map is the kernel map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	if (!__map__is_kernel(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 					     kallsyms_filename))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	/* Modules and kernel must be present at their original addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	if (validate_kcore_addresses(kallsyms_filename, map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	md.dso = dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	INIT_LIST_HEAD(&md.maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	fd = open(kcore_filename, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		pr_debug("Failed to open %s. Note /proc/kcore requires CAP_SYS_RAWIO capability to access.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 			 kcore_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	/* Read new maps into temporary lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	err = file__read_maps(fd, map->prot & PROT_EXEC, kcore_mapfn, &md,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 			      &is_64_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	dso->is_64_bit = is_64_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	if (list_empty(&md.maps)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	/* Remove old maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	maps__for_each_entry_safe(kmaps, old_map, next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		 * We need to preserve eBPF maps even if they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		 * covered by kcore, because we need to access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		 * eBPF dso for source data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		if (old_map != map && !__map__is_bpf_prog(old_map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 			maps__remove(kmaps, old_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	machine->trampolines_mapped = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	/* Find the kernel map using the '_stext' symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (!kallsyms__get_function_start(kallsyms_filename, "_stext", &stext)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		list_for_each_entry(new_map, &md.maps, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 			if (stext >= new_map->start && stext < new_map->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 				replacement_map = new_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	if (!replacement_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		replacement_map = list_entry(md.maps.next, struct map, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	/* Add new maps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	while (!list_empty(&md.maps)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		new_map = list_entry(md.maps.next, struct map, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		list_del_init(&new_map->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		if (new_map == replacement_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 			map->start	= new_map->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			map->end	= new_map->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 			map->pgoff	= new_map->pgoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 			map->map_ip	= new_map->map_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 			map->unmap_ip	= new_map->unmap_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 			/* Ensure maps are correctly ordered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 			map__get(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 			maps__remove(kmaps, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 			maps__insert(kmaps, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 			map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 			map__put(new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 			 * Merge kcore map into existing maps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 			 * and ensure that current maps (eBPF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 			 * stay intact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 			if (maps__merge_in(kmaps, new_map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 				goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	if (machine__is(machine, "x86_64")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		 * If one of the corresponding symbols is there, assume the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		 * entry trampoline maps are too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		if (!kallsyms__get_function_start(kallsyms_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 						  ENTRY_TRAMPOLINE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 						  &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 			machine->trampolines_mapped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	 * Set the data type and long name so that kcore can be read via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	 * dso__data_read_addr().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		dso->binary_type = DSO_BINARY_TYPE__KCORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	dso__set_long_name(dso, strdup(kcore_filename), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	if (map->prot & PROT_EXEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		pr_debug("Using %s for kernel object code\n", kcore_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		pr_debug("Using %s for kernel data\n", kcore_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	while (!list_empty(&md.maps)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		map = list_entry(md.maps.next, struct map, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		list_del_init(&map->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)  * If the kernel is relocated at boot time, kallsyms won't match.  Compute the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)  * delta based on the relocation reference symbol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static int kallsyms__delta(struct kmap *kmap, const char *filename, u64 *delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	if (kallsyms__get_function_start(filename, kmap->ref_reloc_sym->name, &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	*delta = addr - kmap->ref_reloc_sym->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) int __dso__load_kallsyms(struct dso *dso, const char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 			 struct map *map, bool no_kcore)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	struct kmap *kmap = map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	u64 delta = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	if (symbol__restricted_filename(filename, "/proc/kallsyms"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (!kmap || !kmap->kmaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	if (dso__load_all_kallsyms(dso, filename) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	if (kallsyms__delta(kmap, filename, &delta))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	symbols__fixup_end(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	symbols__fixup_duplicate(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	if (!no_kcore && !dso__load_kcore(dso, map, filename))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		return maps__split_kallsyms_for_kcore(kmap->kmaps, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		return maps__split_kallsyms(kmap->kmaps, dso, delta, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) int dso__load_kallsyms(struct dso *dso, const char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		       struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	return __dso__load_kallsyms(dso, filename, map, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) static int dso__load_perf_map(const char *map_path, struct dso *dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	char *line = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	size_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	FILE *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	int nr_syms = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	file = fopen(map_path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	if (file == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		goto out_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	while (!feof(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		u64 start, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		int line_len, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		line_len = getline(&line, &n, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		if (line_len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		if (!line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 			goto out_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		line[--line_len] = '\0'; /* \n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		len = hex2u64(line, &start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		if (len + 2 >= line_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		len += hex2u64(line + len, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		if (len + 2 >= line_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		sym = symbol__new(start, size, STB_GLOBAL, STT_FUNC, line + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		if (sym == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 			goto out_delete_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		symbols__insert(&dso->symbols, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		nr_syms++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	free(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	fclose(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	return nr_syms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) out_delete_line:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	free(line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) out_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) #ifdef HAVE_LIBBFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) #define PACKAGE 'perf'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) #include <bfd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) static int bfd_symbols__cmpvalue(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	const asymbol *as = *(const asymbol **)a, *bs = *(const asymbol **)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	if (bfd_asymbol_value(as) != bfd_asymbol_value(bs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		return bfd_asymbol_value(as) - bfd_asymbol_value(bs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	return bfd_asymbol_name(as)[0] - bfd_asymbol_name(bs)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) static int bfd2elf_binding(asymbol *symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	if (symbol->flags & BSF_WEAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		return STB_WEAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	if (symbol->flags & BSF_GLOBAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		return STB_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	if (symbol->flags & BSF_LOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		return STB_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) int dso__load_bfd_symbols(struct dso *dso, const char *debugfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	int err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	long symbols_size, symbols_count, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	asection *section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	asymbol **symbols, *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	struct symbol *symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	bfd *abfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	u64 start, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	abfd = bfd_openr(dso->long_name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	if (!abfd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	if (!bfd_check_format(abfd, bfd_object)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		pr_debug2("%s: cannot read %s bfd file.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			  dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	if (bfd_get_flavour(abfd) == bfd_target_elf_flavour)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	section = bfd_get_section_by_name(abfd, ".text");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	if (section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		dso->text_offset = section->vma - section->filepos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	bfd_close(abfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	abfd = bfd_openr(debugfile, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	if (!abfd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	if (!bfd_check_format(abfd, bfd_object)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		pr_debug2("%s: cannot read %s bfd file.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 			  debugfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	if (bfd_get_flavour(abfd) == bfd_target_elf_flavour)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	symbols_size = bfd_get_symtab_upper_bound(abfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	if (symbols_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		bfd_close(abfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if (symbols_size < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	symbols = malloc(symbols_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	if (!symbols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	symbols_count = bfd_canonicalize_symtab(abfd, symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	if (symbols_count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	qsort(symbols, symbols_count, sizeof(asymbol *), bfd_symbols__cmpvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) #ifdef bfd_get_section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) #define bfd_asymbol_section bfd_get_section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	for (i = 0; i < symbols_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		sym = symbols[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		section = bfd_asymbol_section(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		if (bfd2elf_binding(sym) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		while (i + 1 < symbols_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		       bfd_asymbol_section(symbols[i + 1]) == section &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		       bfd2elf_binding(symbols[i + 1]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		if (i + 1 < symbols_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		    bfd_asymbol_section(symbols[i + 1]) == section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 			len = symbols[i + 1]->value - sym->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 			len = section->size - sym->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 		start = bfd_asymbol_value(sym) - dso->text_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		symbol = symbol__new(start, len, bfd2elf_binding(sym), STT_FUNC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 				     bfd_asymbol_name(sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		if (!symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		symbols__insert(&dso->symbols, symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) #ifdef bfd_get_section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) #undef bfd_asymbol_section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	symbols__fixup_end(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	symbols__fixup_duplicate(&dso->symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	dso->adjust_symbols = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	free(symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	bfd_close(abfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 					   enum dso_binary_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	case DSO_BINARY_TYPE__JAVA_JIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	case DSO_BINARY_TYPE__DEBUGLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		return !kmod && dso->kernel == DSO_SPACE__USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	case DSO_BINARY_TYPE__KALLSYMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	case DSO_BINARY_TYPE__VMLINUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	case DSO_BINARY_TYPE__KCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		return dso->kernel == DSO_SPACE__KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	case DSO_BINARY_TYPE__GUEST_KALLSYMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	case DSO_BINARY_TYPE__GUEST_VMLINUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	case DSO_BINARY_TYPE__GUEST_KCORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		return dso->kernel == DSO_SPACE__KERNEL_GUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	case DSO_BINARY_TYPE__GUEST_KMODULE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 		 * kernel modules know their symtab type - it's set when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		 * creating a module dso in machine__addnew_module_map().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		return kmod && dso->symtab_type == type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	case DSO_BINARY_TYPE__BPF_PROG_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	case DSO_BINARY_TYPE__BPF_IMAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	case DSO_BINARY_TYPE__OOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	case DSO_BINARY_TYPE__NOT_FOUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) /* Checks for the existence of the perf-<pid>.map file in two different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)  * locations.  First, if the process is a separate mount namespace, check in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)  * that namespace using the pid of the innermost pid namespace.  If's not in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)  * namespace, or the file can't be found there, try in the mount namespace of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)  * the tracing process using our view of its pid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) static int dso__find_perf_map(char *filebuf, size_t bufsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 			      struct nsinfo **nsip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	struct nsinfo *nsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	struct nsinfo *nnsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	int rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	nsi = *nsip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	if (nsi->need_setns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nsi->nstgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		nsinfo__mountns_enter(nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		rc = access(filebuf, R_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	nnsi = nsinfo__copy(nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	if (nnsi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 		nsinfo__put(nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		nnsi->need_setns = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nnsi->tgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		*nsip = nnsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) int dso__load(struct dso *dso, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	u_int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	struct machine *machine = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	char *root_dir = (char *) "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	int ss_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	struct symsrc ss_[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	bool kmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	bool perfmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	struct build_id bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	char newmapname[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	const char *map_path = dso->long_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	perfmap = strncmp(dso->name, "/tmp/perf-", 10) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	if (perfmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		if (dso->nsinfo && (dso__find_perf_map(newmapname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 		    sizeof(newmapname), &dso->nsinfo) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 			map_path = newmapname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	nsinfo__mountns_enter(dso->nsinfo, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	pthread_mutex_lock(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	/* check again under the dso->lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	if (dso__loaded(dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 		dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	if (dso->kernel && !kmod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 		if (dso->kernel == DSO_SPACE__KERNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 			ret = dso__load_kernel_sym(dso, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		else if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 			ret = dso__load_guest_kernel_sym(dso, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		machine = map__kmaps(map)->machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 		if (machine__is(machine, "x86_64"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 			machine__map_x86_64_entry_trampolines(machine, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	dso->adjust_symbols = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	if (perfmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 		ret = dso__load_perf_map(map_path, dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 		dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 					     DSO_BINARY_TYPE__NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	if (machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		root_dir = machine->root_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	name = malloc(PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	 * Read the build id if possible. This is required for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	if (!dso->has_build_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	    is_regular_file(dso->long_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	    __symbol__join_symfs(name, PATH_MAX, dso->long_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 		if (filename__read_build_id(name, &bid) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 			dso__set_build_id(dso, &bid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	 * Iterate over candidate debug images.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	 * Keep track of "interesting" ones (those which have a symtab, dynsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	 * and/or opd section) for processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 		struct symsrc *ss = &ss_[ss_pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		bool next_slot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 		bool is_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		bool nsexit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		int bfdrc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 		int sirc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		enum dso_binary_type symtab_type = binary_type_symtab[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		nsexit = (symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		    symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 		if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 		if (dso__read_binary_type_filename(dso, symtab_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 						   root_dir, name, PATH_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		if (nsexit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 		is_reg = is_regular_file(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) #ifdef HAVE_LIBBFD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		if (is_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			bfdrc = dso__load_bfd_symbols(dso, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		if (is_reg && bfdrc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 			sirc = symsrc__init(ss, dso, name, symtab_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		if (nsexit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 			nsinfo__mountns_enter(dso->nsinfo, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		if (bfdrc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 		if (!is_reg || sirc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		if (!syms_ss && symsrc__has_symtab(ss)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 			syms_ss = ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 			next_slot = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 			if (!dso->symsrc_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 				dso->symsrc_filename = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 		if (!runtime_ss && symsrc__possibly_runtime(ss)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 			runtime_ss = ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 			next_slot = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 		if (next_slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 			ss_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 			if (syms_ss && runtime_ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 			symsrc__destroy(ss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	if (!runtime_ss && !syms_ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	if (runtime_ss && !syms_ss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		syms_ss = runtime_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	/* We'll have to hope for the best */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	if (!runtime_ss && syms_ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 		runtime_ss = syms_ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	if (syms_ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		ret = dso__load_sym(dso, map, syms_ss, runtime_ss, kmod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		int nr_plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		if (nr_plt > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 			ret += nr_plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	for (; ss_pos > 0; ss_pos--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		symsrc__destroy(&ss_[ss_pos - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	free(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	dso__set_loaded(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	pthread_mutex_unlock(&dso->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) static int map__strcmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	const struct map *ma = *(const struct map **)a, *mb = *(const struct map **)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	return strcmp(ma->dso->short_name, mb->dso->short_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) static int map__strcmp_name(const void *name, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	const struct map *map = *(const struct map **)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	return strcmp(name, map->dso->short_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) void __maps__sort_by_name(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	qsort(maps->maps_by_name, maps->nr_maps, sizeof(struct map *), map__strcmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) static int map__groups__sort_by_name_from_rbtree(struct maps *maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	struct map **maps_by_name = realloc(maps->maps_by_name, maps->nr_maps * sizeof(map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	if (maps_by_name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	maps->maps_by_name = maps_by_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	maps->nr_maps_allocated = maps->nr_maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	maps__for_each_entry(maps, map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		maps_by_name[i++] = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	__maps__sort_by_name(maps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) static struct map *__maps__find_by_name(struct maps *maps, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	struct map **mapp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	if (maps->maps_by_name == NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	    map__groups__sort_by_name_from_rbtree(maps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	mapp = bsearch(name, maps->maps_by_name, maps->nr_maps, sizeof(*mapp), map__strcmp_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	if (mapp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		return *mapp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) struct map *maps__find_by_name(struct maps *maps, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	down_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	if (maps->last_search_by_name && strcmp(maps->last_search_by_name->dso->short_name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		map = maps->last_search_by_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	 * If we have maps->maps_by_name, then the name isn't in the rbtree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	 * as maps->maps_by_name mirrors the rbtree when lookups by name are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	 * made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	map = __maps__find_by_name(maps, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	if (map || maps->maps_by_name != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	/* Fallback to traversing the rbtree... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	maps__for_each_entry(maps, map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		if (strcmp(map->dso->short_name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			maps->last_search_by_name = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	up_read(&maps->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) int dso__load_vmlinux(struct dso *dso, struct map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 		      const char *vmlinux, bool vmlinux_allocated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	int err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	struct symsrc ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	char symfs_vmlinux[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	enum dso_binary_type symtab_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	if (vmlinux[0] == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		symbol__join_symfs(symfs_vmlinux, vmlinux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 		symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		symtab_type = DSO_BINARY_TYPE__VMLINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	err = dso__load_sym(dso, map, &ss, &ss, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	symsrc__destroy(&ss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	if (err > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 			dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 			dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 		dso__set_long_name(dso, vmlinux, vmlinux_allocated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 		dso__set_loaded(dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		pr_debug("Using %s for symbols\n", symfs_vmlinux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) int dso__load_vmlinux_path(struct dso *dso, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	char *filename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	pr_debug("Looking at the vmlinux_path (%d entries long)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 		 vmlinux_path__nr_entries + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		err = dso__load_vmlinux(dso, map, vmlinux_path[i], false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 		if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	if (!symbol_conf.ignore_vmlinux_buildid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 		filename = dso__build_id_filename(dso, NULL, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	if (filename != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 		err = dso__load_vmlinux(dso, map, filename, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		free(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static bool visible_dir_filter(const char *name, struct dirent *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	if (d->d_type != DT_DIR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	return lsdir_no_dot_filter(name, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	char kallsyms_filename[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	struct strlist *dirs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	struct str_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	dirs = lsdir(dir, visible_dir_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	if (!dirs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	strlist__for_each_entry(nd, dirs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 			  "%s/%s/kallsyms", dir, nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		if (!validate_kcore_addresses(kallsyms_filename, map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 			strlcpy(dir, kallsyms_filename, dir_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	strlist__delete(dirs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)  * Use open(O_RDONLY) to check readability directly instead of access(R_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)  * since access(R_OK) only checks with real UID/GID but open() use effective
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)  * UID/GID and actual capabilities (e.g. /proc/kcore requires CAP_SYS_RAWIO).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) static bool filename__readable(const char *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	int fd = open(file, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) static char *dso__find_kallsyms(struct dso *dso, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	struct build_id bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	char sbuild_id[SBUILD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	bool is_host = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	char path[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	if (!dso->has_build_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		 * Last resort, if we don't have a build-id and couldn't find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		 * any vmlinux file, try the running kernel kallsyms table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		goto proc_kallsyms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	if (sysfs__read_build_id("/sys/kernel/notes", &bid) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		is_host = dso__build_id_equal(dso, &bid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	/* Try a fast path for /proc/kallsyms if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	if (is_host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		 * Do not check the build-id cache, unless we know we cannot use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		 * /proc/kcore or module maps don't match to /proc/kallsyms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		 * To check readability of /proc/kcore, do not use access(R_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		 * since /proc/kcore requires CAP_SYS_RAWIO to read and access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		 * can't check it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 		if (filename__readable("/proc/kcore") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		    !validate_kcore_addresses("/proc/kallsyms", map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 			goto proc_kallsyms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	build_id__sprintf(&dso->bid, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	/* Find kallsyms in build-id cache with kcore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	scnprintf(path, sizeof(path), "%s/%s/%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		  buildid_dir, DSO__NAME_KCORE, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	if (!find_matching_kcore(map, path, sizeof(path)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		return strdup(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	/* Use current /proc/kallsyms if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	if (is_host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) proc_kallsyms:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 		return strdup("/proc/kallsyms");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	/* Finally, find a cache of kallsyms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	if (!build_id_cache__kallsyms_path(sbuild_id, path, sizeof(path))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 		pr_err("No kallsyms or vmlinux with build-id %s was found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		       sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 	return strdup(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) static int dso__load_kernel_sym(struct dso *dso, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	const char *kallsyms_filename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	char *kallsyms_allocated_filename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	 * Step 1: if the user specified a kallsyms or vmlinux filename, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	 * it and only it, reporting errors to the user if it cannot be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	 * For instance, try to analyse an ARM perf.data file _without_ a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	 * build-id, or if the user specifies the wrong path to the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	 * vmlinux file, obviously we can't fallback to another vmlinux (a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	 * x86_86 one, on the machine where analysis is being performed, say),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	 * or worse, /proc/kallsyms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	 * If the specified file _has_ a build-id and there is a build-id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	 * section in the perf.data file, we will still do the expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	 * validation in dso__load_vmlinux and will bail out if they don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	 * match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	if (symbol_conf.kallsyms_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		kallsyms_filename = symbol_conf.kallsyms_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		goto do_kallsyms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		return dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		err = dso__load_vmlinux_path(dso, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 	/* do not try local files if a symfs was given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	if (symbol_conf.symfs[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	kallsyms_allocated_filename = dso__find_kallsyms(dso, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	if (!kallsyms_allocated_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	kallsyms_filename = kallsyms_allocated_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) do_kallsyms:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	err = dso__load_kallsyms(dso, kallsyms_filename, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		pr_debug("Using %s for symbols\n", kallsyms_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	free(kallsyms_allocated_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	if (err > 0 && !dso__is_kcore(dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 		dso__set_long_name(dso, DSO__NAME_KALLSYMS, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		map__fixup_start(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		map__fixup_end(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	const char *kallsyms_filename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	struct machine *machine = map__kmaps(map)->machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	char path[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	if (machine__is_default_guest(machine)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 		 * if the user specified a vmlinux filename, use it and only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		 * it, reporting errors to the user if it cannot be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 		 * Or use file guest_kallsyms inputted by user on commandline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		if (symbol_conf.default_guest_vmlinux_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 			err = dso__load_vmlinux(dso, map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 						symbol_conf.default_guest_vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 						false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		kallsyms_filename = symbol_conf.default_guest_kallsyms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 		if (!kallsyms_filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 		sprintf(path, "%s/proc/kallsyms", machine->root_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		kallsyms_filename = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	err = dso__load_kallsyms(dso, kallsyms_filename, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		pr_debug("Using %s for symbols\n", kallsyms_filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	if (err > 0 && !dso__is_kcore(dso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 		dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 		dso__set_long_name(dso, machine->mmap_name, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 		map__fixup_start(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		map__fixup_end(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) static void vmlinux_path__exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	while (--vmlinux_path__nr_entries >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 		zfree(&vmlinux_path[vmlinux_path__nr_entries]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	vmlinux_path__nr_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	zfree(&vmlinux_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) static const char * const vmlinux_paths[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	"vmlinux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	"/boot/vmlinux"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static const char * const vmlinux_paths_upd[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	"/boot/vmlinux-%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	"/usr/lib/debug/boot/vmlinux-%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	"/lib/modules/%s/build/vmlinux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	"/usr/lib/debug/lib/modules/%s/vmlinux",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	"/usr/lib/debug/boot/vmlinux-%s.debug"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) static int vmlinux_path__add(const char *new_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	vmlinux_path[vmlinux_path__nr_entries] = strdup(new_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	++vmlinux_path__nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) static int vmlinux_path__init(struct perf_env *env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	struct utsname uts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	char bf[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	char *kernel_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	vmlinux_path = malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			      ARRAY_SIZE(vmlinux_paths_upd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	if (vmlinux_path == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	for (i = 0; i < ARRAY_SIZE(vmlinux_paths); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		if (vmlinux_path__add(vmlinux_paths[i]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	/* only try kernel version if no symfs was given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	if (symbol_conf.symfs[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	if (env) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		kernel_version = env->os_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 		if (uname(&uts) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		kernel_version = uts.release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	for (i = 0; i < ARRAY_SIZE(vmlinux_paths_upd); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 		snprintf(bf, sizeof(bf), vmlinux_paths_upd[i], kernel_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 		if (vmlinux_path__add(bf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) out_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	vmlinux_path__exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) int setup_list(struct strlist **list, const char *list_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		      const char *list_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	if (list_str == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	*list = strlist__new(list_str, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	if (!*list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		pr_err("problems parsing %s list\n", list_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	symbol_conf.has_filter = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) int setup_intlist(struct intlist **list, const char *list_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		  const char *list_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	if (list_str == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	*list = intlist__new(list_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	if (!*list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		pr_err("problems parsing %s list\n", list_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) static bool symbol__read_kptr_restrict(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	bool value = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	if (fp != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 		char line[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 		if (fgets(line, sizeof(line), fp) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 			value = perf_cap__capable(CAP_SYSLOG) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 					(atoi(line) >= 2) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 					(atoi(line) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 		fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	/* Per kernel/kallsyms.c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	 * we also restrict when perf_event_paranoid > 1 w/o CAP_SYSLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	if (perf_event_paranoid() > 1 && !perf_cap__capable(CAP_SYSLOG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		value = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) int symbol__annotation_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	if (symbol_conf.init_annotation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	if (symbol_conf.initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		pr_err("Annotation needs to be init before symbol__init()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	symbol_conf.priv_size += sizeof(struct annotation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	symbol_conf.init_annotation = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) int symbol__init(struct perf_env *env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	const char *symfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	if (symbol_conf.initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	symbol__elf_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	if (symbol_conf.sort_by_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 					  sizeof(struct symbol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 		pr_err("'.' is the only non valid --field-separator argument\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	if (setup_list(&symbol_conf.dso_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 		       symbol_conf.dso_list_str, "dso") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	if (setup_list(&symbol_conf.comm_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 		       symbol_conf.comm_list_str, "comm") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 		goto out_free_dso_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	if (setup_intlist(&symbol_conf.pid_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		       symbol_conf.pid_list_str, "pid") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 		goto out_free_comm_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	if (setup_intlist(&symbol_conf.tid_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 		       symbol_conf.tid_list_str, "tid") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		goto out_free_pid_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	if (setup_list(&symbol_conf.sym_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		       symbol_conf.sym_list_str, "symbol") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 		goto out_free_tid_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	if (setup_list(&symbol_conf.bt_stop_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		       symbol_conf.bt_stop_list_str, "symbol") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 		goto out_free_sym_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	 * A path to symbols of "/" is identical to ""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	 * reset here for simplicity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	symfs = realpath(symbol_conf.symfs, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	if (symfs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		symfs = symbol_conf.symfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	if (strcmp(symfs, "/") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 		symbol_conf.symfs = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	if (symfs != symbol_conf.symfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 		free((void *)symfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	symbol_conf.initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) out_free_sym_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	strlist__delete(symbol_conf.sym_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) out_free_tid_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	intlist__delete(symbol_conf.tid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) out_free_pid_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	intlist__delete(symbol_conf.pid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) out_free_comm_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	strlist__delete(symbol_conf.comm_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) out_free_dso_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	strlist__delete(symbol_conf.dso_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) void symbol__exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	if (!symbol_conf.initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	strlist__delete(symbol_conf.bt_stop_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	strlist__delete(symbol_conf.sym_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	strlist__delete(symbol_conf.dso_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	strlist__delete(symbol_conf.comm_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	intlist__delete(symbol_conf.tid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	intlist__delete(symbol_conf.pid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	vmlinux_path__exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	symbol_conf.bt_stop_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	symbol_conf.initialized = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) int symbol__config_symfs(const struct option *opt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 			 const char *dir, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	char *bf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	symbol_conf.symfs = strdup(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	if (symbol_conf.symfs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	/* skip the locally configured cache if a symfs is given, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	 * config buildid dir to symfs/.debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	ret = asprintf(&bf, "%s/%s", dir, ".debug");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	set_buildid_dir(bf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	free(bf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) struct mem_info *mem_info__get(struct mem_info *mi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	if (mi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 		refcount_inc(&mi->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	return mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) void mem_info__put(struct mem_info *mi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	if (mi && refcount_dec_and_test(&mi->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		free(mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) struct mem_info *mem_info__new(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	struct mem_info *mi = zalloc(sizeof(*mi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	if (mi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 		refcount_set(&mi->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	return mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) }