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