symbol.c 24.6 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 10 11
#include <libelf.h>
#include <gelf.h>
#include <elf.h>
12
#include <sys/utsname.h>
P
Peter Zijlstra 已提交
13

14 15
const char *sym_hist_filter;

16 17 18 19 20 21 22
enum dso_origin {
	DSO__ORIG_KERNEL = 0,
	DSO__ORIG_JAVA_JIT,
	DSO__ORIG_FEDORA,
	DSO__ORIG_UBUNTU,
	DSO__ORIG_BUILDID,
	DSO__ORIG_DSO,
23
	DSO__ORIG_KMODULE,
24 25 26
	DSO__ORIG_NOT_FOUND,
};

27 28 29 30 31
static void dsos__add(struct dso *dso);
static struct dso *dsos__find(const char *name);

static struct symbol *symbol__new(u64 start, u64 len, const char *name,
				  unsigned int priv_size, int v)
32
{
33
	size_t namelen = strlen(name) + 1;
34
	struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen);
35

36 37 38
	if (!self)
		return NULL;

39
	if (v >= 2)
40 41
		printf("new symbol: %016Lx [%08lx]: %s, hist: %p\n",
			start, (unsigned long)len, name, self->hist);
42 43 44 45 46

	self->hist = NULL;
	self->hist_sum = 0;

	if (sym_hist_filter && !strcmp(name, sym_hist_filter))
47
		self->hist = calloc(sizeof(u64), len);
48 49 50 51

	if (priv_size) {
		memset(self, 0, priv_size);
		self = ((void *)self) + priv_size;
52
	}
53
	self->start = start;
54
	self->end   = len ? start + len - 1 : start;
55
	memcpy(self->name, name, namelen);
56 57 58 59

	return self;
}

60
static void symbol__delete(struct symbol *self, unsigned int priv_size)
61
{
62
	free(((void *)self) - priv_size);
63 64 65 66
}

static size_t symbol__fprintf(struct symbol *self, FILE *fp)
{
67
	return fprintf(fp, " %llx-%llx %s\n",
68 69 70
		       self->start, self->end, self->name);
}

71
struct dso *dso__new(const char *name, unsigned int sym_priv_size)
72 73 74 75 76
{
	struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);

	if (self != NULL) {
		strcpy(self->name, name);
77 78
		self->long_name = self->name;
		self->short_name = self->name;
79
		self->syms = RB_ROOT;
80
		self->sym_priv_size = sym_priv_size;
P
Peter Zijlstra 已提交
81
		self->find_symbol = dso__find_symbol;
82
		self->slen_calculated = 0;
83
		self->origin = DSO__ORIG_NOT_FOUND;
84 85 86 87 88 89 90 91 92 93 94 95 96
	}

	return self;
}

static void dso__delete_symbols(struct dso *self)
{
	struct symbol *pos;
	struct rb_node *next = rb_first(&self->syms);

	while (next) {
		pos = rb_entry(next, struct symbol, rb_node);
		next = rb_next(&pos->rb_node);
97
		rb_erase(&pos->rb_node, &self->syms);
98
		symbol__delete(pos, self->sym_priv_size);
99 100 101 102 103 104
	}
}

void dso__delete(struct dso *self)
{
	dso__delete_symbols(self);
105 106
	if (self->long_name != self->name)
		free(self->long_name);
107 108 109 110 111 112 113
	free(self);
}

static void dso__insert_symbol(struct dso *self, struct symbol *sym)
{
	struct rb_node **p = &self->syms.rb_node;
	struct rb_node *parent = NULL;
114
	const u64 ip = sym->start;
115 116 117 118 119 120 121 122 123 124 125 126 127 128
	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);
	rb_insert_color(&sym->rb_node, &self->syms);
}

129
struct symbol *dso__find_symbol(struct dso *self, u64 ip)
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
{
	struct rb_node *n;

	if (self == NULL)
		return NULL;

	n = self->syms.rb_node;

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

size_t dso__fprintf(struct dso *self, FILE *fp)
{
154
	size_t ret = fprintf(fp, "dso: %s\n", self->long_name);
155 156 157 158 159 160 161 162 163 164

	struct rb_node *nd;
	for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) {
		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
		ret += symbol__fprintf(pos, fp);
	}

	return ret;
}

165 166
static int dso__load_kallsyms(struct dso *self, struct map *map,
			      symbol_filter_t filter, int v)
167 168 169 170 171
{
	struct rb_node *nd, *prevnd;
	char *line = NULL;
	size_t n;
	FILE *file = fopen("/proc/kallsyms", "r");
172
	int count = 0;
173 174 175 176 177

	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
178
		u64 start;
179 180 181 182 183 184 185 186 187 188 189 190 191
		struct symbol *sym;
		int line_len, len;
		char symbol_type;

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

		if (!line)
			goto out_failure;

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

192
		len = hex2u64(line, &start);
193 194 195 196 197 198 199 200 201 202 203 204 205 206

		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;
		/*
		 * Well fix up the end later, when we have all sorted.
		 */
207
		sym = symbol__new(start, 0xdead, line + len + 2,
208
				  self->sym_priv_size, v);
209 210 211 212

		if (sym == NULL)
			goto out_delete_line;

213
		if (filter && filter(map, sym))
214
			symbol__delete(sym, self->sym_priv_size);
215
		else {
216
			dso__insert_symbol(self, sym);
217 218
			count++;
		}
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
	}

	/*
	 * Now that we have all sorted out, just set the ->end of all
	 * symbols
	 */
	prevnd = rb_first(&self->syms);

	if (prevnd == NULL)
		goto out_delete_line;

	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
		struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node),
			      *curr = rb_entry(nd, struct symbol, rb_node);

		prev->end = curr->start - 1;
		prevnd = nd;
	}

	free(line);
	fclose(file);

241
	return count;
242 243 244 245 246 247 248

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

249 250
static int dso__load_perf_map(struct dso *self, struct map *map,
			      symbol_filter_t filter, int v)
251 252 253 254 255 256
{
	char *line = NULL;
	size_t n;
	FILE *file;
	int nr_syms = 0;

257
	file = fopen(self->long_name, "r");
258 259 260 261
	if (file == NULL)
		goto out_failure;

	while (!feof(file)) {
262
		u64 start, size;
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
		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;

		sym = symbol__new(start, size, line + len,
288
				  self->sym_priv_size, v);
289 290 291 292

		if (sym == NULL)
			goto out_delete_line;

293
		if (filter && filter(map, sym))
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
			symbol__delete(sym, self->sym_priv_size);
		else {
			dso__insert_symbol(self, sym);
			nr_syms++;
		}
	}

	free(line);
	fclose(file);

	return nr_syms;

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

312 313 314 315
/**
 * elf_symtab__for_each_symbol - iterate thru all the symbols
 *
 * @self: struct elf_symtab instance to iterate
316
 * @idx: uint32_t idx
317 318
 * @sym: GElf_Sym iterator
 */
319 320 321 322
#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))
323 324 325 326 327 328 329 330 331 332 333 334 335 336

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 &&
	       sym->st_shndx != SHN_UNDEF &&
	       sym->st_size != 0;
}

337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
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;
}

357 358 359 360 361 362 363 364
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,
365
				    size_t *idx)
366 367 368 369 370 371 372 373 374 375
{
	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)) {
376 377
			if (idx)
				*idx = cnt;
378 379 380 381 382 383 384 385
			break;
		}
		++cnt;
	}

	return sec;
}

386 387 388 389 390 391 392 393 394 395
#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))

396 397 398 399 400 401 402
/*
 * 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).
 */
403
static int dso__synthesize_plt_symbols(struct  dso *self, int v)
404 405 406
{
	uint32_t nr_rel_entries, idx;
	GElf_Sym sym;
407
	u64 plt_offset;
408 409
	GElf_Shdr shdr_plt;
	struct symbol *f;
410
	GElf_Shdr shdr_rel_plt, shdr_dynsym;
411
	Elf_Data *reldata, *syms, *symstrs;
412 413 414
	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
	size_t dynsym_idx;
	GElf_Ehdr ehdr;
415
	char sympltname[1024];
416 417 418
	Elf *elf;
	int nr = 0, symidx, fd, err = 0;

419
	fd = open(self->long_name, O_RDONLY);
420 421 422 423 424 425 426 427 428 429 430 431 432 433
	if (fd < 0)
		goto out;

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	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;
434

435
	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
436 437
					  ".rela.plt", NULL);
	if (scn_plt_rel == NULL) {
438
		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
439 440
						  ".rel.plt", NULL);
		if (scn_plt_rel == NULL)
441
			goto out_elf_end;
442 443
	}

444 445
	err = -1;

446
	if (shdr_rel_plt.sh_link != dynsym_idx)
447
		goto out_elf_end;
448

449 450
	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
		goto out_elf_end;
451 452

	/*
453
	 * Fetch the relocation section to find the idxes to the GOT
454 455 456 457
	 * and the symbols in the .dynsym they refer to.
	 */
	reldata = elf_getdata(scn_plt_rel, NULL);
	if (reldata == NULL)
458
		goto out_elf_end;
459 460 461

	syms = elf_getdata(scn_dynsym, NULL);
	if (syms == NULL)
462
		goto out_elf_end;
463

464
	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
465
	if (scn_symstrs == NULL)
466
		goto out_elf_end;
467 468 469

	symstrs = elf_getdata(scn_symstrs, NULL);
	if (symstrs == NULL)
470
		goto out_elf_end;
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486

	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,
487
					sympltname, self->sym_priv_size, v);
488
			if (!f)
489
				goto out_elf_end;
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504

			dso__insert_symbol(self, f);
			++nr;
		}
	} 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,
505
					sympltname, self->sym_priv_size, v);
506
			if (!f)
507
				goto out_elf_end;
508 509 510 511 512 513

			dso__insert_symbol(self, f);
			++nr;
		}
	}

514 515 516 517 518 519 520 521 522 523
	err = 0;
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);

	if (err == 0)
		return nr;
out:
	fprintf(stderr, "%s: problems reading %s PLT info.\n",
524
		__func__, self->long_name);
525
	return 0;
526 527
}

528 529 530
static int dso__load_sym(struct dso *self, struct map *map, const char *name,
			 int fd, symbol_filter_t filter, int kernel,
			 int kmodule, int v)
531
{
532
	Elf_Data *symstrs, *secstrs;
533 534
	uint32_t nr_syms;
	int err = -1;
535
	uint32_t idx;
536 537 538 539
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *syms;
	GElf_Sym sym;
540
	Elf_Scn *sec, *sec_strndx;
541
	Elf *elf;
542
	int nr = 0;
543 544 545

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
546
		if (v)
547 548
			fprintf(stderr, "%s: cannot read %s ELF file.\n",
				__func__, name);
549 550 551 552
		goto out_close;
	}

	if (gelf_getehdr(elf, &ehdr) == NULL) {
553
		if (v)
554
			fprintf(stderr, "%s: cannot get elf header.\n", __func__);
555 556 557 558
		goto out_elf_end;
	}

	sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
559
	if (sec == NULL) {
560 561
		sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
		if (sec == NULL)
562 563
			goto out_elf_end;
	}
564 565 566 567 568 569 570 571 572 573 574 575 576

	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;

577 578 579 580 581
	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 已提交
582
	if (secstrs == NULL)
583 584
		goto out_elf_end;

585 586
	nr_syms = shdr.sh_size / shdr.sh_entsize;

587
	memset(&sym, 0, sizeof(sym));
588 589
	if (!kernel) {
		self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
590 591 592
				elf_section_by_name(elf, &ehdr, &shdr,
						     ".gnu.prelink_undo",
						     NULL) != NULL);
593 594
	} else self->adjust_symbols = 0;

595
	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
596
		struct symbol *f;
597
		const char *elf_name;
598
		char *demangled;
599 600
		int is_label = elf_sym__is_label(&sym);
		const char *section_name;
601

602
		if (!is_label && !elf_sym__is_function(&sym))
603 604 605 606 607 608 609
			continue;

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

		gelf_getshdr(sec, &shdr);
610 611 612 613 614

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

		section_name = elf_sec__name(&shdr, secstrs);
615

616
		if (self->adjust_symbols) {
617
			if (v >= 2)
618 619
				printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
					(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
620

621
			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
622 623
		} else if (kmodule)
			sym.st_value += shdr.sh_offset;
624 625 626 627 628
		/*
		 * 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...
		 */
629 630
		elf_name = elf_sym__name(&sym, symstrs);
		demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
631
		if (demangled != NULL)
632
			elf_name = demangled;
633

634
		f = symbol__new(sym.st_value, sym.st_size, elf_name,
635
				self->sym_priv_size, v);
636
		free(demangled);
637 638 639
		if (!f)
			goto out_elf_end;

640
		if (filter && filter(map, f))
641 642 643 644 645
			symbol__delete(f, self->sym_priv_size);
		else {
			dso__insert_symbol(self, f);
			nr++;
		}
646 647 648 649 650 651 652 653 654
	}

	err = nr;
out_elf_end:
	elf_end(elf);
out_close:
	return err;
}

655 656
#define BUILD_ID_SIZE 128

657
static char *dso__read_build_id(struct dso *self, int v)
658 659 660 661 662 663 664 665 666
{
	int i;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;
	Elf_Data *build_id_data;
	Elf_Scn *sec;
	char *build_id = NULL, *bid;
	unsigned char *raw;
	Elf *elf;
667
	int fd = open(self->long_name, O_RDONLY);
668 669 670 671 672 673

	if (fd < 0)
		goto out;

	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	if (elf == NULL) {
674
		if (v)
675
			fprintf(stderr, "%s: cannot read %s ELF file.\n",
676
				__func__, self->long_name);
677 678 679 680
		goto out_close;
	}

	if (gelf_getehdr(elf, &ehdr) == NULL) {
681
		if (v)
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
			fprintf(stderr, "%s: cannot get elf header.\n", __func__);
		goto out_elf_end;
	}

	sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL);
	if (sec == NULL)
		goto out_elf_end;

	build_id_data = elf_getdata(sec, NULL);
	if (build_id_data == NULL)
		goto out_elf_end;
	build_id = malloc(BUILD_ID_SIZE);
	if (build_id == NULL)
		goto out_elf_end;
	raw = build_id_data->d_buf + 16;
	bid = build_id;

	for (i = 0; i < 20; ++i) {
		sprintf(bid, "%02x", *raw);
		++raw;
		bid += 2;
	}
704
	if (v >= 2)
705
		printf("%s(%s): %s\n", __func__, self->long_name, build_id);
706 707 708 709 710 711 712 713
out_elf_end:
	elf_end(elf);
out_close:
	close(fd);
out:
	return build_id;
}

714 715 716 717 718 719 720 721 722
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',
723
		[DSO__ORIG_KMODULE] =  'K',
724 725 726 727 728 729 730
	};

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

731
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter, int v)
732
{
733 734
	int size = PATH_MAX;
	char *name = malloc(size), *build_id = NULL;
735 736 737 738 739 740
	int ret = -1;
	int fd;

	if (!name)
		return -1;

741
	self->adjust_symbols = 0;
742

743
	if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
744
		ret = dso__load_perf_map(self, map, filter, v);
745 746 747 748 749 750
		self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
					 DSO__ORIG_NOT_FOUND;
		return ret;
	}

	self->origin = DSO__ORIG_FEDORA - 1;
751

752 753
more:
	do {
754 755 756
		self->origin++;
		switch (self->origin) {
		case DSO__ORIG_FEDORA:
757 758
			snprintf(name, size, "/usr/lib/debug%s.debug",
				 self->long_name);
759
			break;
760
		case DSO__ORIG_UBUNTU:
761 762
			snprintf(name, size, "/usr/lib/debug%s",
				 self->long_name);
763
			break;
764
		case DSO__ORIG_BUILDID:
765
			build_id = dso__read_build_id(self, v);
766 767 768 769 770 771 772
			if (build_id != NULL) {
				snprintf(name, size,
					 "/usr/lib/debug/.build-id/%.2s/%s.debug",
					build_id, build_id + 2);
				free(build_id);
				break;
			}
773
			self->origin++;
774
			/* Fall thru */
775
		case DSO__ORIG_DSO:
776
			snprintf(name, size, "%s", self->long_name);
777 778 779 780 781 782 783 784 785
			break;

		default:
			goto out;
		}

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

786
	ret = dso__load_sym(self, map, name, fd, filter, 0, 0, v);
787 788 789 790 791 792 793 794
	close(fd);

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

795
	if (ret > 0) {
796
		int nr_plt = dso__synthesize_plt_symbols(self, v);
797 798 799
		if (nr_plt > 0)
			ret += nr_plt;
	}
800 801
out:
	free(name);
802 803
	if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
		return 0;
804 805 806
	return ret;
}

807 808 809 810
static struct rb_root kernel_maps;
struct map *kernel_map;

static void kernel_maps__insert(struct map *map)
811
{
812 813
	maps__insert(&kernel_maps, map);
}
814

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp)
{
	/*
	 * We can't have kernel_map in kernel_maps because it spans an address
	 * space that includes the modules. The right way to fix this is to
	 * create several maps, so that we don't have overlapping ranges with
	 * modules. For now lets look first on the kernel dso.
	 */
	struct map *map = maps__find(&kernel_maps, ip);
	struct symbol *sym;

	if (map) {
		ip = map->map_ip(map, ip);
		sym = map->dso->find_symbol(map->dso, ip);
	} else {
		map = kernel_map;
		sym = map->dso->find_symbol(map->dso, ip);
	}
833

834 835
	if (mapp)
		*mapp = map;
836

837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
	return sym;
}

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

	for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) {
		struct map *map = rb_entry(nd, struct map, rb_node);

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

	return NULL;
}

static int dso__load_module_sym(struct dso *self, struct map *map,
				symbol_filter_t filter, int v)
{
	int err = 0, fd = open(self->long_name, O_RDONLY);

	if (fd < 0) {
		if (v)
			fprintf(stderr, "%s: cannot open %s\n",
				__func__, self->long_name);
863
		return err;
864
	}
865

866
	err = dso__load_sym(self, map, self->long_name, fd, filter, 0, 1, v);
867 868 869 870 871
	close(fd);

	return err;
}

872 873
static int dsos__load_modules_sym_dir(char *dirname,
				      symbol_filter_t filter, int v)
874
{
875 876 877
	struct dirent *dent;
	int nr_symbols = 0, err;
	DIR *dir = opendir(dirname);
878

879 880 881 882 883 884
	if (!dir) {
		if (v)
			fprintf(stderr, "%s: cannot open %s dir\n", __func__,
				dirname);
		return -1;
	}
885

886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932
	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);
			err = dsos__load_modules_sym_dir(path, filter, v);
			if (err < 0)
				goto failure;
		} else {
			char *dot = strrchr(dent->d_name, '.'),
			     dso_name[PATH_MAX];
			struct map *map;
			struct rb_node *last;

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

			map = kernel_maps__find_by_dso_name(dso_name);
			if (map == NULL)
				continue;

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

			map->dso->long_name = strdup(path);
			if (map->dso->long_name == NULL)
				goto failure;

			err = dso__load_module_sym(map->dso, map, filter, v);
			if (err < 0)
				goto failure;
			last = rb_last(&map->dso->syms);
			if (last) {
				struct symbol *sym;
				sym = rb_entry(last, struct symbol, rb_node);
				map->end = map->start + sym->end;
			}
		}
		nr_symbols += err;
	}
933

934 935 936 937 938
	return nr_symbols;
failure:
	closedir(dir);
	return -1;
}
939

940 941 942 943
static int dsos__load_modules_sym(symbol_filter_t filter, int v)
{
	struct utsname uts;
	char modules_path[PATH_MAX];
944

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

948 949
	snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
		 uts.release);
950

951
	return dsos__load_modules_sym_dir(modules_path, filter, v);
952 953
}

954 955 956 957 958 959
/*
 * 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.
 */
static struct map *map__new2(u64 start, struct dso *dso)
960
{
961
	struct map *self = malloc(sizeof(*self));
962

963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
	if (self != NULL) {
		self->start = start;
		/*
		 * Will be filled after we load all the symbols
		 */
		self->end = 0;

		self->pgoff = 0;
		self->dso = dso;
		self->map_ip = map__map_ip;
		RB_CLEAR_NODE(&self->rb_node);
	}
	return self;
}

int dsos__load_modules(unsigned int sym_priv_size,
		       symbol_filter_t filter, int v)
{
	char *line = NULL;
	size_t n;
	FILE *file = fopen("/proc/modules", "r");
	struct map *map;
985

986 987
	if (file == NULL)
		return -1;
988

989 990 991 992 993 994
	while (!feof(file)) {
		char name[PATH_MAX];
		u64 start;
		struct dso *dso;
		char *sep;
		int line_len;
995

996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
		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);
		dso = dso__new(name, sym_priv_size);

		if (dso == NULL)
			goto out_delete_line;

		map = map__new2(start, dso);
		if (map == NULL) {
			dso__delete(dso);
			goto out_delete_line;
1027
		}
1028 1029 1030 1031

		dso->origin = DSO__ORIG_KMODULE;
		kernel_maps__insert(map);
		dsos__add(dso);
1032
	}
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043

	free(line);
	fclose(file);

	v = 1;
	return dsos__load_modules_sym(filter, v);

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

1046 1047
static int dso__load_vmlinux(struct dso *self, struct map *map,
			     const char *vmlinux,
1048
			     symbol_filter_t filter, int v)
1049 1050 1051 1052 1053 1054
{
	int err, fd = open(vmlinux, O_RDONLY);

	if (fd < 0)
		return -1;

1055
	err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0, v);
1056

1057 1058 1059 1060 1061
	close(fd);

	return err;
}

1062 1063
int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size,
		      symbol_filter_t filter, int v, int use_modules)
1064 1065
{
	int err = -1;
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
	struct dso *dso = dso__new(vmlinux, sym_priv_size);

	if (dso == NULL)
		return -1;

	dso->short_name = "[kernel]";
	kernel_map = map__new2(0, dso);
	if (kernel_map == NULL)
		goto out_delete_dso;

	kernel_map->map_ip = vdso__map_ip;
1077

1078
	if (vmlinux) {
1079
		err = dso__load_vmlinux(dso, kernel_map, vmlinux, filter, v);
1080
		if (err > 0 && use_modules) {
1081
			int syms = dsos__load_modules(sym_priv_size, filter, v);
1082 1083

			if (syms < 0) {
1084
				fprintf(stderr, "dsos__load_modules failed!\n");
1085 1086 1087 1088
				return syms;
			}
			err += syms;
		}
1089
	}
1090

1091
	if (err <= 0)
1092 1093 1094 1095 1096
		err = dso__load_kallsyms(dso, kernel_map, filter, v);

	if (err > 0) {
		struct rb_node *node = rb_first(&dso->syms);
		struct symbol *sym = rb_entry(node, struct symbol, rb_node);
1097

1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109
		kernel_map->start = sym->start;
		node = rb_last(&dso->syms);
		sym = rb_entry(node, struct symbol, rb_node);
		kernel_map->end = sym->end;

		dso->origin = DSO__ORIG_KERNEL;
		/*
		 * XXX See kernel_maps__find_symbol comment
		 * kernel_maps__insert(kernel_map)
		 */
		dsos__add(dso);
	}
1110

1111
	return err;
1112 1113 1114 1115

out_delete_dso:
	dso__delete(dso);
	return -1;
1116 1117
}

1118 1119 1120
LIST_HEAD(dsos);
struct dso	*vdso;

1121
const char	*vmlinux_name = "vmlinux";
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
int		modules;

static void dsos__add(struct dso *dso)
{
	list_add_tail(&dso->node, &dsos);
}

static struct dso *dsos__find(const char *name)
{
	struct dso *pos;

	list_for_each_entry(pos, &dsos, node)
		if (strcmp(pos->name, name) == 0)
			return pos;
	return NULL;
}

struct dso *dsos__findnew(const char *name)
{
	struct dso *dso = dsos__find(name);
	int nr;

	if (dso)
		return dso;

	dso = dso__new(name, 0);
	if (!dso)
		goto out_delete_dso;

1151
	nr = dso__load(dso, NULL, NULL, verbose);
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
	if (nr < 0) {
		eprintf("Failed to open: %s\n", name);
		goto out_delete_dso;
	}
	if (!nr)
		eprintf("No symbols found in: %s, maybe install a debug package?\n", name);

	dsos__add(dso);

	return dso;

out_delete_dso:
	dso__delete(dso);
	return NULL;
}

void dsos__fprintf(FILE *fp)
{
	struct dso *pos;

	list_for_each_entry(pos, &dsos, node)
		dso__fprintf(pos, fp);
}

int load_kernel(void)
{
1178
	if (dsos__load_kernel(vmlinux_name, 0, NULL, verbose, modules) <= 0)
1179 1180 1181 1182 1183 1184 1185 1186
		return -1;

	vdso = dso__new("[vdso]", 0);
	if (!vdso)
		return -1;

	dsos__add(vdso);

1187
	return 0;
1188 1189
}

1190 1191 1192 1193
void symbol__init(void)
{
	elf_version(EV_CURRENT);
}