symbol.c 36.2 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__new2(u64 start, struct dso *dso, enum map_type type);
33
static void kernel_maps__insert(struct map *map);
34
struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
35 36
static int dso__load_kernel_sym(struct dso *self, struct map *map,
				symbol_filter_t filter);
37
unsigned int symbol__priv_size;
38 39
static int vmlinux_path__nr_entries;
static char **vmlinux_path;
40
static struct map *kernel_map__functions;
41

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

47
static struct rb_root kernel_maps__functions;
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 kernel_maps__fixup_end(void)
83 84
{
	struct map *prev, *curr;
85
	struct rb_node *nd, *prevnd = rb_first(&kernel_maps__functions);
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 struct symbol *symbol__new(u64 start, u64 len, const char *name)
106
{
107
	size_t namelen = strlen(name) + 1;
108 109 110
	struct symbol *self = zalloc(symbol__priv_size +
				     sizeof(*self) + namelen);
	if (self == NULL)
111 112
		return NULL;

113
	if (symbol__priv_size)
114
		self = ((void *)self) + symbol__priv_size;
115

116
	self->start = start;
117
	self->end   = len ? start + len - 1 : start;
118

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

121
	memcpy(self->name, name, namelen);
122 123 124 125

	return self;
}

126
static void symbol__delete(struct symbol *self)
127
{
128
	free(((void *)self) - symbol__priv_size);
129 130 131 132
}

static size_t symbol__fprintf(struct symbol *self, FILE *fp)
{
133
	return fprintf(fp, " %llx-%llx %s\n",
134 135 136
		       self->start, self->end, self->name);
}

137 138
static void dso__set_long_name(struct dso *self, char *name)
{
139 140
	if (name == NULL)
		return;
141 142 143 144 145 146 147 148 149
	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);
}

150
struct dso *dso__new(const char *name)
151 152 153 154
{
	struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);

	if (self != NULL) {
155
		int i;
156
		strcpy(self->name, name);
157
		dso__set_long_name(self, self->name);
158
		self->short_name = self->name;
159 160 161
		for (i = 0; i < MAP__NR_TYPES; ++i)
			self->symbols[i] = RB_ROOT;
		self->find_symbol = dso__find_symbol;
162
		self->slen_calculated = 0;
163
		self->origin = DSO__ORIG_NOT_FOUND;
164 165
		self->loaded = 0;
		self->has_build_id = 0;
166 167 168 169 170
	}

	return self;
}

171
static void symbols__delete(struct rb_root *self)
172 173
{
	struct symbol *pos;
174
	struct rb_node *next = rb_first(self);
175 176 177 178

	while (next) {
		pos = rb_entry(next, struct symbol, rb_node);
		next = rb_next(&pos->rb_node);
179
		rb_erase(&pos->rb_node, self);
180
		symbol__delete(pos);
181 182 183 184 185
	}
}

void dso__delete(struct dso *self)
{
186 187 188
	int i;
	for (i = 0; i < MAP__NR_TYPES; ++i)
		symbols__delete(&self->symbols[i]);
189 190
	if (self->long_name != self->name)
		free(self->long_name);
191 192 193
	free(self);
}

194 195 196 197 198 199
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;
}

200
static void symbols__insert(struct rb_root *self, struct symbol *sym)
201
{
202
	struct rb_node **p = &self->rb_node;
203
	struct rb_node *parent = NULL;
204
	const u64 ip = sym->start;
205 206 207 208 209 210 211 212 213 214 215
	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);
216
	rb_insert_color(&sym->rb_node, self);
217 218
}

219
static struct symbol *symbols__find(struct rb_root *self, u64 ip)
220 221 222 223 224 225
{
	struct rb_node *n;

	if (self == NULL)
		return NULL;

226
	n = self->rb_node;
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241

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

242
struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr)
243
{
244
	return symbols__find(&self->symbols[type], addr);
245 246
}

247
int build_id__sprintf(u8 *self, int len, char *bf)
248
{
249 250 251
	char *bid = bf;
	u8 *raw = self;
	int i;
252

253 254 255 256 257 258 259 260 261
	for (i = 0; i < len; ++i) {
		sprintf(bid, "%02x", *raw);
		++raw;
		bid += 2;
	}

	return raw - self;
}

262
size_t dso__fprintf_buildid(struct dso *self, FILE *fp)
263 264 265 266
{
	char sbuild_id[BUILD_ID_SIZE * 2 + 1];

	build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id);
267 268 269
	return fprintf(fp, "%s", sbuild_id);
}

270 271 272 273
static const char * map_type__name[MAP__NR_TYPES] = {
	[MAP__FUNCTION] = "Functions",
};

274 275
size_t dso__fprintf(struct dso *self, FILE *fp)
{
276
	int i;
277 278 279 280
	struct rb_node *nd;
	size_t ret = fprintf(fp, "dso: %s (", self->short_name);

	ret += dso__fprintf_buildid(self, fp);
281 282 283
	ret += fprintf(fp, ")\n");
	for (i = 0; i < MAP__NR_TYPES; ++i) {
		ret += fprintf(fp, "%s:\n", map_type__name[i]);
284

285 286 287 288
		for (nd = rb_first(&self->symbols[i]); nd; nd = rb_next(nd)) {
			struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
			ret += symbol__fprintf(pos, fp);
		}
289 290 291 292 293
	}

	return ret;
}

294 295 296 297 298
/*
 * 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.
 */
299
static int kernel_maps__load_all_kallsyms(void)
300 301 302 303 304 305 306 307 308
{
	char *line = NULL;
	size_t n;
	FILE *file = fopen("/proc/kallsyms", "r");

	if (file == NULL)
		goto out_failure;

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

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

		if (!line)
			goto out_failure;

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

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

		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;
336 337

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

343 344 345
		if (sym == NULL)
			goto out_delete_line;

346 347 348 349 350
		/*
		 * We will pass the symbols to the filter later, in
		 * kernel_maps__split_kallsyms, when we have split the
		 * maps per module
		 */
351
		symbols__insert(&kernel_map__functions->dso->symbols[MAP__FUNCTION], sym);
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
	}

	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.
 */
370
static int kernel_maps__split_kallsyms(symbol_filter_t filter)
371
{
372
	struct map *map = kernel_map__functions;
373 374
	struct symbol *pos;
	int count = 0;
375
	struct rb_node *next = rb_first(&kernel_map__functions->dso->symbols[map->type]);
376 377 378 379 380 381 382 383 384 385 386 387
	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) {
			*module++ = '\0';

388 389 390
			if (strcmp(map->dso->name, module)) {
				map = kernel_maps__find_by_dso_name(module);
				if (!map) {
391 392
					pr_err("/proc/{kallsyms,modules} "
					       "inconsistency!\n");
393 394 395
					return -1;
				}
			}
396 397 398 399 400 401
			/*
			 * So that we look just like we get from .ko files,
			 * i.e. not prelinked, relative to map->start.
			 */
			pos->start = map->map_ip(map, pos->start);
			pos->end   = map->map_ip(map, pos->end);
402
		} else if (map != kernel_map__functions) {
403 404 405 406 407 408
			char dso_name[PATH_MAX];
			struct dso *dso;

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

409
			dso = dso__new(dso_name);
410 411 412
			if (dso == NULL)
				return -1;

413
			map = map__new2(pos->start, dso, MAP__FUNCTION);
414 415 416 417
			if (map == NULL) {
				dso__delete(dso);
				return -1;
			}
418

419
			map->map_ip = map->unmap_ip = identity__map_ip;
420 421 422
			kernel_maps__insert(map);
			++kernel_range;
		}
423

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

437
	return count;
438
}
439

440

441
static int kernel_maps__load_kallsyms(symbol_filter_t filter)
442
{
443
	if (kernel_maps__load_all_kallsyms())
444 445
		return -1;

446
	symbols__fixup_end(&kernel_map__functions->dso->symbols[MAP__FUNCTION]);
447
	kernel_map__functions->dso->origin = DSO__ORIG_KERNEL;
448

449
	return kernel_maps__split_kallsyms(filter);
450 451
}

452
size_t kernel_maps__fprintf(FILE *fp)
453
{
454
	size_t printed = fprintf(fp, "Kernel maps:\n");
455 456
	struct rb_node *nd;

457
	for (nd = rb_first(&kernel_maps__functions); nd; nd = rb_next(nd)) {
458 459
		struct map *pos = rb_entry(nd, struct map, rb_node);

460
		printed += fprintf(fp, "Map:");
461
		printed += map__fprintf(pos, fp);
462
		if (verbose > 1) {
463 464 465
			printed += dso__fprintf(pos->dso, fp);
			printed += fprintf(fp, "--\n");
		}
466 467
	}

468
	return printed + fprintf(fp, "END kernel maps\n");
469 470
}

471
static int dso__load_perf_map(struct dso *self, struct map *map,
472
			      symbol_filter_t filter)
473 474 475 476 477 478
{
	char *line = NULL;
	size_t n;
	FILE *file;
	int nr_syms = 0;

479
	file = fopen(self->long_name, "r");
480 481 482 483
	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
484
		u64 start, size;
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
		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;

509
		sym = symbol__new(start, size, line + len);
510 511 512 513

		if (sym == NULL)
			goto out_delete_line;

514
		if (filter && filter(map, sym))
515
			symbol__delete(sym);
516
		else {
517
			symbols__insert(&self->symbols[map->type], sym);
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
			nr_syms++;
		}
	}

	free(line);
	fclose(file);

	return nr_syms;

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

533 534 535 536
/**
 * elf_symtab__for_each_symbol - iterate thru all the symbols
 *
 * @self: struct elf_symtab instance to iterate
537
 * @idx: uint32_t idx
538 539
 * @sym: GElf_Sym iterator
 */
540 541 542 543
#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))
544 545 546 547 548 549 550 551 552 553

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 &&
554
	       sym->st_shndx != SHN_UNDEF;
555 556
}

557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
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;
}

577 578 579 580 581 582 583 584
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,
585
				    size_t *idx)
586 587 588 589 590 591 592 593 594 595
{
	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)) {
596 597
			if (idx)
				*idx = cnt;
598 599 600 601 602 603 604 605
			break;
		}
		++cnt;
	}

	return sec;
}

606 607 608 609 610 611 612 613 614 615
#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))

616 617 618 619 620 621 622
/*
 * 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).
 */
623 624
static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
				       symbol_filter_t filter)
625 626 627
{
	uint32_t nr_rel_entries, idx;
	GElf_Sym sym;
628
	u64 plt_offset;
629 630
	GElf_Shdr shdr_plt;
	struct symbol *f;
631
	GElf_Shdr shdr_rel_plt, shdr_dynsym;
632
	Elf_Data *reldata, *syms, *symstrs;
633 634 635
	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
	size_t dynsym_idx;
	GElf_Ehdr ehdr;
636
	char sympltname[1024];
637 638 639
	Elf *elf;
	int nr = 0, symidx, fd, err = 0;

640
	fd = open(self->long_name, O_RDONLY);
641 642 643
	if (fd < 0)
		goto out;

644
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
645 646 647 648 649 650 651 652 653 654
	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;
655

656
	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
657 658
					  ".rela.plt", NULL);
	if (scn_plt_rel == NULL) {
659
		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
660 661
						  ".rel.plt", NULL);
		if (scn_plt_rel == NULL)
662
			goto out_elf_end;
663 664
	}

665 666
	err = -1;

667
	if (shdr_rel_plt.sh_link != dynsym_idx)
668
		goto out_elf_end;
669

670 671
	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
		goto out_elf_end;
672 673

	/*
674
	 * Fetch the relocation section to find the idxes to the GOT
675 676 677 678
	 * and the symbols in the .dynsym they refer to.
	 */
	reldata = elf_getdata(scn_plt_rel, NULL);
	if (reldata == NULL)
679
		goto out_elf_end;
680 681 682

	syms = elf_getdata(scn_dynsym, NULL);
	if (syms == NULL)
683
		goto out_elf_end;
684

685
	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
686
	if (scn_symstrs == NULL)
687
		goto out_elf_end;
688 689 690

	symstrs = elf_getdata(scn_symstrs, NULL);
	if (symstrs == NULL)
691
		goto out_elf_end;
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707

	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,
708
					sympltname);
709
			if (!f)
710
				goto out_elf_end;
711

712 713 714
			if (filter && filter(map, f))
				symbol__delete(f);
			else {
715
				symbols__insert(&self->symbols[map->type], f);
716 717
				++nr;
			}
718 719 720 721 722 723 724 725 726 727 728 729
		}
	} 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,
730
					sympltname);
731
			if (!f)
732
				goto out_elf_end;
733

734 735 736
			if (filter && filter(map, f))
				symbol__delete(f);
			else {
737
				symbols__insert(&self->symbols[map->type], f);
738 739
				++nr;
			}
740 741 742
		}
	}

743 744 745 746 747 748 749 750 751
	err = 0;
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);

	if (err == 0)
		return nr;
out:
752 753
	pr_warning("%s: problems reading %s PLT info.\n",
		   __func__, self->long_name);
754
	return 0;
755 756
}

757 758
static int dso__load_sym(struct dso *self, struct map *map, const char *name,
			 int fd, symbol_filter_t filter, int kernel,
759
			 int kmodule)
760
{
761 762 763
	struct map *curr_map = map;
	struct dso *curr_dso = self;
	size_t dso_name_len = strlen(self->short_name);
764
	Elf_Data *symstrs, *secstrs;
765 766
	uint32_t nr_syms;
	int err = -1;
767
	uint32_t idx;
768 769 770 771
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *syms;
	GElf_Sym sym;
772
	Elf_Scn *sec, *sec_strndx;
773
	Elf *elf;
774
	int nr = 0;
775

776
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
777
	if (elf == NULL) {
778
		pr_err("%s: cannot read %s ELF file.\n", __func__, name);
779 780 781 782
		goto out_close;
	}

	if (gelf_getehdr(elf, &ehdr) == NULL) {
783
		pr_err("%s: cannot get elf header.\n", __func__);
784 785 786 787
		goto out_elf_end;
	}

	sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
788
	if (sec == NULL) {
789 790
		sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
		if (sec == NULL)
791 792
			goto out_elf_end;
	}
793 794 795 796 797 798 799 800 801 802 803 804 805

	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;

806 807 808 809 810
	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 已提交
811
	if (secstrs == NULL)
812 813
		goto out_elf_end;

814 815
	nr_syms = shdr.sh_size / shdr.sh_entsize;

816
	memset(&sym, 0, sizeof(sym));
817 818
	if (!kernel) {
		self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
819 820 821
				elf_section_by_name(elf, &ehdr, &shdr,
						     ".gnu.prelink_undo",
						     NULL) != NULL);
822 823
	} else self->adjust_symbols = 0;

824
	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
825
		struct symbol *f;
826
		const char *elf_name;
827
		char *demangled = NULL;
828 829
		int is_label = elf_sym__is_label(&sym);
		const char *section_name;
830

831
		if (!is_label && !elf_sym__is_function(&sym))
832 833 834 835 836 837 838
			continue;

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

		gelf_getshdr(sec, &shdr);
839 840 841 842

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

843
		elf_name = elf_sym__name(&sym, symstrs);
844
		section_name = elf_sec__name(&shdr, secstrs);
845

846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
		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);

			curr_map = kernel_maps__find_by_dso_name(dso_name);
			if (curr_map == NULL) {
				u64 start = sym.st_value;

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

869
				curr_dso = dso__new(dso_name);
870 871
				if (curr_dso == NULL)
					goto out_elf_end;
872 873
				curr_map = map__new2(start, curr_dso,
						     MAP__FUNCTION);
874 875 876 877
				if (curr_map == NULL) {
					dso__delete(curr_dso);
					goto out_elf_end;
				}
878 879
				curr_map->map_ip = identity__map_ip;
				curr_map->unmap_ip = identity__map_ip;
880 881
				curr_dso->origin = DSO__ORIG_KERNEL;
				kernel_maps__insert(curr_map);
882
				dsos__add(&dsos__kernel, curr_dso);
883 884 885 886
			} else
				curr_dso = curr_map->dso;

			goto new_symbol;
887 888
		}

889
		if (curr_dso->adjust_symbols) {
890 891 892
			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);
893
			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
894
		}
895 896 897 898 899
		/*
		 * 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...
		 */
900
		demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
901
		if (demangled != NULL)
902
			elf_name = demangled;
903
new_symbol:
904
		f = symbol__new(sym.st_value, sym.st_size, elf_name);
905
		free(demangled);
906 907 908
		if (!f)
			goto out_elf_end;

909
		if (filter && filter(curr_map, f))
910
			symbol__delete(f);
911
		else {
912
			symbols__insert(&curr_dso->symbols[curr_map->type], f);
913 914
			nr++;
		}
915 916
	}

917 918 919 920
	/*
	 * For misannotated, zeroed, ASM function sizes.
	 */
	if (nr > 0)
921
		symbols__fixup_end(&self->symbols[map->type]);
922 923 924 925 926 927 928
	err = nr;
out_elf_end:
	elf_end(elf);
out_close:
	return err;
}

929 930 931 932 933
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;
}

934
static bool __dsos__read_build_ids(struct list_head *head)
935
{
936
	bool have_build_id = false;
937 938
	struct dso *pos;

939
	list_for_each_entry(pos, head, node)
940 941 942 943 944
		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;
		}
945

946
	return have_build_id;
947 948
}

949 950 951 952 953 954
bool dsos__read_build_ids(void)
{
	return __dsos__read_build_ids(&dsos__kernel) ||
	       __dsos__read_build_ids(&dsos__user);
}

955 956 957 958 959
/*
 * Align offset to 4 bytes as needed for note name and descriptor data.
 */
#define NOTE_ALIGN(n) (((n) + 3) & -4U)

960
int filename__read_build_id(const char *filename, void *bf, size_t size)
961
{
962
	int fd, err = -1;
963 964
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
965
	Elf_Data *data;
966
	Elf_Scn *sec;
967
	Elf_Kind ek;
968
	void *ptr;
969 970
	Elf *elf;

971 972 973 974
	if (size < BUILD_ID_SIZE)
		goto out;

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

978
	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
979
	if (elf == NULL) {
980
		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
981 982 983
		goto out_close;
	}

984 985 986 987
	ek = elf_kind(elf);
	if (ek != ELF_K_ELF)
		goto out_elf_end;

988
	if (gelf_getehdr(elf, &ehdr) == NULL) {
989
		pr_err("%s: cannot get elf header.\n", __func__);
990 991 992
		goto out_elf_end;
	}

993 994
	sec = elf_section_by_name(elf, &ehdr, &shdr,
				  ".note.gnu.build-id", NULL);
995 996 997 998 999 1000
	if (sec == NULL) {
		sec = elf_section_by_name(elf, &ehdr, &shdr,
					  ".notes", NULL);
		if (sec == NULL)
			goto out_elf_end;
	}
1001

1002 1003
	data = elf_getdata(sec, NULL);
	if (data == NULL)
1004
		goto out_elf_end;
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025

	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;
	}
1026 1027 1028 1029 1030 1031 1032 1033
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);
out:
	return err;
}

1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
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;

1053 1054
		namesz = NOTE_ALIGN(nhdr.n_namesz);
		descsz = NOTE_ALIGN(nhdr.n_descsz);
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
		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;
}

1078 1079 1080 1081 1082 1083 1084 1085 1086
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',
1087
		[DSO__ORIG_KMODULE] =  'K',
1088 1089 1090 1091 1092 1093 1094
	};

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

1095
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
1096
{
1097
	int size = PATH_MAX;
1098
	char *name;
1099
	u8 build_id[BUILD_ID_SIZE];
1100 1101 1102
	int ret = -1;
	int fd;

1103
	dso__set_loaded(self, map->type);
1104

1105 1106 1107 1108
	if (self->kernel)
		return dso__load_kernel_sym(self, map, filter);

	name = malloc(size);
1109 1110 1111
	if (!name)
		return -1;

1112
	self->adjust_symbols = 0;
1113

1114
	if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
1115
		ret = dso__load_perf_map(self, map, filter);
1116 1117 1118 1119 1120 1121
		self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
					 DSO__ORIG_NOT_FOUND;
		return ret;
	}

	self->origin = DSO__ORIG_FEDORA - 1;
1122

1123 1124
more:
	do {
1125 1126 1127
		self->origin++;
		switch (self->origin) {
		case DSO__ORIG_FEDORA:
1128 1129
			snprintf(name, size, "/usr/lib/debug%s.debug",
				 self->long_name);
1130
			break;
1131
		case DSO__ORIG_UBUNTU:
1132 1133
			snprintf(name, size, "/usr/lib/debug%s",
				 self->long_name);
1134
			break;
1135
		case DSO__ORIG_BUILDID:
1136 1137 1138 1139 1140 1141
			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);
1142 1143
				snprintf(name, size,
					 "/usr/lib/debug/.build-id/%.2s/%s.debug",
1144 1145 1146 1147
					build_id_hex, build_id_hex + 2);
				if (self->has_build_id)
					goto compare_build_id;
				break;
1148
			}
1149
			self->origin++;
1150
			/* Fall thru */
1151
		case DSO__ORIG_DSO:
1152
			snprintf(name, size, "%s", self->long_name);
1153 1154 1155 1156 1157 1158
			break;

		default:
			goto out;
		}

1159
		if (self->has_build_id) {
1160 1161
			if (filename__read_build_id(name, build_id,
						    sizeof(build_id)) < 0)
1162 1163
				goto more;
compare_build_id:
1164
			if (!dso__build_id_equal(self, build_id))
1165 1166 1167
				goto more;
		}

1168 1169 1170
		fd = open(name, O_RDONLY);
	} while (fd < 0);

1171
	ret = dso__load_sym(self, map, name, fd, filter, 0, 0);
1172 1173 1174 1175 1176 1177 1178 1179
	close(fd);

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

1180
	if (ret > 0) {
1181
		int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
1182 1183 1184
		if (nr_plt > 0)
			ret += nr_plt;
	}
1185 1186
out:
	free(name);
1187 1188
	if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
		return 0;
1189 1190 1191
	return ret;
}

1192
static void kernel_maps__insert(struct map *map)
1193
{
1194
	maps__insert(&kernel_maps__functions, map);
1195
}
1196

1197 1198
struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp,
					  symbol_filter_t filter)
1199
{
1200
	struct map *map = maps__find(&kernel_maps__functions, ip);
1201 1202 1203

	if (mapp)
		*mapp = map;
1204 1205 1206

	if (map) {
		ip = map->map_ip(map, ip);
1207
		return map__find_symbol(map, ip, filter);
1208
	} else
1209
		WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps__functions),
1210
			  "Empty kernel_maps, was symbol__init() called?\n");
1211

1212
	return NULL;
1213 1214 1215 1216 1217 1218
}

struct map *kernel_maps__find_by_dso_name(const char *name)
{
	struct rb_node *nd;

1219
	for (nd = rb_first(&kernel_maps__functions); nd; nd = rb_next(nd)) {
1220 1221 1222 1223 1224 1225 1226 1227 1228
		struct map *map = rb_entry(nd, struct map, rb_node);

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

	return NULL;
}

1229
static int dsos__set_modules_path_dir(char *dirname)
1230
{
1231 1232
	struct dirent *dent;
	DIR *dir = opendir(dirname);
1233

1234
	if (!dir) {
1235
		pr_debug("%s: cannot open %s dir\n", __func__, dirname);
1236 1237
		return -1;
	}
1238

1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
	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);
1249
			if (dsos__set_modules_path_dir(path) < 0)
1250 1251 1252 1253 1254
				goto failure;
		} else {
			char *dot = strrchr(dent->d_name, '.'),
			     dso_name[PATH_MAX];
			struct map *map;
1255
			char *long_name;
1256 1257 1258 1259 1260 1261

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

1262
			strxfrchar(dso_name, '-', '_');
1263 1264 1265 1266 1267 1268 1269
			map = kernel_maps__find_by_dso_name(dso_name);
			if (map == NULL)
				continue;

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

1270 1271
			long_name = strdup(path);
			if (long_name == NULL)
1272
				goto failure;
1273
			dso__set_long_name(map->dso, long_name);
1274 1275
		}
	}
1276

1277
	return 0;
1278 1279 1280 1281
failure:
	closedir(dir);
	return -1;
}
1282

1283
static int dsos__set_modules_path(void)
1284 1285 1286
{
	struct utsname uts;
	char modules_path[PATH_MAX];
1287

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

1291 1292
	snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
		 uts.release);
1293

1294
	return dsos__set_modules_path_dir(modules_path);
1295 1296
}

1297 1298 1299 1300 1301
/*
 * 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.
 */
1302
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1303
{
1304
	struct map *self = malloc(sizeof(*self));
1305

1306 1307
	if (self != NULL) {
		/*
1308
		 * ->end will be filled after we load all the symbols
1309
		 */
1310
		map__init(self, type, start, 0, 0, dso);
1311
	}
1312

1313 1314 1315
	return self;
}

1316
static int kernel_maps__create_module_maps(void)
1317 1318 1319 1320 1321
{
	char *line = NULL;
	size_t n;
	FILE *file = fopen("/proc/modules", "r");
	struct map *map;
1322

1323 1324
	if (file == NULL)
		return -1;
1325

1326 1327 1328 1329 1330 1331
	while (!feof(file)) {
		char name[PATH_MAX];
		u64 start;
		struct dso *dso;
		char *sep;
		int line_len;
1332

1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354
		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);
1355
		dso = dso__new(name);
1356 1357 1358 1359

		if (dso == NULL)
			goto out_delete_line;

1360
		map = map__new2(start, dso, MAP__FUNCTION);
1361 1362 1363
		if (map == NULL) {
			dso__delete(dso);
			goto out_delete_line;
1364
		}
1365

1366 1367 1368 1369 1370 1371
		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;

1372 1373
		dso->origin = DSO__ORIG_KMODULE;
		kernel_maps__insert(map);
1374
		dsos__add(&dsos__kernel, dso);
1375
	}
1376 1377 1378 1379

	free(line);
	fclose(file);

1380
	return dsos__set_modules_path();
1381 1382 1383 1384 1385

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

1388
static int dso__load_vmlinux(struct dso *self, struct map *map,
1389
			     const char *vmlinux, symbol_filter_t filter)
1390
{
1391
	int err = -1, fd;
1392

1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
	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;
		}
	}
1416

1417
	fd = open(vmlinux, O_RDONLY);
1418 1419 1420
	if (fd < 0)
		return -1;

1421
	dso__set_loaded(self, map->type);
1422
	err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0);
1423

1424 1425 1426 1427 1428
	close(fd);

	return err;
}

1429 1430
static int dso__load_kernel_sym(struct dso *self, struct map *map,
				symbol_filter_t filter)
1431
{
1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454
	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) {
			err = dso__load_vmlinux(self, map, vmlinux_path[i],
						filter);
			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;
1455

1456
	err = dso__load_vmlinux(self, map, self->long_name, filter);
1457
	if (err <= 0) {
1458 1459 1460 1461
		pr_info("The file %s cannot be used, "
			"trying to use /proc/kallsyms...", self->long_name);
		sleep(2);
do_kallsyms:
1462
		err = kernel_maps__load_kallsyms(filter);
1463
		if (err > 0 && !is_kallsyms)
1464 1465
                        dso__set_long_name(self, strdup("[kernel.kallsyms]"));
	}
1466 1467

	if (err > 0) {
1468
out_fixup:
1469 1470
		map__fixup_start(map);
		map__fixup_end(map);
1471
	}
1472

1473 1474 1475
	return err;
}

1476 1477
LIST_HEAD(dsos__user);
LIST_HEAD(dsos__kernel);
1478
struct dso *vdso;
1479

1480
static void dsos__add(struct list_head *head, struct dso *dso)
1481
{
1482
	list_add_tail(&dso->node, head);
1483 1484
}

1485
static struct dso *dsos__find(struct list_head *head, const char *name)
1486 1487 1488
{
	struct dso *pos;

1489
	list_for_each_entry(pos, head, node)
1490 1491 1492 1493 1494
		if (strcmp(pos->name, name) == 0)
			return pos;
	return NULL;
}

1495
struct dso *dsos__findnew(const char *name)
1496
{
1497
	struct dso *dso = dsos__find(&dsos__user, name);
1498

1499
	if (!dso) {
1500
		dso = dso__new(name);
1501
		if (dso != NULL) {
1502
			dsos__add(&dsos__user, dso);
1503 1504
			dso__set_basename(dso);
		}
1505
	}
1506 1507 1508 1509

	return dso;
}

1510
static void __dsos__fprintf(struct list_head *head, FILE *fp)
1511 1512 1513
{
	struct dso *pos;

1514
	list_for_each_entry(pos, head, node)
1515 1516 1517
		dso__fprintf(pos, fp);
}

1518 1519 1520 1521 1522 1523 1524
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)
1525 1526 1527 1528
{
	struct dso *pos;
	size_t ret = 0;

1529
	list_for_each_entry(pos, head, node) {
1530
		ret += dso__fprintf_buildid(pos, fp);
1531
		ret += fprintf(fp, " %s\n", pos->long_name);
1532 1533 1534 1535
	}
	return ret;
}

1536 1537 1538 1539 1540 1541
size_t dsos__fprintf_buildid(FILE *fp)
{
	return (__dsos__fprintf_buildid(&dsos__kernel, fp) +
		__dsos__fprintf_buildid(&dsos__user, fp));
}

1542
static int kernel_maps__create_kernel_map(const struct symbol_conf *conf)
1543
{
1544
	struct dso *kernel = dso__new(conf->vmlinux_name ?: "[kernel.kallsyms]");
1545

1546
	if (kernel == NULL)
1547 1548
		return -1;

1549
	kernel_map__functions = map__new2(0, kernel, MAP__FUNCTION);
1550
	if (kernel_map__functions == NULL)
1551 1552
		goto out_delete_kernel_dso;

1553
	kernel_map__functions->map_ip	 = kernel_map__functions->unmap_ip = identity__map_ip;
1554 1555
	kernel->short_name	 = "[kernel]";
	kernel->kernel		 = 1;
1556

1557
	vdso = dso__new("[vdso]");
1558 1559
	if (vdso == NULL)
		goto out_delete_kernel_map;
1560
	dso__set_loaded(vdso, MAP__FUNCTION);
1561 1562 1563 1564

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

1566
	kernel_maps__insert(kernel_map__functions);
1567 1568
	dsos__add(&dsos__kernel, kernel);
	dsos__add(&dsos__user, vdso);
1569

1570 1571 1572
	return 0;

out_delete_kernel_map:
1573 1574
	map__delete(kernel_map__functions);
	kernel_map__functions = NULL;
1575 1576 1577
out_delete_kernel_dso:
	dso__delete(kernel);
	return -1;
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 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
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;
}

1635
static int kernel_maps__init(const struct symbol_conf *conf)
1636
{
1637 1638 1639 1640 1641
	const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;

	symbol__priv_size = pconf->priv_size;

	if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
1642 1643
		return -1;

1644
	if (kernel_maps__create_kernel_map(pconf) < 0) {
1645 1646 1647 1648
		vmlinux_path__exit();
		return -1;
	}

1649
	if (pconf->use_modules && kernel_maps__create_module_maps() < 0)
1650 1651
		pr_debug("Failed to load list of modules in use, "
			 "continuing...\n");
1652 1653 1654 1655
	/*
	 * Now that we have all the maps created, just set the ->end of them:
	 */
	kernel_maps__fixup_end();
1656
	return 0;
1657 1658
}

1659
int symbol__init(struct symbol_conf *conf)
1660 1661
{
	elf_version(EV_CURRENT);
1662
	return kernel_maps__init(conf);
1663
}