Home | History | Annotate | Download | only in util
      1 #include <dirent.h>
      2 #include <errno.h>
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include <string.h>
      6 #include <sys/types.h>
      7 #include <sys/stat.h>
      8 #include <sys/param.h>
      9 #include <fcntl.h>
     10 #include <unistd.h>
     11 #include <inttypes.h>
     12 #include "build-id.h"
     13 #include "util.h"
     14 #include "debug.h"
     15 #include "machine.h"
     16 #include "symbol.h"
     17 #include "strlist.h"
     18 
     19 #include <elf.h>
     20 #include <limits.h>
     21 #include <sys/utsname.h>
     22 
     23 #ifndef KSYM_NAME_LEN
     24 #define KSYM_NAME_LEN 256
     25 #endif
     26 
     27 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
     28 				symbol_filter_t filter);
     29 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
     30 			symbol_filter_t filter);
     31 int vmlinux_path__nr_entries;
     32 char **vmlinux_path;
     33 
     34 struct symbol_conf symbol_conf = {
     35 	.use_modules	  = true,
     36 	.try_vmlinux_path = true,
     37 	.annotate_src	  = true,
     38 	.demangle	  = true,
     39 	.symfs            = "",
     40 };
     41 
     42 static enum dso_binary_type binary_type_symtab[] = {
     43 	DSO_BINARY_TYPE__KALLSYMS,
     44 	DSO_BINARY_TYPE__GUEST_KALLSYMS,
     45 	DSO_BINARY_TYPE__JAVA_JIT,
     46 	DSO_BINARY_TYPE__DEBUGLINK,
     47 	DSO_BINARY_TYPE__BUILD_ID_CACHE,
     48 	DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
     49 	DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
     50 	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
     51 	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
     52 	DSO_BINARY_TYPE__GUEST_KMODULE,
     53 	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
     54 	DSO_BINARY_TYPE__NOT_FOUND,
     55 };
     56 
     57 #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
     58 
     59 bool symbol_type__is_a(char symbol_type, enum map_type map_type)
     60 {
     61 	symbol_type = toupper(symbol_type);
     62 
     63 	switch (map_type) {
     64 	case MAP__FUNCTION:
     65 		return symbol_type == 'T' || symbol_type == 'W';
     66 	case MAP__VARIABLE:
     67 		return symbol_type == 'D';
     68 	default:
     69 		return false;
     70 	}
     71 }
     72 
     73 static int prefix_underscores_count(const char *str)
     74 {
     75 	const char *tail = str;
     76 
     77 	while (*tail == '_')
     78 		tail++;
     79 
     80 	return tail - str;
     81 }
     82 
     83 #define SYMBOL_A 0
     84 #define SYMBOL_B 1
     85 
     86 static int choose_best_symbol(struct symbol *syma, struct symbol *symb)
     87 {
     88 	s64 a;
     89 	s64 b;
     90 	size_t na, nb;
     91 
     92 	/* Prefer a symbol with non zero length */
     93 	a = syma->end - syma->start;
     94 	b = symb->end - symb->start;
     95 	if ((b == 0) && (a > 0))
     96 		return SYMBOL_A;
     97 	else if ((a == 0) && (b > 0))
     98 		return SYMBOL_B;
     99 
    100 	/* Prefer a non weak symbol over a weak one */
    101 	a = syma->binding == STB_WEAK;
    102 	b = symb->binding == STB_WEAK;
    103 	if (b && !a)
    104 		return SYMBOL_A;
    105 	if (a && !b)
    106 		return SYMBOL_B;
    107 
    108 	/* Prefer a global symbol over a non global one */
    109 	a = syma->binding == STB_GLOBAL;
    110 	b = symb->binding == STB_GLOBAL;
    111 	if (a && !b)
    112 		return SYMBOL_A;
    113 	if (b && !a)
    114 		return SYMBOL_B;
    115 
    116 	/* Prefer a symbol with less underscores */
    117 	a = prefix_underscores_count(syma->name);
    118 	b = prefix_underscores_count(symb->name);
    119 	if (b > a)
    120 		return SYMBOL_A;
    121 	else if (a > b)
    122 		return SYMBOL_B;
    123 
    124 	/* Choose the symbol with the longest name */
    125 	na = strlen(syma->name);
    126 	nb = strlen(symb->name);
    127 	if (na > nb)
    128 		return SYMBOL_A;
    129 	else if (na < nb)
    130 		return SYMBOL_B;
    131 
    132 	/* Avoid "SyS" kernel syscall aliases */
    133 	if (na >= 3 && !strncmp(syma->name, "SyS", 3))
    134 		return SYMBOL_B;
    135 	if (na >= 10 && !strncmp(syma->name, "compat_SyS", 10))
    136 		return SYMBOL_B;
    137 
    138 	return SYMBOL_A;
    139 }
    140 
    141 void symbols__fixup_duplicate(struct rb_root *symbols)
    142 {
    143 	struct rb_node *nd;
    144 	struct symbol *curr, *next;
    145 
    146 	nd = rb_first(symbols);
    147 
    148 	while (nd) {
    149 		curr = rb_entry(nd, struct symbol, rb_node);
    150 again:
    151 		nd = rb_next(&curr->rb_node);
    152 		next = rb_entry(nd, struct symbol, rb_node);
    153 
    154 		if (!nd)
    155 			break;
    156 
    157 		if (curr->start != next->start)
    158 			continue;
    159 
    160 		if (choose_best_symbol(curr, next) == SYMBOL_A) {
    161 			rb_erase(&next->rb_node, symbols);
    162 			goto again;
    163 		} else {
    164 			nd = rb_next(&curr->rb_node);
    165 			rb_erase(&curr->rb_node, symbols);
    166 		}
    167 	}
    168 }
    169 
    170 void symbols__fixup_end(struct rb_root *symbols)
    171 {
    172 	struct rb_node *nd, *prevnd = rb_first(symbols);
    173 	struct symbol *curr, *prev;
    174 
    175 	if (prevnd == NULL)
    176 		return;
    177 
    178 	curr = rb_entry(prevnd, struct symbol, rb_node);
    179 
    180 	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
    181 		prev = curr;
    182 		curr = rb_entry(nd, struct symbol, rb_node);
    183 
    184 		if (prev->end == prev->start && prev->end != curr->start)
    185 			prev->end = curr->start - 1;
    186 	}
    187 
    188 	/* Last entry */
    189 	if (curr->end == curr->start)
    190 		curr->end = roundup(curr->start, 4096);
    191 }
    192 
    193 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
    194 {
    195 	struct map *prev, *curr;
    196 	struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
    197 
    198 	if (prevnd == NULL)
    199 		return;
    200 
    201 	curr = rb_entry(prevnd, struct map, rb_node);
    202 
    203 	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
    204 		prev = curr;
    205 		curr = rb_entry(nd, struct map, rb_node);
    206 		prev->end = curr->start - 1;
    207 	}
    208 
    209 	/*
    210 	 * We still haven't the actual symbols, so guess the
    211 	 * last map final address.
    212 	 */
    213 	curr->end = ~0ULL;
    214 }
    215 
    216 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
    217 {
    218 	size_t namelen = strlen(name) + 1;
    219 	struct symbol *sym = calloc(1, (symbol_conf.priv_size +
    220 					sizeof(*sym) + namelen));
    221 	if (sym == NULL)
    222 		return NULL;
    223 
    224 	if (symbol_conf.priv_size)
    225 		sym = ((void *)sym) + symbol_conf.priv_size;
    226 
    227 	sym->start   = start;
    228 	sym->end     = len ? start + len - 1 : start;
    229 	sym->binding = binding;
    230 	sym->namelen = namelen - 1;
    231 
    232 	pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
    233 		  __func__, name, start, sym->end);
    234 	memcpy(sym->name, name, namelen);
    235 
    236 	return sym;
    237 }
    238 
    239 void symbol__delete(struct symbol *sym)
    240 {
    241 	free(((void *)sym) - symbol_conf.priv_size);
    242 }
    243 
    244 size_t symbol__fprintf(struct symbol *sym, FILE *fp)
    245 {
    246 	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
    247 		       sym->start, sym->end,
    248 		       sym->binding == STB_GLOBAL ? 'g' :
    249 		       sym->binding == STB_LOCAL  ? 'l' : 'w',
    250 		       sym->name);
    251 }
    252 
    253 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
    254 				    const struct addr_location *al, FILE *fp)
    255 {
    256 	unsigned long offset;
    257 	size_t length;
    258 
    259 	if (sym && sym->name) {
    260 		length = fprintf(fp, "%s", sym->name);
    261 		if (al) {
    262 			if (al->addr < sym->end)
    263 				offset = al->addr - sym->start;
    264 			else
    265 				offset = al->addr - al->map->start - sym->start;
    266 			length += fprintf(fp, "+0x%lx", offset);
    267 		}
    268 		return length;
    269 	} else
    270 		return fprintf(fp, "[unknown]");
    271 }
    272 
    273 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
    274 {
    275 	return symbol__fprintf_symname_offs(sym, NULL, fp);
    276 }
    277 
    278 void symbols__delete(struct rb_root *symbols)
    279 {
    280 	struct symbol *pos;
    281 	struct rb_node *next = rb_first(symbols);
    282 
    283 	while (next) {
    284 		pos = rb_entry(next, struct symbol, rb_node);
    285 		next = rb_next(&pos->rb_node);
    286 		rb_erase(&pos->rb_node, symbols);
    287 		symbol__delete(pos);
    288 	}
    289 }
    290 
    291 void symbols__insert(struct rb_root *symbols, struct symbol *sym)
    292 {
    293 	struct rb_node **p = &symbols->rb_node;
    294 	struct rb_node *parent = NULL;
    295 	const u64 ip = sym->start;
    296 	struct symbol *s;
    297 
    298 	while (*p != NULL) {
    299 		parent = *p;
    300 		s = rb_entry(parent, struct symbol, rb_node);
    301 		if (ip < s->start)
    302 			p = &(*p)->rb_left;
    303 		else
    304 			p = &(*p)->rb_right;
    305 	}
    306 	rb_link_node(&sym->rb_node, parent, p);
    307 	rb_insert_color(&sym->rb_node, symbols);
    308 }
    309 
    310 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
    311 {
    312 	struct rb_node *n;
    313 
    314 	if (symbols == NULL)
    315 		return NULL;
    316 
    317 	n = symbols->rb_node;
    318 
    319 	while (n) {
    320 		struct symbol *s = rb_entry(n, struct symbol, rb_node);
    321 
    322 		if (ip < s->start)
    323 			n = n->rb_left;
    324 		else if (ip > s->end)
    325 			n = n->rb_right;
    326 		else
    327 			return s;
    328 	}
    329 
    330 	return NULL;
    331 }
    332 
    333 static struct symbol *symbols__first(struct rb_root *symbols)
    334 {
    335 	struct rb_node *n = rb_first(symbols);
    336 
    337 	if (n)
    338 		return rb_entry(n, struct symbol, rb_node);
    339 
    340 	return NULL;
    341 }
    342 
    343 struct symbol_name_rb_node {
    344 	struct rb_node	rb_node;
    345 	struct symbol	sym;
    346 };
    347 
    348 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
    349 {
    350 	struct rb_node **p = &symbols->rb_node;
    351 	struct rb_node *parent = NULL;
    352 	struct symbol_name_rb_node *symn, *s;
    353 
    354 	symn = container_of(sym, struct symbol_name_rb_node, sym);
    355 
    356 	while (*p != NULL) {
    357 		parent = *p;
    358 		s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
    359 		if (strcmp(sym->name, s->sym.name) < 0)
    360 			p = &(*p)->rb_left;
    361 		else
    362 			p = &(*p)->rb_right;
    363 	}
    364 	rb_link_node(&symn->rb_node, parent, p);
    365 	rb_insert_color(&symn->rb_node, symbols);
    366 }
    367 
    368 static void symbols__sort_by_name(struct rb_root *symbols,
    369 				  struct rb_root *source)
    370 {
    371 	struct rb_node *nd;
    372 
    373 	for (nd = rb_first(source); nd; nd = rb_next(nd)) {
    374 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
    375 		symbols__insert_by_name(symbols, pos);
    376 	}
    377 }
    378 
    379 static struct symbol *symbols__find_by_name(struct rb_root *symbols,
    380 					    const char *name)
    381 {
    382 	struct rb_node *n;
    383 
    384 	if (symbols == NULL)
    385 		return NULL;
    386 
    387 	n = symbols->rb_node;
    388 
    389 	while (n) {
    390 		struct symbol_name_rb_node *s;
    391 		int cmp;
    392 
    393 		s = rb_entry(n, struct symbol_name_rb_node, rb_node);
    394 		cmp = strcmp(name, s->sym.name);
    395 
    396 		if (cmp < 0)
    397 			n = n->rb_left;
    398 		else if (cmp > 0)
    399 			n = n->rb_right;
    400 		else
    401 			return &s->sym;
    402 	}
    403 
    404 	return NULL;
    405 }
    406 
    407 struct symbol *dso__find_symbol(struct dso *dso,
    408 				enum map_type type, u64 addr)
    409 {
    410 	return symbols__find(&dso->symbols[type], addr);
    411 }
    412 
    413 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
    414 {
    415 	return symbols__first(&dso->symbols[type]);
    416 }
    417 
    418 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
    419 					const char *name)
    420 {
    421 	return symbols__find_by_name(&dso->symbol_names[type], name);
    422 }
    423 
    424 void dso__sort_by_name(struct dso *dso, enum map_type type)
    425 {
    426 	dso__set_sorted_by_name(dso, type);
    427 	return symbols__sort_by_name(&dso->symbol_names[type],
    428 				     &dso->symbols[type]);
    429 }
    430 
    431 size_t dso__fprintf_symbols_by_name(struct dso *dso,
    432 				    enum map_type type, FILE *fp)
    433 {
    434 	size_t ret = 0;
    435 	struct rb_node *nd;
    436 	struct symbol_name_rb_node *pos;
    437 
    438 	for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
    439 		pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
    440 		fprintf(fp, "%s\n", pos->sym.name);
    441 	}
    442 
    443 	return ret;
    444 }
    445 
    446 int kallsyms__parse(const char *filename, void *arg,
    447 		    int (*process_symbol)(void *arg, const char *name,
    448 					  char type, u64 start))
    449 {
    450 	char *line = NULL;
    451 	size_t n;
    452 	int err = -1;
    453 	FILE *file = fopen(filename, "r");
    454 
    455 	if (file == NULL)
    456 		goto out_failure;
    457 
    458 	err = 0;
    459 
    460 	while (!feof(file)) {
    461 		u64 start;
    462 		int line_len, len;
    463 		char symbol_type;
    464 		char *symbol_name;
    465 
    466 		line_len = getline(&line, &n, file);
    467 		if (line_len < 0 || !line)
    468 			break;
    469 
    470 		line[--line_len] = '\0'; /* \n */
    471 
    472 		len = hex2u64(line, &start);
    473 
    474 		len++;
    475 		if (len + 2 >= line_len)
    476 			continue;
    477 
    478 		symbol_type = line[len];
    479 		len += 2;
    480 		symbol_name = line + len;
    481 		len = line_len - len;
    482 
    483 		if (len >= KSYM_NAME_LEN) {
    484 			err = -1;
    485 			break;
    486 		}
    487 
    488 		err = process_symbol(arg, symbol_name,
    489 				     symbol_type, start);
    490 		if (err)
    491 			break;
    492 	}
    493 
    494 	free(line);
    495 	fclose(file);
    496 	return err;
    497 
    498 out_failure:
    499 	return -1;
    500 }
    501 
    502 struct process_kallsyms_args {
    503 	struct map *map;
    504 	struct dso *dso;
    505 };
    506 
    507 static u8 kallsyms2elf_type(char type)
    508 {
    509 	if (type == 'W')
    510 		return STB_WEAK;
    511 
    512 	return isupper(type) ? STB_GLOBAL : STB_LOCAL;
    513 }
    514 
    515 static int map__process_kallsym_symbol(void *arg, const char *name,
    516 				       char type, u64 start)
    517 {
    518 	struct symbol *sym;
    519 	struct process_kallsyms_args *a = arg;
    520 	struct rb_root *root = &a->dso->symbols[a->map->type];
    521 
    522 	if (!symbol_type__is_a(type, a->map->type))
    523 		return 0;
    524 
    525 	/*
    526 	 * module symbols are not sorted so we add all
    527 	 * symbols, setting length to 0, and rely on
    528 	 * symbols__fixup_end() to fix it up.
    529 	 */
    530 	sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
    531 	if (sym == NULL)
    532 		return -ENOMEM;
    533 	/*
    534 	 * We will pass the symbols to the filter later, in
    535 	 * map__split_kallsyms, when we have split the maps per module
    536 	 */
    537 	symbols__insert(root, sym);
    538 
    539 	return 0;
    540 }
    541 
    542 /*
    543  * Loads the function entries in /proc/kallsyms into kernel_map->dso,
    544  * so that we can in the next step set the symbol ->end address and then
    545  * call kernel_maps__split_kallsyms.
    546  */
    547 static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
    548 				  struct map *map)
    549 {
    550 	struct process_kallsyms_args args = { .map = map, .dso = dso, };
    551 	return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
    552 }
    553 
    554 static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
    555 					 symbol_filter_t filter)
    556 {
    557 	struct map_groups *kmaps = map__kmap(map)->kmaps;
    558 	struct map *curr_map;
    559 	struct symbol *pos;
    560 	int count = 0, moved = 0;
    561 	struct rb_root *root = &dso->symbols[map->type];
    562 	struct rb_node *next = rb_first(root);
    563 
    564 	while (next) {
    565 		char *module;
    566 
    567 		pos = rb_entry(next, struct symbol, rb_node);
    568 		next = rb_next(&pos->rb_node);
    569 
    570 		module = strchr(pos->name, '\t');
    571 		if (module)
    572 			*module = '\0';
    573 
    574 		curr_map = map_groups__find(kmaps, map->type, pos->start);
    575 
    576 		if (!curr_map || (filter && filter(curr_map, pos))) {
    577 			rb_erase(&pos->rb_node, root);
    578 			symbol__delete(pos);
    579 		} else {
    580 			pos->start -= curr_map->start - curr_map->pgoff;
    581 			if (pos->end)
    582 				pos->end -= curr_map->start - curr_map->pgoff;
    583 			if (curr_map != map) {
    584 				rb_erase(&pos->rb_node, root);
    585 				symbols__insert(
    586 					&curr_map->dso->symbols[curr_map->type],
    587 					pos);
    588 				++moved;
    589 			} else {
    590 				++count;
    591 			}
    592 		}
    593 	}
    594 
    595 	/* Symbols have been adjusted */
    596 	dso->adjust_symbols = 1;
    597 
    598 	return count + moved;
    599 }
    600 
    601 /*
    602  * Split the symbols into maps, making sure there are no overlaps, i.e. the
    603  * kernel range is broken in several maps, named [kernel].N, as we don't have
    604  * the original ELF section names vmlinux have.
    605  */
    606 static int dso__split_kallsyms(struct dso *dso, struct map *map,
    607 			       symbol_filter_t filter)
    608 {
    609 	struct map_groups *kmaps = map__kmap(map)->kmaps;
    610 	struct machine *machine = kmaps->machine;
    611 	struct map *curr_map = map;
    612 	struct symbol *pos;
    613 	int count = 0, moved = 0;
    614 	struct rb_root *root = &dso->symbols[map->type];
    615 	struct rb_node *next = rb_first(root);
    616 	int kernel_range = 0;
    617 
    618 	while (next) {
    619 		char *module;
    620 
    621 		pos = rb_entry(next, struct symbol, rb_node);
    622 		next = rb_next(&pos->rb_node);
    623 
    624 		module = strchr(pos->name, '\t');
    625 		if (module) {
    626 			if (!symbol_conf.use_modules)
    627 				goto discard_symbol;
    628 
    629 			*module++ = '\0';
    630 
    631 			if (strcmp(curr_map->dso->short_name, module)) {
    632 				if (curr_map != map &&
    633 				    dso->kernel == DSO_TYPE_GUEST_KERNEL &&
    634 				    machine__is_default_guest(machine)) {
    635 					/*
    636 					 * We assume all symbols of a module are
    637 					 * continuous in * kallsyms, so curr_map
    638 					 * points to a module and all its
    639 					 * symbols are in its kmap. Mark it as
    640 					 * loaded.
    641 					 */
    642 					dso__set_loaded(curr_map->dso,
    643 							curr_map->type);
    644 				}
    645 
    646 				curr_map = map_groups__find_by_name(kmaps,
    647 							map->type, module);
    648 				if (curr_map == NULL) {
    649 					pr_debug("%s/proc/{kallsyms,modules} "
    650 					         "inconsistency while looking "
    651 						 "for \"%s\" module!\n",
    652 						 machine->root_dir, module);
    653 					curr_map = map;
    654 					goto discard_symbol;
    655 				}
    656 
    657 				if (curr_map->dso->loaded &&
    658 				    !machine__is_default_guest(machine))
    659 					goto discard_symbol;
    660 			}
    661 			/*
    662 			 * So that we look just like we get from .ko files,
    663 			 * i.e. not prelinked, relative to map->start.
    664 			 */
    665 			pos->start = curr_map->map_ip(curr_map, pos->start);
    666 			pos->end   = curr_map->map_ip(curr_map, pos->end);
    667 		} else if (curr_map != map) {
    668 			char dso_name[PATH_MAX];
    669 			struct dso *ndso;
    670 
    671 			if (count == 0) {
    672 				curr_map = map;
    673 				goto filter_symbol;
    674 			}
    675 
    676 			if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
    677 				snprintf(dso_name, sizeof(dso_name),
    678 					"[guest.kernel].%d",
    679 					kernel_range++);
    680 			else
    681 				snprintf(dso_name, sizeof(dso_name),
    682 					"[kernel].%d",
    683 					kernel_range++);
    684 
    685 			ndso = dso__new(dso_name);
    686 			if (ndso == NULL)
    687 				return -1;
    688 
    689 			ndso->kernel = dso->kernel;
    690 
    691 			curr_map = map__new2(pos->start, ndso, map->type);
    692 			if (curr_map == NULL) {
    693 				dso__delete(ndso);
    694 				return -1;
    695 			}
    696 
    697 			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
    698 			map_groups__insert(kmaps, curr_map);
    699 			++kernel_range;
    700 		}
    701 filter_symbol:
    702 		if (filter && filter(curr_map, pos)) {
    703 discard_symbol:		rb_erase(&pos->rb_node, root);
    704 			symbol__delete(pos);
    705 		} else {
    706 			if (curr_map != map) {
    707 				rb_erase(&pos->rb_node, root);
    708 				symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
    709 				++moved;
    710 			} else
    711 				++count;
    712 		}
    713 	}
    714 
    715 	if (curr_map != map &&
    716 	    dso->kernel == DSO_TYPE_GUEST_KERNEL &&
    717 	    machine__is_default_guest(kmaps->machine)) {
    718 		dso__set_loaded(curr_map->dso, curr_map->type);
    719 	}
    720 
    721 	return count + moved;
    722 }
    723 
    724 bool symbol__restricted_filename(const char *filename,
    725 				 const char *restricted_filename)
    726 {
    727 	bool restricted = false;
    728 
    729 	if (symbol_conf.kptr_restrict) {
    730 		char *r = realpath(filename, NULL);
    731 
    732 		if (r != NULL) {
    733 			restricted = strcmp(r, restricted_filename) == 0;
    734 			free(r);
    735 			return restricted;
    736 		}
    737 	}
    738 
    739 	return restricted;
    740 }
    741 
    742 struct kcore_mapfn_data {
    743 	struct dso *dso;
    744 	enum map_type type;
    745 	struct list_head maps;
    746 };
    747 
    748 static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
    749 {
    750 	struct kcore_mapfn_data *md = data;
    751 	struct map *map;
    752 
    753 	map = map__new2(start, md->dso, md->type);
    754 	if (map == NULL)
    755 		return -ENOMEM;
    756 
    757 	map->end = map->start + len;
    758 	map->pgoff = pgoff;
    759 
    760 	list_add(&map->node, &md->maps);
    761 
    762 	return 0;
    763 }
    764 
    765 /*
    766  * If kallsyms is referenced by name then we look for kcore in the same
    767  * directory.
    768  */
    769 static bool kcore_filename_from_kallsyms_filename(char *kcore_filename,
    770 						  const char *kallsyms_filename)
    771 {
    772 	char *name;
    773 
    774 	strcpy(kcore_filename, kallsyms_filename);
    775 	name = strrchr(kcore_filename, '/');
    776 	if (!name)
    777 		return false;
    778 
    779 	if (!strcmp(name, "/kallsyms")) {
    780 		strcpy(name, "/kcore");
    781 		return true;
    782 	}
    783 
    784 	return false;
    785 }
    786 
    787 static int dso__load_kcore(struct dso *dso, struct map *map,
    788 			   const char *kallsyms_filename)
    789 {
    790 	struct map_groups *kmaps = map__kmap(map)->kmaps;
    791 	struct machine *machine = kmaps->machine;
    792 	struct kcore_mapfn_data md;
    793 	struct map *old_map, *new_map, *replacement_map = NULL;
    794 	bool is_64_bit;
    795 	int err, fd;
    796 	char kcore_filename[PATH_MAX];
    797 	struct symbol *sym;
    798 
    799 	/* This function requires that the map is the kernel map */
    800 	if (map != machine->vmlinux_maps[map->type])
    801 		return -EINVAL;
    802 
    803 	if (!kcore_filename_from_kallsyms_filename(kcore_filename,
    804 						   kallsyms_filename))
    805 		return -EINVAL;
    806 
    807 	md.dso = dso;
    808 	md.type = map->type;
    809 	INIT_LIST_HEAD(&md.maps);
    810 
    811 	fd = open(kcore_filename, O_RDONLY);
    812 	if (fd < 0)
    813 		return -EINVAL;
    814 
    815 	/* Read new maps into temporary lists */
    816 	err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md,
    817 			      &is_64_bit);
    818 	if (err)
    819 		goto out_err;
    820 
    821 	if (list_empty(&md.maps)) {
    822 		err = -EINVAL;
    823 		goto out_err;
    824 	}
    825 
    826 	/* Remove old maps */
    827 	old_map = map_groups__first(kmaps, map->type);
    828 	while (old_map) {
    829 		struct map *next = map_groups__next(old_map);
    830 
    831 		if (old_map != map)
    832 			map_groups__remove(kmaps, old_map);
    833 		old_map = next;
    834 	}
    835 
    836 	/* Find the kernel map using the first symbol */
    837 	sym = dso__first_symbol(dso, map->type);
    838 	list_for_each_entry(new_map, &md.maps, node) {
    839 		if (sym && sym->start >= new_map->start &&
    840 		    sym->start < new_map->end) {
    841 			replacement_map = new_map;
    842 			break;
    843 		}
    844 	}
    845 
    846 	if (!replacement_map)
    847 		replacement_map = list_entry(md.maps.next, struct map, node);
    848 
    849 	/* Add new maps */
    850 	while (!list_empty(&md.maps)) {
    851 		new_map = list_entry(md.maps.next, struct map, node);
    852 		list_del(&new_map->node);
    853 		if (new_map == replacement_map) {
    854 			map->start	= new_map->start;
    855 			map->end	= new_map->end;
    856 			map->pgoff	= new_map->pgoff;
    857 			map->map_ip	= new_map->map_ip;
    858 			map->unmap_ip	= new_map->unmap_ip;
    859 			map__delete(new_map);
    860 			/* Ensure maps are correctly ordered */
    861 			map_groups__remove(kmaps, map);
    862 			map_groups__insert(kmaps, map);
    863 		} else {
    864 			map_groups__insert(kmaps, new_map);
    865 		}
    866 	}
    867 
    868 	/*
    869 	 * Set the data type and long name so that kcore can be read via
    870 	 * dso__data_read_addr().
    871 	 */
    872 	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
    873 		dso->data_type = DSO_BINARY_TYPE__GUEST_KCORE;
    874 	else
    875 		dso->data_type = DSO_BINARY_TYPE__KCORE;
    876 	dso__set_long_name(dso, strdup(kcore_filename));
    877 
    878 	close(fd);
    879 
    880 	if (map->type == MAP__FUNCTION)
    881 		pr_debug("Using %s for kernel object code\n", kcore_filename);
    882 	else
    883 		pr_debug("Using %s for kernel data\n", kcore_filename);
    884 
    885 	return 0;
    886 
    887 out_err:
    888 	while (!list_empty(&md.maps)) {
    889 		map = list_entry(md.maps.next, struct map, node);
    890 		list_del(&map->node);
    891 		map__delete(map);
    892 	}
    893 	close(fd);
    894 	return -EINVAL;
    895 }
    896 
    897 int dso__load_kallsyms(struct dso *dso, const char *filename,
    898 		       struct map *map, symbol_filter_t filter)
    899 {
    900 	if (symbol__restricted_filename(filename, "/proc/kallsyms"))
    901 		return -1;
    902 
    903 	if (dso__load_all_kallsyms(dso, filename, map) < 0)
    904 		return -1;
    905 
    906 	symbols__fixup_duplicate(&dso->symbols[map->type]);
    907 	symbols__fixup_end(&dso->symbols[map->type]);
    908 
    909 	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
    910 		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
    911 	else
    912 		dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
    913 
    914 	if (!dso__load_kcore(dso, map, filename))
    915 		return dso__split_kallsyms_for_kcore(dso, map, filter);
    916 	else
    917 		return dso__split_kallsyms(dso, map, filter);
    918 }
    919 
    920 static int dso__load_perf_map(struct dso *dso, struct map *map,
    921 			      symbol_filter_t filter)
    922 {
    923 	char *line = NULL;
    924 	size_t n;
    925 	FILE *file;
    926 	int nr_syms = 0;
    927 
    928 	file = fopen(dso->long_name, "r");
    929 	if (file == NULL)
    930 		goto out_failure;
    931 
    932 	while (!feof(file)) {
    933 		u64 start, size;
    934 		struct symbol *sym;
    935 		int line_len, len;
    936 
    937 		line_len = getline(&line, &n, file);
    938 		if (line_len < 0)
    939 			break;
    940 
    941 		if (!line)
    942 			goto out_failure;
    943 
    944 		line[--line_len] = '\0'; /* \n */
    945 
    946 		len = hex2u64(line, &start);
    947 
    948 		len++;
    949 		if (len + 2 >= line_len)
    950 			continue;
    951 
    952 		len += hex2u64(line + len, &size);
    953 
    954 		len++;
    955 		if (len + 2 >= line_len)
    956 			continue;
    957 
    958 		sym = symbol__new(start, size, STB_GLOBAL, line + len);
    959 
    960 		if (sym == NULL)
    961 			goto out_delete_line;
    962 
    963 		if (filter && filter(map, sym))
    964 			symbol__delete(sym);
    965 		else {
    966 			symbols__insert(&dso->symbols[map->type], sym);
    967 			nr_syms++;
    968 		}
    969 	}
    970 
    971 	free(line);
    972 	fclose(file);
    973 
    974 	return nr_syms;
    975 
    976 out_delete_line:
    977 	free(line);
    978 out_failure:
    979 	return -1;
    980 }
    981 
    982 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
    983 {
    984 	char *name;
    985 	int ret = -1;
    986 	u_int i;
    987 	struct machine *machine;
    988 	char *root_dir = (char *) "";
    989 	int ss_pos = 0;
    990 	struct symsrc ss_[2];
    991 	struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
    992 
    993 	dso__set_loaded(dso, map->type);
    994 
    995 	if (dso->kernel == DSO_TYPE_KERNEL)
    996 		return dso__load_kernel_sym(dso, map, filter);
    997 	else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
    998 		return dso__load_guest_kernel_sym(dso, map, filter);
    999 
   1000 	if (map->groups && map->groups->machine)
   1001 		machine = map->groups->machine;
   1002 	else
   1003 		machine = NULL;
   1004 
   1005 	dso->adjust_symbols = 0;
   1006 
   1007 	if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
   1008 		struct stat st;
   1009 
   1010 		if (lstat(dso->name, &st) < 0)
   1011 			return -1;
   1012 
   1013 		if (st.st_uid && (st.st_uid != geteuid())) {
   1014 			pr_warning("File %s not owned by current user or root, "
   1015 				"ignoring it.\n", dso->name);
   1016 			return -1;
   1017 		}
   1018 
   1019 		ret = dso__load_perf_map(dso, map, filter);
   1020 		dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
   1021 					     DSO_BINARY_TYPE__NOT_FOUND;
   1022 		return ret;
   1023 	}
   1024 
   1025 	if (machine)
   1026 		root_dir = machine->root_dir;
   1027 
   1028 	name = malloc(PATH_MAX);
   1029 	if (!name)
   1030 		return -1;
   1031 
   1032 	/* Iterate over candidate debug images.
   1033 	 * Keep track of "interesting" ones (those which have a symtab, dynsym,
   1034 	 * and/or opd section) for processing.
   1035 	 */
   1036 	for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
   1037 		struct symsrc *ss = &ss_[ss_pos];
   1038 		bool next_slot = false;
   1039 
   1040 		enum dso_binary_type symtab_type = binary_type_symtab[i];
   1041 
   1042 		if (dso__binary_type_file(dso, symtab_type,
   1043 					  root_dir, name, PATH_MAX))
   1044 			continue;
   1045 
   1046 		/* Name is now the name of the next image to try */
   1047 		if (symsrc__init(ss, dso, name, symtab_type) < 0)
   1048 			continue;
   1049 
   1050 		if (!syms_ss && symsrc__has_symtab(ss)) {
   1051 			syms_ss = ss;
   1052 			next_slot = true;
   1053 		}
   1054 
   1055 		if (!runtime_ss && symsrc__possibly_runtime(ss)) {
   1056 			runtime_ss = ss;
   1057 			next_slot = true;
   1058 		}
   1059 
   1060 		if (next_slot) {
   1061 			ss_pos++;
   1062 
   1063 			if (syms_ss && runtime_ss)
   1064 				break;
   1065 		}
   1066 
   1067 	}
   1068 
   1069 	if (!runtime_ss && !syms_ss)
   1070 		goto out_free;
   1071 
   1072 	if (runtime_ss && !syms_ss) {
   1073 		syms_ss = runtime_ss;
   1074 	}
   1075 
   1076 	/* We'll have to hope for the best */
   1077 	if (!runtime_ss && syms_ss)
   1078 		runtime_ss = syms_ss;
   1079 
   1080 	if (syms_ss) {
   1081 		int km;
   1082 
   1083 		km = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
   1084 		     dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;
   1085 		ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, km);
   1086 	} else {
   1087 		ret = -1;
   1088 	}
   1089 
   1090 	if (ret > 0) {
   1091 		int nr_plt;
   1092 
   1093 		nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter);
   1094 		if (nr_plt > 0)
   1095 			ret += nr_plt;
   1096 	}
   1097 
   1098 	for (; ss_pos > 0; ss_pos--)
   1099 		symsrc__destroy(&ss_[ss_pos - 1]);
   1100 out_free:
   1101 	free(name);
   1102 	if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
   1103 		return 0;
   1104 	return ret;
   1105 }
   1106 
   1107 struct map *map_groups__find_by_name(struct map_groups *mg,
   1108 				     enum map_type type, const char *name)
   1109 {
   1110 	struct rb_node *nd;
   1111 
   1112 	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
   1113 		struct map *map = rb_entry(nd, struct map, rb_node);
   1114 
   1115 		if (map->dso && strcmp(map->dso->short_name, name) == 0)
   1116 			return map;
   1117 	}
   1118 
   1119 	return NULL;
   1120 }
   1121 
   1122 int dso__load_vmlinux(struct dso *dso, struct map *map,
   1123 		      const char *vmlinux, symbol_filter_t filter)
   1124 {
   1125 	int err = -1;
   1126 	struct symsrc ss;
   1127 	char symfs_vmlinux[PATH_MAX];
   1128 	enum dso_binary_type symtab_type;
   1129 
   1130 	if (vmlinux[0] == '/')
   1131 		snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux);
   1132 	else
   1133 		snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s",
   1134 			 symbol_conf.symfs, vmlinux);
   1135 
   1136 	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
   1137 		symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
   1138 	else
   1139 		symtab_type = DSO_BINARY_TYPE__VMLINUX;
   1140 
   1141 	if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
   1142 		return -1;
   1143 
   1144 	err = dso__load_sym(dso, map, &ss, &ss, filter, 0);
   1145 	symsrc__destroy(&ss);
   1146 
   1147 	if (err > 0) {
   1148 		if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
   1149 			dso->data_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
   1150 		else
   1151 			dso->data_type = DSO_BINARY_TYPE__VMLINUX;
   1152 		dso__set_long_name(dso, (char *)vmlinux);
   1153 		dso__set_loaded(dso, map->type);
   1154 		pr_debug("Using %s for symbols\n", symfs_vmlinux);
   1155 	}
   1156 
   1157 	return err;
   1158 }
   1159 
   1160 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
   1161 			   symbol_filter_t filter)
   1162 {
   1163 	int i, err = 0;
   1164 	char *filename;
   1165 
   1166 	pr_debug("Looking at the vmlinux_path (%d entries long)\n",
   1167 		 vmlinux_path__nr_entries + 1);
   1168 
   1169 	filename = dso__build_id_filename(dso, NULL, 0);
   1170 	if (filename != NULL) {
   1171 		err = dso__load_vmlinux(dso, map, filename, filter);
   1172 		if (err > 0) {
   1173 			dso->lname_alloc = 1;
   1174 			goto out;
   1175 		}
   1176 		free(filename);
   1177 	}
   1178 
   1179 	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
   1180 		err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
   1181 		if (err > 0) {
   1182 			dso__set_long_name(dso, strdup(vmlinux_path[i]));
   1183 			dso->lname_alloc = 1;
   1184 			break;
   1185 		}
   1186 	}
   1187 out:
   1188 	return err;
   1189 }
   1190 
   1191 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
   1192 				symbol_filter_t filter)
   1193 {
   1194 	int err;
   1195 	const char *kallsyms_filename = NULL;
   1196 	char *kallsyms_allocated_filename = NULL;
   1197 	/*
   1198 	 * Step 1: if the user specified a kallsyms or vmlinux filename, use
   1199 	 * it and only it, reporting errors to the user if it cannot be used.
   1200 	 *
   1201 	 * For instance, try to analyse an ARM perf.data file _without_ a
   1202 	 * build-id, or if the user specifies the wrong path to the right
   1203 	 * vmlinux file, obviously we can't fallback to another vmlinux (a
   1204 	 * x86_86 one, on the machine where analysis is being performed, say),
   1205 	 * or worse, /proc/kallsyms.
   1206 	 *
   1207 	 * If the specified file _has_ a build-id and there is a build-id
   1208 	 * section in the perf.data file, we will still do the expected
   1209 	 * validation in dso__load_vmlinux and will bail out if they don't
   1210 	 * match.
   1211 	 */
   1212 	if (symbol_conf.kallsyms_name != NULL) {
   1213 		kallsyms_filename = symbol_conf.kallsyms_name;
   1214 		goto do_kallsyms;
   1215 	}
   1216 
   1217 	if (symbol_conf.vmlinux_name != NULL) {
   1218 		err = dso__load_vmlinux(dso, map,
   1219 					symbol_conf.vmlinux_name, filter);
   1220 		if (err > 0) {
   1221 			dso__set_long_name(dso,
   1222 					   strdup(symbol_conf.vmlinux_name));
   1223 			dso->lname_alloc = 1;
   1224 			return err;
   1225 		}
   1226 		return err;
   1227 	}
   1228 
   1229 	if (vmlinux_path != NULL) {
   1230 		err = dso__load_vmlinux_path(dso, map, filter);
   1231 		if (err > 0)
   1232 			return err;
   1233 	}
   1234 
   1235 	/* do not try local files if a symfs was given */
   1236 	if (symbol_conf.symfs[0] != 0)
   1237 		return -1;
   1238 
   1239 	/*
   1240 	 * Say the kernel DSO was created when processing the build-id header table,
   1241 	 * we have a build-id, so check if it is the same as the running kernel,
   1242 	 * using it if it is.
   1243 	 */
   1244 	if (dso->has_build_id) {
   1245 		u8 kallsyms_build_id[BUILD_ID_SIZE];
   1246 		char sbuild_id[BUILD_ID_SIZE * 2 + 1];
   1247 
   1248 		if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
   1249 					 sizeof(kallsyms_build_id)) == 0) {
   1250 			if (dso__build_id_equal(dso, kallsyms_build_id)) {
   1251 				kallsyms_filename = "/proc/kallsyms";
   1252 				goto do_kallsyms;
   1253 			}
   1254 		}
   1255 		/*
   1256 		 * Now look if we have it on the build-id cache in
   1257 		 * $HOME/.debug/[kernel.kallsyms].
   1258 		 */
   1259 		build_id__sprintf(dso->build_id, sizeof(dso->build_id),
   1260 				  sbuild_id);
   1261 
   1262 		if (asprintf(&kallsyms_allocated_filename,
   1263 			     "%s/.debug/[kernel.kallsyms]/%s",
   1264 			     getenv("HOME"), sbuild_id) == -1) {
   1265 			pr_err("Not enough memory for kallsyms file lookup\n");
   1266 			return -1;
   1267 		}
   1268 
   1269 		kallsyms_filename = kallsyms_allocated_filename;
   1270 
   1271 		if (access(kallsyms_filename, F_OK)) {
   1272 			pr_err("No kallsyms or vmlinux with build-id %s "
   1273 			       "was found\n", sbuild_id);
   1274 			free(kallsyms_allocated_filename);
   1275 			return -1;
   1276 		}
   1277 	} else {
   1278 		/*
   1279 		 * Last resort, if we don't have a build-id and couldn't find
   1280 		 * any vmlinux file, try the running kernel kallsyms table.
   1281 		 */
   1282 		kallsyms_filename = "/proc/kallsyms";
   1283 	}
   1284 
   1285 do_kallsyms:
   1286 	err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
   1287 	if (err > 0)
   1288 		pr_debug("Using %s for symbols\n", kallsyms_filename);
   1289 	free(kallsyms_allocated_filename);
   1290 
   1291 	if (err > 0 && !dso__is_kcore(dso)) {
   1292 		dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
   1293 		map__fixup_start(map);
   1294 		map__fixup_end(map);
   1295 	}
   1296 
   1297 	return err;
   1298 }
   1299 
   1300 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
   1301 				      symbol_filter_t filter)
   1302 {
   1303 	int err;
   1304 	const char *kallsyms_filename = NULL;
   1305 	struct machine *machine;
   1306 	char path[PATH_MAX];
   1307 
   1308 	if (!map->groups) {
   1309 		pr_debug("Guest kernel map hasn't the point to groups\n");
   1310 		return -1;
   1311 	}
   1312 	machine = map->groups->machine;
   1313 
   1314 	if (machine__is_default_guest(machine)) {
   1315 		/*
   1316 		 * if the user specified a vmlinux filename, use it and only
   1317 		 * it, reporting errors to the user if it cannot be used.
   1318 		 * Or use file guest_kallsyms inputted by user on commandline
   1319 		 */
   1320 		if (symbol_conf.default_guest_vmlinux_name != NULL) {
   1321 			err = dso__load_vmlinux(dso, map,
   1322 				symbol_conf.default_guest_vmlinux_name, filter);
   1323 			return err;
   1324 		}
   1325 
   1326 		kallsyms_filename = symbol_conf.default_guest_kallsyms;
   1327 		if (!kallsyms_filename)
   1328 			return -1;
   1329 	} else {
   1330 		sprintf(path, "%s/proc/kallsyms", machine->root_dir);
   1331 		kallsyms_filename = path;
   1332 	}
   1333 
   1334 	err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
   1335 	if (err > 0)
   1336 		pr_debug("Using %s for symbols\n", kallsyms_filename);
   1337 	if (err > 0 && !dso__is_kcore(dso)) {
   1338 		machine__mmap_name(machine, path, sizeof(path));
   1339 		dso__set_long_name(dso, strdup(path));
   1340 		map__fixup_start(map);
   1341 		map__fixup_end(map);
   1342 	}
   1343 
   1344 	return err;
   1345 }
   1346 
   1347 static void vmlinux_path__exit(void)
   1348 {
   1349 	while (--vmlinux_path__nr_entries >= 0) {
   1350 		free(vmlinux_path[vmlinux_path__nr_entries]);
   1351 		vmlinux_path[vmlinux_path__nr_entries] = NULL;
   1352 	}
   1353 
   1354 	free(vmlinux_path);
   1355 	vmlinux_path = NULL;
   1356 }
   1357 
   1358 static int vmlinux_path__init(void)
   1359 {
   1360 	struct utsname uts;
   1361 	char bf[PATH_MAX];
   1362 
   1363 	vmlinux_path = malloc(sizeof(char *) * 5);
   1364 	if (vmlinux_path == NULL)
   1365 		return -1;
   1366 
   1367 	vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
   1368 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
   1369 		goto out_fail;
   1370 	++vmlinux_path__nr_entries;
   1371 	vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
   1372 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
   1373 		goto out_fail;
   1374 	++vmlinux_path__nr_entries;
   1375 
   1376 	/* only try running kernel version if no symfs was given */
   1377 	if (symbol_conf.symfs[0] != 0)
   1378 		return 0;
   1379 
   1380 	if (uname(&uts) < 0)
   1381 		return -1;
   1382 
   1383 	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
   1384 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
   1385 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
   1386 		goto out_fail;
   1387 	++vmlinux_path__nr_entries;
   1388 	snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
   1389 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
   1390 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
   1391 		goto out_fail;
   1392 	++vmlinux_path__nr_entries;
   1393 	snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
   1394 		 uts.release);
   1395 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
   1396 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
   1397 		goto out_fail;
   1398 	++vmlinux_path__nr_entries;
   1399 
   1400 	return 0;
   1401 
   1402 out_fail:
   1403 	vmlinux_path__exit();
   1404 	return -1;
   1405 }
   1406 
   1407 static int setup_list(struct strlist **list, const char *list_str,
   1408 		      const char *list_name)
   1409 {
   1410 	if (list_str == NULL)
   1411 		return 0;
   1412 
   1413 	*list = strlist__new(true, list_str);
   1414 	if (!*list) {
   1415 		pr_err("problems parsing %s list\n", list_name);
   1416 		return -1;
   1417 	}
   1418 	return 0;
   1419 }
   1420 
   1421 static bool symbol__read_kptr_restrict(void)
   1422 {
   1423 	bool value = false;
   1424 
   1425 	if (geteuid() != 0) {
   1426 		FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
   1427 		if (fp != NULL) {
   1428 			char line[8];
   1429 
   1430 			if (fgets(line, sizeof(line), fp) != NULL)
   1431 				value = atoi(line) != 0;
   1432 
   1433 			fclose(fp);
   1434 		}
   1435 	}
   1436 
   1437 	return value;
   1438 }
   1439 
   1440 int symbol__init(void)
   1441 {
   1442 	const char *symfs;
   1443 
   1444 	if (symbol_conf.initialized)
   1445 		return 0;
   1446 
   1447 	symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
   1448 
   1449 	symbol__elf_init();
   1450 
   1451 	if (symbol_conf.sort_by_name)
   1452 		symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
   1453 					  sizeof(struct symbol));
   1454 
   1455 	if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
   1456 		return -1;
   1457 
   1458 	if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
   1459 		pr_err("'.' is the only non valid --field-separator argument\n");
   1460 		return -1;
   1461 	}
   1462 
   1463 	if (setup_list(&symbol_conf.dso_list,
   1464 		       symbol_conf.dso_list_str, "dso") < 0)
   1465 		return -1;
   1466 
   1467 	if (setup_list(&symbol_conf.comm_list,
   1468 		       symbol_conf.comm_list_str, "comm") < 0)
   1469 		goto out_free_dso_list;
   1470 
   1471 	if (setup_list(&symbol_conf.sym_list,
   1472 		       symbol_conf.sym_list_str, "symbol") < 0)
   1473 		goto out_free_comm_list;
   1474 
   1475 	/*
   1476 	 * A path to symbols of "/" is identical to ""
   1477 	 * reset here for simplicity.
   1478 	 */
   1479 	symfs = realpath(symbol_conf.symfs, NULL);
   1480 	if (symfs == NULL)
   1481 		symfs = symbol_conf.symfs;
   1482 	if (strcmp(symfs, "/") == 0)
   1483 		symbol_conf.symfs = "";
   1484 	if (symfs != symbol_conf.symfs)
   1485 		free((void *)symfs);
   1486 
   1487 	symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
   1488 
   1489 	symbol_conf.initialized = true;
   1490 	return 0;
   1491 
   1492 out_free_comm_list:
   1493 	strlist__delete(symbol_conf.comm_list);
   1494 out_free_dso_list:
   1495 	strlist__delete(symbol_conf.dso_list);
   1496 	return -1;
   1497 }
   1498 
   1499 void symbol__exit(void)
   1500 {
   1501 	if (!symbol_conf.initialized)
   1502 		return;
   1503 	strlist__delete(symbol_conf.sym_list);
   1504 	strlist__delete(symbol_conf.dso_list);
   1505 	strlist__delete(symbol_conf.comm_list);
   1506 	vmlinux_path__exit();
   1507 	symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
   1508 	symbol_conf.initialized = false;
   1509 }
   1510