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