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