symbol.c 51.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
#define _GNU_SOURCE
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <fcntl.h>
#include <unistd.h>
14
#include "build-id.h"
15
#include "symbol.h"
16
#include "strlist.h"
17 18 19 20

#include <libelf.h>
#include <gelf.h>
#include <elf.h>
21
#include <limits.h>
22
#include <sys/utsname.h>
P
Peter Zijlstra 已提交
23

24 25 26 27
#ifndef NT_GNU_BUILD_ID
#define NT_GNU_BUILD_ID 3
#endif

28
static void dsos__add(struct list_head *head, struct dso *dso);
29
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
30
static int dso__load_kernel_sym(struct dso *self, struct map *map,
31
				symbol_filter_t filter);
32 33
static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
			symbol_filter_t filter);
34 35
static int vmlinux_path__nr_entries;
static char **vmlinux_path;
36

37
struct symbol_conf symbol_conf = {
38
	.exclude_other	  = true,
39 40 41 42
	.use_modules	  = true,
	.try_vmlinux_path = true,
};

43 44 45 46 47
bool dso__loaded(const struct dso *self, enum map_type type)
{
	return self->loaded & (1 << type);
}

48 49 50 51 52 53 54 55 56 57
bool dso__sorted_by_name(const struct dso *self, enum map_type type)
{
	return self->sorted_by_name & (1 << type);
}

static void dso__set_sorted_by_name(struct dso *self, enum map_type type)
{
	self->sorted_by_name |= (1 << type);
}

58
bool symbol_type__is_a(char symbol_type, enum map_type map_type)
59 60 61 62
{
	switch (map_type) {
	case MAP__FUNCTION:
		return symbol_type == 'T' || symbol_type == 'W';
63 64
	case MAP__VARIABLE:
		return symbol_type == 'D' || symbol_type == 'd';
65 66 67 68 69
	default:
		return false;
	}
}

70
static void symbols__fixup_end(struct rb_root *self)
71
{
72
	struct rb_node *nd, *prevnd = rb_first(self);
73
	struct symbol *curr, *prev;
74 75 76 77

	if (prevnd == NULL)
		return;

78 79
	curr = rb_entry(prevnd, struct symbol, rb_node);

80
	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
81 82
		prev = curr;
		curr = rb_entry(nd, struct symbol, rb_node);
83 84 85 86

		if (prev->end == prev->start)
			prev->end = curr->start - 1;
	}
87 88 89 90

	/* Last entry */
	if (curr->end == curr->start)
		curr->end = roundup(curr->start, 4096);
91 92
}

93
static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
94 95
{
	struct map *prev, *curr;
96
	struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
97 98 99 100 101 102 103 104 105 106

	if (prevnd == NULL)
		return;

	curr = rb_entry(prevnd, struct map, rb_node);

	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
		prev = curr;
		curr = rb_entry(nd, struct map, rb_node);
		prev->end = curr->start - 1;
107
	}
108 109 110 111 112 113

	/*
	 * We still haven't the actual symbols, so guess the
	 * last map final address.
	 */
	curr->end = ~0UL;
114 115
}

116
static void map_groups__fixup_end(struct map_groups *self)
117 118 119
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
120
		__map_groups__fixup_end(self, i);
121 122
}

123
static struct symbol *symbol__new(u64 start, u64 len, const char *name)
124
{
125
	size_t namelen = strlen(name) + 1;
126 127
	struct symbol *self = calloc(1, (symbol_conf.priv_size +
					 sizeof(*self) + namelen));
128
	if (self == NULL)
129 130
		return NULL;

131 132
	if (symbol_conf.priv_size)
		self = ((void *)self) + symbol_conf.priv_size;
133

134 135 136
	self->start   = start;
	self->end     = len ? start + len - 1 : start;
	self->namelen = namelen - 1;
137

138
	pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
139

140
	memcpy(self->name, name, namelen);
141 142 143 144

	return self;
}

145
void symbol__delete(struct symbol *self)
146
{
147
	free(((void *)self) - symbol_conf.priv_size);
148 149 150 151
}

static size_t symbol__fprintf(struct symbol *self, FILE *fp)
{
152
	return fprintf(fp, " %llx-%llx %s\n",
153 154 155
		       self->start, self->end, self->name);
}

156
void dso__set_long_name(struct dso *self, char *name)
157
{
158 159
	if (name == NULL)
		return;
160 161 162 163
	self->long_name = name;
	self->long_name_len = strlen(name);
}

164 165 166 167 168 169 170 171
static void dso__set_short_name(struct dso *self, const char *name)
{
	if (name == NULL)
		return;
	self->short_name = name;
	self->short_name_len = strlen(name);
}

172 173
static void dso__set_basename(struct dso *self)
{
174
	dso__set_short_name(self, basename(self->long_name));
175 176
}

177
struct dso *dso__new(const char *name)
178
{
179
	struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1);
180 181

	if (self != NULL) {
182
		int i;
183
		strcpy(self->name, name);
184
		dso__set_long_name(self, self->name);
185
		dso__set_short_name(self, self->name);
186
		for (i = 0; i < MAP__NR_TYPES; ++i)
187
			self->symbols[i] = self->symbol_names[i] = RB_ROOT;
188
		self->slen_calculated = 0;
189
		self->origin = DSO__ORIG_NOT_FOUND;
190
		self->loaded = 0;
191
		self->sorted_by_name = 0;
192
		self->has_build_id = 0;
193
		self->kernel = DSO_TYPE_USER;
194
		INIT_LIST_HEAD(&self->node);
195 196 197 198 199
	}

	return self;
}

200
static void symbols__delete(struct rb_root *self)
201 202
{
	struct symbol *pos;
203
	struct rb_node *next = rb_first(self);
204 205 206 207

	while (next) {
		pos = rb_entry(next, struct symbol, rb_node);
		next = rb_next(&pos->rb_node);
208
		rb_erase(&pos->rb_node, self);
209
		symbol__delete(pos);
210 211 212 213 214
	}
}

void dso__delete(struct dso *self)
{
215 216 217
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
		symbols__delete(&self->symbols[i]);
218 219
	if (self->long_name != self->name)
		free(self->long_name);
220 221 222
	free(self);
}

223 224 225 226 227 228
void dso__set_build_id(struct dso *self, void *build_id)
{
	memcpy(self->build_id, build_id, sizeof(self->build_id));
	self->has_build_id = 1;
}

229
static void symbols__insert(struct rb_root *self, struct symbol *sym)
230
{
231
	struct rb_node **p = &self->rb_node;
232
	struct rb_node *parent = NULL;
233
	const u64 ip = sym->start;
234 235 236 237 238 239 240 241 242 243 244
	struct symbol *s;

	while (*p != NULL) {
		parent = *p;
		s = rb_entry(parent, struct symbol, rb_node);
		if (ip < s->start)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}
	rb_link_node(&sym->rb_node, parent, p);
245
	rb_insert_color(&sym->rb_node, self);
246 247
}

248
static struct symbol *symbols__find(struct rb_root *self, u64 ip)
249 250 251 252 253 254
{
	struct rb_node *n;

	if (self == NULL)
		return NULL;

255
	n = self->rb_node;
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270

	while (n) {
		struct symbol *s = rb_entry(n, struct symbol, rb_node);

		if (ip < s->start)
			n = n->rb_left;
		else if (ip > s->end)
			n = n->rb_right;
		else
			return s;
	}

	return NULL;
}

271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
struct symbol_name_rb_node {
	struct rb_node	rb_node;
	struct symbol	sym;
};

static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
{
	struct rb_node **p = &self->rb_node;
	struct rb_node *parent = NULL;
	struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s;

	while (*p != NULL) {
		parent = *p;
		s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
		if (strcmp(sym->name, s->sym.name) < 0)
			p = &(*p)->rb_left;
		else
			p = &(*p)->rb_right;
	}
	rb_link_node(&symn->rb_node, parent, p);
	rb_insert_color(&symn->rb_node, self);
}

static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source)
{
	struct rb_node *nd;

	for (nd = rb_first(source); nd; nd = rb_next(nd)) {
		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
		symbols__insert_by_name(self, pos);
	}
}

static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name)
{
	struct rb_node *n;

	if (self == NULL)
		return NULL;

	n = self->rb_node;

	while (n) {
		struct symbol_name_rb_node *s;
		int cmp;

		s = rb_entry(n, struct symbol_name_rb_node, rb_node);
		cmp = strcmp(name, s->sym.name);

		if (cmp < 0)
			n = n->rb_left;
		else if (cmp > 0)
			n = n->rb_right;
		else
			return &s->sym;
	}

	return NULL;
}

struct symbol *dso__find_symbol(struct dso *self,
				enum map_type type, u64 addr)
333
{
334
	return symbols__find(&self->symbols[type], addr);
335 336
}

337 338 339 340 341 342 343 344 345 346 347 348 349
struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
					const char *name)
{
	return symbols__find_by_name(&self->symbol_names[type], name);
}

void dso__sort_by_name(struct dso *self, enum map_type type)
{
	dso__set_sorted_by_name(self, type);
	return symbols__sort_by_name(&self->symbol_names[type],
				     &self->symbols[type]);
}

350
int build_id__sprintf(const u8 *self, int len, char *bf)
351
{
352
	char *bid = bf;
353
	const u8 *raw = self;
354
	int i;
355

356 357 358 359 360 361 362 363 364
	for (i = 0; i < len; ++i) {
		sprintf(bid, "%02x", *raw);
		++raw;
		bid += 2;
	}

	return raw - self;
}

365
size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
366 367 368 369
{
	char sbuild_id[BUILD_ID_SIZE * 2 + 1];

	build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
370 371 372
	return fprintf(fp, "%s", sbuild_id);
}

373
size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
374 375 376 377
{
	struct rb_node *nd;
	size_t ret = fprintf(fp, "dso: %s (", self->short_name);

378 379 380 381
	if (self->short_name != self->long_name)
		ret += fprintf(fp, "%s, ", self->long_name);
	ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
		       self->loaded ? "" : "NOT ");
382
	ret += dso__fprintf_buildid(self, fp);
383
	ret += fprintf(fp, ")\n");
384 385 386
	for (nd = rb_first(&self->symbols[type]); nd; nd = rb_next(nd)) {
		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
		ret += symbol__fprintf(pos, fp);
387 388 389 390 391
	}

	return ret;
}

392 393
int kallsyms__parse(const char *filename, void *arg,
		    int (*process_symbol)(void *arg, const char *name,
394
						     char type, u64 start))
395 396 397
{
	char *line = NULL;
	size_t n;
398
	int err = 0;
399
	FILE *file = fopen(filename, "r");
400 401 402 403 404

	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
405
		u64 start;
406 407
		int line_len, len;
		char symbol_type;
408
		char *symbol_name;
409 410

		line_len = getline(&line, &n, file);
411
		if (line_len < 0 || !line)
412 413 414 415
			break;

		line[--line_len] = '\0'; /* \n */

416
		len = hex2u64(line, &start);
417 418 419 420 421 422

		len++;
		if (len + 2 >= line_len)
			continue;

		symbol_type = toupper(line[len]);
423
		symbol_name = line + len + 2;
424 425 426 427

		err = process_symbol(arg, symbol_name, symbol_type, start);
		if (err)
			break;
428 429 430 431
	}

	free(line);
	fclose(file);
432
	return err;
433 434 435 436 437

out_failure:
	return -1;
}

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
struct process_kallsyms_args {
	struct map *map;
	struct dso *dso;
};

static int map__process_kallsym_symbol(void *arg, const char *name,
				       char type, u64 start)
{
	struct symbol *sym;
	struct process_kallsyms_args *a = arg;
	struct rb_root *root = &a->dso->symbols[a->map->type];

	if (!symbol_type__is_a(type, a->map->type))
		return 0;

	/*
	 * Will fix up the end later, when we have all symbols sorted.
	 */
	sym = symbol__new(start, 0, name);

	if (sym == NULL)
		return -ENOMEM;
	/*
	 * We will pass the symbols to the filter later, in
	 * map__split_kallsyms, when we have split the maps per module
	 */
	symbols__insert(root, sym);
465

466 467 468 469 470 471 472 473
	return 0;
}

/*
 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
 * so that we can in the next step set the symbol ->end address and then
 * call kernel_maps__split_kallsyms.
 */
474 475
static int dso__load_all_kallsyms(struct dso *self, const char *filename,
				  struct map *map)
476 477
{
	struct process_kallsyms_args args = { .map = map, .dso = self, };
478
	return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
479 480
}

481 482 483 484 485
/*
 * Split the symbols into maps, making sure there are no overlaps, i.e. the
 * kernel range is broken in several maps, named [kernel].N, as we don't have
 * the original ELF section names vmlinux have.
 */
486
static int dso__split_kallsyms(struct dso *self, struct map *map,
487
			       symbol_filter_t filter)
488
{
489
	struct map_groups *kmaps = map__kmap(map)->kmaps;
490
	struct machine *machine = kmaps->machine;
491
	struct map *curr_map = map;
492 493
	struct symbol *pos;
	int count = 0;
494 495
	struct rb_root *root = &self->symbols[map->type];
	struct rb_node *next = rb_first(root);
496 497 498 499 500 501 502 503 504 505
	int kernel_range = 0;

	while (next) {
		char *module;

		pos = rb_entry(next, struct symbol, rb_node);
		next = rb_next(&pos->rb_node);

		module = strchr(pos->name, '\t');
		if (module) {
506
			if (!symbol_conf.use_modules)
507 508
				goto discard_symbol;

509 510
			*module++ = '\0';

511
			if (strcmp(curr_map->dso->short_name, module)) {
512
				if (curr_map != map &&
513 514
				    self->kernel == DSO_TYPE_GUEST_KERNEL &&
				    machine__is_default_guest(machine)) {
515 516 517 518 519 520 521 522 523 524 525 526 527
					/*
					 * We assume all symbols of a module are
					 * continuous in * kallsyms, so curr_map
					 * points to a module and all its
					 * symbols are in its kmap. Mark it as
					 * loaded.
					 */
					dso__set_loaded(curr_map->dso,
							curr_map->type);
				}

				curr_map = map_groups__find_by_name(kmaps,
							map->type, module);
528
				if (curr_map == NULL) {
529
					pr_debug("%s/proc/{kallsyms,modules} "
530
					         "inconsistency while looking "
531
						 "for \"%s\" module!\n",
532
						 machine->root_dir, module);
533 534
					curr_map = map;
					goto discard_symbol;
535
				}
536

537
				if (curr_map->dso->loaded &&
538
				    !machine__is_default_guest(machine))
539
					goto discard_symbol;
540
			}
541 542 543 544
			/*
			 * So that we look just like we get from .ko files,
			 * i.e. not prelinked, relative to map->start.
			 */
545 546 547
			pos->start = curr_map->map_ip(curr_map, pos->start);
			pos->end   = curr_map->map_ip(curr_map, pos->end);
		} else if (curr_map != map) {
548 549 550
			char dso_name[PATH_MAX];
			struct dso *dso;

551 552 553 554 555 556 557 558
			if (self->kernel == DSO_TYPE_GUEST_KERNEL)
				snprintf(dso_name, sizeof(dso_name),
					"[guest.kernel].%d",
					kernel_range++);
			else
				snprintf(dso_name, sizeof(dso_name),
					"[kernel].%d",
					kernel_range++);
559

560
			dso = dso__new(dso_name);
561 562 563
			if (dso == NULL)
				return -1;

564 565
			dso->kernel = self->kernel;

566
			curr_map = map__new2(pos->start, dso, map->type);
567
			if (curr_map == NULL) {
568 569 570
				dso__delete(dso);
				return -1;
			}
571

572
			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
573
			map_groups__insert(kmaps, curr_map);
574 575
			++kernel_range;
		}
576

577
		if (filter && filter(curr_map, pos)) {
578
discard_symbol:		rb_erase(&pos->rb_node, root);
579
			symbol__delete(pos);
580
		} else {
581 582 583
			if (curr_map != map) {
				rb_erase(&pos->rb_node, root);
				symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
584
			}
585 586
			count++;
		}
587 588
	}

589 590
	if (curr_map != map &&
	    self->kernel == DSO_TYPE_GUEST_KERNEL &&
591
	    machine__is_default_guest(kmaps->machine)) {
592 593 594
		dso__set_loaded(curr_map->dso, curr_map->type);
	}

595
	return count;
596
}
597

598 599
int dso__load_kallsyms(struct dso *self, const char *filename,
		       struct map *map, symbol_filter_t filter)
600
{
601
	if (dso__load_all_kallsyms(self, filename, map) < 0)
602 603
		return -1;

604
	symbols__fixup_end(&self->symbols[map->type]);
605 606 607 608
	if (self->kernel == DSO_TYPE_GUEST_KERNEL)
		self->origin = DSO__ORIG_GUEST_KERNEL;
	else
		self->origin = DSO__ORIG_KERNEL;
609

610
	return dso__split_kallsyms(self, map, filter);
611 612
}

613
static int dso__load_perf_map(struct dso *self, struct map *map,
614
			      symbol_filter_t filter)
615 616 617 618 619 620
{
	char *line = NULL;
	size_t n;
	FILE *file;
	int nr_syms = 0;

621
	file = fopen(self->long_name, "r");
622 623 624 625
	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
626
		u64 start, size;
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
		struct symbol *sym;
		int line_len, len;

		line_len = getline(&line, &n, file);
		if (line_len < 0)
			break;

		if (!line)
			goto out_failure;

		line[--line_len] = '\0'; /* \n */

		len = hex2u64(line, &start);

		len++;
		if (len + 2 >= line_len)
			continue;

		len += hex2u64(line + len, &size);

		len++;
		if (len + 2 >= line_len)
			continue;

651
		sym = symbol__new(start, size, line + len);
652 653 654 655

		if (sym == NULL)
			goto out_delete_line;

656
		if (filter && filter(map, sym))
657
			symbol__delete(sym);
658
		else {
659
			symbols__insert(&self->symbols[map->type], sym);
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
			nr_syms++;
		}
	}

	free(line);
	fclose(file);

	return nr_syms;

out_delete_line:
	free(line);
out_failure:
	return -1;
}

675 676 677 678
/**
 * elf_symtab__for_each_symbol - iterate thru all the symbols
 *
 * @self: struct elf_symtab instance to iterate
679
 * @idx: uint32_t idx
680 681
 * @sym: GElf_Sym iterator
 */
682 683 684 685
#define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
	for (idx = 0, gelf_getsym(syms, idx, &sym);\
	     idx < nr_syms; \
	     idx++, gelf_getsym(syms, idx, &sym))
686 687 688 689 690 691 692 693 694 695

static inline uint8_t elf_sym__type(const GElf_Sym *sym)
{
	return GELF_ST_TYPE(sym->st_info);
}

static inline int elf_sym__is_function(const GElf_Sym *sym)
{
	return elf_sym__type(sym) == STT_FUNC &&
	       sym->st_name != 0 &&
696
	       sym->st_shndx != SHN_UNDEF;
697 698
}

699 700 701 702 703 704 705
static inline bool elf_sym__is_object(const GElf_Sym *sym)
{
	return elf_sym__type(sym) == STT_OBJECT &&
		sym->st_name != 0 &&
		sym->st_shndx != SHN_UNDEF;
}

706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
static inline int elf_sym__is_label(const GElf_Sym *sym)
{
	return elf_sym__type(sym) == STT_NOTYPE &&
		sym->st_name != 0 &&
		sym->st_shndx != SHN_UNDEF &&
		sym->st_shndx != SHN_ABS;
}

static inline const char *elf_sec__name(const GElf_Shdr *shdr,
					const Elf_Data *secstrs)
{
	return secstrs->d_buf + shdr->sh_name;
}

static inline int elf_sec__is_text(const GElf_Shdr *shdr,
					const Elf_Data *secstrs)
{
	return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
}

726 727 728 729 730 731
static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
				    const Elf_Data *secstrs)
{
	return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
}

732 733 734 735 736 737 738 739
static inline const char *elf_sym__name(const GElf_Sym *sym,
					const Elf_Data *symstrs)
{
	return symstrs->d_buf + sym->st_name;
}

static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
				    GElf_Shdr *shp, const char *name,
740
				    size_t *idx)
741 742 743 744 745 746 747 748 749 750
{
	Elf_Scn *sec = NULL;
	size_t cnt = 1;

	while ((sec = elf_nextscn(elf, sec)) != NULL) {
		char *str;

		gelf_getshdr(sec, shp);
		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
		if (!strcmp(name, str)) {
751 752
			if (idx)
				*idx = cnt;
753 754 755 756 757 758 759 760
			break;
		}
		++cnt;
	}

	return sec;
}

761 762 763 764 765 766 767 768 769 770
#define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
	for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
	     idx < nr_entries; \
	     ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))

#define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
	for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
	     idx < nr_entries; \
	     ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))

771 772 773 774 775 776 777
/*
 * We need to check if we have a .dynsym, so that we can handle the
 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
 * .dynsym or .symtab).
 * And always look at the original dso, not at debuginfo packages, that
 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
 */
778 779
static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
				       symbol_filter_t filter)
780 781 782
{
	uint32_t nr_rel_entries, idx;
	GElf_Sym sym;
783
	u64 plt_offset;
784 785
	GElf_Shdr shdr_plt;
	struct symbol *f;
786
	GElf_Shdr shdr_rel_plt, shdr_dynsym;
787
	Elf_Data *reldata, *syms, *symstrs;
788 789 790
	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
	size_t dynsym_idx;
	GElf_Ehdr ehdr;
791
	char sympltname[1024];
792 793 794
	Elf *elf;
	int nr = 0, symidx, fd, err = 0;

795
	fd = open(self->long_name, O_RDONLY);
796 797 798
	if (fd < 0)
		goto out;

799
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
800 801 802 803 804 805 806 807 808 809
	if (elf == NULL)
		goto out_close;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		goto out_elf_end;

	scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
					 ".dynsym", &dynsym_idx);
	if (scn_dynsym == NULL)
		goto out_elf_end;
810

811
	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
812 813
					  ".rela.plt", NULL);
	if (scn_plt_rel == NULL) {
814
		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
815 816
						  ".rel.plt", NULL);
		if (scn_plt_rel == NULL)
817
			goto out_elf_end;
818 819
	}

820 821
	err = -1;

822
	if (shdr_rel_plt.sh_link != dynsym_idx)
823
		goto out_elf_end;
824

825 826
	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
		goto out_elf_end;
827 828

	/*
829
	 * Fetch the relocation section to find the idxes to the GOT
830 831 832 833
	 * and the symbols in the .dynsym they refer to.
	 */
	reldata = elf_getdata(scn_plt_rel, NULL);
	if (reldata == NULL)
834
		goto out_elf_end;
835 836 837

	syms = elf_getdata(scn_dynsym, NULL);
	if (syms == NULL)
838
		goto out_elf_end;
839

840
	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
841
	if (scn_symstrs == NULL)
842
		goto out_elf_end;
843 844 845

	symstrs = elf_getdata(scn_symstrs, NULL);
	if (symstrs == NULL)
846
		goto out_elf_end;
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862

	nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
	plt_offset = shdr_plt.sh_offset;

	if (shdr_rel_plt.sh_type == SHT_RELA) {
		GElf_Rela pos_mem, *pos;

		elf_section__for_each_rela(reldata, pos, pos_mem, idx,
					   nr_rel_entries) {
			symidx = GELF_R_SYM(pos->r_info);
			plt_offset += shdr_plt.sh_entsize;
			gelf_getsym(syms, symidx, &sym);
			snprintf(sympltname, sizeof(sympltname),
				 "%s@plt", elf_sym__name(&sym, symstrs));

			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
863
					sympltname);
864
			if (!f)
865
				goto out_elf_end;
866

867 868 869
			if (filter && filter(map, f))
				symbol__delete(f);
			else {
870
				symbols__insert(&self->symbols[map->type], f);
871 872
				++nr;
			}
873 874 875 876 877 878 879 880 881 882 883 884
		}
	} else if (shdr_rel_plt.sh_type == SHT_REL) {
		GElf_Rel pos_mem, *pos;
		elf_section__for_each_rel(reldata, pos, pos_mem, idx,
					  nr_rel_entries) {
			symidx = GELF_R_SYM(pos->r_info);
			plt_offset += shdr_plt.sh_entsize;
			gelf_getsym(syms, symidx, &sym);
			snprintf(sympltname, sizeof(sympltname),
				 "%s@plt", elf_sym__name(&sym, symstrs));

			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
885
					sympltname);
886
			if (!f)
887
				goto out_elf_end;
888

889 890 891
			if (filter && filter(map, f))
				symbol__delete(f);
			else {
892
				symbols__insert(&self->symbols[map->type], f);
893 894
				++nr;
			}
895 896 897
		}
	}

898 899 900 901 902 903 904 905 906
	err = 0;
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);

	if (err == 0)
		return nr;
out:
907 908
	pr_debug("%s: problems reading %s PLT info.\n",
		 __func__, self->long_name);
909
	return 0;
910 911
}

912 913 914 915 916
static bool elf_sym__is_a(GElf_Sym *self, enum map_type type)
{
	switch (type) {
	case MAP__FUNCTION:
		return elf_sym__is_function(self);
917 918
	case MAP__VARIABLE:
		return elf_sym__is_object(self);
919 920 921 922 923 924 925 926 927 928
	default:
		return false;
	}
}

static bool elf_sec__is_a(GElf_Shdr *self, Elf_Data *secstrs, enum map_type type)
{
	switch (type) {
	case MAP__FUNCTION:
		return elf_sec__is_text(self, secstrs);
929 930
	case MAP__VARIABLE:
		return elf_sec__is_data(self, secstrs);
931 932 933 934 935
	default:
		return false;
	}
}

936 937
static int dso__load_sym(struct dso *self, struct map *map, const char *name,
			 int fd, symbol_filter_t filter, int kmodule)
938
{
939
	struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
940 941
	struct map *curr_map = map;
	struct dso *curr_dso = self;
942
	Elf_Data *symstrs, *secstrs;
943 944
	uint32_t nr_syms;
	int err = -1;
945
	uint32_t idx;
946 947 948 949
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *syms;
	GElf_Sym sym;
950
	Elf_Scn *sec, *sec_strndx;
951
	Elf *elf;
952
	int nr = 0;
953

954
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
955
	if (elf == NULL) {
956
		pr_err("%s: cannot read %s ELF file.\n", __func__, name);
957 958 959 960
		goto out_close;
	}

	if (gelf_getehdr(elf, &ehdr) == NULL) {
961
		pr_err("%s: cannot get elf header.\n", __func__);
962 963 964 965
		goto out_elf_end;
	}

	sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
966
	if (sec == NULL) {
967 968
		sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
		if (sec == NULL)
969 970
			goto out_elf_end;
	}
971 972 973 974 975 976 977 978 979 980 981 982 983

	syms = elf_getdata(sec, NULL);
	if (syms == NULL)
		goto out_elf_end;

	sec = elf_getscn(elf, shdr.sh_link);
	if (sec == NULL)
		goto out_elf_end;

	symstrs = elf_getdata(sec, NULL);
	if (symstrs == NULL)
		goto out_elf_end;

984 985 986 987 988
	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
	if (sec_strndx == NULL)
		goto out_elf_end;

	secstrs = elf_getdata(sec_strndx, NULL);
S
Stoyan Gaydarov 已提交
989
	if (secstrs == NULL)
990 991
		goto out_elf_end;

992 993
	nr_syms = shdr.sh_size / shdr.sh_entsize;

994
	memset(&sym, 0, sizeof(sym));
995
	if (self->kernel == DSO_TYPE_USER) {
996
		self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
997 998 999
				elf_section_by_name(elf, &ehdr, &shdr,
						     ".gnu.prelink_undo",
						     NULL) != NULL);
1000 1001
	} else self->adjust_symbols = 0;

1002
	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1003
		struct symbol *f;
1004
		const char *elf_name = elf_sym__name(&sym, symstrs);
1005
		char *demangled = NULL;
1006 1007
		int is_label = elf_sym__is_label(&sym);
		const char *section_name;
1008

1009 1010 1011
		if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
		    strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
			kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
1012

1013
		if (!is_label && !elf_sym__is_a(&sym, map->type))
1014 1015 1016 1017 1018 1019 1020
			continue;

		sec = elf_getscn(elf, sym.st_shndx);
		if (!sec)
			goto out_elf_end;

		gelf_getshdr(sec, &shdr);
1021

1022
		if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
1023 1024 1025
			continue;

		section_name = elf_sec__name(&shdr, secstrs);
1026

1027
		if (self->kernel != DSO_TYPE_USER || kmodule) {
1028 1029 1030
			char dso_name[PATH_MAX];

			if (strcmp(section_name,
1031 1032
				   (curr_dso->short_name +
				    self->short_name_len)) == 0)
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
				goto new_symbol;

			if (strcmp(section_name, ".text") == 0) {
				curr_map = map;
				curr_dso = self;
				goto new_symbol;
			}

			snprintf(dso_name, sizeof(dso_name),
				 "%s%s", self->short_name, section_name);

1044
			curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1045 1046 1047 1048 1049 1050
			if (curr_map == NULL) {
				u64 start = sym.st_value;

				if (kmodule)
					start += map->start + shdr.sh_offset;

1051
				curr_dso = dso__new(dso_name);
1052 1053
				if (curr_dso == NULL)
					goto out_elf_end;
1054
				curr_dso->kernel = self->kernel;
1055
				curr_map = map__new2(start, curr_dso,
1056
						     map->type);
1057 1058 1059 1060
				if (curr_map == NULL) {
					dso__delete(curr_dso);
					goto out_elf_end;
				}
1061 1062
				curr_map->map_ip = identity__map_ip;
				curr_map->unmap_ip = identity__map_ip;
1063
				curr_dso->origin = self->origin;
1064
				map_groups__insert(kmap->kmaps, curr_map);
1065
				dsos__add(&self->node, curr_dso);
1066
				dso__set_loaded(curr_dso, map->type);
1067 1068 1069 1070
			} else
				curr_dso = curr_map->dso;

			goto new_symbol;
1071 1072
		}

1073
		if (curr_dso->adjust_symbols) {
1074 1075 1076 1077
			pr_debug4("%s: adjusting symbol: st_value: %#Lx "
				  "sh_addr: %#Lx sh_offset: %#Lx\n", __func__,
				  (u64)sym.st_value, (u64)shdr.sh_addr,
				  (u64)shdr.sh_offset);
1078
			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1079
		}
1080 1081 1082 1083 1084
		/*
		 * We need to figure out if the object was created from C++ sources
		 * DWARF DW_compile_unit has this, but we don't always have access
		 * to it...
		 */
1085
		demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
1086
		if (demangled != NULL)
1087
			elf_name = demangled;
1088
new_symbol:
1089
		f = symbol__new(sym.st_value, sym.st_size, elf_name);
1090
		free(demangled);
1091 1092 1093
		if (!f)
			goto out_elf_end;

1094
		if (filter && filter(curr_map, f))
1095
			symbol__delete(f);
1096
		else {
1097
			symbols__insert(&curr_dso->symbols[curr_map->type], f);
1098 1099
			nr++;
		}
1100 1101
	}

1102 1103 1104
	/*
	 * For misannotated, zeroed, ASM function sizes.
	 */
1105
	if (nr > 0) {
1106
		symbols__fixup_end(&self->symbols[map->type]);
1107 1108 1109 1110 1111 1112 1113 1114
		if (kmap) {
			/*
			 * We need to fixup this here too because we create new
			 * maps here, for things like vsyscall sections.
			 */
			__map_groups__fixup_end(kmap->kmaps, map->type);
		}
	}
1115 1116 1117 1118 1119 1120 1121
	err = nr;
out_elf_end:
	elf_end(elf);
out_close:
	return err;
}

1122 1123 1124 1125 1126
static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
{
	return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
}

1127
bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1128
{
1129
	bool have_build_id = false;
1130 1131
	struct dso *pos;

1132 1133 1134
	list_for_each_entry(pos, head, node) {
		if (with_hits && !pos->hit)
			continue;
1135 1136 1137 1138
		if (pos->has_build_id) {
			have_build_id = true;
			continue;
		}
1139 1140 1141 1142 1143
		if (filename__read_build_id(pos->long_name, pos->build_id,
					    sizeof(pos->build_id)) > 0) {
			have_build_id	  = true;
			pos->has_build_id = true;
		}
1144
	}
1145

1146
	return have_build_id;
1147 1148
}

1149 1150 1151 1152 1153
/*
 * Align offset to 4 bytes as needed for note name and descriptor data.
 */
#define NOTE_ALIGN(n) (((n) + 3) & -4U)

1154
int filename__read_build_id(const char *filename, void *bf, size_t size)
1155
{
1156
	int fd, err = -1;
1157 1158
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
1159
	Elf_Data *data;
1160
	Elf_Scn *sec;
1161
	Elf_Kind ek;
1162
	void *ptr;
1163 1164
	Elf *elf;

1165 1166 1167 1168
	if (size < BUILD_ID_SIZE)
		goto out;

	fd = open(filename, O_RDONLY);
1169 1170 1171
	if (fd < 0)
		goto out;

1172
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1173
	if (elf == NULL) {
1174
		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1175 1176 1177
		goto out_close;
	}

1178 1179 1180 1181
	ek = elf_kind(elf);
	if (ek != ELF_K_ELF)
		goto out_elf_end;

1182
	if (gelf_getehdr(elf, &ehdr) == NULL) {
1183
		pr_err("%s: cannot get elf header.\n", __func__);
1184 1185 1186
		goto out_elf_end;
	}

1187 1188
	sec = elf_section_by_name(elf, &ehdr, &shdr,
				  ".note.gnu.build-id", NULL);
1189 1190 1191 1192 1193 1194
	if (sec == NULL) {
		sec = elf_section_by_name(elf, &ehdr, &shdr,
					  ".notes", NULL);
		if (sec == NULL)
			goto out_elf_end;
	}
1195

1196 1197
	data = elf_getdata(sec, NULL);
	if (data == NULL)
1198
		goto out_elf_end;
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219

	ptr = data->d_buf;
	while (ptr < (data->d_buf + data->d_size)) {
		GElf_Nhdr *nhdr = ptr;
		int namesz = NOTE_ALIGN(nhdr->n_namesz),
		    descsz = NOTE_ALIGN(nhdr->n_descsz);
		const char *name;

		ptr += sizeof(*nhdr);
		name = ptr;
		ptr += namesz;
		if (nhdr->n_type == NT_GNU_BUILD_ID &&
		    nhdr->n_namesz == sizeof("GNU")) {
			if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
				memcpy(bf, ptr, BUILD_ID_SIZE);
				err = BUILD_ID_SIZE;
				break;
			}
		}
		ptr += descsz;
	}
1220 1221 1222 1223 1224 1225 1226 1227
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);
out:
	return err;
}

1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
{
	int fd, err = -1;

	if (size < BUILD_ID_SIZE)
		goto out;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		goto out;

	while (1) {
		char bf[BUFSIZ];
		GElf_Nhdr nhdr;
		int namesz, descsz;

		if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
			break;

1247 1248
		namesz = NOTE_ALIGN(nhdr.n_namesz);
		descsz = NOTE_ALIGN(nhdr.n_descsz);
1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271
		if (nhdr.n_type == NT_GNU_BUILD_ID &&
		    nhdr.n_namesz == sizeof("GNU")) {
			if (read(fd, bf, namesz) != namesz)
				break;
			if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
				if (read(fd, build_id,
				    BUILD_ID_SIZE) == BUILD_ID_SIZE) {
					err = 0;
					break;
				}
			} else if (read(fd, bf, descsz) != descsz)
				break;
		} else {
			int n = namesz + descsz;
			if (read(fd, bf, n) != n)
				break;
		}
	}
	close(fd);
out:
	return err;
}

1272 1273 1274 1275 1276
char dso__symtab_origin(const struct dso *self)
{
	static const char origin[] = {
		[DSO__ORIG_KERNEL] =   'k',
		[DSO__ORIG_JAVA_JIT] = 'j',
1277
		[DSO__ORIG_BUILD_ID_CACHE] = 'B',
1278 1279 1280 1281
		[DSO__ORIG_FEDORA] =   'f',
		[DSO__ORIG_UBUNTU] =   'u',
		[DSO__ORIG_BUILDID] =  'b',
		[DSO__ORIG_DSO] =      'd',
1282
		[DSO__ORIG_KMODULE] =  'K',
1283 1284
		[DSO__ORIG_GUEST_KERNEL] =  'g',
		[DSO__ORIG_GUEST_KMODULE] =  'G',
1285 1286 1287 1288 1289 1290 1291
	};

	if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
		return '!';
	return origin[self->origin];
}

1292
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1293
{
1294
	int size = PATH_MAX;
1295
	char *name;
1296
	u8 build_id[BUILD_ID_SIZE];
1297 1298
	int ret = -1;
	int fd;
1299
	struct machine *machine;
1300
	const char *root_dir;
1301

1302
	dso__set_loaded(self, map->type);
1303

1304
	if (self->kernel == DSO_TYPE_KERNEL)
1305
		return dso__load_kernel_sym(self, map, filter);
1306 1307 1308
	else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
		return dso__load_guest_kernel_sym(self, map, filter);

1309 1310
	if (map->groups && map->groups->machine)
		machine = map->groups->machine;
1311
	else
1312
		machine = NULL;
1313 1314

	name = malloc(size);
1315 1316 1317
	if (!name)
		return -1;

1318
	self->adjust_symbols = 0;
1319

1320
	if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1321
		ret = dso__load_perf_map(self, map, filter);
1322 1323 1324 1325 1326
		self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
					 DSO__ORIG_NOT_FOUND;
		return ret;
	}

1327
	self->origin = DSO__ORIG_BUILD_ID_CACHE;
1328
	if (dso__build_id_filename(self, name, size) != NULL)
1329
		goto open_file;
1330 1331
more:
	do {
1332 1333 1334
		self->origin++;
		switch (self->origin) {
		case DSO__ORIG_FEDORA:
1335 1336
			snprintf(name, size, "/usr/lib/debug%s.debug",
				 self->long_name);
1337
			break;
1338
		case DSO__ORIG_UBUNTU:
1339 1340
			snprintf(name, size, "/usr/lib/debug%s",
				 self->long_name);
1341
			break;
1342
		case DSO__ORIG_BUILDID:
1343 1344
			if (filename__read_build_id(self->long_name, build_id,
						    sizeof(build_id))) {
1345
				char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1346 1347
				build_id__sprintf(build_id, sizeof(build_id),
						  build_id_hex);
1348 1349
				snprintf(name, size,
					 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1350 1351 1352 1353
					build_id_hex, build_id_hex + 2);
				if (self->has_build_id)
					goto compare_build_id;
				break;
1354
			}
1355
			self->origin++;
1356
			/* Fall thru */
1357
		case DSO__ORIG_DSO:
1358
			snprintf(name, size, "%s", self->long_name);
1359
			break;
1360
		case DSO__ORIG_GUEST_KMODULE:
1361 1362
			if (map->groups && map->groups->machine)
				root_dir = map->groups->machine->root_dir;
1363 1364 1365 1366
			else
				root_dir = "";
			snprintf(name, size, "%s%s", root_dir, self->long_name);
			break;
1367 1368 1369 1370 1371

		default:
			goto out;
		}

1372
		if (self->has_build_id) {
1373 1374
			if (filename__read_build_id(name, build_id,
						    sizeof(build_id)) < 0)
1375 1376
				goto more;
compare_build_id:
1377
			if (!dso__build_id_equal(self, build_id))
1378 1379
				goto more;
		}
1380
open_file:
1381 1382 1383
		fd = open(name, O_RDONLY);
	} while (fd < 0);

1384
	ret = dso__load_sym(self, map, name, fd, filter, 0);
1385 1386 1387 1388 1389 1390 1391 1392
	close(fd);

	/*
	 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
	 */
	if (!ret)
		goto more;

1393
	if (ret > 0) {
1394
		int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1395 1396 1397
		if (nr_plt > 0)
			ret += nr_plt;
	}
1398 1399
out:
	free(name);
1400 1401
	if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
		return 0;
1402 1403 1404
	return ret;
}

1405 1406
struct map *map_groups__find_by_name(struct map_groups *self,
				     enum map_type type, const char *name)
1407 1408 1409
{
	struct rb_node *nd;

1410
	for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
1411 1412
		struct map *map = rb_entry(nd, struct map, rb_node);

1413
		if (map->dso && strcmp(map->dso->short_name, name) == 0)
1414 1415 1416 1417 1418 1419
			return map;
	}

	return NULL;
}

1420 1421
static int dso__kernel_module_get_build_id(struct dso *self,
				const char *root_dir)
1422 1423 1424 1425 1426 1427 1428 1429 1430
{
	char filename[PATH_MAX];
	/*
	 * kernel module short names are of the form "[module]" and
	 * we need just "module" here.
	 */
	const char *name = self->short_name + 1;

	snprintf(filename, sizeof(filename),
1431 1432
		 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
		 root_dir, (int)strlen(name) - 1, name);
1433 1434 1435 1436 1437 1438 1439 1440

	if (sysfs__read_build_id(filename, self->build_id,
				 sizeof(self->build_id)) == 0)
		self->has_build_id = true;

	return 0;
}

1441 1442
static int map_groups__set_modules_path_dir(struct map_groups *self,
				const char *dir_name)
1443
{
1444
	struct dirent *dent;
1445
	DIR *dir = opendir(dir_name);
1446

1447
	if (!dir) {
1448
		pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
1449 1450
		return -1;
	}
1451

1452 1453
	while ((dent = readdir(dir)) != NULL) {
		char path[PATH_MAX];
1454 1455 1456 1457 1458 1459
		struct stat st;

		/*sshfs might return bad dent->d_type, so we have to stat*/
		sprintf(path, "%s/%s", dir_name, dent->d_name);
		if (stat(path, &st))
			continue;
1460

1461
		if (S_ISDIR(st.st_mode)) {
1462 1463 1464 1465 1466
			if (!strcmp(dent->d_name, ".") ||
			    !strcmp(dent->d_name, ".."))
				continue;

			snprintf(path, sizeof(path), "%s/%s",
1467
				 dir_name, dent->d_name);
1468
			if (map_groups__set_modules_path_dir(self, path) < 0)
1469 1470 1471 1472 1473
				goto failure;
		} else {
			char *dot = strrchr(dent->d_name, '.'),
			     dso_name[PATH_MAX];
			struct map *map;
1474
			char *long_name;
1475 1476 1477 1478 1479 1480

			if (dot == NULL || strcmp(dot, ".ko"))
				continue;
			snprintf(dso_name, sizeof(dso_name), "[%.*s]",
				 (int)(dot - dent->d_name), dent->d_name);

1481
			strxfrchar(dso_name, '-', '_');
1482
			map = map_groups__find_by_name(self, MAP__FUNCTION, dso_name);
1483 1484 1485 1486
			if (map == NULL)
				continue;

			snprintf(path, sizeof(path), "%s/%s",
1487
				 dir_name, dent->d_name);
1488

1489 1490
			long_name = strdup(path);
			if (long_name == NULL)
1491
				goto failure;
1492
			dso__set_long_name(map->dso, long_name);
1493
			dso__kernel_module_get_build_id(map->dso, "");
1494 1495
		}
	}
1496

1497
	return 0;
1498 1499 1500 1501
failure:
	closedir(dir);
	return -1;
}
1502

1503
static char *get_kernel_version(const char *root_dir)
1504
{
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
	char version[PATH_MAX];
	FILE *file;
	char *name, *tmp;
	const char *prefix = "Linux version ";

	sprintf(version, "%s/proc/version", root_dir);
	file = fopen(version, "r");
	if (!file)
		return NULL;

	version[0] = '\0';
	tmp = fgets(version, sizeof(version), file);
	fclose(file);

	name = strstr(version, prefix);
	if (!name)
		return NULL;
	name += strlen(prefix);
	tmp = strchr(name, ' ');
	if (tmp)
		*tmp = '\0';

	return strdup(name);
}

1530
static int machine__set_modules_path(struct machine *self)
1531 1532
{
	char *version;
1533
	char modules_path[PATH_MAX];
1534

1535
	version = get_kernel_version(self->root_dir);
1536
	if (!version)
1537
		return -1;
1538

1539
	snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1540
		 self->root_dir, version);
1541
	free(version);
1542

1543
	return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
1544 1545
}

1546 1547 1548 1549 1550
/*
 * Constructor variant for modules (where we know from /proc/modules where
 * they are loaded) and for vmlinux, where only after we load all the
 * symbols we'll know where it starts and ends.
 */
1551
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1552
{
1553 1554
	struct map *self = calloc(1, (sizeof(*self) +
				      (dso->kernel ? sizeof(struct kmap) : 0)));
1555 1556
	if (self != NULL) {
		/*
1557
		 * ->end will be filled after we load all the symbols
1558
		 */
1559
		map__init(self, type, start, 0, 0, dso);
1560
	}
1561

1562 1563 1564
	return self;
}

1565 1566
struct map *machine__new_module(struct machine *self, u64 start,
				const char *filename)
1567 1568
{
	struct map *map;
1569
	struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
1570 1571 1572 1573 1574 1575 1576 1577

	if (dso == NULL)
		return NULL;

	map = map__new2(start, dso, MAP__FUNCTION);
	if (map == NULL)
		return NULL;

1578
	if (machine__is_host(self))
1579 1580 1581
		dso->origin = DSO__ORIG_KMODULE;
	else
		dso->origin = DSO__ORIG_GUEST_KMODULE;
1582
	map_groups__insert(&self->kmaps, map);
1583 1584 1585
	return map;
}

1586
static int machine__create_modules(struct machine *self)
1587 1588 1589
{
	char *line = NULL;
	size_t n;
1590
	FILE *file;
1591
	struct map *map;
1592 1593 1594
	const char *modules;
	char path[PATH_MAX];

1595
	if (machine__is_default_guest(self))
1596 1597
		modules = symbol_conf.default_guest_modules;
	else {
1598
		sprintf(path, "%s/proc/modules", self->root_dir);
1599 1600
		modules = path;
	}
1601

1602
	file = fopen(modules, "r");
1603 1604
	if (file == NULL)
		return -1;
1605

1606 1607 1608 1609 1610
	while (!feof(file)) {
		char name[PATH_MAX];
		u64 start;
		char *sep;
		int line_len;
1611

1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633
		line_len = getline(&line, &n, file);
		if (line_len < 0)
			break;

		if (!line)
			goto out_failure;

		line[--line_len] = '\0'; /* \n */

		sep = strrchr(line, 'x');
		if (sep == NULL)
			continue;

		hex2u64(sep + 1, &start);

		sep = strchr(line, ' ');
		if (sep == NULL)
			continue;

		*sep = '\0';

		snprintf(name, sizeof(name), "[%s]", line);
1634
		map = machine__new_module(self, start, name);
1635
		if (map == NULL)
1636
			goto out_delete_line;
1637
		dso__kernel_module_get_build_id(map->dso, self->root_dir);
1638
	}
1639 1640 1641 1642

	free(line);
	fclose(file);

1643
	return machine__set_modules_path(self);
1644 1645 1646 1647 1648

out_delete_line:
	free(line);
out_failure:
	return -1;
1649 1650
}

1651
static int dso__load_vmlinux(struct dso *self, struct map *map,
1652
			     const char *vmlinux, symbol_filter_t filter)
1653
{
1654
	int err = -1, fd;
1655

1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
	if (self->has_build_id) {
		u8 build_id[BUILD_ID_SIZE];

		if (filename__read_build_id(vmlinux, build_id,
					    sizeof(build_id)) < 0) {
			pr_debug("No build_id in %s, ignoring it\n", vmlinux);
			return -1;
		}
		if (!dso__build_id_equal(self, build_id)) {
			char expected_build_id[BUILD_ID_SIZE * 2 + 1],
			     vmlinux_build_id[BUILD_ID_SIZE * 2 + 1];

			build_id__sprintf(self->build_id,
					  sizeof(self->build_id),
					  expected_build_id);
			build_id__sprintf(build_id, sizeof(build_id),
					  vmlinux_build_id);
			pr_debug("build_id in %s is %s while expected is %s, "
				 "ignoring it\n", vmlinux, vmlinux_build_id,
				 expected_build_id);
			return -1;
		}
	}
1679

1680
	fd = open(vmlinux, O_RDONLY);
1681 1682 1683
	if (fd < 0)
		return -1;

1684
	dso__set_loaded(self, map->type);
1685
	err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
1686 1687
	close(fd);

1688 1689 1690
	if (err > 0)
		pr_debug("Using %s for symbols\n", vmlinux);

1691 1692 1693
	return err;
}

1694
int dso__load_vmlinux_path(struct dso *self, struct map *map,
1695
			   symbol_filter_t filter)
1696 1697 1698 1699 1700 1701 1702
{
	int i, err = 0;

	pr_debug("Looking at the vmlinux_path (%d entries long)\n",
		 vmlinux_path__nr_entries);

	for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1703
		err = dso__load_vmlinux(self, map, vmlinux_path[i], filter);
1704 1705 1706 1707 1708 1709 1710 1711 1712
		if (err > 0) {
			dso__set_long_name(self, strdup(vmlinux_path[i]));
			break;
		}
	}

	return err;
}

1713
static int dso__load_kernel_sym(struct dso *self, struct map *map,
1714
				symbol_filter_t filter)
1715
{
1716
	int err;
1717 1718
	const char *kallsyms_filename = NULL;
	char *kallsyms_allocated_filename = NULL;
1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734
	/*
	 * Step 1: if the user specified a vmlinux filename, use it and only
	 * it, reporting errors to the user if it cannot be used.
	 *
	 * For instance, try to analyse an ARM perf.data file _without_ a
	 * build-id, or if the user specifies the wrong path to the right
	 * vmlinux file, obviously we can't fallback to another vmlinux (a
	 * x86_86 one, on the machine where analysis is being performed, say),
	 * or worse, /proc/kallsyms.
	 *
	 * If the specified file _has_ a build-id and there is a build-id
	 * section in the perf.data file, we will still do the expected
	 * validation in dso__load_vmlinux and will bail out if they don't
	 * match.
	 */
	if (symbol_conf.vmlinux_name != NULL) {
1735
		err = dso__load_vmlinux(self, map,
1736 1737 1738
					symbol_conf.vmlinux_name, filter);
		goto out_try_fixup;
	}
1739 1740

	if (vmlinux_path != NULL) {
1741
		err = dso__load_vmlinux_path(self, map, filter);
1742 1743
		if (err > 0)
			goto out_fixup;
1744 1745
	}

1746 1747 1748 1749 1750 1751 1752
	/*
	 * Say the kernel DSO was created when processing the build-id header table,
	 * we have a build-id, so check if it is the same as the running kernel,
	 * using it if it is.
	 */
	if (self->has_build_id) {
		u8 kallsyms_build_id[BUILD_ID_SIZE];
1753
		char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1754 1755

		if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1756
					 sizeof(kallsyms_build_id)) == 0) {
1757 1758
			if (dso__build_id_equal(self, kallsyms_build_id)) {
				kallsyms_filename = "/proc/kallsyms";
1759
				goto do_kallsyms;
1760
			}
1761
		}
1762 1763 1764 1765
		/*
		 * Now look if we have it on the build-id cache in
		 * $HOME/.debug/[kernel.kallsyms].
		 */
1766 1767 1768 1769 1770
		build_id__sprintf(self->build_id, sizeof(self->build_id),
				  sbuild_id);

		if (asprintf(&kallsyms_allocated_filename,
			     "%s/.debug/[kernel.kallsyms]/%s",
1771 1772
			     getenv("HOME"), sbuild_id) == -1) {
			pr_err("Not enough memory for kallsyms file lookup\n");
1773
			return -1;
1774
		}
1775

1776 1777
		kallsyms_filename = kallsyms_allocated_filename;

1778
		if (access(kallsyms_filename, F_OK)) {
1779 1780
			pr_err("No kallsyms or vmlinux with build-id %s "
			       "was found\n", sbuild_id);
1781
			free(kallsyms_allocated_filename);
1782
			return -1;
1783
		}
1784 1785 1786 1787 1788
	} else {
		/*
		 * Last resort, if we don't have a build-id and couldn't find
		 * any vmlinux file, try the running kernel kallsyms table.
		 */
1789 1790
		kallsyms_filename = "/proc/kallsyms";
	}
1791

1792
do_kallsyms:
1793
	err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
1794 1795
	if (err > 0)
		pr_debug("Using %s for symbols\n", kallsyms_filename);
1796
	free(kallsyms_allocated_filename);
1797

1798
out_try_fixup:
1799
	if (err > 0) {
1800
out_fixup:
1801
		if (kallsyms_filename != NULL)
1802
			dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1803 1804
		map__fixup_start(map);
		map__fixup_end(map);
1805
	}
1806

1807 1808 1809
	return err;
}

1810 1811 1812 1813 1814
static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
				symbol_filter_t filter)
{
	int err;
	const char *kallsyms_filename = NULL;
1815
	struct machine *machine;
1816 1817 1818 1819 1820 1821
	char path[PATH_MAX];

	if (!map->groups) {
		pr_debug("Guest kernel map hasn't the point to groups\n");
		return -1;
	}
1822
	machine = map->groups->machine;
1823

1824
	if (machine__is_default_guest(machine)) {
1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839
		/*
		 * if the user specified a vmlinux filename, use it and only
		 * it, reporting errors to the user if it cannot be used.
		 * Or use file guest_kallsyms inputted by user on commandline
		 */
		if (symbol_conf.default_guest_vmlinux_name != NULL) {
			err = dso__load_vmlinux(self, map,
				symbol_conf.default_guest_vmlinux_name, filter);
			goto out_try_fixup;
		}

		kallsyms_filename = symbol_conf.default_guest_kallsyms;
		if (!kallsyms_filename)
			return -1;
	} else {
1840
		sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1841 1842 1843 1844 1845 1846 1847 1848 1849 1850
		kallsyms_filename = path;
	}

	err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
	if (err > 0)
		pr_debug("Using %s for symbols\n", kallsyms_filename);

out_try_fixup:
	if (err > 0) {
		if (kallsyms_filename != NULL) {
1851
			machine__mmap_name(machine, path, sizeof(path));
1852
			dso__set_long_name(self, strdup(path));
1853 1854 1855 1856 1857 1858 1859
		}
		map__fixup_start(map);
		map__fixup_end(map);
	}

	return err;
}
1860

1861
static void dsos__add(struct list_head *head, struct dso *dso)
1862
{
1863
	list_add_tail(&dso->node, head);
1864 1865
}

1866
static struct dso *dsos__find(struct list_head *head, const char *name)
1867 1868 1869
{
	struct dso *pos;

1870
	list_for_each_entry(pos, head, node)
1871
		if (strcmp(pos->long_name, name) == 0)
1872 1873 1874 1875
			return pos;
	return NULL;
}

1876
struct dso *__dsos__findnew(struct list_head *head, const char *name)
1877
{
1878
	struct dso *dso = dsos__find(head, name);
1879

1880
	if (!dso) {
1881
		dso = dso__new(name);
1882
		if (dso != NULL) {
1883
			dsos__add(head, dso);
1884 1885
			dso__set_basename(dso);
		}
1886
	}
1887 1888 1889 1890

	return dso;
}

1891
size_t __dsos__fprintf(struct list_head *head, FILE *fp)
1892 1893
{
	struct dso *pos;
1894
	size_t ret = 0;
1895

1896 1897 1898
	list_for_each_entry(pos, head, node) {
		int i;
		for (i = 0; i < MAP__NR_TYPES; ++i)
1899
			ret += dso__fprintf(pos, i, fp);
1900
	}
1901 1902

	return ret;
1903 1904
}

1905
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
1906
{
1907
	struct rb_node *nd;
1908
	size_t ret = 0;
1909

1910
	for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1911
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
1912 1913
		ret += __dsos__fprintf(&pos->kernel_dsos, fp);
		ret += __dsos__fprintf(&pos->user_dsos, fp);
1914
	}
1915 1916

	return ret;
1917 1918
}

1919 1920
static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
				      bool with_hits)
1921 1922 1923 1924
{
	struct dso *pos;
	size_t ret = 0;

1925
	list_for_each_entry(pos, head, node) {
1926 1927
		if (with_hits && !pos->hit)
			continue;
1928
		ret += dso__fprintf_buildid(pos, fp);
1929
		ret += fprintf(fp, " %s\n", pos->long_name);
1930 1931 1932 1933
	}
	return ret;
}

1934 1935 1936 1937 1938 1939
size_t machine__fprintf_dsos_buildid(struct machine *self, FILE *fp, bool with_hits)
{
	return __dsos__fprintf_buildid(&self->kernel_dsos, fp, with_hits) +
	       __dsos__fprintf_buildid(&self->user_dsos, fp, with_hits);
}

1940
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
1941
{
1942 1943 1944
	struct rb_node *nd;
	size_t ret = 0;

1945
	for (nd = rb_first(self); nd; nd = rb_next(nd)) {
1946
		struct machine *pos = rb_entry(nd, struct machine, rb_node);
1947
		ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
1948 1949
	}
	return ret;
1950 1951
}

1952 1953 1954 1955 1956
struct dso *dso__new_kernel(const char *name)
{
	struct dso *self = dso__new(name ?: "[kernel.kallsyms]");

	if (self != NULL) {
1957
		dso__set_short_name(self, "[kernel]");
1958 1959 1960 1961 1962 1963
		self->kernel = DSO_TYPE_KERNEL;
	}

	return self;
}

1964
static struct dso *dso__new_guest_kernel(struct machine *machine,
1965 1966
					const char *name)
{
1967 1968
	char bf[PATH_MAX];
	struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
1969 1970 1971 1972

	if (self != NULL) {
		dso__set_short_name(self, "[guest.kernel]");
		self->kernel = DSO_TYPE_GUEST_KERNEL;
1973 1974 1975 1976 1977
	}

	return self;
}

1978
void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
1979
{
1980 1981
	char path[PATH_MAX];

1982
	if (machine__is_default_guest(machine))
1983
		return;
1984
	sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
1985
	if (sysfs__read_build_id(path, self->build_id,
1986 1987 1988 1989
				 sizeof(self->build_id)) == 0)
		self->has_build_id = true;
}

1990
static struct dso *machine__create_kernel(struct machine *self)
1991
{
1992 1993
	const char *vmlinux_name = NULL;
	struct dso *kernel;
1994

1995
	if (machine__is_host(self)) {
1996 1997 1998
		vmlinux_name = symbol_conf.vmlinux_name;
		kernel = dso__new_kernel(vmlinux_name);
	} else {
1999
		if (machine__is_default_guest(self))
2000
			vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2001
		kernel = dso__new_guest_kernel(self, vmlinux_name);
2002
	}
2003

2004
	if (kernel != NULL) {
2005 2006
		dso__read_running_kernel_build_id(kernel, self);
		dsos__add(&self->kernel_dsos, kernel);
2007
	}
2008 2009 2010
	return kernel;
}

2011
int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2012
{
2013
	enum map_type type;
2014

2015
	for (type = 0; type < MAP__NR_TYPES; ++type) {
2016 2017
		struct kmap *kmap;

2018 2019
		self->vmlinux_maps[type] = map__new2(0, kernel, type);
		if (self->vmlinux_maps[type] == NULL)
2020
			return -1;
2021

2022 2023
		self->vmlinux_maps[type]->map_ip =
			self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
2024

2025 2026 2027
		kmap = map__kmap(self->vmlinux_maps[type]);
		kmap->kmaps = &self->kmaps;
		map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
2028 2029 2030
	}

	return 0;
2031 2032
}

2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049
int machine__create_kernel_maps(struct machine *self)
{
	struct dso *kernel = machine__create_kernel(self);

	if (kernel == NULL ||
	    __machine__create_kernel_maps(self, kernel) < 0)
		return -1;

	if (symbol_conf.use_modules && machine__create_modules(self) < 0)
		pr_debug("Problems creating module maps, continuing anyway...\n");
	/*
	 * Now that we have all the maps created, just set the ->end of them:
	 */
	map_groups__fixup_end(&self->kmaps);
	return 0;
}

2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
static void vmlinux_path__exit(void)
{
	while (--vmlinux_path__nr_entries >= 0) {
		free(vmlinux_path[vmlinux_path__nr_entries]);
		vmlinux_path[vmlinux_path__nr_entries] = NULL;
	}

	free(vmlinux_path);
	vmlinux_path = NULL;
}

static int vmlinux_path__init(void)
{
	struct utsname uts;
	char bf[PATH_MAX];

	if (uname(&uts) < 0)
		return -1;

	vmlinux_path = malloc(sizeof(char *) * 5);
	if (vmlinux_path == NULL)
		return -1;

	vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
		goto out_fail;
	++vmlinux_path__nr_entries;
	vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
		goto out_fail;
	++vmlinux_path__nr_entries;
	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
		goto out_fail;
	++vmlinux_path__nr_entries;
	snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
		goto out_fail;
	++vmlinux_path__nr_entries;
	snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
		 uts.release);
	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
		goto out_fail;
	++vmlinux_path__nr_entries;

	return 0;

out_fail:
	vmlinux_path__exit();
	return -1;
}

2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115
size_t vmlinux_path__fprintf(FILE *fp)
{
	int i;
	size_t printed = 0;

	for (i = 0; i < vmlinux_path__nr_entries; ++i)
		printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]);

	return printed;
}

2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129
static int setup_list(struct strlist **list, const char *list_str,
		      const char *list_name)
{
	if (list_str == NULL)
		return 0;

	*list = strlist__new(true, list_str);
	if (!*list) {
		pr_err("problems parsing %s list\n", list_name);
		return -1;
	}
	return 0;
}

2130
int symbol__init(void)
2131
{
2132
	elf_version(EV_CURRENT);
2133 2134 2135
	if (symbol_conf.sort_by_name)
		symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
					  sizeof(struct symbol));
2136

2137
	if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
2138 2139
		return -1;

2140 2141 2142 2143 2144
	if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
		pr_err("'.' is the only non valid --field-separator argument\n");
		return -1;
	}

2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156
	if (setup_list(&symbol_conf.dso_list,
		       symbol_conf.dso_list_str, "dso") < 0)
		return -1;

	if (setup_list(&symbol_conf.comm_list,
		       symbol_conf.comm_list_str, "comm") < 0)
		goto out_free_dso_list;

	if (setup_list(&symbol_conf.sym_list,
		       symbol_conf.sym_list_str, "symbol") < 0)
		goto out_free_comm_list;

2157
	return 0;
2158 2159 2160 2161 2162 2163

out_free_dso_list:
	strlist__delete(symbol_conf.dso_list);
out_free_comm_list:
	strlist__delete(symbol_conf.comm_list);
	return -1;
2164 2165
}

2166
int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
2167
{
2168
	struct machine *machine = machines__findnew(self, pid);
2169

2170
	if (machine == NULL)
2171
		return -1;
2172

2173
	return machine__create_kernel_maps(machine);
2174
}
2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217

static int hex(char ch)
{
	if ((ch >= '0') && (ch <= '9'))
		return ch - '0';
	if ((ch >= 'a') && (ch <= 'f'))
		return ch - 'a' + 10;
	if ((ch >= 'A') && (ch <= 'F'))
		return ch - 'A' + 10;
	return -1;
}

/*
 * While we find nice hex chars, build a long_val.
 * Return number of chars processed.
 */
int hex2u64(const char *ptr, u64 *long_val)
{
	const char *p = ptr;
	*long_val = 0;

	while (*p) {
		const int hex_val = hex(*p);

		if (hex_val < 0)
			break;

		*long_val = (*long_val << 4) | hex_val;
		p++;
	}

	return p - ptr;
}

char *strxfrchar(char *s, char from, char to)
{
	char *p = s;

	while ((p = strchr(p, from)) != NULL)
		*p++ = to;

	return s;
}
2218

2219
int machines__create_guest_kernel_maps(struct rb_root *self)
2220 2221 2222 2223 2224 2225 2226 2227 2228 2229
{
	int ret = 0;
	struct dirent **namelist = NULL;
	int i, items = 0;
	char path[PATH_MAX];
	pid_t pid;

	if (symbol_conf.default_guest_vmlinux_name ||
	    symbol_conf.default_guest_modules ||
	    symbol_conf.default_guest_kallsyms) {
2230
		machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250
	}

	if (symbol_conf.guestmount) {
		items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
		if (items <= 0)
			return -ENOENT;
		for (i = 0; i < items; i++) {
			if (!isdigit(namelist[i]->d_name[0])) {
				/* Filter out . and .. */
				continue;
			}
			pid = atoi(namelist[i]->d_name);
			sprintf(path, "%s/%s/proc/kallsyms",
				symbol_conf.guestmount,
				namelist[i]->d_name);
			ret = access(path, R_OK);
			if (ret) {
				pr_debug("Can't access file %s\n", path);
				goto failure;
			}
2251
			machines__create_kernel_maps(self, pid);
2252 2253 2254 2255 2256 2257 2258
		}
failure:
		free(namelist);
	}

	return ret;
}
2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291

int machine__load_kallsyms(struct machine *self, const char *filename,
			   enum map_type type, symbol_filter_t filter)
{
	struct map *map = self->vmlinux_maps[type];
	int ret = dso__load_kallsyms(map->dso, filename, map, filter);

	if (ret > 0) {
		dso__set_loaded(map->dso, type);
		/*
		 * Since /proc/kallsyms will have multiple sessions for the
		 * kernel, with modules between them, fixup the end of all
		 * sections.
		 */
		__map_groups__fixup_end(&self->kmaps, type);
	}

	return ret;
}

int machine__load_vmlinux_path(struct machine *self, enum map_type type,
			       symbol_filter_t filter)
{
	struct map *map = self->vmlinux_maps[type];
	int ret = dso__load_vmlinux_path(map->dso, map, filter);

	if (ret > 0) {
		dso__set_loaded(map->dso, type);
		map__reloc_vmlinux(map);
	}

	return ret;
}