xref: /openbmc/linux/tools/perf/util/symbol-elf.c (revision 54cbac81)
1 #include <libelf.h>
2 #include <gelf.h>
3 #include <elf.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <inttypes.h>
10 
11 #include "symbol.h"
12 #include "debug.h"
13 
14 #ifndef NT_GNU_BUILD_ID
15 #define NT_GNU_BUILD_ID 3
16 #endif
17 
18 /**
19  * elf_symtab__for_each_symbol - iterate thru all the symbols
20  *
21  * @syms: struct elf_symtab instance to iterate
22  * @idx: uint32_t idx
23  * @sym: GElf_Sym iterator
24  */
25 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
26 	for (idx = 0, gelf_getsym(syms, idx, &sym);\
27 	     idx < nr_syms; \
28 	     idx++, gelf_getsym(syms, idx, &sym))
29 
30 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
31 {
32 	return GELF_ST_TYPE(sym->st_info);
33 }
34 
35 static inline int elf_sym__is_function(const GElf_Sym *sym)
36 {
37 	return elf_sym__type(sym) == STT_FUNC &&
38 	       sym->st_name != 0 &&
39 	       sym->st_shndx != SHN_UNDEF;
40 }
41 
42 static inline bool elf_sym__is_object(const GElf_Sym *sym)
43 {
44 	return elf_sym__type(sym) == STT_OBJECT &&
45 		sym->st_name != 0 &&
46 		sym->st_shndx != SHN_UNDEF;
47 }
48 
49 static inline int elf_sym__is_label(const GElf_Sym *sym)
50 {
51 	return elf_sym__type(sym) == STT_NOTYPE &&
52 		sym->st_name != 0 &&
53 		sym->st_shndx != SHN_UNDEF &&
54 		sym->st_shndx != SHN_ABS;
55 }
56 
57 static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type)
58 {
59 	switch (type) {
60 	case MAP__FUNCTION:
61 		return elf_sym__is_function(sym);
62 	case MAP__VARIABLE:
63 		return elf_sym__is_object(sym);
64 	default:
65 		return false;
66 	}
67 }
68 
69 static inline const char *elf_sym__name(const GElf_Sym *sym,
70 					const Elf_Data *symstrs)
71 {
72 	return symstrs->d_buf + sym->st_name;
73 }
74 
75 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
76 					const Elf_Data *secstrs)
77 {
78 	return secstrs->d_buf + shdr->sh_name;
79 }
80 
81 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
82 					const Elf_Data *secstrs)
83 {
84 	return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
85 }
86 
87 static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
88 				    const Elf_Data *secstrs)
89 {
90 	return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
91 }
92 
93 static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs,
94 			  enum map_type type)
95 {
96 	switch (type) {
97 	case MAP__FUNCTION:
98 		return elf_sec__is_text(shdr, secstrs);
99 	case MAP__VARIABLE:
100 		return elf_sec__is_data(shdr, secstrs);
101 	default:
102 		return false;
103 	}
104 }
105 
106 static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
107 {
108 	Elf_Scn *sec = NULL;
109 	GElf_Shdr shdr;
110 	size_t cnt = 1;
111 
112 	while ((sec = elf_nextscn(elf, sec)) != NULL) {
113 		gelf_getshdr(sec, &shdr);
114 
115 		if ((addr >= shdr.sh_addr) &&
116 		    (addr < (shdr.sh_addr + shdr.sh_size)))
117 			return cnt;
118 
119 		++cnt;
120 	}
121 
122 	return -1;
123 }
124 
125 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
126 				    GElf_Shdr *shp, const char *name,
127 				    size_t *idx)
128 {
129 	Elf_Scn *sec = NULL;
130 	size_t cnt = 1;
131 
132 	/* Elf is corrupted/truncated, avoid calling elf_strptr. */
133 	if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL))
134 		return NULL;
135 
136 	while ((sec = elf_nextscn(elf, sec)) != NULL) {
137 		char *str;
138 
139 		gelf_getshdr(sec, shp);
140 		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
141 		if (!strcmp(name, str)) {
142 			if (idx)
143 				*idx = cnt;
144 			break;
145 		}
146 		++cnt;
147 	}
148 
149 	return sec;
150 }
151 
152 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
153 	for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
154 	     idx < nr_entries; \
155 	     ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
156 
157 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
158 	for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
159 	     idx < nr_entries; \
160 	     ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
161 
162 /*
163  * We need to check if we have a .dynsym, so that we can handle the
164  * .plt, synthesizing its symbols, that aren't on the symtabs (be it
165  * .dynsym or .symtab).
166  * And always look at the original dso, not at debuginfo packages, that
167  * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
168  */
169 int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *map,
170 				symbol_filter_t filter)
171 {
172 	uint32_t nr_rel_entries, idx;
173 	GElf_Sym sym;
174 	u64 plt_offset;
175 	GElf_Shdr shdr_plt;
176 	struct symbol *f;
177 	GElf_Shdr shdr_rel_plt, shdr_dynsym;
178 	Elf_Data *reldata, *syms, *symstrs;
179 	Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
180 	size_t dynsym_idx;
181 	GElf_Ehdr ehdr;
182 	char sympltname[1024];
183 	Elf *elf;
184 	int nr = 0, symidx, err = 0;
185 
186 	if (!ss->dynsym)
187 		return 0;
188 
189 	elf = ss->elf;
190 	ehdr = ss->ehdr;
191 
192 	scn_dynsym = ss->dynsym;
193 	shdr_dynsym = ss->dynshdr;
194 	dynsym_idx = ss->dynsym_idx;
195 
196 	if (scn_dynsym == NULL)
197 		goto out_elf_end;
198 
199 	scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
200 					  ".rela.plt", NULL);
201 	if (scn_plt_rel == NULL) {
202 		scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
203 						  ".rel.plt", NULL);
204 		if (scn_plt_rel == NULL)
205 			goto out_elf_end;
206 	}
207 
208 	err = -1;
209 
210 	if (shdr_rel_plt.sh_link != dynsym_idx)
211 		goto out_elf_end;
212 
213 	if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
214 		goto out_elf_end;
215 
216 	/*
217 	 * Fetch the relocation section to find the idxes to the GOT
218 	 * and the symbols in the .dynsym they refer to.
219 	 */
220 	reldata = elf_getdata(scn_plt_rel, NULL);
221 	if (reldata == NULL)
222 		goto out_elf_end;
223 
224 	syms = elf_getdata(scn_dynsym, NULL);
225 	if (syms == NULL)
226 		goto out_elf_end;
227 
228 	scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
229 	if (scn_symstrs == NULL)
230 		goto out_elf_end;
231 
232 	symstrs = elf_getdata(scn_symstrs, NULL);
233 	if (symstrs == NULL)
234 		goto out_elf_end;
235 
236 	if (symstrs->d_size == 0)
237 		goto out_elf_end;
238 
239 	nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
240 	plt_offset = shdr_plt.sh_offset;
241 
242 	if (shdr_rel_plt.sh_type == SHT_RELA) {
243 		GElf_Rela pos_mem, *pos;
244 
245 		elf_section__for_each_rela(reldata, pos, pos_mem, idx,
246 					   nr_rel_entries) {
247 			symidx = GELF_R_SYM(pos->r_info);
248 			plt_offset += shdr_plt.sh_entsize;
249 			gelf_getsym(syms, symidx, &sym);
250 			snprintf(sympltname, sizeof(sympltname),
251 				 "%s@plt", elf_sym__name(&sym, symstrs));
252 
253 			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
254 					STB_GLOBAL, sympltname);
255 			if (!f)
256 				goto out_elf_end;
257 
258 			if (filter && filter(map, f))
259 				symbol__delete(f);
260 			else {
261 				symbols__insert(&dso->symbols[map->type], f);
262 				++nr;
263 			}
264 		}
265 	} else if (shdr_rel_plt.sh_type == SHT_REL) {
266 		GElf_Rel pos_mem, *pos;
267 		elf_section__for_each_rel(reldata, pos, pos_mem, idx,
268 					  nr_rel_entries) {
269 			symidx = GELF_R_SYM(pos->r_info);
270 			plt_offset += shdr_plt.sh_entsize;
271 			gelf_getsym(syms, symidx, &sym);
272 			snprintf(sympltname, sizeof(sympltname),
273 				 "%s@plt", elf_sym__name(&sym, symstrs));
274 
275 			f = symbol__new(plt_offset, shdr_plt.sh_entsize,
276 					STB_GLOBAL, sympltname);
277 			if (!f)
278 				goto out_elf_end;
279 
280 			if (filter && filter(map, f))
281 				symbol__delete(f);
282 			else {
283 				symbols__insert(&dso->symbols[map->type], f);
284 				++nr;
285 			}
286 		}
287 	}
288 
289 	err = 0;
290 out_elf_end:
291 	if (err == 0)
292 		return nr;
293 	pr_debug("%s: problems reading %s PLT info.\n",
294 		 __func__, dso->long_name);
295 	return 0;
296 }
297 
298 /*
299  * Align offset to 4 bytes as needed for note name and descriptor data.
300  */
301 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
302 
303 static int elf_read_build_id(Elf *elf, void *bf, size_t size)
304 {
305 	int err = -1;
306 	GElf_Ehdr ehdr;
307 	GElf_Shdr shdr;
308 	Elf_Data *data;
309 	Elf_Scn *sec;
310 	Elf_Kind ek;
311 	void *ptr;
312 
313 	if (size < BUILD_ID_SIZE)
314 		goto out;
315 
316 	ek = elf_kind(elf);
317 	if (ek != ELF_K_ELF)
318 		goto out;
319 
320 	if (gelf_getehdr(elf, &ehdr) == NULL) {
321 		pr_err("%s: cannot get elf header.\n", __func__);
322 		goto out;
323 	}
324 
325 	/*
326 	 * Check following sections for notes:
327 	 *   '.note.gnu.build-id'
328 	 *   '.notes'
329 	 *   '.note' (VDSO specific)
330 	 */
331 	do {
332 		sec = elf_section_by_name(elf, &ehdr, &shdr,
333 					  ".note.gnu.build-id", NULL);
334 		if (sec)
335 			break;
336 
337 		sec = elf_section_by_name(elf, &ehdr, &shdr,
338 					  ".notes", NULL);
339 		if (sec)
340 			break;
341 
342 		sec = elf_section_by_name(elf, &ehdr, &shdr,
343 					  ".note", NULL);
344 		if (sec)
345 			break;
346 
347 		return err;
348 
349 	} while (0);
350 
351 	data = elf_getdata(sec, NULL);
352 	if (data == NULL)
353 		goto out;
354 
355 	ptr = data->d_buf;
356 	while (ptr < (data->d_buf + data->d_size)) {
357 		GElf_Nhdr *nhdr = ptr;
358 		size_t namesz = NOTE_ALIGN(nhdr->n_namesz),
359 		       descsz = NOTE_ALIGN(nhdr->n_descsz);
360 		const char *name;
361 
362 		ptr += sizeof(*nhdr);
363 		name = ptr;
364 		ptr += namesz;
365 		if (nhdr->n_type == NT_GNU_BUILD_ID &&
366 		    nhdr->n_namesz == sizeof("GNU")) {
367 			if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
368 				size_t sz = min(size, descsz);
369 				memcpy(bf, ptr, sz);
370 				memset(bf + sz, 0, size - sz);
371 				err = descsz;
372 				break;
373 			}
374 		}
375 		ptr += descsz;
376 	}
377 
378 out:
379 	return err;
380 }
381 
382 int filename__read_build_id(const char *filename, void *bf, size_t size)
383 {
384 	int fd, err = -1;
385 	Elf *elf;
386 
387 	if (size < BUILD_ID_SIZE)
388 		goto out;
389 
390 	fd = open(filename, O_RDONLY);
391 	if (fd < 0)
392 		goto out;
393 
394 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
395 	if (elf == NULL) {
396 		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
397 		goto out_close;
398 	}
399 
400 	err = elf_read_build_id(elf, bf, size);
401 
402 	elf_end(elf);
403 out_close:
404 	close(fd);
405 out:
406 	return err;
407 }
408 
409 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
410 {
411 	int fd, err = -1;
412 
413 	if (size < BUILD_ID_SIZE)
414 		goto out;
415 
416 	fd = open(filename, O_RDONLY);
417 	if (fd < 0)
418 		goto out;
419 
420 	while (1) {
421 		char bf[BUFSIZ];
422 		GElf_Nhdr nhdr;
423 		size_t namesz, descsz;
424 
425 		if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
426 			break;
427 
428 		namesz = NOTE_ALIGN(nhdr.n_namesz);
429 		descsz = NOTE_ALIGN(nhdr.n_descsz);
430 		if (nhdr.n_type == NT_GNU_BUILD_ID &&
431 		    nhdr.n_namesz == sizeof("GNU")) {
432 			if (read(fd, bf, namesz) != (ssize_t)namesz)
433 				break;
434 			if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
435 				size_t sz = min(descsz, size);
436 				if (read(fd, build_id, sz) == (ssize_t)sz) {
437 					memset(build_id + sz, 0, size - sz);
438 					err = 0;
439 					break;
440 				}
441 			} else if (read(fd, bf, descsz) != (ssize_t)descsz)
442 				break;
443 		} else {
444 			int n = namesz + descsz;
445 			if (read(fd, bf, n) != n)
446 				break;
447 		}
448 	}
449 	close(fd);
450 out:
451 	return err;
452 }
453 
454 int filename__read_debuglink(const char *filename, char *debuglink,
455 			     size_t size)
456 {
457 	int fd, err = -1;
458 	Elf *elf;
459 	GElf_Ehdr ehdr;
460 	GElf_Shdr shdr;
461 	Elf_Data *data;
462 	Elf_Scn *sec;
463 	Elf_Kind ek;
464 
465 	fd = open(filename, O_RDONLY);
466 	if (fd < 0)
467 		goto out;
468 
469 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
470 	if (elf == NULL) {
471 		pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
472 		goto out_close;
473 	}
474 
475 	ek = elf_kind(elf);
476 	if (ek != ELF_K_ELF)
477 		goto out_close;
478 
479 	if (gelf_getehdr(elf, &ehdr) == NULL) {
480 		pr_err("%s: cannot get elf header.\n", __func__);
481 		goto out_close;
482 	}
483 
484 	sec = elf_section_by_name(elf, &ehdr, &shdr,
485 				  ".gnu_debuglink", NULL);
486 	if (sec == NULL)
487 		goto out_close;
488 
489 	data = elf_getdata(sec, NULL);
490 	if (data == NULL)
491 		goto out_close;
492 
493 	/* the start of this section is a zero-terminated string */
494 	strncpy(debuglink, data->d_buf, size);
495 
496 	elf_end(elf);
497 
498 out_close:
499 	close(fd);
500 out:
501 	return err;
502 }
503 
504 static int dso__swap_init(struct dso *dso, unsigned char eidata)
505 {
506 	static unsigned int const endian = 1;
507 
508 	dso->needs_swap = DSO_SWAP__NO;
509 
510 	switch (eidata) {
511 	case ELFDATA2LSB:
512 		/* We are big endian, DSO is little endian. */
513 		if (*(unsigned char const *)&endian != 1)
514 			dso->needs_swap = DSO_SWAP__YES;
515 		break;
516 
517 	case ELFDATA2MSB:
518 		/* We are little endian, DSO is big endian. */
519 		if (*(unsigned char const *)&endian != 0)
520 			dso->needs_swap = DSO_SWAP__YES;
521 		break;
522 
523 	default:
524 		pr_err("unrecognized DSO data encoding %d\n", eidata);
525 		return -EINVAL;
526 	}
527 
528 	return 0;
529 }
530 
531 bool symsrc__possibly_runtime(struct symsrc *ss)
532 {
533 	return ss->dynsym || ss->opdsec;
534 }
535 
536 bool symsrc__has_symtab(struct symsrc *ss)
537 {
538 	return ss->symtab != NULL;
539 }
540 
541 void symsrc__destroy(struct symsrc *ss)
542 {
543 	free(ss->name);
544 	elf_end(ss->elf);
545 	close(ss->fd);
546 }
547 
548 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
549 		 enum dso_binary_type type)
550 {
551 	int err = -1;
552 	GElf_Ehdr ehdr;
553 	Elf *elf;
554 	int fd;
555 
556 	fd = open(name, O_RDONLY);
557 	if (fd < 0)
558 		return -1;
559 
560 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
561 	if (elf == NULL) {
562 		pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
563 		goto out_close;
564 	}
565 
566 	if (gelf_getehdr(elf, &ehdr) == NULL) {
567 		pr_debug("%s: cannot get elf header.\n", __func__);
568 		goto out_elf_end;
569 	}
570 
571 	if (dso__swap_init(dso, ehdr.e_ident[EI_DATA]))
572 		goto out_elf_end;
573 
574 	/* Always reject images with a mismatched build-id: */
575 	if (dso->has_build_id) {
576 		u8 build_id[BUILD_ID_SIZE];
577 
578 		if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0)
579 			goto out_elf_end;
580 
581 		if (!dso__build_id_equal(dso, build_id))
582 			goto out_elf_end;
583 	}
584 
585 	ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",
586 			NULL);
587 	if (ss->symshdr.sh_type != SHT_SYMTAB)
588 		ss->symtab = NULL;
589 
590 	ss->dynsym_idx = 0;
591 	ss->dynsym = elf_section_by_name(elf, &ehdr, &ss->dynshdr, ".dynsym",
592 			&ss->dynsym_idx);
593 	if (ss->dynshdr.sh_type != SHT_DYNSYM)
594 		ss->dynsym = NULL;
595 
596 	ss->opdidx = 0;
597 	ss->opdsec = elf_section_by_name(elf, &ehdr, &ss->opdshdr, ".opd",
598 			&ss->opdidx);
599 	if (ss->opdshdr.sh_type != SHT_PROGBITS)
600 		ss->opdsec = NULL;
601 
602 	if (dso->kernel == DSO_TYPE_USER) {
603 		GElf_Shdr shdr;
604 		ss->adjust_symbols = (ehdr.e_type == ET_EXEC ||
605 				elf_section_by_name(elf, &ehdr, &shdr,
606 						     ".gnu.prelink_undo",
607 						     NULL) != NULL);
608 	} else {
609 		ss->adjust_symbols = 0;
610 	}
611 
612 	ss->name   = strdup(name);
613 	if (!ss->name)
614 		goto out_elf_end;
615 
616 	ss->elf    = elf;
617 	ss->fd     = fd;
618 	ss->ehdr   = ehdr;
619 	ss->type   = type;
620 
621 	return 0;
622 
623 out_elf_end:
624 	elf_end(elf);
625 out_close:
626 	close(fd);
627 	return err;
628 }
629 
630 int dso__load_sym(struct dso *dso, struct map *map,
631 		  struct symsrc *syms_ss, struct symsrc *runtime_ss,
632 		  symbol_filter_t filter, int kmodule)
633 {
634 	struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
635 	struct map *curr_map = map;
636 	struct dso *curr_dso = dso;
637 	Elf_Data *symstrs, *secstrs;
638 	uint32_t nr_syms;
639 	int err = -1;
640 	uint32_t idx;
641 	GElf_Ehdr ehdr;
642 	GElf_Shdr shdr;
643 	Elf_Data *syms, *opddata = NULL;
644 	GElf_Sym sym;
645 	Elf_Scn *sec, *sec_strndx;
646 	Elf *elf;
647 	int nr = 0;
648 
649 	dso->symtab_type = syms_ss->type;
650 
651 	if (!syms_ss->symtab) {
652 		syms_ss->symtab  = syms_ss->dynsym;
653 		syms_ss->symshdr = syms_ss->dynshdr;
654 	}
655 
656 	elf = syms_ss->elf;
657 	ehdr = syms_ss->ehdr;
658 	sec = syms_ss->symtab;
659 	shdr = syms_ss->symshdr;
660 
661 	if (runtime_ss->opdsec)
662 		opddata = elf_rawdata(runtime_ss->opdsec, NULL);
663 
664 	syms = elf_getdata(sec, NULL);
665 	if (syms == NULL)
666 		goto out_elf_end;
667 
668 	sec = elf_getscn(elf, shdr.sh_link);
669 	if (sec == NULL)
670 		goto out_elf_end;
671 
672 	symstrs = elf_getdata(sec, NULL);
673 	if (symstrs == NULL)
674 		goto out_elf_end;
675 
676 	sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
677 	if (sec_strndx == NULL)
678 		goto out_elf_end;
679 
680 	secstrs = elf_getdata(sec_strndx, NULL);
681 	if (secstrs == NULL)
682 		goto out_elf_end;
683 
684 	nr_syms = shdr.sh_size / shdr.sh_entsize;
685 
686 	memset(&sym, 0, sizeof(sym));
687 	dso->adjust_symbols = runtime_ss->adjust_symbols;
688 	elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
689 		struct symbol *f;
690 		const char *elf_name = elf_sym__name(&sym, symstrs);
691 		char *demangled = NULL;
692 		int is_label = elf_sym__is_label(&sym);
693 		const char *section_name;
694 		bool used_opd = false;
695 
696 		if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
697 		    strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
698 			kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
699 
700 		if (!is_label && !elf_sym__is_a(&sym, map->type))
701 			continue;
702 
703 		/* Reject ARM ELF "mapping symbols": these aren't unique and
704 		 * don't identify functions, so will confuse the profile
705 		 * output: */
706 		if (ehdr.e_machine == EM_ARM) {
707 			if (!strcmp(elf_name, "$a") ||
708 			    !strcmp(elf_name, "$d") ||
709 			    !strcmp(elf_name, "$t"))
710 				continue;
711 		}
712 
713 		if (runtime_ss->opdsec && sym.st_shndx == runtime_ss->opdidx) {
714 			u32 offset = sym.st_value - syms_ss->opdshdr.sh_addr;
715 			u64 *opd = opddata->d_buf + offset;
716 			sym.st_value = DSO__SWAP(dso, u64, *opd);
717 			sym.st_shndx = elf_addr_to_index(runtime_ss->elf,
718 					sym.st_value);
719 			used_opd = true;
720 		}
721 
722 		sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
723 		if (!sec)
724 			goto out_elf_end;
725 
726 		gelf_getshdr(sec, &shdr);
727 
728 		if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
729 			continue;
730 
731 		section_name = elf_sec__name(&shdr, secstrs);
732 
733 		/* On ARM, symbols for thumb functions have 1 added to
734 		 * the symbol address as a flag - remove it */
735 		if ((ehdr.e_machine == EM_ARM) &&
736 		    (map->type == MAP__FUNCTION) &&
737 		    (sym.st_value & 1))
738 			--sym.st_value;
739 
740 		if (dso->kernel != DSO_TYPE_USER || kmodule) {
741 			char dso_name[PATH_MAX];
742 
743 			if (strcmp(section_name,
744 				   (curr_dso->short_name +
745 				    dso->short_name_len)) == 0)
746 				goto new_symbol;
747 
748 			if (strcmp(section_name, ".text") == 0) {
749 				curr_map = map;
750 				curr_dso = dso;
751 				goto new_symbol;
752 			}
753 
754 			snprintf(dso_name, sizeof(dso_name),
755 				 "%s%s", dso->short_name, section_name);
756 
757 			curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
758 			if (curr_map == NULL) {
759 				u64 start = sym.st_value;
760 
761 				if (kmodule)
762 					start += map->start + shdr.sh_offset;
763 
764 				curr_dso = dso__new(dso_name);
765 				if (curr_dso == NULL)
766 					goto out_elf_end;
767 				curr_dso->kernel = dso->kernel;
768 				curr_dso->long_name = dso->long_name;
769 				curr_dso->long_name_len = dso->long_name_len;
770 				curr_map = map__new2(start, curr_dso,
771 						     map->type);
772 				if (curr_map == NULL) {
773 					dso__delete(curr_dso);
774 					goto out_elf_end;
775 				}
776 				curr_map->map_ip = identity__map_ip;
777 				curr_map->unmap_ip = identity__map_ip;
778 				curr_dso->symtab_type = dso->symtab_type;
779 				map_groups__insert(kmap->kmaps, curr_map);
780 				dsos__add(&dso->node, curr_dso);
781 				dso__set_loaded(curr_dso, map->type);
782 			} else
783 				curr_dso = curr_map->dso;
784 
785 			goto new_symbol;
786 		}
787 
788 		if ((used_opd && runtime_ss->adjust_symbols)
789 				|| (!used_opd && syms_ss->adjust_symbols)) {
790 			pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
791 				  "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
792 				  (u64)sym.st_value, (u64)shdr.sh_addr,
793 				  (u64)shdr.sh_offset);
794 			sym.st_value -= shdr.sh_addr - shdr.sh_offset;
795 		}
796 		/*
797 		 * We need to figure out if the object was created from C++ sources
798 		 * DWARF DW_compile_unit has this, but we don't always have access
799 		 * to it...
800 		 */
801 		demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
802 		if (demangled != NULL)
803 			elf_name = demangled;
804 new_symbol:
805 		f = symbol__new(sym.st_value, sym.st_size,
806 				GELF_ST_BIND(sym.st_info), elf_name);
807 		free(demangled);
808 		if (!f)
809 			goto out_elf_end;
810 
811 		if (filter && filter(curr_map, f))
812 			symbol__delete(f);
813 		else {
814 			symbols__insert(&curr_dso->symbols[curr_map->type], f);
815 			nr++;
816 		}
817 	}
818 
819 	/*
820 	 * For misannotated, zeroed, ASM function sizes.
821 	 */
822 	if (nr > 0) {
823 		symbols__fixup_duplicate(&dso->symbols[map->type]);
824 		symbols__fixup_end(&dso->symbols[map->type]);
825 		if (kmap) {
826 			/*
827 			 * We need to fixup this here too because we create new
828 			 * maps here, for things like vsyscall sections.
829 			 */
830 			__map_groups__fixup_end(kmap->kmaps, map->type);
831 		}
832 	}
833 	err = nr;
834 out_elf_end:
835 	return err;
836 }
837 
838 void symbol__elf_init(void)
839 {
840 	elf_version(EV_CURRENT);
841 }
842