xref: /linux/tools/perf/util/symbol.c (revision 1a5aeeecd550ee4344cfba1791f1134739b16dc6)
1 #include "util.h"
2 #include "../perf.h"
3 #include "string.h"
4 #include "symbol.h"
5 
6 #include <libelf.h>
7 #include <gelf.h>
8 #include <elf.h>
9 
10 #ifndef NO_DEMANGLE
11 #include <bfd.h>
12 #else
13 static inline
14 char *bfd_demangle(void __used *v, const char __used *c, int __used i)
15 {
16 	return NULL;
17 }
18 #endif
19 
20 const char *sym_hist_filter;
21 
22 #ifndef DMGL_PARAMS
23 #define DMGL_PARAMS      (1 << 0)       /* Include function args */
24 #define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */
25 #endif
26 
27 static struct symbol *symbol__new(u64 start, u64 len,
28 				  const char *name, unsigned int priv_size,
29 				  u64 obj_start, int verbose)
30 {
31 	size_t namelen = strlen(name) + 1;
32 	struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen);
33 
34 	if (!self)
35 		return NULL;
36 
37 	if (verbose >= 2)
38 		printf("new symbol: %016Lx [%08lx]: %s, hist: %p, obj_start: %p\n",
39 			(u64)start, (unsigned long)len, name, self->hist, (void *)(unsigned long)obj_start);
40 
41 	self->obj_start= obj_start;
42 	self->hist = NULL;
43 	self->hist_sum = 0;
44 
45 	if (sym_hist_filter && !strcmp(name, sym_hist_filter))
46 		self->hist = calloc(sizeof(u64), len);
47 
48 	if (priv_size) {
49 		memset(self, 0, priv_size);
50 		self = ((void *)self) + priv_size;
51 	}
52 	self->start = start;
53 	self->end   = len ? start + len - 1 : start;
54 	memcpy(self->name, name, namelen);
55 
56 	return self;
57 }
58 
59 static void symbol__delete(struct symbol *self, unsigned int priv_size)
60 {
61 	free(((void *)self) - priv_size);
62 }
63 
64 static size_t symbol__fprintf(struct symbol *self, FILE *fp)
65 {
66 	if (!self->module)
67 		return fprintf(fp, " %llx-%llx %s\n",
68 		       self->start, self->end, self->name);
69 	else
70 		return fprintf(fp, " %llx-%llx %s \t[%s]\n",
71 		       self->start, self->end, self->name, self->module->name);
72 }
73 
74 struct dso *dso__new(const char *name, unsigned int sym_priv_size)
75 {
76 	struct dso *self = malloc(sizeof(*self) + strlen(name) + 1);
77 
78 	if (self != NULL) {
79 		strcpy(self->name, name);
80 		self->syms = RB_ROOT;
81 		self->sym_priv_size = sym_priv_size;
82 		self->find_symbol = dso__find_symbol;
83 		self->slen_calculated = 0;
84 	}
85 
86 	return self;
87 }
88 
89 static void dso__delete_symbols(struct dso *self)
90 {
91 	struct symbol *pos;
92 	struct rb_node *next = rb_first(&self->syms);
93 
94 	while (next) {
95 		pos = rb_entry(next, struct symbol, rb_node);
96 		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 void dso__delete(struct dso *self)
103 {
104 	dso__delete_symbols(self);
105 	free(self);
106 }
107 
108 static void dso__insert_symbol(struct dso *self, struct symbol *sym)
109 {
110 	struct rb_node **p = &self->syms.rb_node;
111 	struct rb_node *parent = NULL;
112 	const u64 ip = sym->start;
113 	struct symbol *s;
114 
115 	while (*p != NULL) {
116 		parent = *p;
117 		s = rb_entry(parent, struct symbol, rb_node);
118 		if (ip < s->start)
119 			p = &(*p)->rb_left;
120 		else
121 			p = &(*p)->rb_right;
122 	}
123 	rb_link_node(&sym->rb_node, parent, p);
124 	rb_insert_color(&sym->rb_node, &self->syms);
125 }
126 
127 struct symbol *dso__find_symbol(struct dso *self, u64 ip)
128 {
129 	struct rb_node *n;
130 
131 	if (self == NULL)
132 		return NULL;
133 
134 	n = self->syms.rb_node;
135 
136 	while (n) {
137 		struct symbol *s = rb_entry(n, struct symbol, rb_node);
138 
139 		if (ip < s->start)
140 			n = n->rb_left;
141 		else if (ip > s->end)
142 			n = n->rb_right;
143 		else
144 			return s;
145 	}
146 
147 	return NULL;
148 }
149 
150 size_t dso__fprintf(struct dso *self, FILE *fp)
151 {
152 	size_t ret = fprintf(fp, "dso: %s\n", self->name);
153 
154 	struct rb_node *nd;
155 	for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) {
156 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
157 		ret += symbol__fprintf(pos, fp);
158 	}
159 
160 	return ret;
161 }
162 
163 static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verbose)
164 {
165 	struct rb_node *nd, *prevnd;
166 	char *line = NULL;
167 	size_t n;
168 	FILE *file = fopen("/proc/kallsyms", "r");
169 	int count = 0;
170 
171 	if (file == NULL)
172 		goto out_failure;
173 
174 	while (!feof(file)) {
175 		u64 start;
176 		struct symbol *sym;
177 		int line_len, len;
178 		char symbol_type;
179 
180 		line_len = getline(&line, &n, file);
181 		if (line_len < 0)
182 			break;
183 
184 		if (!line)
185 			goto out_failure;
186 
187 		line[--line_len] = '\0'; /* \n */
188 
189 		len = hex2u64(line, &start);
190 
191 		len++;
192 		if (len + 2 >= line_len)
193 			continue;
194 
195 		symbol_type = toupper(line[len]);
196 		/*
197 		 * We're interested only in code ('T'ext)
198 		 */
199 		if (symbol_type != 'T' && symbol_type != 'W')
200 			continue;
201 		/*
202 		 * Well fix up the end later, when we have all sorted.
203 		 */
204 		sym = symbol__new(start, 0xdead, line + len + 2,
205 				  self->sym_priv_size, 0, verbose);
206 
207 		if (sym == NULL)
208 			goto out_delete_line;
209 
210 		if (filter && filter(self, sym))
211 			symbol__delete(sym, self->sym_priv_size);
212 		else {
213 			dso__insert_symbol(self, sym);
214 			count++;
215 		}
216 	}
217 
218 	/*
219 	 * Now that we have all sorted out, just set the ->end of all
220 	 * symbols
221 	 */
222 	prevnd = rb_first(&self->syms);
223 
224 	if (prevnd == NULL)
225 		goto out_delete_line;
226 
227 	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
228 		struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node),
229 			      *curr = rb_entry(nd, struct symbol, rb_node);
230 
231 		prev->end = curr->start - 1;
232 		prevnd = nd;
233 	}
234 
235 	free(line);
236 	fclose(file);
237 
238 	return count;
239 
240 out_delete_line:
241 	free(line);
242 out_failure:
243 	return -1;
244 }
245 
246 static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int verbose)
247 {
248 	char *line = NULL;
249 	size_t n;
250 	FILE *file;
251 	int nr_syms = 0;
252 
253 	file = fopen(self->name, "r");
254 	if (file == NULL)
255 		goto out_failure;
256 
257 	while (!feof(file)) {
258 		u64 start, size;
259 		struct symbol *sym;
260 		int line_len, len;
261 
262 		line_len = getline(&line, &n, file);
263 		if (line_len < 0)
264 			break;
265 
266 		if (!line)
267 			goto out_failure;
268 
269 		line[--line_len] = '\0'; /* \n */
270 
271 		len = hex2u64(line, &start);
272 
273 		len++;
274 		if (len + 2 >= line_len)
275 			continue;
276 
277 		len += hex2u64(line + len, &size);
278 
279 		len++;
280 		if (len + 2 >= line_len)
281 			continue;
282 
283 		sym = symbol__new(start, size, line + len,
284 				  self->sym_priv_size, start, verbose);
285 
286 		if (sym == NULL)
287 			goto out_delete_line;
288 
289 		if (filter && filter(self, sym))
290 			symbol__delete(sym, self->sym_priv_size);
291 		else {
292 			dso__insert_symbol(self, sym);
293 			nr_syms++;
294 		}
295 	}
296 
297 	free(line);
298 	fclose(file);
299 
300 	return nr_syms;
301 
302 out_delete_line:
303 	free(line);
304 out_failure:
305 	return -1;
306 }
307 
308 /**
309  * elf_symtab__for_each_symbol - iterate thru all the symbols
310  *
311  * @self: struct elf_symtab instance to iterate
312  * @index: uint32_t index
313  * @sym: GElf_Sym iterator
314  */
315 #define elf_symtab__for_each_symbol(syms, nr_syms, index, sym) \
316 	for (index = 0, gelf_getsym(syms, index, &sym);\
317 	     index < nr_syms; \
318 	     index++, gelf_getsym(syms, index, &sym))
319 
320 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
321 {
322 	return GELF_ST_TYPE(sym->st_info);
323 }
324 
325 static inline int elf_sym__is_function(const GElf_Sym *sym)
326 {
327 	return elf_sym__type(sym) == STT_FUNC &&
328 	       sym->st_name != 0 &&
329 	       sym->st_shndx != SHN_UNDEF &&
330 	       sym->st_size != 0;
331 }
332 
333 static inline int elf_sym__is_label(const GElf_Sym *sym)
334 {
335 	return elf_sym__type(sym) == STT_NOTYPE &&
336 		sym->st_name != 0 &&
337 		sym->st_shndx != SHN_UNDEF &&
338 		sym->st_shndx != SHN_ABS;
339 }
340 
341 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
342 					const Elf_Data *secstrs)
343 {
344 	return secstrs->d_buf + shdr->sh_name;
345 }
346 
347 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
348 					const Elf_Data *secstrs)
349 {
350 	return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
351 }
352 
353 static inline const char *elf_sym__name(const GElf_Sym *sym,
354 					const Elf_Data *symstrs)
355 {
356 	return symstrs->d_buf + sym->st_name;
357 }
358 
359 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
360 				    GElf_Shdr *shp, const char *name,
361 				    size_t *index)
362 {
363 	Elf_Scn *sec = NULL;
364 	size_t cnt = 1;
365 
366 	while ((sec = elf_nextscn(elf, sec)) != NULL) {
367 		char *str;
368 
369 		gelf_getshdr(sec, shp);
370 		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
371 		if (!strcmp(name, str)) {
372 			if (index)
373 				*index = cnt;
374 			break;
375 		}
376 		++cnt;
377 	}
378 
379 	return sec;
380 }
381 
382 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
383 	for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
384 	     idx < nr_entries; \
385 	     ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
386 
387 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
388 	for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
389 	     idx < nr_entries; \
390 	     ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
391 
392 /*
393  * We need to check if we have a .dynsym, so that we can handle the
394  * .plt, synthesizing its symbols, that aren't on the symtabs (be it
395  * .dynsym or .symtab).
396  * And always look at the original dso, not at debuginfo packages, that
397  * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
398  */
399 static int dso__synthesize_plt_symbols(struct  dso *self, int verbose)
400 {
401 	uint32_t nr_rel_entries, idx;
402 	GElf_Sym sym;
403 	u64 plt_offset;
404 	GElf_Shdr shdr_plt;
405 	struct symbol *f;
406 	GElf_Shdr shdr_rel_plt, shdr_dynsym;
407 	Elf_Data *reldata, *syms, *symstrs;
408 	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
409 	size_t dynsym_idx;
410 	GElf_Ehdr ehdr;
411 	char sympltname[1024];
412 	Elf *elf;
413 	int nr = 0, symidx, fd, err = 0;
414 
415 	fd = open(self->name, O_RDONLY);
416 	if (fd < 0)
417 		goto out;
418 
419 	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
420 	if (elf == NULL)
421 		goto out_close;
422 
423 	if (gelf_getehdr(elf, &ehdr) == NULL)
424 		goto out_elf_end;
425 
426 	scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
427 					 ".dynsym", &dynsym_idx);
428 	if (scn_dynsym == NULL)
429 		goto out_elf_end;
430 
431 	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
432 					  ".rela.plt", NULL);
433 	if (scn_plt_rel == NULL) {
434 		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
435 						  ".rel.plt", NULL);
436 		if (scn_plt_rel == NULL)
437 			goto out_elf_end;
438 	}
439 
440 	err = -1;
441 
442 	if (shdr_rel_plt.sh_link != dynsym_idx)
443 		goto out_elf_end;
444 
445 	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
446 		goto out_elf_end;
447 
448 	/*
449 	 * Fetch the relocation section to find the indexes to the GOT
450 	 * and the symbols in the .dynsym they refer to.
451 	 */
452 	reldata = elf_getdata(scn_plt_rel, NULL);
453 	if (reldata == NULL)
454 		goto out_elf_end;
455 
456 	syms = elf_getdata(scn_dynsym, NULL);
457 	if (syms == NULL)
458 		goto out_elf_end;
459 
460 	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
461 	if (scn_symstrs == NULL)
462 		goto out_elf_end;
463 
464 	symstrs = elf_getdata(scn_symstrs, NULL);
465 	if (symstrs == NULL)
466 		goto out_elf_end;
467 
468 	nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
469 	plt_offset = shdr_plt.sh_offset;
470 
471 	if (shdr_rel_plt.sh_type == SHT_RELA) {
472 		GElf_Rela pos_mem, *pos;
473 
474 		elf_section__for_each_rela(reldata, pos, pos_mem, idx,
475 					   nr_rel_entries) {
476 			symidx = GELF_R_SYM(pos->r_info);
477 			plt_offset += shdr_plt.sh_entsize;
478 			gelf_getsym(syms, symidx, &sym);
479 			snprintf(sympltname, sizeof(sympltname),
480 				 "%s@plt", elf_sym__name(&sym, symstrs));
481 
482 			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
483 					sympltname, self->sym_priv_size, 0, verbose);
484 			if (!f)
485 				goto out_elf_end;
486 
487 			dso__insert_symbol(self, f);
488 			++nr;
489 		}
490 	} else if (shdr_rel_plt.sh_type == SHT_REL) {
491 		GElf_Rel pos_mem, *pos;
492 		elf_section__for_each_rel(reldata, pos, pos_mem, idx,
493 					  nr_rel_entries) {
494 			symidx = GELF_R_SYM(pos->r_info);
495 			plt_offset += shdr_plt.sh_entsize;
496 			gelf_getsym(syms, symidx, &sym);
497 			snprintf(sympltname, sizeof(sympltname),
498 				 "%s@plt", elf_sym__name(&sym, symstrs));
499 
500 			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
501 					sympltname, self->sym_priv_size, 0, verbose);
502 			if (!f)
503 				goto out_elf_end;
504 
505 			dso__insert_symbol(self, f);
506 			++nr;
507 		}
508 	}
509 
510 	err = 0;
511 out_elf_end:
512 	elf_end(elf);
513 out_close:
514 	close(fd);
515 
516 	if (err == 0)
517 		return nr;
518 out:
519 	fprintf(stderr, "%s: problems reading %s PLT info.\n",
520 		__func__, self->name);
521 	return 0;
522 }
523 
524 static int dso__load_sym(struct dso *self, int fd, const char *name,
525 			 symbol_filter_t filter, int verbose, struct module *mod)
526 {
527 	Elf_Data *symstrs, *secstrs;
528 	uint32_t nr_syms;
529 	int err = -1;
530 	uint32_t index;
531 	GElf_Ehdr ehdr;
532 	GElf_Shdr shdr;
533 	Elf_Data *syms;
534 	GElf_Sym sym;
535 	Elf_Scn *sec, *sec_strndx;
536 	Elf *elf;
537 	int nr = 0, kernel = !strcmp("[kernel]", self->name);
538 
539 	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
540 	if (elf == NULL) {
541 		if (verbose)
542 			fprintf(stderr, "%s: cannot read %s ELF file.\n",
543 				__func__, name);
544 		goto out_close;
545 	}
546 
547 	if (gelf_getehdr(elf, &ehdr) == NULL) {
548 		if (verbose)
549 			fprintf(stderr, "%s: cannot get elf header.\n", __func__);
550 		goto out_elf_end;
551 	}
552 
553 	sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
554 	if (sec == NULL) {
555 		sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
556 		if (sec == NULL)
557 			goto out_elf_end;
558 	}
559 
560 	syms = elf_getdata(sec, NULL);
561 	if (syms == NULL)
562 		goto out_elf_end;
563 
564 	sec = elf_getscn(elf, shdr.sh_link);
565 	if (sec == NULL)
566 		goto out_elf_end;
567 
568 	symstrs = elf_getdata(sec, NULL);
569 	if (symstrs == NULL)
570 		goto out_elf_end;
571 
572 	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
573 	if (sec_strndx == NULL)
574 		goto out_elf_end;
575 
576 	secstrs = elf_getdata(sec_strndx, NULL);
577 	if (secstrs == NULL)
578 		goto out_elf_end;
579 
580 	nr_syms = shdr.sh_size / shdr.sh_entsize;
581 
582 	memset(&sym, 0, sizeof(sym));
583 	if (!kernel) {
584 		self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
585 				elf_section_by_name(elf, &ehdr, &shdr,
586 						     ".gnu.prelink_undo",
587 						     NULL) != NULL);
588 	} else self->adjust_symbols = 0;
589 
590 	elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
591 		struct symbol *f;
592 		const char *name;
593 		char *demangled;
594 		u64 obj_start;
595 		struct section *section = NULL;
596 		int is_label = elf_sym__is_label(&sym);
597 		const char *section_name;
598 
599 		if (!is_label && !elf_sym__is_function(&sym))
600 			continue;
601 
602 		sec = elf_getscn(elf, sym.st_shndx);
603 		if (!sec)
604 			goto out_elf_end;
605 
606 		gelf_getshdr(sec, &shdr);
607 
608 		if (is_label && !elf_sec__is_text(&shdr, secstrs))
609 			continue;
610 
611 		section_name = elf_sec__name(&shdr, secstrs);
612 		obj_start = sym.st_value;
613 
614 		if (self->adjust_symbols) {
615 			if (verbose >= 2)
616 				printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
617 					(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
618 
619 			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
620 		}
621 
622 		if (mod) {
623 			section = mod->sections->find_section(mod->sections, section_name);
624 			if (section)
625 				sym.st_value += section->vma;
626 			else {
627 				fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n",
628 					mod->name, section_name);
629 				goto out_elf_end;
630 			}
631 		}
632 		/*
633 		 * We need to figure out if the object was created from C++ sources
634 		 * DWARF DW_compile_unit has this, but we don't always have access
635 		 * to it...
636 		 */
637 		name = elf_sym__name(&sym, symstrs);
638 		demangled = bfd_demangle(NULL, name, DMGL_PARAMS | DMGL_ANSI);
639 		if (demangled != NULL)
640 			name = demangled;
641 
642 		f = symbol__new(sym.st_value, sym.st_size, name,
643 				self->sym_priv_size, obj_start, verbose);
644 		free(demangled);
645 		if (!f)
646 			goto out_elf_end;
647 
648 		if (filter && filter(self, f))
649 			symbol__delete(f, self->sym_priv_size);
650 		else {
651 			f->module = mod;
652 			dso__insert_symbol(self, f);
653 			nr++;
654 		}
655 	}
656 
657 	err = nr;
658 out_elf_end:
659 	elf_end(elf);
660 out_close:
661 	return err;
662 }
663 
664 #define BUILD_ID_SIZE 128
665 
666 static char *dso__read_build_id(struct dso *self, int verbose)
667 {
668 	int i;
669 	GElf_Ehdr ehdr;
670 	GElf_Shdr shdr;
671 	Elf_Data *build_id_data;
672 	Elf_Scn *sec;
673 	char *build_id = NULL, *bid;
674 	unsigned char *raw;
675 	Elf *elf;
676 	int fd = open(self->name, O_RDONLY);
677 
678 	if (fd < 0)
679 		goto out;
680 
681 	elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
682 	if (elf == NULL) {
683 		if (verbose)
684 			fprintf(stderr, "%s: cannot read %s ELF file.\n",
685 				__func__, self->name);
686 		goto out_close;
687 	}
688 
689 	if (gelf_getehdr(elf, &ehdr) == NULL) {
690 		if (verbose)
691 			fprintf(stderr, "%s: cannot get elf header.\n", __func__);
692 		goto out_elf_end;
693 	}
694 
695 	sec = elf_section_by_name(elf, &ehdr, &shdr, ".note.gnu.build-id", NULL);
696 	if (sec == NULL)
697 		goto out_elf_end;
698 
699 	build_id_data = elf_getdata(sec, NULL);
700 	if (build_id_data == NULL)
701 		goto out_elf_end;
702 	build_id = malloc(BUILD_ID_SIZE);
703 	if (build_id == NULL)
704 		goto out_elf_end;
705 	raw = build_id_data->d_buf + 16;
706 	bid = build_id;
707 
708 	for (i = 0; i < 20; ++i) {
709 		sprintf(bid, "%02x", *raw);
710 		++raw;
711 		bid += 2;
712 	}
713 	if (verbose)
714 		printf("%s(%s): %s\n", __func__, self->name, build_id);
715 out_elf_end:
716 	elf_end(elf);
717 out_close:
718 	close(fd);
719 out:
720 	return build_id;
721 }
722 
723 int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
724 {
725 	int size = PATH_MAX;
726 	char *name = malloc(size), *build_id = NULL;
727 	int variant = 0;
728 	int ret = -1;
729 	int fd;
730 
731 	if (!name)
732 		return -1;
733 
734 	self->adjust_symbols = 0;
735 
736 	if (strncmp(self->name, "/tmp/perf-", 10) == 0)
737 		return dso__load_perf_map(self, filter, verbose);
738 
739 more:
740 	do {
741 		switch (variant) {
742 		case 0: /* Fedora */
743 			snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
744 			break;
745 		case 1: /* Ubuntu */
746 			snprintf(name, size, "/usr/lib/debug%s", self->name);
747 			break;
748 		case 2:
749 			build_id = dso__read_build_id(self, verbose);
750 			if (build_id != NULL) {
751 				snprintf(name, size,
752 					 "/usr/lib/debug/.build-id/%.2s/%s.debug",
753 					build_id, build_id + 2);
754 				free(build_id);
755 				break;
756 			}
757 			variant++;
758 			/* Fall thru */
759 		case 3: /* Sane people */
760 			snprintf(name, size, "%s", self->name);
761 			break;
762 
763 		default:
764 			goto out;
765 		}
766 		variant++;
767 
768 		fd = open(name, O_RDONLY);
769 	} while (fd < 0);
770 
771 	ret = dso__load_sym(self, fd, name, filter, verbose, NULL);
772 	close(fd);
773 
774 	/*
775 	 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
776 	 */
777 	if (!ret)
778 		goto more;
779 
780 	if (ret > 0) {
781 		int nr_plt = dso__synthesize_plt_symbols(self, verbose);
782 		if (nr_plt > 0)
783 			ret += nr_plt;
784 	}
785 out:
786 	free(name);
787 	return ret;
788 }
789 
790 static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name,
791 			     symbol_filter_t filter, int verbose)
792 {
793 	struct module *mod = mod_dso__find_module(mods, name);
794 	int err = 0, fd;
795 
796 	if (mod == NULL || !mod->active)
797 		return err;
798 
799 	fd = open(mod->path, O_RDONLY);
800 
801 	if (fd < 0)
802 		return err;
803 
804 	err = dso__load_sym(self, fd, name, filter, verbose, mod);
805 	close(fd);
806 
807 	return err;
808 }
809 
810 int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose)
811 {
812 	struct mod_dso *mods = mod_dso__new_dso("modules");
813 	struct module *pos;
814 	struct rb_node *next;
815 	int err;
816 
817 	err = mod_dso__load_modules(mods);
818 
819 	if (err <= 0)
820 		return err;
821 
822 	/*
823 	 * Iterate over modules, and load active symbols.
824 	 */
825 	next = rb_first(&mods->mods);
826 	while (next) {
827 		pos = rb_entry(next, struct module, rb_node);
828 		err = dso__load_module(self, mods, pos->name, filter, verbose);
829 
830 		if (err < 0)
831 			break;
832 
833 		next = rb_next(&pos->rb_node);
834 	}
835 
836 	if (err < 0) {
837 		mod_dso__delete_modules(mods);
838 		mod_dso__delete_self(mods);
839 	}
840 
841 	return err;
842 }
843 
844 static inline void dso__fill_symbol_holes(struct dso *self)
845 {
846 	struct symbol *prev = NULL;
847 	struct rb_node *nd;
848 
849 	for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) {
850 		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
851 
852 		if (prev) {
853 			u64 hole = 0;
854 			int alias = pos->start == prev->start;
855 
856 			if (!alias)
857 				hole = prev->start - pos->end - 1;
858 
859 			if (hole || alias) {
860 				if (alias)
861 					pos->end = prev->end;
862 				else if (hole)
863 					pos->end = prev->start - 1;
864 			}
865 		}
866 		prev = pos;
867 	}
868 }
869 
870 static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
871 			     symbol_filter_t filter, int verbose)
872 {
873 	int err, fd = open(vmlinux, O_RDONLY);
874 
875 	if (fd < 0)
876 		return -1;
877 
878 	err = dso__load_sym(self, fd, vmlinux, filter, verbose, NULL);
879 
880 	if (err > 0)
881 		dso__fill_symbol_holes(self);
882 
883 	close(fd);
884 
885 	return err;
886 }
887 
888 int dso__load_kernel(struct dso *self, const char *vmlinux,
889 		     symbol_filter_t filter, int verbose, int modules)
890 {
891 	int err = -1;
892 
893 	if (vmlinux) {
894 		err = dso__load_vmlinux(self, vmlinux, filter, verbose);
895 		if (err > 0 && modules)
896 			err = dso__load_modules(self, filter, verbose);
897 	}
898 
899 	if (err <= 0)
900 		err = dso__load_kallsyms(self, filter, verbose);
901 
902 	return err;
903 }
904 
905 void symbol__init(void)
906 {
907 	elf_version(EV_CURRENT);
908 }
909