Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
symbol-elf.c
Go to the documentation of this file.
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 
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,
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 
532 {
533  return ss->dynsym || ss->opdsec;
534 }
535 
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) {
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 
839 {
840  elf_version(EV_CURRENT);
841 }