• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define _GNU_SOURCE
2 #include <ctype.h>
3 #include <dirent.h>
4 #include <errno.h>
5 #include <libgen.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <sys/param.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <inttypes.h>
15 #include "build-id.h"
16 #include "debug.h"
17 #include "symbol.h"
18 #include "strlist.h"
19 
20 #include <libelf.h>
21 #include <gelf.h>
22 #include <elf.h>
23 #include <limits.h>
24 #include <sys/utsname.h>
25 
26 #ifndef KSYM_NAME_LEN
27 #define KSYM_NAME_LEN 128
28 #endif
29 
30 #ifndef NT_GNU_BUILD_ID
31 #define NT_GNU_BUILD_ID 3
32 #endif
33 
34 /* ANDROID_CHANGE_BEGIN */
35 #ifdef __BIONIC__
36 #define roundup(x, y)  ((((x) + ((y) - 1)) / (y)) * (y))
37 #endif
38 /* ANDROID_CHANGE_END */
39 
40 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
41 static int elf_read_build_id(Elf *elf, void *bf, size_t size);
42 static void dsos__add(struct list_head *head, struct dso *dso);
43 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
44 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
45 				symbol_filter_t filter);
46 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
47 			symbol_filter_t filter);
48 static int vmlinux_path__nr_entries;
49 static char **vmlinux_path;
50 
51 struct symbol_conf symbol_conf = {
52 	.exclude_other	  = true,
53 	.use_modules	  = true,
54 	.try_vmlinux_path = true,
55 	.symfs            = "",
56 };
57 
dso__name_len(const struct dso * dso)58 int dso__name_len(const struct dso *dso)
59 {
60 	if (verbose)
61 		return dso->long_name_len;
62 
63 	return dso->short_name_len;
64 }
65 
dso__loaded(const struct dso * dso,enum map_type type)66 bool dso__loaded(const struct dso *dso, enum map_type type)
67 {
68 	return dso->loaded & (1 << type);
69 }
70 
dso__sorted_by_name(const struct dso * dso,enum map_type type)71 bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
72 {
73 	return dso->sorted_by_name & (1 << type);
74 }
75 
dso__set_sorted_by_name(struct dso * dso,enum map_type type)76 static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
77 {
78 	dso->sorted_by_name |= (1 << type);
79 }
80 
symbol_type__is_a(char symbol_type,enum map_type map_type)81 bool symbol_type__is_a(char symbol_type, enum map_type map_type)
82 {
83 	switch (map_type) {
84 	case MAP__FUNCTION:
85 		return symbol_type == 'T' || symbol_type == 'W';
86 	case MAP__VARIABLE:
87 		return symbol_type == 'D' || symbol_type == 'd';
88 	default:
89 		return false;
90 	}
91 }
92 
symbols__fixup_end(struct rb_root * symbols)93 static void symbols__fixup_end(struct rb_root *symbols)
94 {
95 	struct rb_node *nd, *prevnd = rb_first(symbols);
96 	struct symbol *curr, *prev;
97 
98 	if (prevnd == NULL)
99 		return;
100 
101 	curr = rb_entry(prevnd, struct symbol, rb_node);
102 
103 	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
104 		prev = curr;
105 		curr = rb_entry(nd, struct symbol, rb_node);
106 
107 		if (prev->end == prev->start && prev->end != curr->start)
108 			prev->end = curr->start - 1;
109 	}
110 
111 	/* Last entry */
112 	if (curr->end == curr->start)
113 		curr->end = roundup(curr->start, 4096);
114 }
115 
__map_groups__fixup_end(struct map_groups * mg,enum map_type type)116 static void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
117 {
118 	struct map *prev, *curr;
119 	struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
120 
121 	if (prevnd == NULL)
122 		return;
123 
124 	curr = rb_entry(prevnd, struct map, rb_node);
125 
126 	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
127 		prev = curr;
128 		curr = rb_entry(nd, struct map, rb_node);
129 		prev->end = curr->start - 1;
130 	}
131 
132 	/*
133 	 * We still haven't the actual symbols, so guess the
134 	 * last map final address.
135 	 */
136 	curr->end = ~0ULL;
137 }
138 
map_groups__fixup_end(struct map_groups * mg)139 static void map_groups__fixup_end(struct map_groups *mg)
140 {
141 	int i;
142 	for (i = 0; i < MAP__NR_TYPES; ++i)
143 		__map_groups__fixup_end(mg, i);
144 }
145 
symbol__new(u64 start,u64 len,u8 binding,const char * name)146 static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
147 				  const char *name)
148 {
149 	size_t namelen = strlen(name) + 1;
150 	struct symbol *sym = calloc(1, (symbol_conf.priv_size +
151 					sizeof(*sym) + namelen));
152 	if (sym == NULL)
153 		return NULL;
154 
155 	if (symbol_conf.priv_size)
156 		sym = ((void *)sym) + symbol_conf.priv_size;
157 
158 	sym->start   = start;
159 	sym->end     = len ? start + len - 1 : start;
160 	sym->binding = binding;
161 	sym->namelen = namelen - 1;
162 
163 	pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
164 		  __func__, name, start, sym->end);
165 	memcpy(sym->name, name, namelen);
166 
167 	return sym;
168 }
169 
symbol__delete(struct symbol * sym)170 void symbol__delete(struct symbol *sym)
171 {
172 	free(((void *)sym) - symbol_conf.priv_size);
173 }
174 
symbol__fprintf(struct symbol * sym,FILE * fp)175 static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
176 {
177 	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
178 		       sym->start, sym->end,
179 		       sym->binding == STB_GLOBAL ? 'g' :
180 		       sym->binding == STB_LOCAL  ? 'l' : 'w',
181 		       sym->name);
182 }
183 
dso__set_long_name(struct dso * dso,char * name)184 void dso__set_long_name(struct dso *dso, char *name)
185 {
186 	if (name == NULL)
187 		return;
188 	dso->long_name = name;
189 	dso->long_name_len = strlen(name);
190 }
191 
dso__set_short_name(struct dso * dso,const char * name)192 static void dso__set_short_name(struct dso *dso, const char *name)
193 {
194 	if (name == NULL)
195 		return;
196 	dso->short_name = name;
197 	dso->short_name_len = strlen(name);
198 }
199 
dso__set_basename(struct dso * dso)200 static void dso__set_basename(struct dso *dso)
201 {
202 	dso__set_short_name(dso, basename(dso->long_name));
203 }
204 
dso__new(const char * name)205 struct dso *dso__new(const char *name)
206 {
207 	struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
208 
209 	if (dso != NULL) {
210 		int i;
211 		strcpy(dso->name, name);
212 		dso__set_long_name(dso, dso->name);
213 		dso__set_short_name(dso, dso->name);
214 		for (i = 0; i < MAP__NR_TYPES; ++i)
215 			dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
216 		dso->symtab_type = SYMTAB__NOT_FOUND;
217 		dso->loaded = 0;
218 		dso->sorted_by_name = 0;
219 		dso->has_build_id = 0;
220 		dso->kernel = DSO_TYPE_USER;
221 		INIT_LIST_HEAD(&dso->node);
222 	}
223 
224 	return dso;
225 }
226 
symbols__delete(struct rb_root * symbols)227 static void symbols__delete(struct rb_root *symbols)
228 {
229 	struct symbol *pos;
230 	struct rb_node *next = rb_first(symbols);
231 
232 	while (next) {
233 		pos = rb_entry(next, struct symbol, rb_node);
234 		next = rb_next(&pos->rb_node);
235 		rb_erase(&pos->rb_node, symbols);
236 		symbol__delete(pos);
237 	}
238 }
239 
dso__delete(struct dso * dso)240 void dso__delete(struct dso *dso)
241 {
242 	int i;
243 	for (i = 0; i < MAP__NR_TYPES; ++i)
244 		symbols__delete(&dso->symbols[i]);
245 	if (dso->sname_alloc)
246 		free((char *)dso->short_name);
247 	if (dso->lname_alloc)
248 		free(dso->long_name);
249 	free(dso);
250 }
251 
dso__set_build_id(struct dso * dso,void * build_id)252 void dso__set_build_id(struct dso *dso, void *build_id)
253 {
254 	memcpy(dso->build_id, build_id, sizeof(dso->build_id));
255 	dso->has_build_id = 1;
256 }
257 
symbols__insert(struct rb_root * symbols,struct symbol * sym)258 static void symbols__insert(struct rb_root *symbols, struct symbol *sym)
259 {
260 	struct rb_node **p = &symbols->rb_node;
261 	struct rb_node *parent = NULL;
262 	const u64 ip = sym->start;
263 	struct symbol *s;
264 
265 	while (*p != NULL) {
266 		parent = *p;
267 		s = rb_entry(parent, struct symbol, rb_node);
268 		if (ip < s->start)
269 			p = &(*p)->rb_left;
270 		else
271 			p = &(*p)->rb_right;
272 	}
273 	rb_link_node(&sym->rb_node, parent, p);
274 	rb_insert_color(&sym->rb_node, symbols);
275 }
276 
symbols__find(struct rb_root * symbols,u64 ip)277 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
278 {
279 	struct rb_node *n;
280 
281 	if (symbols == NULL)
282 		return NULL;
283 
284 	n = symbols->rb_node;
285 
286 	while (n) {
287 		struct symbol *s = rb_entry(n, struct symbol, rb_node);
288 
289 		if (ip < s->start)
290 			n = n->rb_left;
291 		else if (ip > s->end)
292 			n = n->rb_right;
293 		else
294 			return s;
295 	}
296 
297 	return NULL;
298 }
299 
300 struct symbol_name_rb_node {
301 	struct rb_node	rb_node;
302 	struct symbol	sym;
303 };
304 
symbols__insert_by_name(struct rb_root * symbols,struct symbol * sym)305 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
306 {
307 	struct rb_node **p = &symbols->rb_node;
308 	struct rb_node *parent = NULL;
309 	struct symbol_name_rb_node *symn, *s;
310 
311 	symn = container_of(sym, struct symbol_name_rb_node, sym);
312 
313 	while (*p != NULL) {
314 		parent = *p;
315 		s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
316 		if (strcmp(sym->name, s->sym.name) < 0)
317 			p = &(*p)->rb_left;
318 		else
319 			p = &(*p)->rb_right;
320 	}
321 	rb_link_node(&symn->rb_node, parent, p);
322 	rb_insert_color(&symn->rb_node, symbols);
323 }
324 
symbols__sort_by_name(struct rb_root * symbols,struct rb_root * source)325 static void symbols__sort_by_name(struct rb_root *symbols,
326 				  struct rb_root *source)
327 {
328 	struct rb_node *nd;
329 
330 	for (nd = rb_first(source); nd; nd = rb_next(nd)) {
331 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
332 		symbols__insert_by_name(symbols, pos);
333 	}
334 }
335 
symbols__find_by_name(struct rb_root * symbols,const char * name)336 static struct symbol *symbols__find_by_name(struct rb_root *symbols,
337 					    const char *name)
338 {
339 	struct rb_node *n;
340 
341 	if (symbols == NULL)
342 		return NULL;
343 
344 	n = symbols->rb_node;
345 
346 	while (n) {
347 		struct symbol_name_rb_node *s;
348 		int cmp;
349 
350 		s = rb_entry(n, struct symbol_name_rb_node, rb_node);
351 		cmp = strcmp(name, s->sym.name);
352 
353 		if (cmp < 0)
354 			n = n->rb_left;
355 		else if (cmp > 0)
356 			n = n->rb_right;
357 		else
358 			return &s->sym;
359 	}
360 
361 	return NULL;
362 }
363 
dso__find_symbol(struct dso * dso,enum map_type type,u64 addr)364 struct symbol *dso__find_symbol(struct dso *dso,
365 				enum map_type type, u64 addr)
366 {
367 	return symbols__find(&dso->symbols[type], addr);
368 }
369 
dso__find_symbol_by_name(struct dso * dso,enum map_type type,const char * name)370 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
371 					const char *name)
372 {
373 	return symbols__find_by_name(&dso->symbol_names[type], name);
374 }
375 
dso__sort_by_name(struct dso * dso,enum map_type type)376 void dso__sort_by_name(struct dso *dso, enum map_type type)
377 {
378 	dso__set_sorted_by_name(dso, type);
379 	return symbols__sort_by_name(&dso->symbol_names[type],
380 				     &dso->symbols[type]);
381 }
382 
build_id__sprintf(const u8 * build_id,int len,char * bf)383 int build_id__sprintf(const u8 *build_id, int len, char *bf)
384 {
385 	char *bid = bf;
386 	const u8 *raw = build_id;
387 	int i;
388 
389 	for (i = 0; i < len; ++i) {
390 		sprintf(bid, "%02x", *raw);
391 		++raw;
392 		bid += 2;
393 	}
394 
395 	return raw - build_id;
396 }
397 
dso__fprintf_buildid(struct dso * dso,FILE * fp)398 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
399 {
400 	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
401 
402 	build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
403 	return fprintf(fp, "%s", sbuild_id);
404 }
405 
dso__fprintf_symbols_by_name(struct dso * dso,enum map_type type,FILE * fp)406 size_t dso__fprintf_symbols_by_name(struct dso *dso,
407 				    enum map_type type, FILE *fp)
408 {
409 	size_t ret = 0;
410 	struct rb_node *nd;
411 	struct symbol_name_rb_node *pos;
412 
413 	for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
414 		pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
415 		fprintf(fp, "%s\n", pos->sym.name);
416 	}
417 
418 	return ret;
419 }
420 
dso__fprintf(struct dso * dso,enum map_type type,FILE * fp)421 size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
422 {
423 	struct rb_node *nd;
424 	size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
425 
426 	if (dso->short_name != dso->long_name)
427 		ret += fprintf(fp, "%s, ", dso->long_name);
428 	ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
429 		       dso->loaded ? "" : "NOT ");
430 	ret += dso__fprintf_buildid(dso, fp);
431 	ret += fprintf(fp, ")\n");
432 	for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
433 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
434 		ret += symbol__fprintf(pos, fp);
435 	}
436 
437 	return ret;
438 }
439 
kallsyms__parse(const char * filename,void * arg,int (* process_symbol)(void * arg,const char * name,char type,u64 start,u64 end))440 int kallsyms__parse(const char *filename, void *arg,
441 		    int (*process_symbol)(void *arg, const char *name,
442 					  char type, u64 start, u64 end))
443 {
444 	char *line = NULL;
445 	size_t n;
446 	int err = -1;
447 	u64 prev_start = 0;
448 	char prev_symbol_type = 0;
449 	char *prev_symbol_name;
450 	FILE *file = fopen(filename, "r");
451 
452 	if (file == NULL)
453 		goto out_failure;
454 
455 	prev_symbol_name = malloc(KSYM_NAME_LEN);
456 	if (prev_symbol_name == NULL)
457 		goto out_close;
458 
459 	err = 0;
460 
461 	while (!feof(file)) {
462 		u64 start;
463 		int line_len, len;
464 		char symbol_type;
465 		char *symbol_name;
466 
467 		line_len = getline(&line, &n, file);
468 		if (line_len < 0 || !line)
469 			break;
470 
471 		line[--line_len] = '\0'; /* \n */
472 
473 		len = hex2u64(line, &start);
474 
475 		len++;
476 		if (len + 2 >= line_len)
477 			continue;
478 
479 		symbol_type = toupper(line[len]);
480 		len += 2;
481 		symbol_name = line + len;
482 		len = line_len - len;
483 
484 		if (len >= KSYM_NAME_LEN) {
485 			err = -1;
486 			break;
487 		}
488 
489 		if (prev_symbol_type) {
490 			u64 end = start;
491 			if (end != prev_start)
492 				--end;
493 			err = process_symbol(arg, prev_symbol_name,
494 					     prev_symbol_type, prev_start, end);
495 			if (err)
496 				break;
497 		}
498 
499 		memcpy(prev_symbol_name, symbol_name, len + 1);
500 		prev_symbol_type = symbol_type;
501 		prev_start = start;
502 	}
503 
504 	free(prev_symbol_name);
505 	free(line);
506 out_close:
507 	fclose(file);
508 	return err;
509 
510 out_failure:
511 	return -1;
512 }
513 
514 struct process_kallsyms_args {
515 	struct map *map;
516 	struct dso *dso;
517 };
518 
kallsyms2elf_type(char type)519 static u8 kallsyms2elf_type(char type)
520 {
521 	if (type == 'W')
522 		return STB_WEAK;
523 
524 	return isupper(type) ? STB_GLOBAL : STB_LOCAL;
525 }
526 
map__process_kallsym_symbol(void * arg,const char * name,char type,u64 start,u64 end)527 static int map__process_kallsym_symbol(void *arg, const char *name,
528 				       char type, u64 start, u64 end)
529 {
530 	struct symbol *sym;
531 	struct process_kallsyms_args *a = arg;
532 	struct rb_root *root = &a->dso->symbols[a->map->type];
533 
534 	if (!symbol_type__is_a(type, a->map->type))
535 		return 0;
536 
537 	sym = symbol__new(start, end - start + 1,
538 			  kallsyms2elf_type(type), name);
539 	if (sym == NULL)
540 		return -ENOMEM;
541 	/*
542 	 * We will pass the symbols to the filter later, in
543 	 * map__split_kallsyms, when we have split the maps per module
544 	 */
545 	symbols__insert(root, sym);
546 
547 	return 0;
548 }
549 
550 /*
551  * Loads the function entries in /proc/kallsyms into kernel_map->dso,
552  * so that we can in the next step set the symbol ->end address and then
553  * call kernel_maps__split_kallsyms.
554  */
dso__load_all_kallsyms(struct dso * dso,const char * filename,struct map * map)555 static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
556 				  struct map *map)
557 {
558 	struct process_kallsyms_args args = { .map = map, .dso = dso, };
559 	return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
560 }
561 
562 /*
563  * Split the symbols into maps, making sure there are no overlaps, i.e. the
564  * kernel range is broken in several maps, named [kernel].N, as we don't have
565  * the original ELF section names vmlinux have.
566  */
dso__split_kallsyms(struct dso * dso,struct map * map,symbol_filter_t filter)567 static int dso__split_kallsyms(struct dso *dso, struct map *map,
568 			       symbol_filter_t filter)
569 {
570 	struct map_groups *kmaps = map__kmap(map)->kmaps;
571 	struct machine *machine = kmaps->machine;
572 	struct map *curr_map = map;
573 	struct symbol *pos;
574 	int count = 0, moved = 0;
575 	struct rb_root *root = &dso->symbols[map->type];
576 	struct rb_node *next = rb_first(root);
577 	int kernel_range = 0;
578 
579 	while (next) {
580 		char *module;
581 
582 		pos = rb_entry(next, struct symbol, rb_node);
583 		next = rb_next(&pos->rb_node);
584 
585 		module = strchr(pos->name, '\t');
586 		if (module) {
587 			if (!symbol_conf.use_modules)
588 				goto discard_symbol;
589 
590 			*module++ = '\0';
591 
592 			if (strcmp(curr_map->dso->short_name, module)) {
593 				if (curr_map != map &&
594 				    dso->kernel == DSO_TYPE_GUEST_KERNEL &&
595 				    machine__is_default_guest(machine)) {
596 					/*
597 					 * We assume all symbols of a module are
598 					 * continuous in * kallsyms, so curr_map
599 					 * points to a module and all its
600 					 * symbols are in its kmap. Mark it as
601 					 * loaded.
602 					 */
603 					dso__set_loaded(curr_map->dso,
604 							curr_map->type);
605 				}
606 
607 				curr_map = map_groups__find_by_name(kmaps,
608 							map->type, module);
609 				if (curr_map == NULL) {
610 					pr_debug("%s/proc/{kallsyms,modules} "
611 					         "inconsistency while looking "
612 						 "for \"%s\" module!\n",
613 						 machine->root_dir, module);
614 					curr_map = map;
615 					goto discard_symbol;
616 				}
617 
618 				if (curr_map->dso->loaded &&
619 				    !machine__is_default_guest(machine))
620 					goto discard_symbol;
621 			}
622 			/*
623 			 * So that we look just like we get from .ko files,
624 			 * i.e. not prelinked, relative to map->start.
625 			 */
626 			pos->start = curr_map->map_ip(curr_map, pos->start);
627 			pos->end   = curr_map->map_ip(curr_map, pos->end);
628 		} else if (curr_map != map) {
629 			char dso_name[PATH_MAX];
630 			struct dso *ndso;
631 
632 			if (count == 0) {
633 				curr_map = map;
634 				goto filter_symbol;
635 			}
636 
637 			if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
638 				snprintf(dso_name, sizeof(dso_name),
639 					"[guest.kernel].%d",
640 					kernel_range++);
641 			else
642 				snprintf(dso_name, sizeof(dso_name),
643 					"[kernel].%d",
644 					kernel_range++);
645 
646 			ndso = dso__new(dso_name);
647 			if (ndso == NULL)
648 				return -1;
649 
650 			ndso->kernel = dso->kernel;
651 
652 			curr_map = map__new2(pos->start, ndso, map->type);
653 			if (curr_map == NULL) {
654 				dso__delete(ndso);
655 				return -1;
656 			}
657 
658 			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
659 			map_groups__insert(kmaps, curr_map);
660 			++kernel_range;
661 		}
662 filter_symbol:
663 		if (filter && filter(curr_map, pos)) {
664 discard_symbol:		rb_erase(&pos->rb_node, root);
665 			symbol__delete(pos);
666 		} else {
667 			if (curr_map != map) {
668 				rb_erase(&pos->rb_node, root);
669 				symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
670 				++moved;
671 			} else
672 				++count;
673 		}
674 	}
675 
676 	if (curr_map != map &&
677 	    dso->kernel == DSO_TYPE_GUEST_KERNEL &&
678 	    machine__is_default_guest(kmaps->machine)) {
679 		dso__set_loaded(curr_map->dso, curr_map->type);
680 	}
681 
682 	return count + moved;
683 }
684 
symbol__restricted_filename(const char * filename,const char * restricted_filename)685 static bool symbol__restricted_filename(const char *filename,
686 					const char *restricted_filename)
687 {
688 	bool restricted = false;
689 
690 	if (symbol_conf.kptr_restrict) {
691 		char *r = realpath(filename, NULL);
692 
693 		if (r != NULL) {
694 			restricted = strcmp(r, restricted_filename) == 0;
695 			free(r);
696 			return restricted;
697 		}
698 	}
699 
700 	return restricted;
701 }
702 
dso__load_kallsyms(struct dso * dso,const char * filename,struct map * map,symbol_filter_t filter)703 int dso__load_kallsyms(struct dso *dso, const char *filename,
704 		       struct map *map, symbol_filter_t filter)
705 {
706 	if (symbol__restricted_filename(filename, "/proc/kallsyms"))
707 		return -1;
708 
709 	if (dso__load_all_kallsyms(dso, filename, map) < 0)
710 		return -1;
711 
712 	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
713 		dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
714 	else
715 		dso->symtab_type = SYMTAB__KALLSYMS;
716 
717 	return dso__split_kallsyms(dso, map, filter);
718 }
719 
dso__load_perf_map(struct dso * dso,struct map * map,symbol_filter_t filter)720 static int dso__load_perf_map(struct dso *dso, struct map *map,
721 			      symbol_filter_t filter)
722 {
723 	char *line = NULL;
724 	size_t n;
725 	FILE *file;
726 	int nr_syms = 0;
727 
728 	file = fopen(dso->long_name, "r");
729 	if (file == NULL)
730 		goto out_failure;
731 
732 	while (!feof(file)) {
733 		u64 start, size;
734 		struct symbol *sym;
735 		int line_len, len;
736 
737 		line_len = getline(&line, &n, file);
738 		if (line_len < 0)
739 			break;
740 
741 		if (!line)
742 			goto out_failure;
743 
744 		line[--line_len] = '\0'; /* \n */
745 
746 		len = hex2u64(line, &start);
747 
748 		len++;
749 		if (len + 2 >= line_len)
750 			continue;
751 
752 		len += hex2u64(line + len, &size);
753 
754 		len++;
755 		if (len + 2 >= line_len)
756 			continue;
757 
758 		sym = symbol__new(start, size, STB_GLOBAL, line + len);
759 
760 		if (sym == NULL)
761 			goto out_delete_line;
762 
763 		if (filter && filter(map, sym))
764 			symbol__delete(sym);
765 		else {
766 			symbols__insert(&dso->symbols[map->type], sym);
767 			nr_syms++;
768 		}
769 	}
770 
771 	free(line);
772 	fclose(file);
773 
774 	return nr_syms;
775 
776 out_delete_line:
777 	free(line);
778 out_failure:
779 	return -1;
780 }
781 
782 /**
783  * elf_symtab__for_each_symbol - iterate thru all the symbols
784  *
785  * @syms: struct elf_symtab instance to iterate
786  * @idx: uint32_t idx
787  * @sym: GElf_Sym iterator
788  */
789 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
790 	for (idx = 0, gelf_getsym(syms, idx, &sym);\
791 	     idx < nr_syms; \
792 	     idx++, gelf_getsym(syms, idx, &sym))
793 
elf_sym__type(const GElf_Sym * sym)794 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
795 {
796 	return GELF_ST_TYPE(sym->st_info);
797 }
798 
elf_sym__is_function(const GElf_Sym * sym)799 static inline int elf_sym__is_function(const GElf_Sym *sym)
800 {
801 	return elf_sym__type(sym) == STT_FUNC &&
802 	       sym->st_name != 0 &&
803 	       sym->st_shndx != SHN_UNDEF;
804 }
805 
elf_sym__is_object(const GElf_Sym * sym)806 static inline bool elf_sym__is_object(const GElf_Sym *sym)
807 {
808 	return elf_sym__type(sym) == STT_OBJECT &&
809 		sym->st_name != 0 &&
810 		sym->st_shndx != SHN_UNDEF;
811 }
812 
elf_sym__is_label(const GElf_Sym * sym)813 static inline int elf_sym__is_label(const GElf_Sym *sym)
814 {
815 	return elf_sym__type(sym) == STT_NOTYPE &&
816 		sym->st_name != 0 &&
817 		sym->st_shndx != SHN_UNDEF &&
818 		sym->st_shndx != SHN_ABS;
819 }
820 
elf_sec__name(const GElf_Shdr * shdr,const Elf_Data * secstrs)821 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
822 					const Elf_Data *secstrs)
823 {
824 	return secstrs->d_buf + shdr->sh_name;
825 }
826 
elf_sec__is_text(const GElf_Shdr * shdr,const Elf_Data * secstrs)827 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
828 					const Elf_Data *secstrs)
829 {
830 	return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
831 }
832 
elf_sec__is_data(const GElf_Shdr * shdr,const Elf_Data * secstrs)833 static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
834 				    const Elf_Data *secstrs)
835 {
836 	return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
837 }
838 
elf_sym__name(const GElf_Sym * sym,const Elf_Data * symstrs)839 static inline const char *elf_sym__name(const GElf_Sym *sym,
840 					const Elf_Data *symstrs)
841 {
842 	return symstrs->d_buf + sym->st_name;
843 }
844 
elf_section_by_name(Elf * elf,GElf_Ehdr * ep,GElf_Shdr * shp,const char * name,size_t * idx)845 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
846 				    GElf_Shdr *shp, const char *name,
847 				    size_t *idx)
848 {
849 	Elf_Scn *sec = NULL;
850 	size_t cnt = 1;
851 
852 	while ((sec = elf_nextscn(elf, sec)) != NULL) {
853 		char *str;
854 
855 		gelf_getshdr(sec, shp);
856 		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
857 		if (!strcmp(name, str)) {
858 			if (idx)
859 				*idx = cnt;
860 			break;
861 		}
862 		++cnt;
863 	}
864 
865 	return sec;
866 }
867 
868 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
869 	for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
870 	     idx < nr_entries; \
871 	     ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
872 
873 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
874 	for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
875 	     idx < nr_entries; \
876 	     ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
877 
878 /*
879  * We need to check if we have a .dynsym, so that we can handle the
880  * .plt, synthesizing its symbols, that aren't on the symtabs (be it
881  * .dynsym or .symtab).
882  * And always look at the original dso, not at debuginfo packages, that
883  * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
884  */
dso__synthesize_plt_symbols(struct dso * dso,struct map * map,symbol_filter_t filter)885 static int dso__synthesize_plt_symbols(struct  dso *dso, struct map *map,
886 				       symbol_filter_t filter)
887 {
888 	uint32_t nr_rel_entries, idx;
889 	GElf_Sym sym;
890 	u64 plt_offset;
891 	GElf_Shdr shdr_plt;
892 	struct symbol *f;
893 	GElf_Shdr shdr_rel_plt, shdr_dynsym;
894 	Elf_Data *reldata, *syms, *symstrs;
895 	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
896 	size_t dynsym_idx;
897 	GElf_Ehdr ehdr;
898 	char sympltname[1024];
899 	Elf *elf;
900 	int nr = 0, symidx, fd, err = 0;
901 	char name[PATH_MAX];
902 
903 	snprintf(name, sizeof(name), "%s%s",
904 		 symbol_conf.symfs, dso->long_name);
905 	fd = open(name, O_RDONLY);
906 	if (fd < 0)
907 		goto out;
908 
909 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
910 	if (elf == NULL)
911 		goto out_close;
912 
913 	if (gelf_getehdr(elf, &ehdr) == NULL)
914 		goto out_elf_end;
915 
916 	scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
917 					 ".dynsym", &dynsym_idx);
918 	if (scn_dynsym == NULL)
919 		goto out_elf_end;
920 
921 	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
922 					  ".rela.plt", NULL);
923 	if (scn_plt_rel == NULL) {
924 		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
925 						  ".rel.plt", NULL);
926 		if (scn_plt_rel == NULL)
927 			goto out_elf_end;
928 	}
929 
930 	err = -1;
931 
932 	if (shdr_rel_plt.sh_link != dynsym_idx)
933 		goto out_elf_end;
934 
935 	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
936 		goto out_elf_end;
937 
938 	/*
939 	 * Fetch the relocation section to find the idxes to the GOT
940 	 * and the symbols in the .dynsym they refer to.
941 	 */
942 	reldata = elf_getdata(scn_plt_rel, NULL);
943 	if (reldata == NULL)
944 		goto out_elf_end;
945 
946 	syms = elf_getdata(scn_dynsym, NULL);
947 	if (syms == NULL)
948 		goto out_elf_end;
949 
950 	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
951 	if (scn_symstrs == NULL)
952 		goto out_elf_end;
953 
954 	symstrs = elf_getdata(scn_symstrs, NULL);
955 	if (symstrs == NULL)
956 		goto out_elf_end;
957 
958 	nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
959 	plt_offset = shdr_plt.sh_offset;
960 
961 	if (shdr_rel_plt.sh_type == SHT_RELA) {
962 		GElf_Rela pos_mem, *pos;
963 
964 		elf_section__for_each_rela(reldata, pos, pos_mem, idx,
965 					   nr_rel_entries) {
966 			symidx = GELF_R_SYM(pos->r_info);
967 			plt_offset += shdr_plt.sh_entsize;
968 			gelf_getsym(syms, symidx, &sym);
969 			snprintf(sympltname, sizeof(sympltname),
970 				 "%s@plt", elf_sym__name(&sym, symstrs));
971 
972 			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
973 					STB_GLOBAL, sympltname);
974 			if (!f)
975 				goto out_elf_end;
976 
977 			if (filter && filter(map, f))
978 				symbol__delete(f);
979 			else {
980 				symbols__insert(&dso->symbols[map->type], f);
981 				++nr;
982 			}
983 		}
984 	} else if (shdr_rel_plt.sh_type == SHT_REL) {
985 		GElf_Rel pos_mem, *pos;
986 		elf_section__for_each_rel(reldata, pos, pos_mem, idx,
987 					  nr_rel_entries) {
988 			symidx = GELF_R_SYM(pos->r_info);
989 			plt_offset += shdr_plt.sh_entsize;
990 			gelf_getsym(syms, symidx, &sym);
991 			snprintf(sympltname, sizeof(sympltname),
992 				 "%s@plt", elf_sym__name(&sym, symstrs));
993 
994 			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
995 					STB_GLOBAL, sympltname);
996 			if (!f)
997 				goto out_elf_end;
998 
999 			if (filter && filter(map, f))
1000 				symbol__delete(f);
1001 			else {
1002 				symbols__insert(&dso->symbols[map->type], f);
1003 				++nr;
1004 			}
1005 		}
1006 	}
1007 
1008 	err = 0;
1009 out_elf_end:
1010 	elf_end(elf);
1011 out_close:
1012 	close(fd);
1013 
1014 	if (err == 0)
1015 		return nr;
1016 out:
1017 	pr_debug("%s: problems reading %s PLT info.\n",
1018 		 __func__, dso->long_name);
1019 	return 0;
1020 }
1021 
elf_sym__is_a(GElf_Sym * sym,enum map_type type)1022 static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type)
1023 {
1024 	switch (type) {
1025 	case MAP__FUNCTION:
1026 		return elf_sym__is_function(sym);
1027 	case MAP__VARIABLE:
1028 		return elf_sym__is_object(sym);
1029 	default:
1030 		return false;
1031 	}
1032 }
1033 
elf_sec__is_a(GElf_Shdr * shdr,Elf_Data * secstrs,enum map_type type)1034 static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs,
1035 			  enum map_type type)
1036 {
1037 	switch (type) {
1038 	case MAP__FUNCTION:
1039 		return elf_sec__is_text(shdr, secstrs);
1040 	case MAP__VARIABLE:
1041 		return elf_sec__is_data(shdr, secstrs);
1042 	default:
1043 		return false;
1044 	}
1045 }
1046 
elf_addr_to_index(Elf * elf,GElf_Addr addr)1047 static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
1048 {
1049 	Elf_Scn *sec = NULL;
1050 	GElf_Shdr shdr;
1051 	size_t cnt = 1;
1052 
1053 	while ((sec = elf_nextscn(elf, sec)) != NULL) {
1054 		gelf_getshdr(sec, &shdr);
1055 
1056 		if ((addr >= shdr.sh_addr) &&
1057 		    (addr < (shdr.sh_addr + shdr.sh_size)))
1058 			return cnt;
1059 
1060 		++cnt;
1061 	}
1062 
1063 	return -1;
1064 }
1065 
dso__load_sym(struct dso * dso,struct map * map,const char * name,int fd,symbol_filter_t filter,int kmodule,int want_symtab)1066 static int dso__load_sym(struct dso *dso, struct map *map, const char *name,
1067 			 int fd, symbol_filter_t filter, int kmodule,
1068 			 int want_symtab)
1069 {
1070 	struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
1071 	struct map *curr_map = map;
1072 	struct dso *curr_dso = dso;
1073 	Elf_Data *symstrs, *secstrs;
1074 	uint32_t nr_syms;
1075 	int err = -1;
1076 	uint32_t idx;
1077 	GElf_Ehdr ehdr;
1078 	GElf_Shdr shdr, opdshdr;
1079 	Elf_Data *syms, *opddata = NULL;
1080 	GElf_Sym sym;
1081 	Elf_Scn *sec, *sec_strndx, *opdsec;
1082 	Elf *elf;
1083 	int nr = 0;
1084 	size_t opdidx = 0;
1085 
1086 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1087 	if (elf == NULL) {
1088 		pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
1089 		goto out_close;
1090 	}
1091 
1092 	if (gelf_getehdr(elf, &ehdr) == NULL) {
1093 		pr_debug("%s: cannot get elf header.\n", __func__);
1094 		goto out_elf_end;
1095 	}
1096 
1097 	/* Always reject images with a mismatched build-id: */
1098 	if (dso->has_build_id) {
1099 		u8 build_id[BUILD_ID_SIZE];
1100 
1101 		if (elf_read_build_id(elf, build_id,
1102 				      BUILD_ID_SIZE) != BUILD_ID_SIZE)
1103 			goto out_elf_end;
1104 
1105 		if (!dso__build_id_equal(dso, build_id))
1106 			goto out_elf_end;
1107 	}
1108 
1109 	sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
1110 	if (sec == NULL) {
1111 		if (want_symtab)
1112 			goto out_elf_end;
1113 
1114 		sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
1115 		if (sec == NULL)
1116 			goto out_elf_end;
1117 	}
1118 
1119 	opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx);
1120 	if (opdshdr.sh_type != SHT_PROGBITS)
1121 		opdsec = NULL;
1122 	if (opdsec)
1123 		opddata = elf_rawdata(opdsec, NULL);
1124 
1125 	syms = elf_getdata(sec, NULL);
1126 	if (syms == NULL)
1127 		goto out_elf_end;
1128 
1129 	sec = elf_getscn(elf, shdr.sh_link);
1130 	if (sec == NULL)
1131 		goto out_elf_end;
1132 
1133 	symstrs = elf_getdata(sec, NULL);
1134 	if (symstrs == NULL)
1135 		goto out_elf_end;
1136 
1137 	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
1138 	if (sec_strndx == NULL)
1139 		goto out_elf_end;
1140 
1141 	secstrs = elf_getdata(sec_strndx, NULL);
1142 	if (secstrs == NULL)
1143 		goto out_elf_end;
1144 
1145 	nr_syms = shdr.sh_size / shdr.sh_entsize;
1146 
1147 	memset(&sym, 0, sizeof(sym));
1148 	if (dso->kernel == DSO_TYPE_USER) {
1149 		dso->adjust_symbols = (ehdr.e_type == ET_EXEC ||
1150 				elf_section_by_name(elf, &ehdr, &shdr,
1151 						     ".gnu.prelink_undo",
1152 						     NULL) != NULL);
1153 	} else {
1154 		dso->adjust_symbols = 0;
1155 	}
1156 	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1157 		struct symbol *f;
1158 		const char *elf_name = elf_sym__name(&sym, symstrs);
1159 		char *demangled = NULL;
1160 		int is_label = elf_sym__is_label(&sym);
1161 		const char *section_name;
1162 
1163 		if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
1164 		    strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
1165 			kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
1166 
1167 		if (!is_label && !elf_sym__is_a(&sym, map->type))
1168 			continue;
1169 
1170 		/* Reject ARM ELF "mapping symbols": these aren't unique and
1171 		 * don't identify functions, so will confuse the profile
1172 		 * output: */
1173 		if (ehdr.e_machine == EM_ARM) {
1174 			if (!strcmp(elf_name, "$a") ||
1175 			    !strcmp(elf_name, "$d") ||
1176 			    !strcmp(elf_name, "$t"))
1177 				continue;
1178 		}
1179 
1180 		if (opdsec && sym.st_shndx == opdidx) {
1181 			u32 offset = sym.st_value - opdshdr.sh_addr;
1182 			u64 *opd = opddata->d_buf + offset;
1183 			sym.st_value = *opd;
1184 			sym.st_shndx = elf_addr_to_index(elf, sym.st_value);
1185 		}
1186 
1187 		sec = elf_getscn(elf, sym.st_shndx);
1188 		if (!sec)
1189 			goto out_elf_end;
1190 
1191 		gelf_getshdr(sec, &shdr);
1192 
1193 		if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
1194 			continue;
1195 
1196 		section_name = elf_sec__name(&shdr, secstrs);
1197 
1198 		/* On ARM, symbols for thumb functions have 1 added to
1199 		 * the symbol address as a flag - remove it */
1200 		if ((ehdr.e_machine == EM_ARM) &&
1201 		    (map->type == MAP__FUNCTION) &&
1202 		    (sym.st_value & 1))
1203 			--sym.st_value;
1204 
1205 		if (dso->kernel != DSO_TYPE_USER || kmodule) {
1206 			char dso_name[PATH_MAX];
1207 
1208 			if (strcmp(section_name,
1209 				   (curr_dso->short_name +
1210 				    dso->short_name_len)) == 0)
1211 				goto new_symbol;
1212 
1213 			if (strcmp(section_name, ".text") == 0) {
1214 				curr_map = map;
1215 				curr_dso = dso;
1216 				goto new_symbol;
1217 			}
1218 
1219 			snprintf(dso_name, sizeof(dso_name),
1220 				 "%s%s", dso->short_name, section_name);
1221 
1222 			curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1223 			if (curr_map == NULL) {
1224 				u64 start = sym.st_value;
1225 
1226 				if (kmodule)
1227 					start += map->start + shdr.sh_offset;
1228 
1229 				curr_dso = dso__new(dso_name);
1230 				if (curr_dso == NULL)
1231 					goto out_elf_end;
1232 				curr_dso->kernel = dso->kernel;
1233 				curr_dso->long_name = dso->long_name;
1234 				curr_dso->long_name_len = dso->long_name_len;
1235 				curr_map = map__new2(start, curr_dso,
1236 						     map->type);
1237 				if (curr_map == NULL) {
1238 					dso__delete(curr_dso);
1239 					goto out_elf_end;
1240 				}
1241 				curr_map->map_ip = identity__map_ip;
1242 				curr_map->unmap_ip = identity__map_ip;
1243 				curr_dso->symtab_type = dso->symtab_type;
1244 				map_groups__insert(kmap->kmaps, curr_map);
1245 				dsos__add(&dso->node, curr_dso);
1246 				dso__set_loaded(curr_dso, map->type);
1247 			} else
1248 				curr_dso = curr_map->dso;
1249 
1250 			goto new_symbol;
1251 		}
1252 
1253 		if (curr_dso->adjust_symbols) {
1254 			pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1255 				  "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1256 				  (u64)sym.st_value, (u64)shdr.sh_addr,
1257 				  (u64)shdr.sh_offset);
1258 			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1259 		}
1260 		/*
1261 		 * We need to figure out if the object was created from C++ sources
1262 		 * DWARF DW_compile_unit has this, but we don't always have access
1263 		 * to it...
1264 		 */
1265 		demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
1266 		if (demangled != NULL)
1267 			elf_name = demangled;
1268 new_symbol:
1269 		f = symbol__new(sym.st_value, sym.st_size,
1270 				GELF_ST_BIND(sym.st_info), elf_name);
1271 		free(demangled);
1272 		if (!f)
1273 			goto out_elf_end;
1274 
1275 		if (filter && filter(curr_map, f))
1276 			symbol__delete(f);
1277 		else {
1278 			symbols__insert(&curr_dso->symbols[curr_map->type], f);
1279 			nr++;
1280 		}
1281 	}
1282 
1283 	/*
1284 	 * For misannotated, zeroed, ASM function sizes.
1285 	 */
1286 	if (nr > 0) {
1287 		symbols__fixup_end(&dso->symbols[map->type]);
1288 		if (kmap) {
1289 			/*
1290 			 * We need to fixup this here too because we create new
1291 			 * maps here, for things like vsyscall sections.
1292 			 */
1293 			__map_groups__fixup_end(kmap->kmaps, map->type);
1294 		}
1295 	}
1296 	err = nr;
1297 out_elf_end:
1298 	elf_end(elf);
1299 out_close:
1300 	return err;
1301 }
1302 
dso__build_id_equal(const struct dso * dso,u8 * build_id)1303 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
1304 {
1305 	return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
1306 }
1307 
__dsos__read_build_ids(struct list_head * head,bool with_hits)1308 bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1309 {
1310 	bool have_build_id = false;
1311 	struct dso *pos;
1312 
1313 	list_for_each_entry(pos, head, node) {
1314 		if (with_hits && !pos->hit)
1315 			continue;
1316 		if (pos->has_build_id) {
1317 			have_build_id = true;
1318 			continue;
1319 		}
1320 		if (filename__read_build_id(pos->long_name, pos->build_id,
1321 					    sizeof(pos->build_id)) > 0) {
1322 			have_build_id	  = true;
1323 			pos->has_build_id = true;
1324 		}
1325 	}
1326 
1327 	return have_build_id;
1328 }
1329 
1330 /*
1331  * Align offset to 4 bytes as needed for note name and descriptor data.
1332  */
1333 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
1334 
elf_read_build_id(Elf * elf,void * bf,size_t size)1335 static int elf_read_build_id(Elf *elf, void *bf, size_t size)
1336 {
1337 	int err = -1;
1338 	GElf_Ehdr ehdr;
1339 	GElf_Shdr shdr;
1340 	Elf_Data *data;
1341 	Elf_Scn *sec;
1342 	Elf_Kind ek;
1343 	void *ptr;
1344 
1345 	if (size < BUILD_ID_SIZE)
1346 		goto out;
1347 
1348 	ek = elf_kind(elf);
1349 	if (ek != ELF_K_ELF)
1350 		goto out;
1351 
1352 	if (gelf_getehdr(elf, &ehdr) == NULL) {
1353 		pr_err("%s: cannot get elf header.\n", __func__);
1354 		goto out;
1355 	}
1356 
1357 	sec = elf_section_by_name(elf, &ehdr, &shdr,
1358 				  ".note.gnu.build-id", NULL);
1359 	if (sec == NULL) {
1360 		sec = elf_section_by_name(elf, &ehdr, &shdr,
1361 					  ".notes", NULL);
1362 		if (sec == NULL)
1363 			goto out;
1364 	}
1365 
1366 	data = elf_getdata(sec, NULL);
1367 	if (data == NULL)
1368 		goto out;
1369 
1370 	ptr = data->d_buf;
1371 	while (ptr < (data->d_buf + data->d_size)) {
1372 		GElf_Nhdr *nhdr = ptr;
1373 		int namesz = NOTE_ALIGN(nhdr->n_namesz),
1374 		    descsz = NOTE_ALIGN(nhdr->n_descsz);
1375 		const char *name;
1376 
1377 		ptr += sizeof(*nhdr);
1378 		name = ptr;
1379 		ptr += namesz;
1380 		if (nhdr->n_type == NT_GNU_BUILD_ID &&
1381 		    nhdr->n_namesz == sizeof("GNU")) {
1382 			if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1383 				memcpy(bf, ptr, BUILD_ID_SIZE);
1384 				err = BUILD_ID_SIZE;
1385 				break;
1386 			}
1387 		}
1388 		ptr += descsz;
1389 	}
1390 
1391 out:
1392 	return err;
1393 }
1394 
filename__read_build_id(const char * filename,void * bf,size_t size)1395 int filename__read_build_id(const char *filename, void *bf, size_t size)
1396 {
1397 	int fd, err = -1;
1398 	Elf *elf;
1399 
1400 	if (size < BUILD_ID_SIZE)
1401 		goto out;
1402 
1403 	fd = open(filename, O_RDONLY);
1404 	if (fd < 0)
1405 		goto out;
1406 
1407 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1408 	if (elf == NULL) {
1409 		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1410 		goto out_close;
1411 	}
1412 
1413 	err = elf_read_build_id(elf, bf, size);
1414 
1415 	elf_end(elf);
1416 out_close:
1417 	close(fd);
1418 out:
1419 	return err;
1420 }
1421 
sysfs__read_build_id(const char * filename,void * build_id,size_t size)1422 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1423 {
1424 	int fd, err = -1;
1425 
1426 	if (size < BUILD_ID_SIZE)
1427 		goto out;
1428 
1429 	fd = open(filename, O_RDONLY);
1430 	if (fd < 0)
1431 		goto out;
1432 
1433 	while (1) {
1434 		char bf[BUFSIZ];
1435 		GElf_Nhdr nhdr;
1436 		int namesz, descsz;
1437 
1438 		if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1439 			break;
1440 
1441 		namesz = NOTE_ALIGN(nhdr.n_namesz);
1442 		descsz = NOTE_ALIGN(nhdr.n_descsz);
1443 		if (nhdr.n_type == NT_GNU_BUILD_ID &&
1444 		    nhdr.n_namesz == sizeof("GNU")) {
1445 			if (read(fd, bf, namesz) != namesz)
1446 				break;
1447 			if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1448 				if (read(fd, build_id,
1449 				    BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1450 					err = 0;
1451 					break;
1452 				}
1453 			} else if (read(fd, bf, descsz) != descsz)
1454 				break;
1455 		} else {
1456 			int n = namesz + descsz;
1457 			if (read(fd, bf, n) != n)
1458 				break;
1459 		}
1460 	}
1461 	close(fd);
1462 out:
1463 	return err;
1464 }
1465 
dso__symtab_origin(const struct dso * dso)1466 char dso__symtab_origin(const struct dso *dso)
1467 {
1468 	static const char origin[] = {
1469 		[SYMTAB__KALLSYMS]	      = 'k',
1470 		[SYMTAB__JAVA_JIT]	      = 'j',
1471 		[SYMTAB__BUILD_ID_CACHE]      = 'B',
1472 		[SYMTAB__FEDORA_DEBUGINFO]    = 'f',
1473 		[SYMTAB__UBUNTU_DEBUGINFO]    = 'u',
1474 		[SYMTAB__BUILDID_DEBUGINFO]   = 'b',
1475 		[SYMTAB__SYSTEM_PATH_DSO]     = 'd',
1476 		[SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
1477 		[SYMTAB__GUEST_KALLSYMS]      =  'g',
1478 		[SYMTAB__GUEST_KMODULE]	      =  'G',
1479 	};
1480 
1481 	if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND)
1482 		return '!';
1483 	return origin[dso->symtab_type];
1484 }
1485 
dso__load(struct dso * dso,struct map * map,symbol_filter_t filter)1486 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1487 {
1488 	int size = PATH_MAX;
1489 	char *name;
1490 	int ret = -1;
1491 	int fd;
1492 	struct machine *machine;
1493 	const char *root_dir;
1494 	int want_symtab;
1495 
1496 	dso__set_loaded(dso, map->type);
1497 
1498 	if (dso->kernel == DSO_TYPE_KERNEL)
1499 		return dso__load_kernel_sym(dso, map, filter);
1500 	else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1501 		return dso__load_guest_kernel_sym(dso, map, filter);
1502 
1503 	if (map->groups && map->groups->machine)
1504 		machine = map->groups->machine;
1505 	else
1506 		machine = NULL;
1507 
1508 	name = malloc(size);
1509 	if (!name)
1510 		return -1;
1511 
1512 	dso->adjust_symbols = 0;
1513 
1514 	if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1515 		ret = dso__load_perf_map(dso, map, filter);
1516 		dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
1517 					      SYMTAB__NOT_FOUND;
1518 		return ret;
1519 	}
1520 
1521 	/* Iterate over candidate debug images.
1522 	 * On the first pass, only load images if they have a full symtab.
1523 	 * Failing that, do a second pass where we accept .dynsym also
1524 	 */
1525 	want_symtab = 1;
1526 restart:
1527 	for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE;
1528 	     dso->symtab_type != SYMTAB__NOT_FOUND;
1529 	     dso->symtab_type++) {
1530 		switch (dso->symtab_type) {
1531 		case SYMTAB__BUILD_ID_CACHE:
1532 			/* skip the locally configured cache if a symfs is given */
1533 			if (symbol_conf.symfs[0] ||
1534 			    (dso__build_id_filename(dso, name, size) == NULL)) {
1535 				continue;
1536 			}
1537 			break;
1538 		case SYMTAB__FEDORA_DEBUGINFO:
1539 			snprintf(name, size, "%s/usr/lib/debug%s.debug",
1540 				 symbol_conf.symfs, dso->long_name);
1541 			break;
1542 		case SYMTAB__UBUNTU_DEBUGINFO:
1543 			snprintf(name, size, "%s/usr/lib/debug%s",
1544 				 symbol_conf.symfs, dso->long_name);
1545 			break;
1546 		case SYMTAB__BUILDID_DEBUGINFO: {
1547 			char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1548 
1549 			if (!dso->has_build_id)
1550 				continue;
1551 
1552 			build_id__sprintf(dso->build_id,
1553 					  sizeof(dso->build_id),
1554 					  build_id_hex);
1555 			snprintf(name, size,
1556 				 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
1557 				 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
1558 			}
1559 			break;
1560 		case SYMTAB__SYSTEM_PATH_DSO:
1561 			snprintf(name, size, "%s%s",
1562 			     symbol_conf.symfs, dso->long_name);
1563 			break;
1564 		case SYMTAB__GUEST_KMODULE:
1565 			if (map->groups && machine)
1566 				root_dir = machine->root_dir;
1567 			else
1568 				root_dir = "";
1569 			snprintf(name, size, "%s%s%s", symbol_conf.symfs,
1570 				 root_dir, dso->long_name);
1571 			break;
1572 
1573 		case SYMTAB__SYSTEM_PATH_KMODULE:
1574 			snprintf(name, size, "%s%s", symbol_conf.symfs,
1575 				 dso->long_name);
1576 			break;
1577 		default:;
1578 		}
1579 
1580 		/* Name is now the name of the next image to try */
1581 		fd = open(name, O_RDONLY);
1582 		if (fd < 0)
1583 			continue;
1584 
1585 		ret = dso__load_sym(dso, map, name, fd, filter, 0,
1586 				    want_symtab);
1587 		close(fd);
1588 
1589 		/*
1590 		 * Some people seem to have debuginfo files _WITHOUT_ debug
1591 		 * info!?!?
1592 		 */
1593 		if (!ret)
1594 			continue;
1595 
1596 		if (ret > 0) {
1597 			int nr_plt = dso__synthesize_plt_symbols(dso, map,
1598 								 filter);
1599 			if (nr_plt > 0)
1600 				ret += nr_plt;
1601 			break;
1602 		}
1603 	}
1604 
1605 	/*
1606 	 * If we wanted a full symtab but no image had one,
1607 	 * relax our requirements and repeat the search.
1608 	 */
1609 	if (ret <= 0 && want_symtab) {
1610 		want_symtab = 0;
1611 		goto restart;
1612 	}
1613 
1614 	free(name);
1615 	if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1616 		return 0;
1617 	return ret;
1618 }
1619 
map_groups__find_by_name(struct map_groups * mg,enum map_type type,const char * name)1620 struct map *map_groups__find_by_name(struct map_groups *mg,
1621 				     enum map_type type, const char *name)
1622 {
1623 	struct rb_node *nd;
1624 
1625 	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1626 		struct map *map = rb_entry(nd, struct map, rb_node);
1627 
1628 		if (map->dso && strcmp(map->dso->short_name, name) == 0)
1629 			return map;
1630 	}
1631 
1632 	return NULL;
1633 }
1634 
dso__kernel_module_get_build_id(struct dso * dso,const char * root_dir)1635 static int dso__kernel_module_get_build_id(struct dso *dso,
1636 					   const char *root_dir)
1637 {
1638 	char filename[PATH_MAX];
1639 	/*
1640 	 * kernel module short names are of the form "[module]" and
1641 	 * we need just "module" here.
1642 	 */
1643 	const char *name = dso->short_name + 1;
1644 
1645 	snprintf(filename, sizeof(filename),
1646 		 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1647 		 root_dir, (int)strlen(name) - 1, name);
1648 
1649 	if (sysfs__read_build_id(filename, dso->build_id,
1650 				 sizeof(dso->build_id)) == 0)
1651 		dso->has_build_id = true;
1652 
1653 	return 0;
1654 }
1655 
map_groups__set_modules_path_dir(struct map_groups * mg,const char * dir_name)1656 static int map_groups__set_modules_path_dir(struct map_groups *mg,
1657 				const char *dir_name)
1658 {
1659 	struct dirent *dent;
1660 	DIR *dir = opendir(dir_name);
1661 	int ret = 0;
1662 
1663 	if (!dir) {
1664 		pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
1665 		return -1;
1666 	}
1667 
1668 	while ((dent = readdir(dir)) != NULL) {
1669 		char path[PATH_MAX];
1670 		struct stat st;
1671 
1672 		/*sshfs might return bad dent->d_type, so we have to stat*/
1673 		sprintf(path, "%s/%s", dir_name, dent->d_name);
1674 		if (stat(path, &st))
1675 			continue;
1676 
1677 		if (S_ISDIR(st.st_mode)) {
1678 			if (!strcmp(dent->d_name, ".") ||
1679 			    !strcmp(dent->d_name, ".."))
1680 				continue;
1681 
1682 			snprintf(path, sizeof(path), "%s/%s",
1683 				 dir_name, dent->d_name);
1684 			ret = map_groups__set_modules_path_dir(mg, path);
1685 			if (ret < 0)
1686 				goto out;
1687 		} else {
1688 			char *dot = strrchr(dent->d_name, '.'),
1689 			     dso_name[PATH_MAX];
1690 			struct map *map;
1691 			char *long_name;
1692 
1693 			if (dot == NULL || strcmp(dot, ".ko"))
1694 				continue;
1695 			snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1696 				 (int)(dot - dent->d_name), dent->d_name);
1697 
1698 			strxfrchar(dso_name, '-', '_');
1699 			map = map_groups__find_by_name(mg, MAP__FUNCTION,
1700 						       dso_name);
1701 			if (map == NULL)
1702 				continue;
1703 
1704 			snprintf(path, sizeof(path), "%s/%s",
1705 				 dir_name, dent->d_name);
1706 
1707 			long_name = strdup(path);
1708 			if (long_name == NULL) {
1709 				ret = -1;
1710 				goto out;
1711 			}
1712 			dso__set_long_name(map->dso, long_name);
1713 			map->dso->lname_alloc = 1;
1714 			dso__kernel_module_get_build_id(map->dso, "");
1715 		}
1716 	}
1717 
1718 out:
1719 	closedir(dir);
1720 	return ret;
1721 }
1722 
get_kernel_version(const char * root_dir)1723 static char *get_kernel_version(const char *root_dir)
1724 {
1725 	char version[PATH_MAX];
1726 	FILE *file;
1727 	char *name, *tmp;
1728 	const char *prefix = "Linux version ";
1729 
1730 	sprintf(version, "%s/proc/version", root_dir);
1731 	file = fopen(version, "r");
1732 	if (!file)
1733 		return NULL;
1734 
1735 	version[0] = '\0';
1736 	tmp = fgets(version, sizeof(version), file);
1737 	fclose(file);
1738 
1739 	name = strstr(version, prefix);
1740 	if (!name)
1741 		return NULL;
1742 	name += strlen(prefix);
1743 	tmp = strchr(name, ' ');
1744 	if (tmp)
1745 		*tmp = '\0';
1746 
1747 	return strdup(name);
1748 }
1749 
machine__set_modules_path(struct machine * machine)1750 static int machine__set_modules_path(struct machine *machine)
1751 {
1752 	char *version;
1753 	char modules_path[PATH_MAX];
1754 
1755 	version = get_kernel_version(machine->root_dir);
1756 	if (!version)
1757 		return -1;
1758 
1759 	snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1760 		 machine->root_dir, version);
1761 	free(version);
1762 
1763 	return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
1764 }
1765 
1766 /*
1767  * Constructor variant for modules (where we know from /proc/modules where
1768  * they are loaded) and for vmlinux, where only after we load all the
1769  * symbols we'll know where it starts and ends.
1770  */
map__new2(u64 start,struct dso * dso,enum map_type type)1771 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1772 {
1773 	struct map *map = calloc(1, (sizeof(*map) +
1774 				     (dso->kernel ? sizeof(struct kmap) : 0)));
1775 	if (map != NULL) {
1776 		/*
1777 		 * ->end will be filled after we load all the symbols
1778 		 */
1779 		map__init(map, type, start, 0, 0, dso);
1780 	}
1781 
1782 	return map;
1783 }
1784 
machine__new_module(struct machine * machine,u64 start,const char * filename)1785 struct map *machine__new_module(struct machine *machine, u64 start,
1786 				const char *filename)
1787 {
1788 	struct map *map;
1789 	struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
1790 
1791 	if (dso == NULL)
1792 		return NULL;
1793 
1794 	map = map__new2(start, dso, MAP__FUNCTION);
1795 	if (map == NULL)
1796 		return NULL;
1797 
1798 	if (machine__is_host(machine))
1799 		dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
1800 	else
1801 		dso->symtab_type = SYMTAB__GUEST_KMODULE;
1802 	map_groups__insert(&machine->kmaps, map);
1803 	return map;
1804 }
1805 
machine__create_modules(struct machine * machine)1806 static int machine__create_modules(struct machine *machine)
1807 {
1808 	char *line = NULL;
1809 	size_t n;
1810 	FILE *file;
1811 	struct map *map;
1812 	const char *modules;
1813 	char path[PATH_MAX];
1814 
1815 	if (machine__is_default_guest(machine))
1816 		modules = symbol_conf.default_guest_modules;
1817 	else {
1818 		sprintf(path, "%s/proc/modules", machine->root_dir);
1819 		modules = path;
1820 	}
1821 
1822 	if (symbol__restricted_filename(path, "/proc/modules"))
1823 		return -1;
1824 
1825 	file = fopen(modules, "r");
1826 	if (file == NULL)
1827 		return -1;
1828 
1829 	while (!feof(file)) {
1830 		char name[PATH_MAX];
1831 		u64 start;
1832 		char *sep;
1833 		int line_len;
1834 
1835 		line_len = getline(&line, &n, file);
1836 		if (line_len < 0)
1837 			break;
1838 
1839 		if (!line)
1840 			goto out_failure;
1841 
1842 		line[--line_len] = '\0'; /* \n */
1843 
1844 		sep = strrchr(line, 'x');
1845 		if (sep == NULL)
1846 			continue;
1847 
1848 		hex2u64(sep + 1, &start);
1849 
1850 		sep = strchr(line, ' ');
1851 		if (sep == NULL)
1852 			continue;
1853 
1854 		*sep = '\0';
1855 
1856 		snprintf(name, sizeof(name), "[%s]", line);
1857 		map = machine__new_module(machine, start, name);
1858 		if (map == NULL)
1859 			goto out_delete_line;
1860 		dso__kernel_module_get_build_id(map->dso, machine->root_dir);
1861 	}
1862 
1863 	free(line);
1864 	fclose(file);
1865 
1866 	return machine__set_modules_path(machine);
1867 
1868 out_delete_line:
1869 	free(line);
1870 out_failure:
1871 	return -1;
1872 }
1873 
dso__load_vmlinux(struct dso * dso,struct map * map,const char * vmlinux,symbol_filter_t filter)1874 int dso__load_vmlinux(struct dso *dso, struct map *map,
1875 		      const char *vmlinux, symbol_filter_t filter)
1876 {
1877 	int err = -1, fd;
1878 	char symfs_vmlinux[PATH_MAX];
1879 
1880 	snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s",
1881 		 symbol_conf.symfs, vmlinux);
1882 	fd = open(symfs_vmlinux, O_RDONLY);
1883 	if (fd < 0)
1884 		return -1;
1885 
1886 	dso__set_long_name(dso, (char *)vmlinux);
1887 	dso__set_loaded(dso, map->type);
1888 	err = dso__load_sym(dso, map, symfs_vmlinux, fd, filter, 0, 0);
1889 	close(fd);
1890 
1891 	if (err > 0)
1892 		pr_debug("Using %s for symbols\n", symfs_vmlinux);
1893 
1894 	return err;
1895 }
1896 
dso__load_vmlinux_path(struct dso * dso,struct map * map,symbol_filter_t filter)1897 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1898 			   symbol_filter_t filter)
1899 {
1900 	int i, err = 0;
1901 	char *filename;
1902 
1903 	pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1904 		 vmlinux_path__nr_entries + 1);
1905 
1906 	filename = dso__build_id_filename(dso, NULL, 0);
1907 	if (filename != NULL) {
1908 		err = dso__load_vmlinux(dso, map, filename, filter);
1909 		if (err > 0) {
1910 			dso__set_long_name(dso, filename);
1911 			goto out;
1912 		}
1913 		free(filename);
1914 	}
1915 
1916 	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1917 		err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
1918 		if (err > 0) {
1919 			dso__set_long_name(dso, strdup(vmlinux_path[i]));
1920 			break;
1921 		}
1922 	}
1923 out:
1924 	return err;
1925 }
1926 
dso__load_kernel_sym(struct dso * dso,struct map * map,symbol_filter_t filter)1927 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1928 				symbol_filter_t filter)
1929 {
1930 	int err;
1931 	const char *kallsyms_filename = NULL;
1932 	char *kallsyms_allocated_filename = NULL;
1933 	/*
1934 	 * Step 1: if the user specified a kallsyms or vmlinux filename, use
1935 	 * it and only it, reporting errors to the user if it cannot be used.
1936 	 *
1937 	 * For instance, try to analyse an ARM perf.data file _without_ a
1938 	 * build-id, or if the user specifies the wrong path to the right
1939 	 * vmlinux file, obviously we can't fallback to another vmlinux (a
1940 	 * x86_86 one, on the machine where analysis is being performed, say),
1941 	 * or worse, /proc/kallsyms.
1942 	 *
1943 	 * If the specified file _has_ a build-id and there is a build-id
1944 	 * section in the perf.data file, we will still do the expected
1945 	 * validation in dso__load_vmlinux and will bail out if they don't
1946 	 * match.
1947 	 */
1948 	if (symbol_conf.kallsyms_name != NULL) {
1949 		kallsyms_filename = symbol_conf.kallsyms_name;
1950 		goto do_kallsyms;
1951 	}
1952 
1953 	if (symbol_conf.vmlinux_name != NULL) {
1954 		err = dso__load_vmlinux(dso, map,
1955 					symbol_conf.vmlinux_name, filter);
1956 		if (err > 0) {
1957 			dso__set_long_name(dso,
1958 					   strdup(symbol_conf.vmlinux_name));
1959 			goto out_fixup;
1960 		}
1961 		return err;
1962 	}
1963 
1964 	if (vmlinux_path != NULL) {
1965 		err = dso__load_vmlinux_path(dso, map, filter);
1966 		if (err > 0)
1967 			goto out_fixup;
1968 	}
1969 
1970 	/* do not try local files if a symfs was given */
1971 	if (symbol_conf.symfs[0] != 0)
1972 		return -1;
1973 
1974 	/*
1975 	 * Say the kernel DSO was created when processing the build-id header table,
1976 	 * we have a build-id, so check if it is the same as the running kernel,
1977 	 * using it if it is.
1978 	 */
1979 	if (dso->has_build_id) {
1980 		u8 kallsyms_build_id[BUILD_ID_SIZE];
1981 		char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1982 
1983 		if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1984 					 sizeof(kallsyms_build_id)) == 0) {
1985 			if (dso__build_id_equal(dso, kallsyms_build_id)) {
1986 				kallsyms_filename = "/proc/kallsyms";
1987 				goto do_kallsyms;
1988 			}
1989 		}
1990 		/*
1991 		 * Now look if we have it on the build-id cache in
1992 		 * $HOME/.debug/[kernel.kallsyms].
1993 		 */
1994 		build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1995 				  sbuild_id);
1996 
1997 		if (asprintf(&kallsyms_allocated_filename,
1998 			     "%s/.debug/[kernel.kallsyms]/%s",
1999 			     getenv("HOME"), sbuild_id) == -1) {
2000 			pr_err("Not enough memory for kallsyms file lookup\n");
2001 			return -1;
2002 		}
2003 
2004 		kallsyms_filename = kallsyms_allocated_filename;
2005 
2006 		if (access(kallsyms_filename, F_OK)) {
2007 			pr_err("No kallsyms or vmlinux with build-id %s "
2008 			       "was found\n", sbuild_id);
2009 			free(kallsyms_allocated_filename);
2010 			return -1;
2011 		}
2012 	} else {
2013 		/*
2014 		 * Last resort, if we don't have a build-id and couldn't find
2015 		 * any vmlinux file, try the running kernel kallsyms table.
2016 		 */
2017 		kallsyms_filename = "/proc/kallsyms";
2018 	}
2019 
2020 do_kallsyms:
2021 	err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
2022 	if (err > 0)
2023 		pr_debug("Using %s for symbols\n", kallsyms_filename);
2024 	free(kallsyms_allocated_filename);
2025 
2026 	if (err > 0) {
2027 out_fixup:
2028 		if (kallsyms_filename != NULL)
2029 			dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
2030 		map__fixup_start(map);
2031 		map__fixup_end(map);
2032 	}
2033 
2034 	return err;
2035 }
2036 
dso__load_guest_kernel_sym(struct dso * dso,struct map * map,symbol_filter_t filter)2037 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
2038 				      symbol_filter_t filter)
2039 {
2040 	int err;
2041 	const char *kallsyms_filename = NULL;
2042 	struct machine *machine;
2043 	char path[PATH_MAX];
2044 
2045 	if (!map->groups) {
2046 		pr_debug("Guest kernel map hasn't the point to groups\n");
2047 		return -1;
2048 	}
2049 	machine = map->groups->machine;
2050 
2051 	if (machine__is_default_guest(machine)) {
2052 		/*
2053 		 * if the user specified a vmlinux filename, use it and only
2054 		 * it, reporting errors to the user if it cannot be used.
2055 		 * Or use file guest_kallsyms inputted by user on commandline
2056 		 */
2057 		if (symbol_conf.default_guest_vmlinux_name != NULL) {
2058 			err = dso__load_vmlinux(dso, map,
2059 				symbol_conf.default_guest_vmlinux_name, filter);
2060 			goto out_try_fixup;
2061 		}
2062 
2063 		kallsyms_filename = symbol_conf.default_guest_kallsyms;
2064 		if (!kallsyms_filename)
2065 			return -1;
2066 	} else {
2067 		sprintf(path, "%s/proc/kallsyms", machine->root_dir);
2068 		kallsyms_filename = path;
2069 	}
2070 
2071 	err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
2072 	if (err > 0)
2073 		pr_debug("Using %s for symbols\n", kallsyms_filename);
2074 
2075 out_try_fixup:
2076 	if (err > 0) {
2077 		if (kallsyms_filename != NULL) {
2078 			machine__mmap_name(machine, path, sizeof(path));
2079 			dso__set_long_name(dso, strdup(path));
2080 		}
2081 		map__fixup_start(map);
2082 		map__fixup_end(map);
2083 	}
2084 
2085 	return err;
2086 }
2087 
dsos__add(struct list_head * head,struct dso * dso)2088 static void dsos__add(struct list_head *head, struct dso *dso)
2089 {
2090 	list_add_tail(&dso->node, head);
2091 }
2092 
dsos__find(struct list_head * head,const char * name)2093 static struct dso *dsos__find(struct list_head *head, const char *name)
2094 {
2095 	struct dso *pos;
2096 
2097 	list_for_each_entry(pos, head, node)
2098 		if (strcmp(pos->long_name, name) == 0)
2099 			return pos;
2100 	return NULL;
2101 }
2102 
__dsos__findnew(struct list_head * head,const char * name)2103 struct dso *__dsos__findnew(struct list_head *head, const char *name)
2104 {
2105 	struct dso *dso = dsos__find(head, name);
2106 
2107 	if (!dso) {
2108 		dso = dso__new(name);
2109 		if (dso != NULL) {
2110 			dsos__add(head, dso);
2111 			dso__set_basename(dso);
2112 		}
2113 	}
2114 
2115 	return dso;
2116 }
2117 
__dsos__fprintf(struct list_head * head,FILE * fp)2118 size_t __dsos__fprintf(struct list_head *head, FILE *fp)
2119 {
2120 	struct dso *pos;
2121 	size_t ret = 0;
2122 
2123 	list_for_each_entry(pos, head, node) {
2124 		int i;
2125 		for (i = 0; i < MAP__NR_TYPES; ++i)
2126 			ret += dso__fprintf(pos, i, fp);
2127 	}
2128 
2129 	return ret;
2130 }
2131 
machines__fprintf_dsos(struct rb_root * machines,FILE * fp)2132 size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
2133 {
2134 	struct rb_node *nd;
2135 	size_t ret = 0;
2136 
2137 	for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2138 		struct machine *pos = rb_entry(nd, struct machine, rb_node);
2139 		ret += __dsos__fprintf(&pos->kernel_dsos, fp);
2140 		ret += __dsos__fprintf(&pos->user_dsos, fp);
2141 	}
2142 
2143 	return ret;
2144 }
2145 
__dsos__fprintf_buildid(struct list_head * head,FILE * fp,bool with_hits)2146 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
2147 				      bool with_hits)
2148 {
2149 	struct dso *pos;
2150 	size_t ret = 0;
2151 
2152 	list_for_each_entry(pos, head, node) {
2153 		if (with_hits && !pos->hit)
2154 			continue;
2155 		ret += dso__fprintf_buildid(pos, fp);
2156 		ret += fprintf(fp, " %s\n", pos->long_name);
2157 	}
2158 	return ret;
2159 }
2160 
machine__fprintf_dsos_buildid(struct machine * machine,FILE * fp,bool with_hits)2161 size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
2162 				     bool with_hits)
2163 {
2164 	return __dsos__fprintf_buildid(&machine->kernel_dsos, fp, with_hits) +
2165 	       __dsos__fprintf_buildid(&machine->user_dsos, fp, with_hits);
2166 }
2167 
machines__fprintf_dsos_buildid(struct rb_root * machines,FILE * fp,bool with_hits)2168 size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
2169 				      FILE *fp, bool with_hits)
2170 {
2171 	struct rb_node *nd;
2172 	size_t ret = 0;
2173 
2174 	for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2175 		struct machine *pos = rb_entry(nd, struct machine, rb_node);
2176 		ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
2177 	}
2178 	return ret;
2179 }
2180 
dso__new_kernel(const char * name)2181 struct dso *dso__new_kernel(const char *name)
2182 {
2183 	struct dso *dso = dso__new(name ?: "[kernel.kallsyms]");
2184 
2185 	if (dso != NULL) {
2186 		dso__set_short_name(dso, "[kernel]");
2187 		dso->kernel = DSO_TYPE_KERNEL;
2188 	}
2189 
2190 	return dso;
2191 }
2192 
dso__new_guest_kernel(struct machine * machine,const char * name)2193 static struct dso *dso__new_guest_kernel(struct machine *machine,
2194 					const char *name)
2195 {
2196 	char bf[PATH_MAX];
2197 	struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf,
2198 							      sizeof(bf)));
2199 	if (dso != NULL) {
2200 		dso__set_short_name(dso, "[guest.kernel]");
2201 		dso->kernel = DSO_TYPE_GUEST_KERNEL;
2202 	}
2203 
2204 	return dso;
2205 }
2206 
dso__read_running_kernel_build_id(struct dso * dso,struct machine * machine)2207 void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
2208 {
2209 	char path[PATH_MAX];
2210 
2211 	if (machine__is_default_guest(machine))
2212 		return;
2213 	sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
2214 	if (sysfs__read_build_id(path, dso->build_id,
2215 				 sizeof(dso->build_id)) == 0)
2216 		dso->has_build_id = true;
2217 }
2218 
machine__create_kernel(struct machine * machine)2219 static struct dso *machine__create_kernel(struct machine *machine)
2220 {
2221 	const char *vmlinux_name = NULL;
2222 	struct dso *kernel;
2223 
2224 	if (machine__is_host(machine)) {
2225 		vmlinux_name = symbol_conf.vmlinux_name;
2226 		kernel = dso__new_kernel(vmlinux_name);
2227 	} else {
2228 		if (machine__is_default_guest(machine))
2229 			vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2230 		kernel = dso__new_guest_kernel(machine, vmlinux_name);
2231 	}
2232 
2233 	if (kernel != NULL) {
2234 		dso__read_running_kernel_build_id(kernel, machine);
2235 		dsos__add(&machine->kernel_dsos, kernel);
2236 	}
2237 	return kernel;
2238 }
2239 
2240 struct process_args {
2241 	u64 start;
2242 };
2243 
symbol__in_kernel(void * arg,const char * name,char type __used,u64 start,u64 end __used)2244 static int symbol__in_kernel(void *arg, const char *name,
2245 			     char type __used, u64 start, u64 end __used)
2246 {
2247 	struct process_args *args = arg;
2248 
2249 	if (strchr(name, '['))
2250 		return 0;
2251 
2252 	args->start = start;
2253 	return 1;
2254 }
2255 
2256 /* Figure out the start address of kernel map from /proc/kallsyms */
machine__get_kernel_start_addr(struct machine * machine)2257 static u64 machine__get_kernel_start_addr(struct machine *machine)
2258 {
2259 	const char *filename;
2260 	char path[PATH_MAX];
2261 	struct process_args args;
2262 
2263 	if (machine__is_host(machine)) {
2264 		filename = "/proc/kallsyms";
2265 	} else {
2266 		if (machine__is_default_guest(machine))
2267 			filename = (char *)symbol_conf.default_guest_kallsyms;
2268 		else {
2269 			sprintf(path, "%s/proc/kallsyms", machine->root_dir);
2270 			filename = path;
2271 		}
2272 	}
2273 
2274 	if (symbol__restricted_filename(filename, "/proc/kallsyms"))
2275 		return 0;
2276 
2277 	if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
2278 		return 0;
2279 
2280 	return args.start;
2281 }
2282 
__machine__create_kernel_maps(struct machine * machine,struct dso * kernel)2283 int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
2284 {
2285 	enum map_type type;
2286 	u64 start = machine__get_kernel_start_addr(machine);
2287 
2288 	for (type = 0; type < MAP__NR_TYPES; ++type) {
2289 		struct kmap *kmap;
2290 
2291 		machine->vmlinux_maps[type] = map__new2(start, kernel, type);
2292 		if (machine->vmlinux_maps[type] == NULL)
2293 			return -1;
2294 
2295 		machine->vmlinux_maps[type]->map_ip =
2296 			machine->vmlinux_maps[type]->unmap_ip =
2297 				identity__map_ip;
2298 		kmap = map__kmap(machine->vmlinux_maps[type]);
2299 		kmap->kmaps = &machine->kmaps;
2300 		map_groups__insert(&machine->kmaps,
2301 				   machine->vmlinux_maps[type]);
2302 	}
2303 
2304 	return 0;
2305 }
2306 
machine__destroy_kernel_maps(struct machine * machine)2307 void machine__destroy_kernel_maps(struct machine *machine)
2308 {
2309 	enum map_type type;
2310 
2311 	for (type = 0; type < MAP__NR_TYPES; ++type) {
2312 		struct kmap *kmap;
2313 
2314 		if (machine->vmlinux_maps[type] == NULL)
2315 			continue;
2316 
2317 		kmap = map__kmap(machine->vmlinux_maps[type]);
2318 		map_groups__remove(&machine->kmaps,
2319 				   machine->vmlinux_maps[type]);
2320 		if (kmap->ref_reloc_sym) {
2321 			/*
2322 			 * ref_reloc_sym is shared among all maps, so free just
2323 			 * on one of them.
2324 			 */
2325 			if (type == MAP__FUNCTION) {
2326 				free((char *)kmap->ref_reloc_sym->name);
2327 				kmap->ref_reloc_sym->name = NULL;
2328 				free(kmap->ref_reloc_sym);
2329 			}
2330 			kmap->ref_reloc_sym = NULL;
2331 		}
2332 
2333 		map__delete(machine->vmlinux_maps[type]);
2334 		machine->vmlinux_maps[type] = NULL;
2335 	}
2336 }
2337 
machine__create_kernel_maps(struct machine * machine)2338 int machine__create_kernel_maps(struct machine *machine)
2339 {
2340 	struct dso *kernel = machine__create_kernel(machine);
2341 
2342 	if (kernel == NULL ||
2343 	    __machine__create_kernel_maps(machine, kernel) < 0)
2344 		return -1;
2345 
2346 	if (symbol_conf.use_modules && machine__create_modules(machine) < 0)
2347 		pr_debug("Problems creating module maps, continuing anyway...\n");
2348 	/*
2349 	 * Now that we have all the maps created, just set the ->end of them:
2350 	 */
2351 	map_groups__fixup_end(&machine->kmaps);
2352 	return 0;
2353 }
2354 
vmlinux_path__exit(void)2355 static void vmlinux_path__exit(void)
2356 {
2357 	while (--vmlinux_path__nr_entries >= 0) {
2358 		free(vmlinux_path[vmlinux_path__nr_entries]);
2359 		vmlinux_path[vmlinux_path__nr_entries] = NULL;
2360 	}
2361 
2362 	free(vmlinux_path);
2363 	vmlinux_path = NULL;
2364 }
2365 
vmlinux_path__init(void)2366 static int vmlinux_path__init(void)
2367 {
2368 	struct utsname uts;
2369 	char bf[PATH_MAX];
2370 
2371 	vmlinux_path = malloc(sizeof(char *) * 5);
2372 	if (vmlinux_path == NULL)
2373 		return -1;
2374 
2375 	vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
2376 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2377 		goto out_fail;
2378 	++vmlinux_path__nr_entries;
2379 	vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
2380 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2381 		goto out_fail;
2382 	++vmlinux_path__nr_entries;
2383 
2384 	/* only try running kernel version if no symfs was given */
2385 	if (symbol_conf.symfs[0] != 0)
2386 		return 0;
2387 
2388 	if (uname(&uts) < 0)
2389 		return -1;
2390 
2391 	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
2392 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2393 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2394 		goto out_fail;
2395 	++vmlinux_path__nr_entries;
2396 	snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
2397 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2398 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2399 		goto out_fail;
2400 	++vmlinux_path__nr_entries;
2401 	snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
2402 		 uts.release);
2403 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2404 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2405 		goto out_fail;
2406 	++vmlinux_path__nr_entries;
2407 
2408 	return 0;
2409 
2410 out_fail:
2411 	vmlinux_path__exit();
2412 	return -1;
2413 }
2414 
machine__fprintf_vmlinux_path(struct machine * machine,FILE * fp)2415 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
2416 {
2417 	int i;
2418 	size_t printed = 0;
2419 	struct dso *kdso = machine->vmlinux_maps[MAP__FUNCTION]->dso;
2420 
2421 	if (kdso->has_build_id) {
2422 		char filename[PATH_MAX];
2423 		if (dso__build_id_filename(kdso, filename, sizeof(filename)))
2424 			printed += fprintf(fp, "[0] %s\n", filename);
2425 	}
2426 
2427 	for (i = 0; i < vmlinux_path__nr_entries; ++i)
2428 		printed += fprintf(fp, "[%d] %s\n",
2429 				   i + kdso->has_build_id, vmlinux_path[i]);
2430 
2431 	return printed;
2432 }
2433 
setup_list(struct strlist ** list,const char * list_str,const char * list_name)2434 static int setup_list(struct strlist **list, const char *list_str,
2435 		      const char *list_name)
2436 {
2437 	if (list_str == NULL)
2438 		return 0;
2439 
2440 	*list = strlist__new(true, list_str);
2441 	if (!*list) {
2442 		pr_err("problems parsing %s list\n", list_name);
2443 		return -1;
2444 	}
2445 	return 0;
2446 }
2447 
symbol__read_kptr_restrict(void)2448 static bool symbol__read_kptr_restrict(void)
2449 {
2450 	bool value = false;
2451 
2452 	if (geteuid() != 0) {
2453 		FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
2454 		if (fp != NULL) {
2455 			char line[8];
2456 
2457 			if (fgets(line, sizeof(line), fp) != NULL)
2458 				value = atoi(line) != 0;
2459 
2460 			fclose(fp);
2461 		}
2462 	}
2463 
2464 	return value;
2465 }
2466 
symbol__init(void)2467 int symbol__init(void)
2468 {
2469 	const char *symfs;
2470 
2471 	if (symbol_conf.initialized)
2472 		return 0;
2473 
2474         /* ANDROID_CHANGE_BEGIN */
2475 #if defined(__BIONIC__) || defined(__APPLE__)
2476 	symbol_conf.priv_size = KERNEL_ALIGN(symbol_conf.priv_size, sizeof(u64));
2477 #else
2478 	symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64));
2479 #endif
2480         /* ANDROID_CHANGE_END */
2481 
2482 	elf_version(EV_CURRENT);
2483 	if (symbol_conf.sort_by_name)
2484 		symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
2485 					  sizeof(struct symbol));
2486 
2487 	if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
2488 		return -1;
2489 
2490 	if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
2491 		pr_err("'.' is the only non valid --field-separator argument\n");
2492 		return -1;
2493 	}
2494 
2495 	if (setup_list(&symbol_conf.dso_list,
2496 		       symbol_conf.dso_list_str, "dso") < 0)
2497 		return -1;
2498 
2499 	if (setup_list(&symbol_conf.comm_list,
2500 		       symbol_conf.comm_list_str, "comm") < 0)
2501 		goto out_free_dso_list;
2502 
2503 	if (setup_list(&symbol_conf.sym_list,
2504 		       symbol_conf.sym_list_str, "symbol") < 0)
2505 		goto out_free_comm_list;
2506 
2507 	/*
2508 	 * A path to symbols of "/" is identical to ""
2509 	 * reset here for simplicity.
2510 	 */
2511 	symfs = realpath(symbol_conf.symfs, NULL);
2512 	if (symfs == NULL)
2513 		symfs = symbol_conf.symfs;
2514 	if (strcmp(symfs, "/") == 0)
2515 		symbol_conf.symfs = "";
2516 	if (symfs != symbol_conf.symfs)
2517 		free((void *)symfs);
2518 
2519 	symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
2520 
2521 	symbol_conf.initialized = true;
2522 	return 0;
2523 
2524 out_free_dso_list:
2525 	strlist__delete(symbol_conf.dso_list);
2526 out_free_comm_list:
2527 	strlist__delete(symbol_conf.comm_list);
2528 	return -1;
2529 }
2530 
symbol__exit(void)2531 void symbol__exit(void)
2532 {
2533 	if (!symbol_conf.initialized)
2534 		return;
2535 	strlist__delete(symbol_conf.sym_list);
2536 	strlist__delete(symbol_conf.dso_list);
2537 	strlist__delete(symbol_conf.comm_list);
2538 	vmlinux_path__exit();
2539 	symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
2540 	symbol_conf.initialized = false;
2541 }
2542 
machines__create_kernel_maps(struct rb_root * machines,pid_t pid)2543 int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
2544 {
2545 	struct machine *machine = machines__findnew(machines, pid);
2546 
2547 	if (machine == NULL)
2548 		return -1;
2549 
2550 	return machine__create_kernel_maps(machine);
2551 }
2552 
hex(char ch)2553 static int hex(char ch)
2554 {
2555 	if ((ch >= '0') && (ch <= '9'))
2556 		return ch - '0';
2557 	if ((ch >= 'a') && (ch <= 'f'))
2558 		return ch - 'a' + 10;
2559 	if ((ch >= 'A') && (ch <= 'F'))
2560 		return ch - 'A' + 10;
2561 	return -1;
2562 }
2563 
2564 /*
2565  * While we find nice hex chars, build a long_val.
2566  * Return number of chars processed.
2567  */
hex2u64(const char * ptr,u64 * long_val)2568 int hex2u64(const char *ptr, u64 *long_val)
2569 {
2570 	const char *p = ptr;
2571 	*long_val = 0;
2572 
2573 	while (*p) {
2574 		const int hex_val = hex(*p);
2575 
2576 		if (hex_val < 0)
2577 			break;
2578 
2579 		*long_val = (*long_val << 4) | hex_val;
2580 		p++;
2581 	}
2582 
2583 	return p - ptr;
2584 }
2585 
strxfrchar(char * s,char from,char to)2586 char *strxfrchar(char *s, char from, char to)
2587 {
2588 	char *p = s;
2589 
2590 	while ((p = strchr(p, from)) != NULL)
2591 		*p++ = to;
2592 
2593 	return s;
2594 }
2595 
machines__create_guest_kernel_maps(struct rb_root * machines)2596 int machines__create_guest_kernel_maps(struct rb_root *machines)
2597 {
2598 	int ret = 0;
2599 	struct dirent **namelist = NULL;
2600 	int i, items = 0;
2601 	char path[PATH_MAX];
2602 	pid_t pid;
2603 
2604 	if (symbol_conf.default_guest_vmlinux_name ||
2605 	    symbol_conf.default_guest_modules ||
2606 	    symbol_conf.default_guest_kallsyms) {
2607 		machines__create_kernel_maps(machines, DEFAULT_GUEST_KERNEL_ID);
2608 	}
2609 
2610 	if (symbol_conf.guestmount) {
2611 		items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
2612 		if (items <= 0)
2613 			return -ENOENT;
2614 		for (i = 0; i < items; i++) {
2615 			if (!isdigit(namelist[i]->d_name[0])) {
2616 				/* Filter out . and .. */
2617 				continue;
2618 			}
2619 			pid = atoi(namelist[i]->d_name);
2620 			sprintf(path, "%s/%s/proc/kallsyms",
2621 				symbol_conf.guestmount,
2622 				namelist[i]->d_name);
2623 			ret = access(path, R_OK);
2624 			if (ret) {
2625 				pr_debug("Can't access file %s\n", path);
2626 				goto failure;
2627 			}
2628 			machines__create_kernel_maps(machines, pid);
2629 		}
2630 failure:
2631 		free(namelist);
2632 	}
2633 
2634 	return ret;
2635 }
2636 
machines__destroy_guest_kernel_maps(struct rb_root * machines)2637 void machines__destroy_guest_kernel_maps(struct rb_root *machines)
2638 {
2639 	struct rb_node *next = rb_first(machines);
2640 
2641 	while (next) {
2642 		struct machine *pos = rb_entry(next, struct machine, rb_node);
2643 
2644 		next = rb_next(&pos->rb_node);
2645 		rb_erase(&pos->rb_node, machines);
2646 		machine__delete(pos);
2647 	}
2648 }
2649 
machine__load_kallsyms(struct machine * machine,const char * filename,enum map_type type,symbol_filter_t filter)2650 int machine__load_kallsyms(struct machine *machine, const char *filename,
2651 			   enum map_type type, symbol_filter_t filter)
2652 {
2653 	struct map *map = machine->vmlinux_maps[type];
2654 	int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2655 
2656 	if (ret > 0) {
2657 		dso__set_loaded(map->dso, type);
2658 		/*
2659 		 * Since /proc/kallsyms will have multiple sessions for the
2660 		 * kernel, with modules between them, fixup the end of all
2661 		 * sections.
2662 		 */
2663 		__map_groups__fixup_end(&machine->kmaps, type);
2664 	}
2665 
2666 	return ret;
2667 }
2668 
machine__load_vmlinux_path(struct machine * machine,enum map_type type,symbol_filter_t filter)2669 int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
2670 			       symbol_filter_t filter)
2671 {
2672 	struct map *map = machine->vmlinux_maps[type];
2673 	int ret = dso__load_vmlinux_path(map->dso, map, filter);
2674 
2675 	if (ret > 0) {
2676 		dso__set_loaded(map->dso, type);
2677 		map__reloc_vmlinux(map);
2678 	}
2679 
2680 	return ret;
2681 }
2682