Merge branch 'msm-fixes-3.19' of git://people.freedesktop.org/~robclark/linux into...
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / symbol-elf.c
1 #include <fcntl.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <inttypes.h>
7
8 #include "symbol.h"
9 #include "machine.h"
10 #include "vdso.h"
11 #include <symbol/kallsyms.h>
12 #include "debug.h"
13
14 #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
15 extern char *cplus_demangle(const char *, int);
16
17 static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i)
18 {
19         return cplus_demangle(c, i);
20 }
21 #else
22 #ifdef NO_DEMANGLE
23 static inline char *bfd_demangle(void __maybe_unused *v,
24                                  const char __maybe_unused *c,
25                                  int __maybe_unused i)
26 {
27         return NULL;
28 }
29 #else
30 #define PACKAGE 'perf'
31 #include <bfd.h>
32 #endif
33 #endif
34
35 #ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
36 static int elf_getphdrnum(Elf *elf, size_t *dst)
37 {
38         GElf_Ehdr gehdr;
39         GElf_Ehdr *ehdr;
40
41         ehdr = gelf_getehdr(elf, &gehdr);
42         if (!ehdr)
43                 return -1;
44
45         *dst = ehdr->e_phnum;
46
47         return 0;
48 }
49 #endif
50
51 #ifndef NT_GNU_BUILD_ID
52 #define NT_GNU_BUILD_ID 3
53 #endif
54
55 /**
56  * elf_symtab__for_each_symbol - iterate thru all the symbols
57  *
58  * @syms: struct elf_symtab instance to iterate
59  * @idx: uint32_t idx
60  * @sym: GElf_Sym iterator
61  */
62 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
63         for (idx = 0, gelf_getsym(syms, idx, &sym);\
64              idx < nr_syms; \
65              idx++, gelf_getsym(syms, idx, &sym))
66
67 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
68 {
69         return GELF_ST_TYPE(sym->st_info);
70 }
71
72 static inline int elf_sym__is_function(const GElf_Sym *sym)
73 {
74         return (elf_sym__type(sym) == STT_FUNC ||
75                 elf_sym__type(sym) == STT_GNU_IFUNC) &&
76                sym->st_name != 0 &&
77                sym->st_shndx != SHN_UNDEF;
78 }
79
80 static inline bool elf_sym__is_object(const GElf_Sym *sym)
81 {
82         return elf_sym__type(sym) == STT_OBJECT &&
83                 sym->st_name != 0 &&
84                 sym->st_shndx != SHN_UNDEF;
85 }
86
87 static inline int elf_sym__is_label(const GElf_Sym *sym)
88 {
89         return elf_sym__type(sym) == STT_NOTYPE &&
90                 sym->st_name != 0 &&
91                 sym->st_shndx != SHN_UNDEF &&
92                 sym->st_shndx != SHN_ABS;
93 }
94
95 static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type)
96 {
97         switch (type) {
98         case MAP__FUNCTION:
99                 return elf_sym__is_function(sym);
100         case MAP__VARIABLE:
101                 return elf_sym__is_object(sym);
102         default:
103                 return false;
104         }
105 }
106
107 static inline const char *elf_sym__name(const GElf_Sym *sym,
108                                         const Elf_Data *symstrs)
109 {
110         return symstrs->d_buf + sym->st_name;
111 }
112
113 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
114                                         const Elf_Data *secstrs)
115 {
116         return secstrs->d_buf + shdr->sh_name;
117 }
118
119 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
120                                         const Elf_Data *secstrs)
121 {
122         return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
123 }
124
125 static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
126                                     const Elf_Data *secstrs)
127 {
128         return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
129 }
130
131 static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs,
132                           enum map_type type)
133 {
134         switch (type) {
135         case MAP__FUNCTION:
136                 return elf_sec__is_text(shdr, secstrs);
137         case MAP__VARIABLE:
138                 return elf_sec__is_data(shdr, secstrs);
139         default:
140                 return false;
141         }
142 }
143
144 static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
145 {
146         Elf_Scn *sec = NULL;
147         GElf_Shdr shdr;
148         size_t cnt = 1;
149
150         while ((sec = elf_nextscn(elf, sec)) != NULL) {
151                 gelf_getshdr(sec, &shdr);
152
153                 if ((addr >= shdr.sh_addr) &&
154                     (addr < (shdr.sh_addr + shdr.sh_size)))
155                         return cnt;
156
157                 ++cnt;
158         }
159
160         return -1;
161 }
162
163 Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
164                              GElf_Shdr *shp, const char *name, size_t *idx)
165 {
166         Elf_Scn *sec = NULL;
167         size_t cnt = 1;
168
169         /* Elf is corrupted/truncated, avoid calling elf_strptr. */
170         if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL))
171                 return NULL;
172
173         while ((sec = elf_nextscn(elf, sec)) != NULL) {
174                 char *str;
175
176                 gelf_getshdr(sec, shp);
177                 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
178                 if (str && !strcmp(name, str)) {
179                         if (idx)
180                                 *idx = cnt;
181                         return sec;
182                 }
183                 ++cnt;
184         }
185
186         return NULL;
187 }
188
189 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
190         for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
191              idx < nr_entries; \
192              ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
193
194 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
195         for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
196              idx < nr_entries; \
197              ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
198
199 /*
200  * We need to check if we have a .dynsym, so that we can handle the
201  * .plt, synthesizing its symbols, that aren't on the symtabs (be it
202  * .dynsym or .symtab).
203  * And always look at the original dso, not at debuginfo packages, that
204  * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
205  */
206 int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *map,
207                                 symbol_filter_t filter)
208 {
209         uint32_t nr_rel_entries, idx;
210         GElf_Sym sym;
211         u64 plt_offset;
212         GElf_Shdr shdr_plt;
213         struct symbol *f;
214         GElf_Shdr shdr_rel_plt, shdr_dynsym;
215         Elf_Data *reldata, *syms, *symstrs;
216         Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
217         size_t dynsym_idx;
218         GElf_Ehdr ehdr;
219         char sympltname[1024];
220         Elf *elf;
221         int nr = 0, symidx, err = 0;
222
223         if (!ss->dynsym)
224                 return 0;
225
226         elf = ss->elf;
227         ehdr = ss->ehdr;
228
229         scn_dynsym = ss->dynsym;
230         shdr_dynsym = ss->dynshdr;
231         dynsym_idx = ss->dynsym_idx;
232
233         if (scn_dynsym == NULL)
234                 goto out_elf_end;
235
236         scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
237                                           ".rela.plt", NULL);
238         if (scn_plt_rel == NULL) {
239                 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
240                                                   ".rel.plt", NULL);
241                 if (scn_plt_rel == NULL)
242                         goto out_elf_end;
243         }
244
245         err = -1;
246
247         if (shdr_rel_plt.sh_link != dynsym_idx)
248                 goto out_elf_end;
249
250         if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
251                 goto out_elf_end;
252
253         /*
254          * Fetch the relocation section to find the idxes to the GOT
255          * and the symbols in the .dynsym they refer to.
256          */
257         reldata = elf_getdata(scn_plt_rel, NULL);
258         if (reldata == NULL)
259                 goto out_elf_end;
260
261         syms = elf_getdata(scn_dynsym, NULL);
262         if (syms == NULL)
263                 goto out_elf_end;
264
265         scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
266         if (scn_symstrs == NULL)
267                 goto out_elf_end;
268
269         symstrs = elf_getdata(scn_symstrs, NULL);
270         if (symstrs == NULL)
271                 goto out_elf_end;
272
273         if (symstrs->d_size == 0)
274                 goto out_elf_end;
275
276         nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
277         plt_offset = shdr_plt.sh_offset;
278
279         if (shdr_rel_plt.sh_type == SHT_RELA) {
280                 GElf_Rela pos_mem, *pos;
281
282                 elf_section__for_each_rela(reldata, pos, pos_mem, idx,
283                                            nr_rel_entries) {
284                         symidx = GELF_R_SYM(pos->r_info);
285                         plt_offset += shdr_plt.sh_entsize;
286                         gelf_getsym(syms, symidx, &sym);
287                         snprintf(sympltname, sizeof(sympltname),
288                                  "%s@plt", elf_sym__name(&sym, symstrs));
289
290                         f = symbol__new(plt_offset, shdr_plt.sh_entsize,
291                                         STB_GLOBAL, sympltname);
292                         if (!f)
293                                 goto out_elf_end;
294
295                         if (filter && filter(map, f))
296                                 symbol__delete(f);
297                         else {
298                                 symbols__insert(&dso->symbols[map->type], f);
299                                 ++nr;
300                         }
301                 }
302         } else if (shdr_rel_plt.sh_type == SHT_REL) {
303                 GElf_Rel pos_mem, *pos;
304                 elf_section__for_each_rel(reldata, pos, pos_mem, idx,
305                                           nr_rel_entries) {
306                         symidx = GELF_R_SYM(pos->r_info);
307                         plt_offset += shdr_plt.sh_entsize;
308                         gelf_getsym(syms, symidx, &sym);
309                         snprintf(sympltname, sizeof(sympltname),
310                                  "%s@plt", elf_sym__name(&sym, symstrs));
311
312                         f = symbol__new(plt_offset, shdr_plt.sh_entsize,
313                                         STB_GLOBAL, sympltname);
314                         if (!f)
315                                 goto out_elf_end;
316
317                         if (filter && filter(map, f))
318                                 symbol__delete(f);
319                         else {
320                                 symbols__insert(&dso->symbols[map->type], f);
321                                 ++nr;
322                         }
323                 }
324         }
325
326         err = 0;
327 out_elf_end:
328         if (err == 0)
329                 return nr;
330         pr_debug("%s: problems reading %s PLT info.\n",
331                  __func__, dso->long_name);
332         return 0;
333 }
334
335 /*
336  * Align offset to 4 bytes as needed for note name and descriptor data.
337  */
338 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
339
340 static int elf_read_build_id(Elf *elf, void *bf, size_t size)
341 {
342         int err = -1;
343         GElf_Ehdr ehdr;
344         GElf_Shdr shdr;
345         Elf_Data *data;
346         Elf_Scn *sec;
347         Elf_Kind ek;
348         void *ptr;
349
350         if (size < BUILD_ID_SIZE)
351                 goto out;
352
353         ek = elf_kind(elf);
354         if (ek != ELF_K_ELF)
355                 goto out;
356
357         if (gelf_getehdr(elf, &ehdr) == NULL) {
358                 pr_err("%s: cannot get elf header.\n", __func__);
359                 goto out;
360         }
361
362         /*
363          * Check following sections for notes:
364          *   '.note.gnu.build-id'
365          *   '.notes'
366          *   '.note' (VDSO specific)
367          */
368         do {
369                 sec = elf_section_by_name(elf, &ehdr, &shdr,
370                                           ".note.gnu.build-id", NULL);
371                 if (sec)
372                         break;
373
374                 sec = elf_section_by_name(elf, &ehdr, &shdr,
375                                           ".notes", NULL);
376                 if (sec)
377                         break;
378
379                 sec = elf_section_by_name(elf, &ehdr, &shdr,
380                                           ".note", NULL);
381                 if (sec)
382                         break;
383
384                 return err;
385
386         } while (0);
387
388         data = elf_getdata(sec, NULL);
389         if (data == NULL)
390                 goto out;
391
392         ptr = data->d_buf;
393         while (ptr < (data->d_buf + data->d_size)) {
394                 GElf_Nhdr *nhdr = ptr;
395                 size_t namesz = NOTE_ALIGN(nhdr->n_namesz),
396                        descsz = NOTE_ALIGN(nhdr->n_descsz);
397                 const char *name;
398
399                 ptr += sizeof(*nhdr);
400                 name = ptr;
401                 ptr += namesz;
402                 if (nhdr->n_type == NT_GNU_BUILD_ID &&
403                     nhdr->n_namesz == sizeof("GNU")) {
404                         if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
405                                 size_t sz = min(size, descsz);
406                                 memcpy(bf, ptr, sz);
407                                 memset(bf + sz, 0, size - sz);
408                                 err = descsz;
409                                 break;
410                         }
411                 }
412                 ptr += descsz;
413         }
414
415 out:
416         return err;
417 }
418
419 int filename__read_build_id(const char *filename, void *bf, size_t size)
420 {
421         int fd, err = -1;
422         Elf *elf;
423
424         if (size < BUILD_ID_SIZE)
425                 goto out;
426
427         fd = open(filename, O_RDONLY);
428         if (fd < 0)
429                 goto out;
430
431         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
432         if (elf == NULL) {
433                 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
434                 goto out_close;
435         }
436
437         err = elf_read_build_id(elf, bf, size);
438
439         elf_end(elf);
440 out_close:
441         close(fd);
442 out:
443         return err;
444 }
445
446 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
447 {
448         int fd, err = -1;
449
450         if (size < BUILD_ID_SIZE)
451                 goto out;
452
453         fd = open(filename, O_RDONLY);
454         if (fd < 0)
455                 goto out;
456
457         while (1) {
458                 char bf[BUFSIZ];
459                 GElf_Nhdr nhdr;
460                 size_t namesz, descsz;
461
462                 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
463                         break;
464
465                 namesz = NOTE_ALIGN(nhdr.n_namesz);
466                 descsz = NOTE_ALIGN(nhdr.n_descsz);
467                 if (nhdr.n_type == NT_GNU_BUILD_ID &&
468                     nhdr.n_namesz == sizeof("GNU")) {
469                         if (read(fd, bf, namesz) != (ssize_t)namesz)
470                                 break;
471                         if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
472                                 size_t sz = min(descsz, size);
473                                 if (read(fd, build_id, sz) == (ssize_t)sz) {
474                                         memset(build_id + sz, 0, size - sz);
475                                         err = 0;
476                                         break;
477                                 }
478                         } else if (read(fd, bf, descsz) != (ssize_t)descsz)
479                                 break;
480                 } else {
481                         int n = namesz + descsz;
482                         if (read(fd, bf, n) != n)
483                                 break;
484                 }
485         }
486         close(fd);
487 out:
488         return err;
489 }
490
491 int filename__read_debuglink(const char *filename, char *debuglink,
492                              size_t size)
493 {
494         int fd, err = -1;
495         Elf *elf;
496         GElf_Ehdr ehdr;
497         GElf_Shdr shdr;
498         Elf_Data *data;
499         Elf_Scn *sec;
500         Elf_Kind ek;
501
502         fd = open(filename, O_RDONLY);
503         if (fd < 0)
504                 goto out;
505
506         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
507         if (elf == NULL) {
508                 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
509                 goto out_close;
510         }
511
512         ek = elf_kind(elf);
513         if (ek != ELF_K_ELF)
514                 goto out_elf_end;
515
516         if (gelf_getehdr(elf, &ehdr) == NULL) {
517                 pr_err("%s: cannot get elf header.\n", __func__);
518                 goto out_elf_end;
519         }
520
521         sec = elf_section_by_name(elf, &ehdr, &shdr,
522                                   ".gnu_debuglink", NULL);
523         if (sec == NULL)
524                 goto out_elf_end;
525
526         data = elf_getdata(sec, NULL);
527         if (data == NULL)
528                 goto out_elf_end;
529
530         /* the start of this section is a zero-terminated string */
531         strncpy(debuglink, data->d_buf, size);
532
533         err = 0;
534
535 out_elf_end:
536         elf_end(elf);
537 out_close:
538         close(fd);
539 out:
540         return err;
541 }
542
543 static int dso__swap_init(struct dso *dso, unsigned char eidata)
544 {
545         static unsigned int const endian = 1;
546
547         dso->needs_swap = DSO_SWAP__NO;
548
549         switch (eidata) {
550         case ELFDATA2LSB:
551                 /* We are big endian, DSO is little endian. */
552                 if (*(unsigned char const *)&endian != 1)
553                         dso->needs_swap = DSO_SWAP__YES;
554                 break;
555
556         case ELFDATA2MSB:
557                 /* We are little endian, DSO is big endian. */
558                 if (*(unsigned char const *)&endian != 0)
559                         dso->needs_swap = DSO_SWAP__YES;
560                 break;
561
562         default:
563                 pr_err("unrecognized DSO data encoding %d\n", eidata);
564                 return -EINVAL;
565         }
566
567         return 0;
568 }
569
570 static int decompress_kmodule(struct dso *dso, const char *name,
571                               enum dso_binary_type type)
572 {
573         int fd;
574         const char *ext = strrchr(name, '.');
575         char tmpbuf[] = "/tmp/perf-kmod-XXXXXX";
576
577         if ((type != DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP &&
578              type != DSO_BINARY_TYPE__GUEST_KMODULE_COMP) ||
579             type != dso->symtab_type)
580                 return -1;
581
582         if (!ext || !is_supported_compression(ext + 1))
583                 return -1;
584
585         fd = mkstemp(tmpbuf);
586         if (fd < 0)
587                 return -1;
588
589         if (!decompress_to_file(ext + 1, name, fd)) {
590                 close(fd);
591                 fd = -1;
592         }
593
594         unlink(tmpbuf);
595
596         return fd;
597 }
598
599 bool symsrc__possibly_runtime(struct symsrc *ss)
600 {
601         return ss->dynsym || ss->opdsec;
602 }
603
604 bool symsrc__has_symtab(struct symsrc *ss)
605 {
606         return ss->symtab != NULL;
607 }
608
609 void symsrc__destroy(struct symsrc *ss)
610 {
611         zfree(&ss->name);
612         elf_end(ss->elf);
613         close(ss->fd);
614 }
615
616 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
617                  enum dso_binary_type type)
618 {
619         int err = -1;
620         GElf_Ehdr ehdr;
621         Elf *elf;
622         int fd;
623
624         if (dso__needs_decompress(dso))
625                 fd = decompress_kmodule(dso, name, type);
626         else
627                 fd = open(name, O_RDONLY);
628
629         if (fd < 0)
630                 return -1;
631
632         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
633         if (elf == NULL) {
634                 pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
635                 goto out_close;
636         }
637
638         if (gelf_getehdr(elf, &ehdr) == NULL) {
639                 pr_debug("%s: cannot get elf header.\n", __func__);
640                 goto out_elf_end;
641         }
642
643         if (dso__swap_init(dso, ehdr.e_ident[EI_DATA]))
644                 goto out_elf_end;
645
646         /* Always reject images with a mismatched build-id: */
647         if (dso->has_build_id) {
648                 u8 build_id[BUILD_ID_SIZE];
649
650                 if (elf_read_build_id(elf, build_id, BUILD_ID_SIZE) < 0)
651                         goto out_elf_end;
652
653                 if (!dso__build_id_equal(dso, build_id))
654                         goto out_elf_end;
655         }
656
657         ss->is_64_bit = (gelf_getclass(elf) == ELFCLASS64);
658
659         ss->symtab = elf_section_by_name(elf, &ehdr, &ss->symshdr, ".symtab",
660                         NULL);
661         if (ss->symshdr.sh_type != SHT_SYMTAB)
662                 ss->symtab = NULL;
663
664         ss->dynsym_idx = 0;
665         ss->dynsym = elf_section_by_name(elf, &ehdr, &ss->dynshdr, ".dynsym",
666                         &ss->dynsym_idx);
667         if (ss->dynshdr.sh_type != SHT_DYNSYM)
668                 ss->dynsym = NULL;
669
670         ss->opdidx = 0;
671         ss->opdsec = elf_section_by_name(elf, &ehdr, &ss->opdshdr, ".opd",
672                         &ss->opdidx);
673         if (ss->opdshdr.sh_type != SHT_PROGBITS)
674                 ss->opdsec = NULL;
675
676         if (dso->kernel == DSO_TYPE_USER) {
677                 GElf_Shdr shdr;
678                 ss->adjust_symbols = (ehdr.e_type == ET_EXEC ||
679                                 ehdr.e_type == ET_REL ||
680                                 dso__is_vdso(dso) ||
681                                 elf_section_by_name(elf, &ehdr, &shdr,
682                                                      ".gnu.prelink_undo",
683                                                      NULL) != NULL);
684         } else {
685                 ss->adjust_symbols = ehdr.e_type == ET_EXEC ||
686                                      ehdr.e_type == ET_REL;
687         }
688
689         ss->name   = strdup(name);
690         if (!ss->name)
691                 goto out_elf_end;
692
693         ss->elf    = elf;
694         ss->fd     = fd;
695         ss->ehdr   = ehdr;
696         ss->type   = type;
697
698         return 0;
699
700 out_elf_end:
701         elf_end(elf);
702 out_close:
703         close(fd);
704         return err;
705 }
706
707 /**
708  * ref_reloc_sym_not_found - has kernel relocation symbol been found.
709  * @kmap: kernel maps and relocation reference symbol
710  *
711  * This function returns %true if we are dealing with the kernel maps and the
712  * relocation reference symbol has not yet been found.  Otherwise %false is
713  * returned.
714  */
715 static bool ref_reloc_sym_not_found(struct kmap *kmap)
716 {
717         return kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
718                !kmap->ref_reloc_sym->unrelocated_addr;
719 }
720
721 /**
722  * ref_reloc - kernel relocation offset.
723  * @kmap: kernel maps and relocation reference symbol
724  *
725  * This function returns the offset of kernel addresses as determined by using
726  * the relocation reference symbol i.e. if the kernel has not been relocated
727  * then the return value is zero.
728  */
729 static u64 ref_reloc(struct kmap *kmap)
730 {
731         if (kmap && kmap->ref_reloc_sym &&
732             kmap->ref_reloc_sym->unrelocated_addr)
733                 return kmap->ref_reloc_sym->addr -
734                        kmap->ref_reloc_sym->unrelocated_addr;
735         return 0;
736 }
737
738 static bool want_demangle(bool is_kernel_sym)
739 {
740         return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
741 }
742
743 int dso__load_sym(struct dso *dso, struct map *map,
744                   struct symsrc *syms_ss, struct symsrc *runtime_ss,
745                   symbol_filter_t filter, int kmodule)
746 {
747         struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
748         struct map *curr_map = map;
749         struct dso *curr_dso = dso;
750         Elf_Data *symstrs, *secstrs;
751         uint32_t nr_syms;
752         int err = -1;
753         uint32_t idx;
754         GElf_Ehdr ehdr;
755         GElf_Shdr shdr;
756         Elf_Data *syms, *opddata = NULL;
757         GElf_Sym sym;
758         Elf_Scn *sec, *sec_strndx;
759         Elf *elf;
760         int nr = 0;
761         bool remap_kernel = false, adjust_kernel_syms = false;
762
763         dso->symtab_type = syms_ss->type;
764         dso->is_64_bit = syms_ss->is_64_bit;
765         dso->rel = syms_ss->ehdr.e_type == ET_REL;
766
767         /*
768          * Modules may already have symbols from kallsyms, but those symbols
769          * have the wrong values for the dso maps, so remove them.
770          */
771         if (kmodule && syms_ss->symtab)
772                 symbols__delete(&dso->symbols[map->type]);
773
774         if (!syms_ss->symtab) {
775                 /*
776                  * If the vmlinux is stripped, fail so we will fall back
777                  * to using kallsyms. The vmlinux runtime symbols aren't
778                  * of much use.
779                  */
780                 if (dso->kernel)
781                         goto out_elf_end;
782
783                 syms_ss->symtab  = syms_ss->dynsym;
784                 syms_ss->symshdr = syms_ss->dynshdr;
785         }
786
787         elf = syms_ss->elf;
788         ehdr = syms_ss->ehdr;
789         sec = syms_ss->symtab;
790         shdr = syms_ss->symshdr;
791
792         if (runtime_ss->opdsec)
793                 opddata = elf_rawdata(runtime_ss->opdsec, NULL);
794
795         syms = elf_getdata(sec, NULL);
796         if (syms == NULL)
797                 goto out_elf_end;
798
799         sec = elf_getscn(elf, shdr.sh_link);
800         if (sec == NULL)
801                 goto out_elf_end;
802
803         symstrs = elf_getdata(sec, NULL);
804         if (symstrs == NULL)
805                 goto out_elf_end;
806
807         sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
808         if (sec_strndx == NULL)
809                 goto out_elf_end;
810
811         secstrs = elf_getdata(sec_strndx, NULL);
812         if (secstrs == NULL)
813                 goto out_elf_end;
814
815         nr_syms = shdr.sh_size / shdr.sh_entsize;
816
817         memset(&sym, 0, sizeof(sym));
818
819         /*
820          * The kernel relocation symbol is needed in advance in order to adjust
821          * kernel maps correctly.
822          */
823         if (ref_reloc_sym_not_found(kmap)) {
824                 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
825                         const char *elf_name = elf_sym__name(&sym, symstrs);
826
827                         if (strcmp(elf_name, kmap->ref_reloc_sym->name))
828                                 continue;
829                         kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
830                         map->reloc = kmap->ref_reloc_sym->addr -
831                                      kmap->ref_reloc_sym->unrelocated_addr;
832                         break;
833                 }
834         }
835
836         dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
837         /*
838          * Initial kernel and module mappings do not map to the dso.  For
839          * function mappings, flag the fixups.
840          */
841         if (map->type == MAP__FUNCTION && (dso->kernel || kmodule)) {
842                 remap_kernel = true;
843                 adjust_kernel_syms = dso->adjust_symbols;
844         }
845         elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
846                 struct symbol *f;
847                 const char *elf_name = elf_sym__name(&sym, symstrs);
848                 char *demangled = NULL;
849                 int is_label = elf_sym__is_label(&sym);
850                 const char *section_name;
851                 bool used_opd = false;
852
853                 if (!is_label && !elf_sym__is_a(&sym, map->type))
854                         continue;
855
856                 /* Reject ARM ELF "mapping symbols": these aren't unique and
857                  * don't identify functions, so will confuse the profile
858                  * output: */
859                 if (ehdr.e_machine == EM_ARM) {
860                         if (!strcmp(elf_name, "$a") ||
861                             !strcmp(elf_name, "$d") ||
862                             !strcmp(elf_name, "$t"))
863                                 continue;
864                 }
865
866                 if (runtime_ss->opdsec && sym.st_shndx == runtime_ss->opdidx) {
867                         u32 offset = sym.st_value - syms_ss->opdshdr.sh_addr;
868                         u64 *opd = opddata->d_buf + offset;
869                         sym.st_value = DSO__SWAP(dso, u64, *opd);
870                         sym.st_shndx = elf_addr_to_index(runtime_ss->elf,
871                                         sym.st_value);
872                         used_opd = true;
873                 }
874                 /*
875                  * When loading symbols in a data mapping, ABS symbols (which
876                  * has a value of SHN_ABS in its st_shndx) failed at
877                  * elf_getscn().  And it marks the loading as a failure so
878                  * already loaded symbols cannot be fixed up.
879                  *
880                  * I'm not sure what should be done. Just ignore them for now.
881                  * - Namhyung Kim
882                  */
883                 if (sym.st_shndx == SHN_ABS)
884                         continue;
885
886                 sec = elf_getscn(runtime_ss->elf, sym.st_shndx);
887                 if (!sec)
888                         goto out_elf_end;
889
890                 gelf_getshdr(sec, &shdr);
891
892                 if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
893                         continue;
894
895                 section_name = elf_sec__name(&shdr, secstrs);
896
897                 /* On ARM, symbols for thumb functions have 1 added to
898                  * the symbol address as a flag - remove it */
899                 if ((ehdr.e_machine == EM_ARM) &&
900                     (map->type == MAP__FUNCTION) &&
901                     (sym.st_value & 1))
902                         --sym.st_value;
903
904                 if (dso->kernel || kmodule) {
905                         char dso_name[PATH_MAX];
906
907                         /* Adjust symbol to map to file offset */
908                         if (adjust_kernel_syms)
909                                 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
910
911                         if (strcmp(section_name,
912                                    (curr_dso->short_name +
913                                     dso->short_name_len)) == 0)
914                                 goto new_symbol;
915
916                         if (strcmp(section_name, ".text") == 0) {
917                                 /*
918                                  * The initial kernel mapping is based on
919                                  * kallsyms and identity maps.  Overwrite it to
920                                  * map to the kernel dso.
921                                  */
922                                 if (remap_kernel && dso->kernel) {
923                                         remap_kernel = false;
924                                         map->start = shdr.sh_addr +
925                                                      ref_reloc(kmap);
926                                         map->end = map->start + shdr.sh_size;
927                                         map->pgoff = shdr.sh_offset;
928                                         map->map_ip = map__map_ip;
929                                         map->unmap_ip = map__unmap_ip;
930                                         /* Ensure maps are correctly ordered */
931                                         map_groups__remove(kmap->kmaps, map);
932                                         map_groups__insert(kmap->kmaps, map);
933                                 }
934
935                                 /*
936                                  * The initial module mapping is based on
937                                  * /proc/modules mapped to offset zero.
938                                  * Overwrite it to map to the module dso.
939                                  */
940                                 if (remap_kernel && kmodule) {
941                                         remap_kernel = false;
942                                         map->pgoff = shdr.sh_offset;
943                                 }
944
945                                 curr_map = map;
946                                 curr_dso = dso;
947                                 goto new_symbol;
948                         }
949
950                         if (!kmap)
951                                 goto new_symbol;
952
953                         snprintf(dso_name, sizeof(dso_name),
954                                  "%s%s", dso->short_name, section_name);
955
956                         curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
957                         if (curr_map == NULL) {
958                                 u64 start = sym.st_value;
959
960                                 if (kmodule)
961                                         start += map->start + shdr.sh_offset;
962
963                                 curr_dso = dso__new(dso_name);
964                                 if (curr_dso == NULL)
965                                         goto out_elf_end;
966                                 curr_dso->kernel = dso->kernel;
967                                 curr_dso->long_name = dso->long_name;
968                                 curr_dso->long_name_len = dso->long_name_len;
969                                 curr_map = map__new2(start, curr_dso,
970                                                      map->type);
971                                 if (curr_map == NULL) {
972                                         dso__delete(curr_dso);
973                                         goto out_elf_end;
974                                 }
975                                 if (adjust_kernel_syms) {
976                                         curr_map->start = shdr.sh_addr +
977                                                           ref_reloc(kmap);
978                                         curr_map->end = curr_map->start +
979                                                         shdr.sh_size;
980                                         curr_map->pgoff = shdr.sh_offset;
981                                 } else {
982                                         curr_map->map_ip = identity__map_ip;
983                                         curr_map->unmap_ip = identity__map_ip;
984                                 }
985                                 curr_dso->symtab_type = dso->symtab_type;
986                                 map_groups__insert(kmap->kmaps, curr_map);
987                                 /*
988                                  * The new DSO should go to the kernel DSOS
989                                  */
990                                 dsos__add(&map->groups->machine->kernel_dsos,
991                                           curr_dso);
992                                 dso__set_loaded(curr_dso, map->type);
993                         } else
994                                 curr_dso = curr_map->dso;
995
996                         goto new_symbol;
997                 }
998
999                 if ((used_opd && runtime_ss->adjust_symbols)
1000                                 || (!used_opd && syms_ss->adjust_symbols)) {
1001                         pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1002                                   "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1003                                   (u64)sym.st_value, (u64)shdr.sh_addr,
1004                                   (u64)shdr.sh_offset);
1005                         sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1006                 }
1007 new_symbol:
1008                 /*
1009                  * We need to figure out if the object was created from C++ sources
1010                  * DWARF DW_compile_unit has this, but we don't always have access
1011                  * to it...
1012                  */
1013                 if (want_demangle(dso->kernel || kmodule)) {
1014                         int demangle_flags = DMGL_NO_OPTS;
1015                         if (verbose)
1016                                 demangle_flags = DMGL_PARAMS | DMGL_ANSI;
1017
1018                         demangled = bfd_demangle(NULL, elf_name, demangle_flags);
1019                         if (demangled != NULL)
1020                                 elf_name = demangled;
1021                 }
1022                 f = symbol__new(sym.st_value, sym.st_size,
1023                                 GELF_ST_BIND(sym.st_info), elf_name);
1024                 free(demangled);
1025                 if (!f)
1026                         goto out_elf_end;
1027
1028                 if (filter && filter(curr_map, f))
1029                         symbol__delete(f);
1030                 else {
1031                         symbols__insert(&curr_dso->symbols[curr_map->type], f);
1032                         nr++;
1033                 }
1034         }
1035
1036         /*
1037          * For misannotated, zeroed, ASM function sizes.
1038          */
1039         if (nr > 0) {
1040                 symbols__fixup_duplicate(&dso->symbols[map->type]);
1041                 symbols__fixup_end(&dso->symbols[map->type]);
1042                 if (kmap) {
1043                         /*
1044                          * We need to fixup this here too because we create new
1045                          * maps here, for things like vsyscall sections.
1046                          */
1047                         __map_groups__fixup_end(kmap->kmaps, map->type);
1048                 }
1049         }
1050         err = nr;
1051 out_elf_end:
1052         return err;
1053 }
1054
1055 static int elf_read_maps(Elf *elf, bool exe, mapfn_t mapfn, void *data)
1056 {
1057         GElf_Phdr phdr;
1058         size_t i, phdrnum;
1059         int err;
1060         u64 sz;
1061
1062         if (elf_getphdrnum(elf, &phdrnum))
1063                 return -1;
1064
1065         for (i = 0; i < phdrnum; i++) {
1066                 if (gelf_getphdr(elf, i, &phdr) == NULL)
1067                         return -1;
1068                 if (phdr.p_type != PT_LOAD)
1069                         continue;
1070                 if (exe) {
1071                         if (!(phdr.p_flags & PF_X))
1072                                 continue;
1073                 } else {
1074                         if (!(phdr.p_flags & PF_R))
1075                                 continue;
1076                 }
1077                 sz = min(phdr.p_memsz, phdr.p_filesz);
1078                 if (!sz)
1079                         continue;
1080                 err = mapfn(phdr.p_vaddr, sz, phdr.p_offset, data);
1081                 if (err)
1082                         return err;
1083         }
1084         return 0;
1085 }
1086
1087 int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
1088                     bool *is_64_bit)
1089 {
1090         int err;
1091         Elf *elf;
1092
1093         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1094         if (elf == NULL)
1095                 return -1;
1096
1097         if (is_64_bit)
1098                 *is_64_bit = (gelf_getclass(elf) == ELFCLASS64);
1099
1100         err = elf_read_maps(elf, exe, mapfn, data);
1101
1102         elf_end(elf);
1103         return err;
1104 }
1105
1106 enum dso_type dso__type_fd(int fd)
1107 {
1108         enum dso_type dso_type = DSO__TYPE_UNKNOWN;
1109         GElf_Ehdr ehdr;
1110         Elf_Kind ek;
1111         Elf *elf;
1112
1113         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1114         if (elf == NULL)
1115                 goto out;
1116
1117         ek = elf_kind(elf);
1118         if (ek != ELF_K_ELF)
1119                 goto out_end;
1120
1121         if (gelf_getclass(elf) == ELFCLASS64) {
1122                 dso_type = DSO__TYPE_64BIT;
1123                 goto out_end;
1124         }
1125
1126         if (gelf_getehdr(elf, &ehdr) == NULL)
1127                 goto out_end;
1128
1129         if (ehdr.e_machine == EM_X86_64)
1130                 dso_type = DSO__TYPE_X32BIT;
1131         else
1132                 dso_type = DSO__TYPE_32BIT;
1133 out_end:
1134         elf_end(elf);
1135 out:
1136         return dso_type;
1137 }
1138
1139 static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len)
1140 {
1141         ssize_t r;
1142         size_t n;
1143         int err = -1;
1144         char *buf = malloc(page_size);
1145
1146         if (buf == NULL)
1147                 return -1;
1148
1149         if (lseek(to, to_offs, SEEK_SET) != to_offs)
1150                 goto out;
1151
1152         if (lseek(from, from_offs, SEEK_SET) != from_offs)
1153                 goto out;
1154
1155         while (len) {
1156                 n = page_size;
1157                 if (len < n)
1158                         n = len;
1159                 /* Use read because mmap won't work on proc files */
1160                 r = read(from, buf, n);
1161                 if (r < 0)
1162                         goto out;
1163                 if (!r)
1164                         break;
1165                 n = r;
1166                 r = write(to, buf, n);
1167                 if (r < 0)
1168                         goto out;
1169                 if ((size_t)r != n)
1170                         goto out;
1171                 len -= n;
1172         }
1173
1174         err = 0;
1175 out:
1176         free(buf);
1177         return err;
1178 }
1179
1180 struct kcore {
1181         int fd;
1182         int elfclass;
1183         Elf *elf;
1184         GElf_Ehdr ehdr;
1185 };
1186
1187 static int kcore__open(struct kcore *kcore, const char *filename)
1188 {
1189         GElf_Ehdr *ehdr;
1190
1191         kcore->fd = open(filename, O_RDONLY);
1192         if (kcore->fd == -1)
1193                 return -1;
1194
1195         kcore->elf = elf_begin(kcore->fd, ELF_C_READ, NULL);
1196         if (!kcore->elf)
1197                 goto out_close;
1198
1199         kcore->elfclass = gelf_getclass(kcore->elf);
1200         if (kcore->elfclass == ELFCLASSNONE)
1201                 goto out_end;
1202
1203         ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
1204         if (!ehdr)
1205                 goto out_end;
1206
1207         return 0;
1208
1209 out_end:
1210         elf_end(kcore->elf);
1211 out_close:
1212         close(kcore->fd);
1213         return -1;
1214 }
1215
1216 static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
1217                        bool temp)
1218 {
1219         GElf_Ehdr *ehdr;
1220
1221         kcore->elfclass = elfclass;
1222
1223         if (temp)
1224                 kcore->fd = mkstemp(filename);
1225         else
1226                 kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400);
1227         if (kcore->fd == -1)
1228                 return -1;
1229
1230         kcore->elf = elf_begin(kcore->fd, ELF_C_WRITE, NULL);
1231         if (!kcore->elf)
1232                 goto out_close;
1233
1234         if (!gelf_newehdr(kcore->elf, elfclass))
1235                 goto out_end;
1236
1237         ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr);
1238         if (!ehdr)
1239                 goto out_end;
1240
1241         return 0;
1242
1243 out_end:
1244         elf_end(kcore->elf);
1245 out_close:
1246         close(kcore->fd);
1247         unlink(filename);
1248         return -1;
1249 }
1250
1251 static void kcore__close(struct kcore *kcore)
1252 {
1253         elf_end(kcore->elf);
1254         close(kcore->fd);
1255 }
1256
1257 static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count)
1258 {
1259         GElf_Ehdr *ehdr = &to->ehdr;
1260         GElf_Ehdr *kehdr = &from->ehdr;
1261
1262         memcpy(ehdr->e_ident, kehdr->e_ident, EI_NIDENT);
1263         ehdr->e_type      = kehdr->e_type;
1264         ehdr->e_machine   = kehdr->e_machine;
1265         ehdr->e_version   = kehdr->e_version;
1266         ehdr->e_entry     = 0;
1267         ehdr->e_shoff     = 0;
1268         ehdr->e_flags     = kehdr->e_flags;
1269         ehdr->e_phnum     = count;
1270         ehdr->e_shentsize = 0;
1271         ehdr->e_shnum     = 0;
1272         ehdr->e_shstrndx  = 0;
1273
1274         if (from->elfclass == ELFCLASS32) {
1275                 ehdr->e_phoff     = sizeof(Elf32_Ehdr);
1276                 ehdr->e_ehsize    = sizeof(Elf32_Ehdr);
1277                 ehdr->e_phentsize = sizeof(Elf32_Phdr);
1278         } else {
1279                 ehdr->e_phoff     = sizeof(Elf64_Ehdr);
1280                 ehdr->e_ehsize    = sizeof(Elf64_Ehdr);
1281                 ehdr->e_phentsize = sizeof(Elf64_Phdr);
1282         }
1283
1284         if (!gelf_update_ehdr(to->elf, ehdr))
1285                 return -1;
1286
1287         if (!gelf_newphdr(to->elf, count))
1288                 return -1;
1289
1290         return 0;
1291 }
1292
1293 static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset,
1294                            u64 addr, u64 len)
1295 {
1296         GElf_Phdr gphdr;
1297         GElf_Phdr *phdr;
1298
1299         phdr = gelf_getphdr(kcore->elf, idx, &gphdr);
1300         if (!phdr)
1301                 return -1;
1302
1303         phdr->p_type    = PT_LOAD;
1304         phdr->p_flags   = PF_R | PF_W | PF_X;
1305         phdr->p_offset  = offset;
1306         phdr->p_vaddr   = addr;
1307         phdr->p_paddr   = 0;
1308         phdr->p_filesz  = len;
1309         phdr->p_memsz   = len;
1310         phdr->p_align   = page_size;
1311
1312         if (!gelf_update_phdr(kcore->elf, idx, phdr))
1313                 return -1;
1314
1315         return 0;
1316 }
1317
1318 static off_t kcore__write(struct kcore *kcore)
1319 {
1320         return elf_update(kcore->elf, ELF_C_WRITE);
1321 }
1322
1323 struct phdr_data {
1324         off_t offset;
1325         u64 addr;
1326         u64 len;
1327 };
1328
1329 struct kcore_copy_info {
1330         u64 stext;
1331         u64 etext;
1332         u64 first_symbol;
1333         u64 last_symbol;
1334         u64 first_module;
1335         u64 last_module_symbol;
1336         struct phdr_data kernel_map;
1337         struct phdr_data modules_map;
1338 };
1339
1340 static int kcore_copy__process_kallsyms(void *arg, const char *name, char type,
1341                                         u64 start)
1342 {
1343         struct kcore_copy_info *kci = arg;
1344
1345         if (!symbol_type__is_a(type, MAP__FUNCTION))
1346                 return 0;
1347
1348         if (strchr(name, '[')) {
1349                 if (start > kci->last_module_symbol)
1350                         kci->last_module_symbol = start;
1351                 return 0;
1352         }
1353
1354         if (!kci->first_symbol || start < kci->first_symbol)
1355                 kci->first_symbol = start;
1356
1357         if (!kci->last_symbol || start > kci->last_symbol)
1358                 kci->last_symbol = start;
1359
1360         if (!strcmp(name, "_stext")) {
1361                 kci->stext = start;
1362                 return 0;
1363         }
1364
1365         if (!strcmp(name, "_etext")) {
1366                 kci->etext = start;
1367                 return 0;
1368         }
1369
1370         return 0;
1371 }
1372
1373 static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci,
1374                                       const char *dir)
1375 {
1376         char kallsyms_filename[PATH_MAX];
1377
1378         scnprintf(kallsyms_filename, PATH_MAX, "%s/kallsyms", dir);
1379
1380         if (symbol__restricted_filename(kallsyms_filename, "/proc/kallsyms"))
1381                 return -1;
1382
1383         if (kallsyms__parse(kallsyms_filename, kci,
1384                             kcore_copy__process_kallsyms) < 0)
1385                 return -1;
1386
1387         return 0;
1388 }
1389
1390 static int kcore_copy__process_modules(void *arg,
1391                                        const char *name __maybe_unused,
1392                                        u64 start)
1393 {
1394         struct kcore_copy_info *kci = arg;
1395
1396         if (!kci->first_module || start < kci->first_module)
1397                 kci->first_module = start;
1398
1399         return 0;
1400 }
1401
1402 static int kcore_copy__parse_modules(struct kcore_copy_info *kci,
1403                                      const char *dir)
1404 {
1405         char modules_filename[PATH_MAX];
1406
1407         scnprintf(modules_filename, PATH_MAX, "%s/modules", dir);
1408
1409         if (symbol__restricted_filename(modules_filename, "/proc/modules"))
1410                 return -1;
1411
1412         if (modules__parse(modules_filename, kci,
1413                            kcore_copy__process_modules) < 0)
1414                 return -1;
1415
1416         return 0;
1417 }
1418
1419 static void kcore_copy__map(struct phdr_data *p, u64 start, u64 end, u64 pgoff,
1420                             u64 s, u64 e)
1421 {
1422         if (p->addr || s < start || s >= end)
1423                 return;
1424
1425         p->addr = s;
1426         p->offset = (s - start) + pgoff;
1427         p->len = e < end ? e - s : end - s;
1428 }
1429
1430 static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data)
1431 {
1432         struct kcore_copy_info *kci = data;
1433         u64 end = start + len;
1434
1435         kcore_copy__map(&kci->kernel_map, start, end, pgoff, kci->stext,
1436                         kci->etext);
1437
1438         kcore_copy__map(&kci->modules_map, start, end, pgoff, kci->first_module,
1439                         kci->last_module_symbol);
1440
1441         return 0;
1442 }
1443
1444 static int kcore_copy__read_maps(struct kcore_copy_info *kci, Elf *elf)
1445 {
1446         if (elf_read_maps(elf, true, kcore_copy__read_map, kci) < 0)
1447                 return -1;
1448
1449         return 0;
1450 }
1451
1452 static int kcore_copy__calc_maps(struct kcore_copy_info *kci, const char *dir,
1453                                  Elf *elf)
1454 {
1455         if (kcore_copy__parse_kallsyms(kci, dir))
1456                 return -1;
1457
1458         if (kcore_copy__parse_modules(kci, dir))
1459                 return -1;
1460
1461         if (kci->stext)
1462                 kci->stext = round_down(kci->stext, page_size);
1463         else
1464                 kci->stext = round_down(kci->first_symbol, page_size);
1465
1466         if (kci->etext) {
1467                 kci->etext = round_up(kci->etext, page_size);
1468         } else if (kci->last_symbol) {
1469                 kci->etext = round_up(kci->last_symbol, page_size);
1470                 kci->etext += page_size;
1471         }
1472
1473         kci->first_module = round_down(kci->first_module, page_size);
1474
1475         if (kci->last_module_symbol) {
1476                 kci->last_module_symbol = round_up(kci->last_module_symbol,
1477                                                    page_size);
1478                 kci->last_module_symbol += page_size;
1479         }
1480
1481         if (!kci->stext || !kci->etext)
1482                 return -1;
1483
1484         if (kci->first_module && !kci->last_module_symbol)
1485                 return -1;
1486
1487         return kcore_copy__read_maps(kci, elf);
1488 }
1489
1490 static int kcore_copy__copy_file(const char *from_dir, const char *to_dir,
1491                                  const char *name)
1492 {
1493         char from_filename[PATH_MAX];
1494         char to_filename[PATH_MAX];
1495
1496         scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
1497         scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
1498
1499         return copyfile_mode(from_filename, to_filename, 0400);
1500 }
1501
1502 static int kcore_copy__unlink(const char *dir, const char *name)
1503 {
1504         char filename[PATH_MAX];
1505
1506         scnprintf(filename, PATH_MAX, "%s/%s", dir, name);
1507
1508         return unlink(filename);
1509 }
1510
1511 static int kcore_copy__compare_fds(int from, int to)
1512 {
1513         char *buf_from;
1514         char *buf_to;
1515         ssize_t ret;
1516         size_t len;
1517         int err = -1;
1518
1519         buf_from = malloc(page_size);
1520         buf_to = malloc(page_size);
1521         if (!buf_from || !buf_to)
1522                 goto out;
1523
1524         while (1) {
1525                 /* Use read because mmap won't work on proc files */
1526                 ret = read(from, buf_from, page_size);
1527                 if (ret < 0)
1528                         goto out;
1529
1530                 if (!ret)
1531                         break;
1532
1533                 len = ret;
1534
1535                 if (readn(to, buf_to, len) != (int)len)
1536                         goto out;
1537
1538                 if (memcmp(buf_from, buf_to, len))
1539                         goto out;
1540         }
1541
1542         err = 0;
1543 out:
1544         free(buf_to);
1545         free(buf_from);
1546         return err;
1547 }
1548
1549 static int kcore_copy__compare_files(const char *from_filename,
1550                                      const char *to_filename)
1551 {
1552         int from, to, err = -1;
1553
1554         from = open(from_filename, O_RDONLY);
1555         if (from < 0)
1556                 return -1;
1557
1558         to = open(to_filename, O_RDONLY);
1559         if (to < 0)
1560                 goto out_close_from;
1561
1562         err = kcore_copy__compare_fds(from, to);
1563
1564         close(to);
1565 out_close_from:
1566         close(from);
1567         return err;
1568 }
1569
1570 static int kcore_copy__compare_file(const char *from_dir, const char *to_dir,
1571                                     const char *name)
1572 {
1573         char from_filename[PATH_MAX];
1574         char to_filename[PATH_MAX];
1575
1576         scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name);
1577         scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name);
1578
1579         return kcore_copy__compare_files(from_filename, to_filename);
1580 }
1581
1582 /**
1583  * kcore_copy - copy kallsyms, modules and kcore from one directory to another.
1584  * @from_dir: from directory
1585  * @to_dir: to directory
1586  *
1587  * This function copies kallsyms, modules and kcore files from one directory to
1588  * another.  kallsyms and modules are copied entirely.  Only code segments are
1589  * copied from kcore.  It is assumed that two segments suffice: one for the
1590  * kernel proper and one for all the modules.  The code segments are determined
1591  * from kallsyms and modules files.  The kernel map starts at _stext or the
1592  * lowest function symbol, and ends at _etext or the highest function symbol.
1593  * The module map starts at the lowest module address and ends at the highest
1594  * module symbol.  Start addresses are rounded down to the nearest page.  End
1595  * addresses are rounded up to the nearest page.  An extra page is added to the
1596  * highest kernel symbol and highest module symbol to, hopefully, encompass that
1597  * symbol too.  Because it contains only code sections, the resulting kcore is
1598  * unusual.  One significant peculiarity is that the mapping (start -> pgoff)
1599  * is not the same for the kernel map and the modules map.  That happens because
1600  * the data is copied adjacently whereas the original kcore has gaps.  Finally,
1601  * kallsyms and modules files are compared with their copies to check that
1602  * modules have not been loaded or unloaded while the copies were taking place.
1603  *
1604  * Return: %0 on success, %-1 on failure.
1605  */
1606 int kcore_copy(const char *from_dir, const char *to_dir)
1607 {
1608         struct kcore kcore;
1609         struct kcore extract;
1610         size_t count = 2;
1611         int idx = 0, err = -1;
1612         off_t offset = page_size, sz, modules_offset = 0;
1613         struct kcore_copy_info kci = { .stext = 0, };
1614         char kcore_filename[PATH_MAX];
1615         char extract_filename[PATH_MAX];
1616
1617         if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms"))
1618                 return -1;
1619
1620         if (kcore_copy__copy_file(from_dir, to_dir, "modules"))
1621                 goto out_unlink_kallsyms;
1622
1623         scnprintf(kcore_filename, PATH_MAX, "%s/kcore", from_dir);
1624         scnprintf(extract_filename, PATH_MAX, "%s/kcore", to_dir);
1625
1626         if (kcore__open(&kcore, kcore_filename))
1627                 goto out_unlink_modules;
1628
1629         if (kcore_copy__calc_maps(&kci, from_dir, kcore.elf))
1630                 goto out_kcore_close;
1631
1632         if (kcore__init(&extract, extract_filename, kcore.elfclass, false))
1633                 goto out_kcore_close;
1634
1635         if (!kci.modules_map.addr)
1636                 count -= 1;
1637
1638         if (kcore__copy_hdr(&kcore, &extract, count))
1639                 goto out_extract_close;
1640
1641         if (kcore__add_phdr(&extract, idx++, offset, kci.kernel_map.addr,
1642                             kci.kernel_map.len))
1643                 goto out_extract_close;
1644
1645         if (kci.modules_map.addr) {
1646                 modules_offset = offset + kci.kernel_map.len;
1647                 if (kcore__add_phdr(&extract, idx, modules_offset,
1648                                     kci.modules_map.addr, kci.modules_map.len))
1649                         goto out_extract_close;
1650         }
1651
1652         sz = kcore__write(&extract);
1653         if (sz < 0 || sz > offset)
1654                 goto out_extract_close;
1655
1656         if (copy_bytes(kcore.fd, kci.kernel_map.offset, extract.fd, offset,
1657                        kci.kernel_map.len))
1658                 goto out_extract_close;
1659
1660         if (modules_offset && copy_bytes(kcore.fd, kci.modules_map.offset,
1661                                          extract.fd, modules_offset,
1662                                          kci.modules_map.len))
1663                 goto out_extract_close;
1664
1665         if (kcore_copy__compare_file(from_dir, to_dir, "modules"))
1666                 goto out_extract_close;
1667
1668         if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms"))
1669                 goto out_extract_close;
1670
1671         err = 0;
1672
1673 out_extract_close:
1674         kcore__close(&extract);
1675         if (err)
1676                 unlink(extract_filename);
1677 out_kcore_close:
1678         kcore__close(&kcore);
1679 out_unlink_modules:
1680         if (err)
1681                 kcore_copy__unlink(to_dir, "modules");
1682 out_unlink_kallsyms:
1683         if (err)
1684                 kcore_copy__unlink(to_dir, "kallsyms");
1685
1686         return err;
1687 }
1688
1689 int kcore_extract__create(struct kcore_extract *kce)
1690 {
1691         struct kcore kcore;
1692         struct kcore extract;
1693         size_t count = 1;
1694         int idx = 0, err = -1;
1695         off_t offset = page_size, sz;
1696
1697         if (kcore__open(&kcore, kce->kcore_filename))
1698                 return -1;
1699
1700         strcpy(kce->extract_filename, PERF_KCORE_EXTRACT);
1701         if (kcore__init(&extract, kce->extract_filename, kcore.elfclass, true))
1702                 goto out_kcore_close;
1703
1704         if (kcore__copy_hdr(&kcore, &extract, count))
1705                 goto out_extract_close;
1706
1707         if (kcore__add_phdr(&extract, idx, offset, kce->addr, kce->len))
1708                 goto out_extract_close;
1709
1710         sz = kcore__write(&extract);
1711         if (sz < 0 || sz > offset)
1712                 goto out_extract_close;
1713
1714         if (copy_bytes(kcore.fd, kce->offs, extract.fd, offset, kce->len))
1715                 goto out_extract_close;
1716
1717         err = 0;
1718
1719 out_extract_close:
1720         kcore__close(&extract);
1721         if (err)
1722                 unlink(kce->extract_filename);
1723 out_kcore_close:
1724         kcore__close(&kcore);
1725
1726         return err;
1727 }
1728
1729 void kcore_extract__delete(struct kcore_extract *kce)
1730 {
1731         unlink(kce->extract_filename);
1732 }
1733
1734 void symbol__elf_init(void)
1735 {
1736         elf_version(EV_CURRENT);
1737 }