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