symbol.c 35.7 KB
Newer Older
1 2
#include "util.h"
#include "../perf.h"
3
#include "string.h"
4
#include "symbol.h"
5
#include "thread.h"
6

7 8
#include "debug.h"

9
#include <asm/bug.h>
10 11 12
#include <libelf.h>
#include <gelf.h>
#include <elf.h>
13
#include <limits.h>
14
#include <sys/utsname.h>
P
Peter Zijlstra 已提交
15

16 17 18 19
#ifndef NT_GNU_BUILD_ID
#define NT_GNU_BUILD_ID 3
#endif

20 21 22 23 24 25 26
enum dso_origin {
	DSO__ORIG_KERNEL = 0,
	DSO__ORIG_JAVA_JIT,
	DSO__ORIG_FEDORA,
	DSO__ORIG_UBUNTU,
	DSO__ORIG_BUILDID,
	DSO__ORIG_DSO,
27
	DSO__ORIG_KMODULE,
28 29 30
	DSO__ORIG_NOT_FOUND,
};

31
static void dsos__add(struct list_head *head, struct dso *dso);
32
static struct map *map_groups__find_by_name(struct map_groups *self, char *name);
33
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
34
struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
35
static int dso__load_kernel_sym(struct dso *self, struct map *map,
36
				struct map_groups *mg, symbol_filter_t filter);
37
unsigned int symbol__priv_size;
38 39
static int vmlinux_path__nr_entries;
static char **vmlinux_path;
40

41 42 43 44 45
static struct symbol_conf symbol_conf__defaults = {
	.use_modules	  = true,
	.try_vmlinux_path = true,
};

46 47
static struct map_groups kmaps_mem;
struct map_groups *kmaps = &kmaps_mem;
48

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

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

59
static void symbols__fixup_end(struct rb_root *self)
60
{
61
	struct rb_node *nd, *prevnd = rb_first(self);
62
	struct symbol *curr, *prev;
63 64 65 66

	if (prevnd == NULL)
		return;

67 68
	curr = rb_entry(prevnd, struct symbol, rb_node);

69
	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
70 71
		prev = curr;
		curr = rb_entry(nd, struct symbol, rb_node);
72 73 74 75

		if (prev->end == prev->start)
			prev->end = curr->start - 1;
	}
76 77 78 79

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

82
static void __map_groups__fixup_end(struct map_groups *self, enum map_type type)
83 84
{
	struct map *prev, *curr;
85
	struct rb_node *nd, *prevnd = rb_first(&self->maps[type]);
86 87 88 89 90 91 92 93 94 95

	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;
96
	}
97 98 99 100 101 102

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

105
static void map_groups__fixup_end(struct map_groups *self)
106 107 108
{
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
109
		__map_groups__fixup_end(self, i);
110 111
}

112
static struct symbol *symbol__new(u64 start, u64 len, const char *name)
113
{
114
	size_t namelen = strlen(name) + 1;
115 116 117
	struct symbol *self = zalloc(symbol__priv_size +
				     sizeof(*self) + namelen);
	if (self == NULL)
118 119
		return NULL;

120
	if (symbol__priv_size)
121
		self = ((void *)self) + symbol__priv_size;
122

123
	self->start = start;
124
	self->end   = len ? start + len - 1 : start;
125

126
	pr_debug3("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
127

128
	memcpy(self->name, name, namelen);
129 130 131 132

	return self;
}

133
static void symbol__delete(struct symbol *self)
134
{
135
	free(((void *)self) - symbol__priv_size);
136 137 138 139
}

static size_t symbol__fprintf(struct symbol *self, FILE *fp)
{
140
	return fprintf(fp, " %llx-%llx %s\n",
141 142 143
		       self->start, self->end, self->name);
}

144 145
static void dso__set_long_name(struct dso *self, char *name)
{
146 147
	if (name == NULL)
		return;
148 149 150 151 152 153 154 155 156
	self->long_name = name;
	self->long_name_len = strlen(name);
}

static void dso__set_basename(struct dso *self)
{
	self->short_name = basename(self->long_name);
}

157
struct dso *dso__new(const char *name)
158 159 160 161
{
	struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);

	if (self != NULL) {
162
		int i;
163
		strcpy(self->name, name);
164
		dso__set_long_name(self, self->name);
165
		self->short_name = self->name;
166 167 168
		for (i = 0; i < MAP__NR_TYPES; ++i)
			self->symbols[i] = RB_ROOT;
		self->find_symbol = dso__find_symbol;
169
		self->slen_calculated = 0;
170
		self->origin = DSO__ORIG_NOT_FOUND;
171 172
		self->loaded = 0;
		self->has_build_id = 0;
173 174 175 176 177
	}

	return self;
}

178
static void symbols__delete(struct rb_root *self)
179 180
{
	struct symbol *pos;
181
	struct rb_node *next = rb_first(self);
182 183 184 185

	while (next) {
		pos = rb_entry(next, struct symbol, rb_node);
		next = rb_next(&pos->rb_node);
186
		rb_erase(&pos->rb_node, self);
187
		symbol__delete(pos);
188 189 190 191 192
	}
}

void dso__delete(struct dso *self)
{
193 194 195
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
		symbols__delete(&self->symbols[i]);
196 197
	if (self->long_name != self->name)
		free(self->long_name);
198 199 200
	free(self);
}

201 202 203 204 205 206
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;
}

207
static void symbols__insert(struct rb_root *self, struct symbol *sym)
208
{
209
	struct rb_node **p = &self->rb_node;
210
	struct rb_node *parent = NULL;
211
	const u64 ip = sym->start;
212 213 214 215 216 217 218 219 220 221 222
	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);
223
	rb_insert_color(&sym->rb_node, self);
224 225
}

226
static struct symbol *symbols__find(struct rb_root *self, u64 ip)
227 228 229 230 231 232
{
	struct rb_node *n;

	if (self == NULL)
		return NULL;

233
	n = self->rb_node;
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248

	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;
}

249
struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr)
250
{
251
	return symbols__find(&self->symbols[type], addr);
252 253
}

254
int build_id__sprintf(u8 *self, int len, char *bf)
255
{
256 257 258
	char *bid = bf;
	u8 *raw = self;
	int i;
259

260 261 262 263 264 265 266 267 268
	for (i = 0; i < len; ++i) {
		sprintf(bid, "%02x", *raw);
		++raw;
		bid += 2;
	}

	return raw - self;
}

269
size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
270 271 272 273
{
	char sbuild_id[BUILD_ID_SIZE * 2 + 1];

	build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
274 275 276
	return fprintf(fp, "%s", sbuild_id);
}

277
size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp)
278 279 280 281 282
{
	struct rb_node *nd;
	size_t ret = fprintf(fp, "dso: %s (", self->short_name);

	ret += dso__fprintf_buildid(self, fp);
283
	ret += fprintf(fp, ")\n");
284 285 286
	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);
287 288 289 290 291
	}

	return ret;
}

292 293 294 295 296
/*
 * 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.
 */
297
static int dso__load_all_kallsyms(struct dso *self, struct map *map)
298 299 300
{
	char *line = NULL;
	size_t n;
301
	struct rb_root *root = &self->symbols[map->type];
302 303 304 305 306 307
	FILE *file = fopen("/proc/kallsyms", "r");

	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
308
		u64 start;
309 310 311
		struct symbol *sym;
		int line_len, len;
		char symbol_type;
312
		char *symbol_name;
313 314 315 316 317 318 319 320 321 322

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

		if (!line)
			goto out_failure;

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

323
		len = hex2u64(line, &start);
324 325 326 327 328 329 330 331 332 333 334

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

		symbol_type = toupper(line[len]);
		/*
		 * We're interested only in code ('T'ext)
		 */
		if (symbol_type != 'T' && symbol_type != 'W')
			continue;
335 336

		symbol_name = line + len + 2;
337 338 339
		/*
		 * Will fix up the end later, when we have all symbols sorted.
		 */
340
		sym = symbol__new(start, 0, symbol_name);
341

342 343
		if (sym == NULL)
			goto out_delete_line;
344 345
		/*
		 * We will pass the symbols to the filter later, in
346
		 * map__split_kallsyms, when we have split the maps per module
347
		 */
348
		symbols__insert(root, sym);
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
	}

	free(line);
	fclose(file);

	return 0;

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

/*
 * 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.
 */
367 368
static int dso__split_kallsyms(struct dso *self, struct map *map,
			       struct map_groups *mg, symbol_filter_t filter)
369
{
370
	struct map *curr_map = map;
371 372
	struct symbol *pos;
	int count = 0;
373 374
	struct rb_root *root = &self->symbols[map->type];
	struct rb_node *next = rb_first(root);
375 376 377 378 379 380 381 382 383 384
	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) {
385
			if (!mg->use_modules)
386 387
				goto discard_symbol;

388 389
			*module++ = '\0';

390
			if (strcmp(self->name, module)) {
391
				curr_map = map_groups__find_by_name(mg, module);
392
				if (curr_map == NULL) {
393 394
					pr_debug("/proc/{kallsyms,modules} "
					         "inconsistency!\n");
395 396 397
					return -1;
				}
			}
398 399 400 401
			/*
			 * So that we look just like we get from .ko files,
			 * i.e. not prelinked, relative to map->start.
			 */
402 403 404
			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) {
405 406 407 408 409 410
			char dso_name[PATH_MAX];
			struct dso *dso;

			snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
				 kernel_range++);

411
			dso = dso__new(dso_name);
412 413 414
			if (dso == NULL)
				return -1;

415
			curr_map = map__new2(pos->start, dso, map->type);
416 417 418 419
			if (map == NULL) {
				dso__delete(dso);
				return -1;
			}
420

421
			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
422
			map_groups__insert(mg, curr_map);
423 424
			++kernel_range;
		}
425

426
		if (filter && filter(curr_map, pos)) {
427
discard_symbol:		rb_erase(&pos->rb_node, root);
428
			symbol__delete(pos);
429
		} else {
430 431 432
			if (curr_map != map) {
				rb_erase(&pos->rb_node, root);
				symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
433
			}
434 435
			count++;
		}
436 437
	}

438
	return count;
439
}
440

441

442
static int dso__load_kallsyms(struct dso *self, struct map *map,
443
			      struct map_groups *mg, symbol_filter_t filter)
444
{
445
	if (dso__load_all_kallsyms(self, map) < 0)
446 447
		return -1;

448 449
	symbols__fixup_end(&self->symbols[map->type]);
	self->origin = DSO__ORIG_KERNEL;
450

451
	return dso__split_kallsyms(self, map, mg, filter);
452 453 454 455 456
}

size_t kernel_maps__fprintf(FILE *fp)
{
	size_t printed = fprintf(fp, "Kernel maps:\n");
457
	printed += map_groups__fprintf_maps(kmaps, fp);
458
	return printed + fprintf(fp, "END kernel maps\n");
459 460
}

461
static int dso__load_perf_map(struct dso *self, struct map *map,
462
			      symbol_filter_t filter)
463 464 465 466 467 468
{
	char *line = NULL;
	size_t n;
	FILE *file;
	int nr_syms = 0;

469
	file = fopen(self->long_name, "r");
470 471 472 473
	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
474
		u64 start, size;
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
		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;

499
		sym = symbol__new(start, size, line + len);
500 501 502 503

		if (sym == NULL)
			goto out_delete_line;

504
		if (filter && filter(map, sym))
505
			symbol__delete(sym);
506
		else {
507
			symbols__insert(&self->symbols[map->type], sym);
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
			nr_syms++;
		}
	}

	free(line);
	fclose(file);

	return nr_syms;

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

523 524 525 526
/**
 * elf_symtab__for_each_symbol - iterate thru all the symbols
 *
 * @self: struct elf_symtab instance to iterate
527
 * @idx: uint32_t idx
528 529
 * @sym: GElf_Sym iterator
 */
530 531 532 533
#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))
534 535 536 537 538 539 540 541 542 543

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 &&
544
	       sym->st_shndx != SHN_UNDEF;
545 546
}

547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
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;
}

567 568 569 570 571 572 573 574
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,
575
				    size_t *idx)
576 577 578 579 580 581 582 583 584 585
{
	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)) {
586 587
			if (idx)
				*idx = cnt;
588 589 590 591 592 593 594 595
			break;
		}
		++cnt;
	}

	return sec;
}

596 597 598 599 600 601 602 603 604 605
#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))

606 607 608 609 610 611 612
/*
 * 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).
 */
613 614
static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
				       symbol_filter_t filter)
615 616 617
{
	uint32_t nr_rel_entries, idx;
	GElf_Sym sym;
618
	u64 plt_offset;
619 620
	GElf_Shdr shdr_plt;
	struct symbol *f;
621
	GElf_Shdr shdr_rel_plt, shdr_dynsym;
622
	Elf_Data *reldata, *syms, *symstrs;
623 624 625
	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
	size_t dynsym_idx;
	GElf_Ehdr ehdr;
626
	char sympltname[1024];
627 628 629
	Elf *elf;
	int nr = 0, symidx, fd, err = 0;

630
	fd = open(self->long_name, O_RDONLY);
631 632 633
	if (fd < 0)
		goto out;

634
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
635 636 637 638 639 640 641 642 643 644
	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;
645

646
	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
647 648
					  ".rela.plt", NULL);
	if (scn_plt_rel == NULL) {
649
		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
650 651
						  ".rel.plt", NULL);
		if (scn_plt_rel == NULL)
652
			goto out_elf_end;
653 654
	}

655 656
	err = -1;

657
	if (shdr_rel_plt.sh_link != dynsym_idx)
658
		goto out_elf_end;
659

660 661
	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
		goto out_elf_end;
662 663

	/*
664
	 * Fetch the relocation section to find the idxes to the GOT
665 666 667 668
	 * and the symbols in the .dynsym they refer to.
	 */
	reldata = elf_getdata(scn_plt_rel, NULL);
	if (reldata == NULL)
669
		goto out_elf_end;
670 671 672

	syms = elf_getdata(scn_dynsym, NULL);
	if (syms == NULL)
673
		goto out_elf_end;
674

675
	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
676
	if (scn_symstrs == NULL)
677
		goto out_elf_end;
678 679 680

	symstrs = elf_getdata(scn_symstrs, NULL);
	if (symstrs == NULL)
681
		goto out_elf_end;
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697

	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,
698
					sympltname);
699
			if (!f)
700
				goto out_elf_end;
701

702 703 704
			if (filter && filter(map, f))
				symbol__delete(f);
			else {
705
				symbols__insert(&self->symbols[map->type], f);
706 707
				++nr;
			}
708 709 710 711 712 713 714 715 716 717 718 719
		}
	} 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,
720
					sympltname);
721
			if (!f)
722
				goto out_elf_end;
723

724 725 726
			if (filter && filter(map, f))
				symbol__delete(f);
			else {
727
				symbols__insert(&self->symbols[map->type], f);
728 729
				++nr;
			}
730 731 732
		}
	}

733 734 735 736 737 738 739 740 741
	err = 0;
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);

	if (err == 0)
		return nr;
out:
742 743
	pr_warning("%s: problems reading %s PLT info.\n",
		   __func__, self->long_name);
744
	return 0;
745 746
}

747
static int dso__load_sym(struct dso *self, struct map *map,
748
			 struct map_groups *mg, const char *name, int fd,
749
			 symbol_filter_t filter, int kernel, int kmodule)
750
{
751 752 753
	struct map *curr_map = map;
	struct dso *curr_dso = self;
	size_t dso_name_len = strlen(self->short_name);
754
	Elf_Data *symstrs, *secstrs;
755 756
	uint32_t nr_syms;
	int err = -1;
757
	uint32_t idx;
758 759 760 761
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *syms;
	GElf_Sym sym;
762
	Elf_Scn *sec, *sec_strndx;
763
	Elf *elf;
764
	int nr = 0;
765

766
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
767
	if (elf == NULL) {
768
		pr_err("%s: cannot read %s ELF file.\n", __func__, name);
769 770 771 772
		goto out_close;
	}

	if (gelf_getehdr(elf, &ehdr) == NULL) {
773
		pr_err("%s: cannot get elf header.\n", __func__);
774 775 776 777
		goto out_elf_end;
	}

	sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
778
	if (sec == NULL) {
779 780
		sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
		if (sec == NULL)
781 782
			goto out_elf_end;
	}
783 784 785 786 787 788 789 790 791 792 793 794 795

	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;

796 797 798 799 800
	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 已提交
801
	if (secstrs == NULL)
802 803
		goto out_elf_end;

804 805
	nr_syms = shdr.sh_size / shdr.sh_entsize;

806
	memset(&sym, 0, sizeof(sym));
807 808
	if (!kernel) {
		self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
809 810 811
				elf_section_by_name(elf, &ehdr, &shdr,
						     ".gnu.prelink_undo",
						     NULL) != NULL);
812 813
	} else self->adjust_symbols = 0;

814
	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
815
		struct symbol *f;
816
		const char *elf_name;
817
		char *demangled = NULL;
818 819
		int is_label = elf_sym__is_label(&sym);
		const char *section_name;
820

821
		if (!is_label && !elf_sym__is_function(&sym))
822 823 824 825 826 827 828
			continue;

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

		gelf_getshdr(sec, &shdr);
829 830 831 832

		if (is_label && !elf_sec__is_text(&shdr, secstrs))
			continue;

833
		elf_name = elf_sym__name(&sym, symstrs);
834
		section_name = elf_sec__name(&shdr, secstrs);
835

836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
		if (kernel || kmodule) {
			char dso_name[PATH_MAX];

			if (strcmp(section_name,
				   curr_dso->short_name + dso_name_len) == 0)
				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);

852
			curr_map = map_groups__find_by_name(mg, dso_name);
853 854 855 856 857 858
			if (curr_map == NULL) {
				u64 start = sym.st_value;

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

859
				curr_dso = dso__new(dso_name);
860 861
				if (curr_dso == NULL)
					goto out_elf_end;
862 863
				curr_map = map__new2(start, curr_dso,
						     MAP__FUNCTION);
864 865 866 867
				if (curr_map == NULL) {
					dso__delete(curr_dso);
					goto out_elf_end;
				}
868 869
				curr_map->map_ip = identity__map_ip;
				curr_map->unmap_ip = identity__map_ip;
870
				curr_dso->origin = DSO__ORIG_KERNEL;
871
				map_groups__insert(kmaps, curr_map);
872
				dsos__add(&dsos__kernel, curr_dso);
873 874 875 876
			} else
				curr_dso = curr_map->dso;

			goto new_symbol;
877 878
		}

879
		if (curr_dso->adjust_symbols) {
880 881 882
			pr_debug2("adjusting symbol: st_value: %Lx sh_addr: "
				  "%Lx sh_offset: %Lx\n", (u64)sym.st_value,
				  (u64)shdr.sh_addr, (u64)shdr.sh_offset);
883
			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
884
		}
885 886 887 888 889
		/*
		 * 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...
		 */
890
		demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
891
		if (demangled != NULL)
892
			elf_name = demangled;
893
new_symbol:
894
		f = symbol__new(sym.st_value, sym.st_size, elf_name);
895
		free(demangled);
896 897 898
		if (!f)
			goto out_elf_end;

899
		if (filter && filter(curr_map, f))
900
			symbol__delete(f);
901
		else {
902
			symbols__insert(&curr_dso->symbols[curr_map->type], f);
903 904
			nr++;
		}
905 906
	}

907 908 909 910
	/*
	 * For misannotated, zeroed, ASM function sizes.
	 */
	if (nr > 0)
911
		symbols__fixup_end(&self->symbols[map->type]);
912 913 914 915 916 917 918
	err = nr;
out_elf_end:
	elf_end(elf);
out_close:
	return err;
}

919 920 921 922 923
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;
}

924
static bool __dsos__read_build_ids(struct list_head *head)
925
{
926
	bool have_build_id = false;
927 928
	struct dso *pos;

929
	list_for_each_entry(pos, head, node)
930 931 932 933 934
		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;
		}
935

936
	return have_build_id;
937 938
}

939 940
bool dsos__read_build_ids(void)
{
941 942 943
	bool kbuildids = __dsos__read_build_ids(&dsos__kernel),
	     ubuildids = __dsos__read_build_ids(&dsos__user);
	return kbuildids || ubuildids;
944 945
}

946 947 948 949 950
/*
 * Align offset to 4 bytes as needed for note name and descriptor data.
 */
#define NOTE_ALIGN(n) (((n) + 3) & -4U)

951
int filename__read_build_id(const char *filename, void *bf, size_t size)
952
{
953
	int fd, err = -1;
954 955
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
956
	Elf_Data *data;
957
	Elf_Scn *sec;
958
	Elf_Kind ek;
959
	void *ptr;
960 961
	Elf *elf;

962 963 964 965
	if (size < BUILD_ID_SIZE)
		goto out;

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

969
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
970
	if (elf == NULL) {
971
		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
972 973 974
		goto out_close;
	}

975 976 977 978
	ek = elf_kind(elf);
	if (ek != ELF_K_ELF)
		goto out_elf_end;

979
	if (gelf_getehdr(elf, &ehdr) == NULL) {
980
		pr_err("%s: cannot get elf header.\n", __func__);
981 982 983
		goto out_elf_end;
	}

984 985
	sec = elf_section_by_name(elf, &ehdr, &shdr,
				  ".note.gnu.build-id", NULL);
986 987 988 989 990 991
	if (sec == NULL) {
		sec = elf_section_by_name(elf, &ehdr, &shdr,
					  ".notes", NULL);
		if (sec == NULL)
			goto out_elf_end;
	}
992

993 994
	data = elf_getdata(sec, NULL);
	if (data == NULL)
995
		goto out_elf_end;
996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016

	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;
	}
1017 1018 1019 1020 1021 1022 1023 1024
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);
out:
	return err;
}

1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
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;

1044 1045
		namesz = NOTE_ALIGN(nhdr.n_namesz);
		descsz = NOTE_ALIGN(nhdr.n_descsz);
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
		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;
}

1069 1070 1071 1072 1073 1074 1075 1076 1077
char dso__symtab_origin(const struct dso *self)
{
	static const char origin[] = {
		[DSO__ORIG_KERNEL] =   'k',
		[DSO__ORIG_JAVA_JIT] = 'j',
		[DSO__ORIG_FEDORA] =   'f',
		[DSO__ORIG_UBUNTU] =   'u',
		[DSO__ORIG_BUILDID] =  'b',
		[DSO__ORIG_DSO] =      'd',
1078
		[DSO__ORIG_KMODULE] =  'K',
1079 1080 1081 1082 1083 1084 1085
	};

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

1086
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1087
{
1088
	int size = PATH_MAX;
1089
	char *name;
1090
	u8 build_id[BUILD_ID_SIZE];
1091 1092 1093
	int ret = -1;
	int fd;

1094
	dso__set_loaded(self, map->type);
1095

1096
	if (self->kernel)
1097
		return dso__load_kernel_sym(self, map, kmaps, filter);
1098 1099

	name = malloc(size);
1100 1101 1102
	if (!name)
		return -1;

1103
	self->adjust_symbols = 0;
1104

1105
	if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1106
		ret = dso__load_perf_map(self, map, filter);
1107 1108 1109 1110 1111 1112
		self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
					 DSO__ORIG_NOT_FOUND;
		return ret;
	}

	self->origin = DSO__ORIG_FEDORA - 1;
1113

1114 1115
more:
	do {
1116 1117 1118
		self->origin++;
		switch (self->origin) {
		case DSO__ORIG_FEDORA:
1119 1120
			snprintf(name, size, "/usr/lib/debug%s.debug",
				 self->long_name);
1121
			break;
1122
		case DSO__ORIG_UBUNTU:
1123 1124
			snprintf(name, size, "/usr/lib/debug%s",
				 self->long_name);
1125
			break;
1126
		case DSO__ORIG_BUILDID:
1127 1128 1129 1130 1131 1132
			if (filename__read_build_id(self->long_name, build_id,
						    sizeof(build_id))) {
				char build_id_hex[BUILD_ID_SIZE * 2 + 1];

				build_id__sprintf(build_id, sizeof(build_id),
						  build_id_hex);
1133 1134
				snprintf(name, size,
					 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1135 1136 1137 1138
					build_id_hex, build_id_hex + 2);
				if (self->has_build_id)
					goto compare_build_id;
				break;
1139
			}
1140
			self->origin++;
1141
			/* Fall thru */
1142
		case DSO__ORIG_DSO:
1143
			snprintf(name, size, "%s", self->long_name);
1144 1145 1146 1147 1148 1149
			break;

		default:
			goto out;
		}

1150
		if (self->has_build_id) {
1151 1152
			if (filename__read_build_id(name, build_id,
						    sizeof(build_id)) < 0)
1153 1154
				goto more;
compare_build_id:
1155
			if (!dso__build_id_equal(self, build_id))
1156 1157 1158
				goto more;
		}

1159 1160 1161
		fd = open(name, O_RDONLY);
	} while (fd < 0);

1162
	ret = dso__load_sym(self, map, NULL, name, fd, filter, 0, 0);
1163 1164 1165 1166 1167 1168 1169 1170
	close(fd);

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

1171
	if (ret > 0) {
1172
		int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1173 1174 1175
		if (nr_plt > 0)
			ret += nr_plt;
	}
1176 1177
out:
	free(name);
1178 1179
	if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
		return 0;
1180 1181 1182
	return ret;
}

1183
static struct map *map_groups__find_by_name(struct map_groups *self, char *name)
1184 1185 1186
{
	struct rb_node *nd;

1187
	for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
1188 1189 1190 1191 1192 1193 1194 1195 1196
		struct map *map = rb_entry(nd, struct map, rb_node);

		if (map->dso && strcmp(map->dso->name, name) == 0)
			return map;
	}

	return NULL;
}

1197
static int dsos__set_modules_path_dir(char *dirname)
1198
{
1199 1200
	struct dirent *dent;
	DIR *dir = opendir(dirname);
1201

1202
	if (!dir) {
1203
		pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1204 1205
		return -1;
	}
1206

1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
	while ((dent = readdir(dir)) != NULL) {
		char path[PATH_MAX];

		if (dent->d_type == DT_DIR) {
			if (!strcmp(dent->d_name, ".") ||
			    !strcmp(dent->d_name, ".."))
				continue;

			snprintf(path, sizeof(path), "%s/%s",
				 dirname, dent->d_name);
1217
			if (dsos__set_modules_path_dir(path) < 0)
1218 1219 1220 1221 1222
				goto failure;
		} else {
			char *dot = strrchr(dent->d_name, '.'),
			     dso_name[PATH_MAX];
			struct map *map;
1223
			char *long_name;
1224 1225 1226 1227 1228 1229

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

1230
			strxfrchar(dso_name, '-', '_');
1231
			map = map_groups__find_by_name(kmaps, dso_name);
1232 1233 1234 1235 1236 1237
			if (map == NULL)
				continue;

			snprintf(path, sizeof(path), "%s/%s",
				 dirname, dent->d_name);

1238 1239
			long_name = strdup(path);
			if (long_name == NULL)
1240
				goto failure;
1241
			dso__set_long_name(map->dso, long_name);
1242 1243
		}
	}
1244

1245
	return 0;
1246 1247 1248 1249
failure:
	closedir(dir);
	return -1;
}
1250

1251
static int dsos__set_modules_path(void)
1252 1253 1254
{
	struct utsname uts;
	char modules_path[PATH_MAX];
1255

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

1259 1260
	snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
		 uts.release);
1261

1262
	return dsos__set_modules_path_dir(modules_path);
1263 1264
}

1265 1266 1267 1268 1269
/*
 * 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.
 */
1270
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1271
{
1272
	struct map *self = malloc(sizeof(*self));
1273

1274 1275
	if (self != NULL) {
		/*
1276
		 * ->end will be filled after we load all the symbols
1277
		 */
1278
		map__init(self, type, start, 0, 0, dso);
1279
	}
1280

1281 1282 1283
	return self;
}

1284
static int map_groups__create_module_maps(struct map_groups *self)
1285 1286 1287 1288 1289
{
	char *line = NULL;
	size_t n;
	FILE *file = fopen("/proc/modules", "r");
	struct map *map;
1290

1291 1292
	if (file == NULL)
		return -1;
1293

1294 1295 1296 1297 1298 1299
	while (!feof(file)) {
		char name[PATH_MAX];
		u64 start;
		struct dso *dso;
		char *sep;
		int line_len;
1300

1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322
		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);
1323
		dso = dso__new(name);
1324 1325 1326 1327

		if (dso == NULL)
			goto out_delete_line;

1328
		map = map__new2(start, dso, MAP__FUNCTION);
1329 1330 1331
		if (map == NULL) {
			dso__delete(dso);
			goto out_delete_line;
1332
		}
1333

1334 1335 1336 1337 1338 1339
		snprintf(name, sizeof(name),
			 "/sys/module/%s/notes/.note.gnu.build-id", line);
		if (sysfs__read_build_id(name, dso->build_id,
					 sizeof(dso->build_id)) == 0)
			dso->has_build_id = true;

1340
		dso->origin = DSO__ORIG_KMODULE;
1341
		map_groups__insert(self, map);
1342
		dsos__add(&dsos__kernel, dso);
1343
	}
1344 1345 1346 1347

	free(line);
	fclose(file);

1348
	return dsos__set_modules_path();
1349 1350 1351 1352 1353

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

1356 1357
static int dso__load_vmlinux(struct dso *self, struct map *map,
			     struct map_groups *mg,
1358
			     const char *vmlinux, symbol_filter_t filter)
1359
{
1360
	int err = -1, fd;
1361

1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
	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;
		}
	}
1385

1386
	fd = open(vmlinux, O_RDONLY);
1387 1388 1389
	if (fd < 0)
		return -1;

1390
	dso__set_loaded(self, map->type);
1391
	err = dso__load_sym(self, map, mg, self->long_name, fd, filter, 1, 0);
1392 1393 1394 1395 1396
	close(fd);

	return err;
}

1397
static int dso__load_kernel_sym(struct dso *self, struct map *map,
1398
				struct map_groups *mg, symbol_filter_t filter)
1399
{
1400 1401 1402 1403 1404 1405 1406 1407
	int err;
	bool is_kallsyms;

	if (vmlinux_path != NULL) {
		int i;
		pr_debug("Looking at the vmlinux_path (%d entries long)\n",
			 vmlinux_path__nr_entries);
		for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1408
			err = dso__load_vmlinux(self, map, mg,
1409
						vmlinux_path[i], filter);
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
			if (err > 0) {
				pr_debug("Using %s for symbols\n",
					 vmlinux_path[i]);
				dso__set_long_name(self,
						   strdup(vmlinux_path[i]));
				goto out_fixup;
			}
		}
	}

	is_kallsyms = self->long_name[0] == '[';
	if (is_kallsyms)
		goto do_kallsyms;
1423

1424
	err = dso__load_vmlinux(self, map, mg, self->long_name, filter);
1425
	if (err <= 0) {
1426 1427 1428
		pr_info("The file %s cannot be used, "
			"trying to use /proc/kallsyms...", self->long_name);
do_kallsyms:
1429
		err = dso__load_kallsyms(self, map, mg, filter);
1430
		if (err > 0 && !is_kallsyms)
1431 1432
                        dso__set_long_name(self, strdup("[kernel.kallsyms]"));
	}
1433 1434

	if (err > 0) {
1435
out_fixup:
1436 1437
		map__fixup_start(map);
		map__fixup_end(map);
1438
	}
1439

1440 1441 1442
	return err;
}

1443 1444
LIST_HEAD(dsos__user);
LIST_HEAD(dsos__kernel);
1445
struct dso *vdso;
1446

1447
static void dsos__add(struct list_head *head, struct dso *dso)
1448
{
1449
	list_add_tail(&dso->node, head);
1450 1451
}

1452
static struct dso *dsos__find(struct list_head *head, const char *name)
1453 1454 1455
{
	struct dso *pos;

1456
	list_for_each_entry(pos, head, node)
1457 1458 1459 1460 1461
		if (strcmp(pos->name, name) == 0)
			return pos;
	return NULL;
}

1462
struct dso *dsos__findnew(const char *name)
1463
{
1464
	struct dso *dso = dsos__find(&dsos__user, name);
1465

1466
	if (!dso) {
1467
		dso = dso__new(name);
1468
		if (dso != NULL) {
1469
			dsos__add(&dsos__user, dso);
1470 1471
			dso__set_basename(dso);
		}
1472
	}
1473 1474 1475 1476

	return dso;
}

1477
static void __dsos__fprintf(struct list_head *head, FILE *fp)
1478 1479 1480
{
	struct dso *pos;

1481 1482 1483 1484 1485
	list_for_each_entry(pos, head, node) {
		int i;
		for (i = 0; i < MAP__NR_TYPES; ++i)
			dso__fprintf(pos, i, fp);
	}
1486 1487
}

1488 1489 1490 1491 1492 1493 1494
void dsos__fprintf(FILE *fp)
{
	__dsos__fprintf(&dsos__kernel, fp);
	__dsos__fprintf(&dsos__user, fp);
}

static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp)
1495 1496 1497 1498
{
	struct dso *pos;
	size_t ret = 0;

1499
	list_for_each_entry(pos, head, node) {
1500
		ret += dso__fprintf_buildid(pos, fp);
1501
		ret += fprintf(fp, " %s\n", pos->long_name);
1502 1503 1504 1505
	}
	return ret;
}

1506 1507 1508 1509 1510 1511
size_t dsos__fprintf_buildid(FILE *fp)
{
	return (__dsos__fprintf_buildid(&dsos__kernel, fp) +
		__dsos__fprintf_buildid(&dsos__user, fp));
}

1512
static int map_groups__create_kernel_map(struct map_groups *self, const char *vmlinux)
1513
{
1514
	struct map *kmap;
1515
	struct dso *kernel = dso__new(vmlinux ?: "[kernel.kallsyms]");
1516

1517
	if (kernel == NULL)
1518 1519
		return -1;

1520 1521
	kmap = map__new2(0, kernel, MAP__FUNCTION);
	if (kmap == NULL)
1522 1523
		goto out_delete_kernel_dso;

1524 1525 1526
	kmap->map_ip	   = kmap->unmap_ip = identity__map_ip;
	kernel->short_name = "[kernel]";
	kernel->kernel	   = 1;
1527

1528
	vdso = dso__new("[vdso]");
1529 1530
	if (vdso == NULL)
		goto out_delete_kernel_map;
1531
	dso__set_loaded(vdso, MAP__FUNCTION);
1532 1533 1534 1535

	if (sysfs__read_build_id("/sys/kernel/notes", kernel->build_id,
				 sizeof(kernel->build_id)) == 0)
		kernel->has_build_id = true;
1536

1537
	map_groups__insert(self, kmap);
1538 1539
	dsos__add(&dsos__kernel, kernel);
	dsos__add(&dsos__user, vdso);
1540

1541 1542 1543
	return 0;

out_delete_kernel_map:
1544
	map__delete(kmap);
1545 1546 1547
out_delete_kernel_dso:
	dso__delete(kernel);
	return -1;
1548 1549
}

1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604
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;
}

1605
int symbol__init(struct symbol_conf *conf)
1606
{
1607 1608
	const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;

1609
	elf_version(EV_CURRENT);
1610
	symbol__priv_size = pconf->priv_size;
1611
	map_groups__init(kmaps);
1612 1613

	if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1614 1615
		return -1;

1616
	if (map_groups__create_kernel_map(kmaps, pconf->vmlinux_name) < 0) {
1617 1618 1619 1620
		vmlinux_path__exit();
		return -1;
	}

1621 1622
	kmaps->use_modules = pconf->use_modules;
	if (pconf->use_modules && map_groups__create_module_maps(kmaps) < 0)
1623 1624
		pr_debug("Failed to load list of modules in use, "
			 "continuing...\n");
1625 1626 1627
	/*
	 * Now that we have all the maps created, just set the ->end of them:
	 */
1628
	map_groups__fixup_end(kmaps);
1629
	return 0;
1630
}