1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * elf.c - ELF access library 4 * 5 * Adapted from kpatch (https://github.com/dynup/kpatch): 6 * Copyright (C) 2013-2015 Josh Poimboeuf <jpoimboe@redhat.com> 7 * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 8 */ 9 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <sys/mman.h> 13 #include <fcntl.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <unistd.h> 18 #include <errno.h> 19 #include <objtool/builtin.h> 20 21 #include <objtool/elf.h> 22 #include <objtool/warn.h> 23 24 #define MAX_NAME_LEN 128 25 26 static inline u32 str_hash(const char *str) 27 { 28 return jhash(str, strlen(str), 0); 29 } 30 31 #define __elf_table(name) (elf->name##_hash) 32 #define __elf_bits(name) (elf->name##_bits) 33 34 #define elf_hash_add(name, node, key) \ 35 hlist_add_head(node, &__elf_table(name)[hash_min(key, __elf_bits(name))]) 36 37 #define elf_hash_for_each_possible(name, obj, member, key) \ 38 hlist_for_each_entry(obj, &__elf_table(name)[hash_min(key, __elf_bits(name))], member) 39 40 #define elf_alloc_hash(name, size) \ 41 ({ \ 42 __elf_bits(name) = max(10, ilog2(size)); \ 43 __elf_table(name) = mmap(NULL, sizeof(struct hlist_head) << __elf_bits(name), \ 44 PROT_READ|PROT_WRITE, \ 45 MAP_PRIVATE|MAP_ANON, -1, 0); \ 46 if (__elf_table(name) == (void *)-1L) { \ 47 WARN("mmap fail " #name); \ 48 __elf_table(name) = NULL; \ 49 } \ 50 __elf_table(name); \ 51 }) 52 53 static bool symbol_to_offset(struct rb_node *a, const struct rb_node *b) 54 { 55 struct symbol *sa = rb_entry(a, struct symbol, node); 56 struct symbol *sb = rb_entry(b, struct symbol, node); 57 58 if (sa->offset < sb->offset) 59 return true; 60 if (sa->offset > sb->offset) 61 return false; 62 63 if (sa->len < sb->len) 64 return true; 65 if (sa->len > sb->len) 66 return false; 67 68 sa->alias = sb; 69 70 return false; 71 } 72 73 static int symbol_by_offset(const void *key, const struct rb_node *node) 74 { 75 const struct symbol *s = rb_entry(node, struct symbol, node); 76 const unsigned long *o = key; 77 78 if (*o < s->offset) 79 return -1; 80 if (*o >= s->offset + s->len) 81 return 1; 82 83 return 0; 84 } 85 86 struct section *find_section_by_name(const struct elf *elf, const char *name) 87 { 88 struct section *sec; 89 90 elf_hash_for_each_possible(section_name, sec, name_hash, str_hash(name)) { 91 if (!strcmp(sec->name, name)) 92 return sec; 93 } 94 95 return NULL; 96 } 97 98 static struct section *find_section_by_index(struct elf *elf, 99 unsigned int idx) 100 { 101 struct section *sec; 102 103 elf_hash_for_each_possible(section, sec, hash, idx) { 104 if (sec->idx == idx) 105 return sec; 106 } 107 108 return NULL; 109 } 110 111 static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx) 112 { 113 struct symbol *sym; 114 115 elf_hash_for_each_possible(symbol, sym, hash, idx) { 116 if (sym->idx == idx) 117 return sym; 118 } 119 120 return NULL; 121 } 122 123 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) 124 { 125 struct rb_node *node; 126 127 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { 128 struct symbol *s = rb_entry(node, struct symbol, node); 129 130 if (s->offset == offset && s->type != STT_SECTION) 131 return s; 132 } 133 134 return NULL; 135 } 136 137 struct symbol *find_func_by_offset(struct section *sec, unsigned long offset) 138 { 139 struct rb_node *node; 140 141 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { 142 struct symbol *s = rb_entry(node, struct symbol, node); 143 144 if (s->offset == offset && s->type == STT_FUNC) 145 return s; 146 } 147 148 return NULL; 149 } 150 151 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset) 152 { 153 struct rb_node *node; 154 155 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { 156 struct symbol *s = rb_entry(node, struct symbol, node); 157 158 if (s->type != STT_SECTION) 159 return s; 160 } 161 162 return NULL; 163 } 164 165 struct symbol *find_func_containing(struct section *sec, unsigned long offset) 166 { 167 struct rb_node *node; 168 169 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { 170 struct symbol *s = rb_entry(node, struct symbol, node); 171 172 if (s->type == STT_FUNC) 173 return s; 174 } 175 176 return NULL; 177 } 178 179 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name) 180 { 181 struct symbol *sym; 182 183 elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { 184 if (!strcmp(sym->name, name)) 185 return sym; 186 } 187 188 return NULL; 189 } 190 191 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, 192 unsigned long offset, unsigned int len) 193 { 194 struct reloc *reloc, *r = NULL; 195 unsigned long o; 196 197 if (!sec->reloc) 198 return NULL; 199 200 sec = sec->reloc; 201 202 for_offset_range(o, offset, offset + len) { 203 elf_hash_for_each_possible(reloc, reloc, hash, 204 sec_offset_hash(sec, o)) { 205 if (reloc->sec != sec) 206 continue; 207 208 if (reloc->offset >= offset && reloc->offset < offset + len) { 209 if (!r || reloc->offset < r->offset) 210 r = reloc; 211 } 212 } 213 if (r) 214 return r; 215 } 216 217 return NULL; 218 } 219 220 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) 221 { 222 return find_reloc_by_dest_range(elf, sec, offset, 1); 223 } 224 225 static int read_sections(struct elf *elf) 226 { 227 Elf_Scn *s = NULL; 228 struct section *sec; 229 size_t shstrndx, sections_nr; 230 int i; 231 232 if (elf_getshdrnum(elf->elf, §ions_nr)) { 233 WARN_ELF("elf_getshdrnum"); 234 return -1; 235 } 236 237 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { 238 WARN_ELF("elf_getshdrstrndx"); 239 return -1; 240 } 241 242 if (!elf_alloc_hash(section, sections_nr) || 243 !elf_alloc_hash(section_name, sections_nr)) 244 return -1; 245 246 for (i = 0; i < sections_nr; i++) { 247 sec = malloc(sizeof(*sec)); 248 if (!sec) { 249 perror("malloc"); 250 return -1; 251 } 252 memset(sec, 0, sizeof(*sec)); 253 254 INIT_LIST_HEAD(&sec->symbol_list); 255 INIT_LIST_HEAD(&sec->reloc_list); 256 257 s = elf_getscn(elf->elf, i); 258 if (!s) { 259 WARN_ELF("elf_getscn"); 260 return -1; 261 } 262 263 sec->idx = elf_ndxscn(s); 264 265 if (!gelf_getshdr(s, &sec->sh)) { 266 WARN_ELF("gelf_getshdr"); 267 return -1; 268 } 269 270 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); 271 if (!sec->name) { 272 WARN_ELF("elf_strptr"); 273 return -1; 274 } 275 276 if (sec->sh.sh_size != 0) { 277 sec->data = elf_getdata(s, NULL); 278 if (!sec->data) { 279 WARN_ELF("elf_getdata"); 280 return -1; 281 } 282 if (sec->data->d_off != 0 || 283 sec->data->d_size != sec->sh.sh_size) { 284 WARN("unexpected data attributes for %s", 285 sec->name); 286 return -1; 287 } 288 } 289 290 if (sec->sh.sh_flags & SHF_EXECINSTR) 291 elf->text_size += sec->sh.sh_size; 292 293 list_add_tail(&sec->list, &elf->sections); 294 elf_hash_add(section, &sec->hash, sec->idx); 295 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 296 } 297 298 if (stats) { 299 printf("nr_sections: %lu\n", (unsigned long)sections_nr); 300 printf("section_bits: %d\n", elf->section_bits); 301 } 302 303 /* sanity check, one more call to elf_nextscn() should return NULL */ 304 if (elf_nextscn(elf->elf, s)) { 305 WARN("section entry mismatch"); 306 return -1; 307 } 308 309 return 0; 310 } 311 312 static void elf_add_symbol(struct elf *elf, struct symbol *sym) 313 { 314 struct list_head *entry; 315 struct rb_node *pnode; 316 317 sym->type = GELF_ST_TYPE(sym->sym.st_info); 318 sym->bind = GELF_ST_BIND(sym->sym.st_info); 319 320 sym->offset = sym->sym.st_value; 321 sym->len = sym->sym.st_size; 322 323 rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset); 324 pnode = rb_prev(&sym->node); 325 if (pnode) 326 entry = &rb_entry(pnode, struct symbol, node)->list; 327 else 328 entry = &sym->sec->symbol_list; 329 list_add(&sym->list, entry); 330 elf_hash_add(symbol, &sym->hash, sym->idx); 331 elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); 332 333 /* 334 * Don't store empty STT_NOTYPE symbols in the rbtree. They 335 * can exist within a function, confusing the sorting. 336 */ 337 if (!sym->len) 338 rb_erase(&sym->node, &sym->sec->symbol_tree); 339 } 340 341 static int read_symbols(struct elf *elf) 342 { 343 struct section *symtab, *symtab_shndx, *sec; 344 struct symbol *sym, *pfunc; 345 int symbols_nr, i; 346 char *coldstr; 347 Elf_Data *shndx_data = NULL; 348 Elf32_Word shndx; 349 350 symtab = find_section_by_name(elf, ".symtab"); 351 if (symtab) { 352 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 353 if (symtab_shndx) 354 shndx_data = symtab_shndx->data; 355 356 symbols_nr = symtab->sh.sh_size / symtab->sh.sh_entsize; 357 } else { 358 /* 359 * A missing symbol table is actually possible if it's an empty 360 * .o file. This can happen for thunk_64.o. Make sure to at 361 * least allocate the symbol hash tables so we can do symbol 362 * lookups without crashing. 363 */ 364 symbols_nr = 0; 365 } 366 367 if (!elf_alloc_hash(symbol, symbols_nr) || 368 !elf_alloc_hash(symbol_name, symbols_nr)) 369 return -1; 370 371 for (i = 0; i < symbols_nr; i++) { 372 sym = malloc(sizeof(*sym)); 373 if (!sym) { 374 perror("malloc"); 375 return -1; 376 } 377 memset(sym, 0, sizeof(*sym)); 378 sym->alias = sym; 379 380 sym->idx = i; 381 382 if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, 383 &shndx)) { 384 WARN_ELF("gelf_getsymshndx"); 385 goto err; 386 } 387 388 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, 389 sym->sym.st_name); 390 if (!sym->name) { 391 WARN_ELF("elf_strptr"); 392 goto err; 393 } 394 395 if ((sym->sym.st_shndx > SHN_UNDEF && 396 sym->sym.st_shndx < SHN_LORESERVE) || 397 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { 398 if (sym->sym.st_shndx != SHN_XINDEX) 399 shndx = sym->sym.st_shndx; 400 401 sym->sec = find_section_by_index(elf, shndx); 402 if (!sym->sec) { 403 WARN("couldn't find section for symbol %s", 404 sym->name); 405 goto err; 406 } 407 if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { 408 sym->name = sym->sec->name; 409 sym->sec->sym = sym; 410 } 411 } else 412 sym->sec = find_section_by_index(elf, 0); 413 414 elf_add_symbol(elf, sym); 415 } 416 417 if (stats) { 418 printf("nr_symbols: %lu\n", (unsigned long)symbols_nr); 419 printf("symbol_bits: %d\n", elf->symbol_bits); 420 } 421 422 /* Create parent/child links for any cold subfunctions */ 423 list_for_each_entry(sec, &elf->sections, list) { 424 list_for_each_entry(sym, &sec->symbol_list, list) { 425 char pname[MAX_NAME_LEN + 1]; 426 size_t pnamelen; 427 if (sym->type != STT_FUNC) 428 continue; 429 430 if (sym->pfunc == NULL) 431 sym->pfunc = sym; 432 433 if (sym->cfunc == NULL) 434 sym->cfunc = sym; 435 436 coldstr = strstr(sym->name, ".cold"); 437 if (!coldstr) 438 continue; 439 440 pnamelen = coldstr - sym->name; 441 if (pnamelen > MAX_NAME_LEN) { 442 WARN("%s(): parent function name exceeds maximum length of %d characters", 443 sym->name, MAX_NAME_LEN); 444 return -1; 445 } 446 447 strncpy(pname, sym->name, pnamelen); 448 pname[pnamelen] = '\0'; 449 pfunc = find_symbol_by_name(elf, pname); 450 451 if (!pfunc) { 452 WARN("%s(): can't find parent function", 453 sym->name); 454 return -1; 455 } 456 457 sym->pfunc = pfunc; 458 pfunc->cfunc = sym; 459 460 /* 461 * Unfortunately, -fnoreorder-functions puts the child 462 * inside the parent. Remove the overlap so we can 463 * have sane assumptions. 464 * 465 * Note that pfunc->len now no longer matches 466 * pfunc->sym.st_size. 467 */ 468 if (sym->sec == pfunc->sec && 469 sym->offset >= pfunc->offset && 470 sym->offset + sym->len == pfunc->offset + pfunc->len) { 471 pfunc->len -= sym->len; 472 } 473 } 474 } 475 476 return 0; 477 478 err: 479 free(sym); 480 return -1; 481 } 482 483 static struct section *elf_create_reloc_section(struct elf *elf, 484 struct section *base, 485 int reltype); 486 487 int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, 488 unsigned int type, struct symbol *sym, int addend) 489 { 490 struct reloc *reloc; 491 492 if (!sec->reloc && !elf_create_reloc_section(elf, sec, SHT_RELA)) 493 return -1; 494 495 reloc = malloc(sizeof(*reloc)); 496 if (!reloc) { 497 perror("malloc"); 498 return -1; 499 } 500 memset(reloc, 0, sizeof(*reloc)); 501 502 reloc->sec = sec->reloc; 503 reloc->offset = offset; 504 reloc->type = type; 505 reloc->sym = sym; 506 reloc->addend = addend; 507 508 list_add_tail(&reloc->list, &sec->reloc->reloc_list); 509 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 510 511 sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize; 512 sec->reloc->changed = true; 513 514 return 0; 515 } 516 517 int elf_add_reloc_to_insn(struct elf *elf, struct section *sec, 518 unsigned long offset, unsigned int type, 519 struct section *insn_sec, unsigned long insn_off) 520 { 521 struct symbol *sym; 522 int addend; 523 524 if (insn_sec->sym) { 525 sym = insn_sec->sym; 526 addend = insn_off; 527 528 } else { 529 /* 530 * The Clang assembler strips section symbols, so we have to 531 * reference the function symbol instead: 532 */ 533 sym = find_symbol_containing(insn_sec, insn_off); 534 if (!sym) { 535 /* 536 * Hack alert. This happens when we need to reference 537 * the NOP pad insn immediately after the function. 538 */ 539 sym = find_symbol_containing(insn_sec, insn_off - 1); 540 } 541 542 if (!sym) { 543 WARN("can't find symbol containing %s+0x%lx", insn_sec->name, insn_off); 544 return -1; 545 } 546 547 addend = insn_off - sym->offset; 548 } 549 550 return elf_add_reloc(elf, sec, offset, type, sym, addend); 551 } 552 553 static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) 554 { 555 if (!gelf_getrel(sec->data, i, &reloc->rel)) { 556 WARN_ELF("gelf_getrel"); 557 return -1; 558 } 559 reloc->type = GELF_R_TYPE(reloc->rel.r_info); 560 reloc->addend = 0; 561 reloc->offset = reloc->rel.r_offset; 562 *symndx = GELF_R_SYM(reloc->rel.r_info); 563 return 0; 564 } 565 566 static int read_rela_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) 567 { 568 if (!gelf_getrela(sec->data, i, &reloc->rela)) { 569 WARN_ELF("gelf_getrela"); 570 return -1; 571 } 572 reloc->type = GELF_R_TYPE(reloc->rela.r_info); 573 reloc->addend = reloc->rela.r_addend; 574 reloc->offset = reloc->rela.r_offset; 575 *symndx = GELF_R_SYM(reloc->rela.r_info); 576 return 0; 577 } 578 579 static int read_relocs(struct elf *elf) 580 { 581 struct section *sec; 582 struct reloc *reloc; 583 int i; 584 unsigned int symndx; 585 unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0; 586 587 if (!elf_alloc_hash(reloc, elf->text_size / 16)) 588 return -1; 589 590 list_for_each_entry(sec, &elf->sections, list) { 591 if ((sec->sh.sh_type != SHT_RELA) && 592 (sec->sh.sh_type != SHT_REL)) 593 continue; 594 595 sec->base = find_section_by_index(elf, sec->sh.sh_info); 596 if (!sec->base) { 597 WARN("can't find base section for reloc section %s", 598 sec->name); 599 return -1; 600 } 601 602 sec->base->reloc = sec; 603 604 nr_reloc = 0; 605 for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) { 606 reloc = malloc(sizeof(*reloc)); 607 if (!reloc) { 608 perror("malloc"); 609 return -1; 610 } 611 memset(reloc, 0, sizeof(*reloc)); 612 switch (sec->sh.sh_type) { 613 case SHT_REL: 614 if (read_rel_reloc(sec, i, reloc, &symndx)) 615 return -1; 616 break; 617 case SHT_RELA: 618 if (read_rela_reloc(sec, i, reloc, &symndx)) 619 return -1; 620 break; 621 default: return -1; 622 } 623 624 reloc->sec = sec; 625 reloc->idx = i; 626 reloc->sym = find_symbol_by_index(elf, symndx); 627 if (!reloc->sym) { 628 WARN("can't find reloc entry symbol %d for %s", 629 symndx, sec->name); 630 return -1; 631 } 632 633 list_add_tail(&reloc->list, &sec->reloc_list); 634 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 635 636 nr_reloc++; 637 } 638 max_reloc = max(max_reloc, nr_reloc); 639 tot_reloc += nr_reloc; 640 } 641 642 if (stats) { 643 printf("max_reloc: %lu\n", max_reloc); 644 printf("tot_reloc: %lu\n", tot_reloc); 645 printf("reloc_bits: %d\n", elf->reloc_bits); 646 } 647 648 return 0; 649 } 650 651 struct elf *elf_open_read(const char *name, int flags) 652 { 653 struct elf *elf; 654 Elf_Cmd cmd; 655 656 elf_version(EV_CURRENT); 657 658 elf = malloc(sizeof(*elf)); 659 if (!elf) { 660 perror("malloc"); 661 return NULL; 662 } 663 memset(elf, 0, offsetof(struct elf, sections)); 664 665 INIT_LIST_HEAD(&elf->sections); 666 667 elf->fd = open(name, flags); 668 if (elf->fd == -1) { 669 fprintf(stderr, "objtool: Can't open '%s': %s\n", 670 name, strerror(errno)); 671 goto err; 672 } 673 674 if ((flags & O_ACCMODE) == O_RDONLY) 675 cmd = ELF_C_READ_MMAP; 676 else if ((flags & O_ACCMODE) == O_RDWR) 677 cmd = ELF_C_RDWR; 678 else /* O_WRONLY */ 679 cmd = ELF_C_WRITE; 680 681 elf->elf = elf_begin(elf->fd, cmd, NULL); 682 if (!elf->elf) { 683 WARN_ELF("elf_begin"); 684 goto err; 685 } 686 687 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { 688 WARN_ELF("gelf_getehdr"); 689 goto err; 690 } 691 692 if (read_sections(elf)) 693 goto err; 694 695 if (read_symbols(elf)) 696 goto err; 697 698 if (read_relocs(elf)) 699 goto err; 700 701 return elf; 702 703 err: 704 elf_close(elf); 705 return NULL; 706 } 707 708 static int elf_add_string(struct elf *elf, struct section *strtab, char *str) 709 { 710 Elf_Data *data; 711 Elf_Scn *s; 712 int len; 713 714 if (!strtab) 715 strtab = find_section_by_name(elf, ".strtab"); 716 if (!strtab) { 717 WARN("can't find .strtab section"); 718 return -1; 719 } 720 721 s = elf_getscn(elf->elf, strtab->idx); 722 if (!s) { 723 WARN_ELF("elf_getscn"); 724 return -1; 725 } 726 727 data = elf_newdata(s); 728 if (!data) { 729 WARN_ELF("elf_newdata"); 730 return -1; 731 } 732 733 data->d_buf = str; 734 data->d_size = strlen(str) + 1; 735 data->d_align = 1; 736 737 len = strtab->sh.sh_size; 738 strtab->sh.sh_size += data->d_size; 739 strtab->changed = true; 740 741 return len; 742 } 743 744 struct section *elf_create_section(struct elf *elf, const char *name, 745 unsigned int sh_flags, size_t entsize, int nr) 746 { 747 struct section *sec, *shstrtab; 748 size_t size = entsize * nr; 749 Elf_Scn *s; 750 751 sec = malloc(sizeof(*sec)); 752 if (!sec) { 753 perror("malloc"); 754 return NULL; 755 } 756 memset(sec, 0, sizeof(*sec)); 757 758 INIT_LIST_HEAD(&sec->symbol_list); 759 INIT_LIST_HEAD(&sec->reloc_list); 760 761 s = elf_newscn(elf->elf); 762 if (!s) { 763 WARN_ELF("elf_newscn"); 764 return NULL; 765 } 766 767 sec->name = strdup(name); 768 if (!sec->name) { 769 perror("strdup"); 770 return NULL; 771 } 772 773 sec->idx = elf_ndxscn(s); 774 sec->changed = true; 775 776 sec->data = elf_newdata(s); 777 if (!sec->data) { 778 WARN_ELF("elf_newdata"); 779 return NULL; 780 } 781 782 sec->data->d_size = size; 783 sec->data->d_align = 1; 784 785 if (size) { 786 sec->data->d_buf = malloc(size); 787 if (!sec->data->d_buf) { 788 perror("malloc"); 789 return NULL; 790 } 791 memset(sec->data->d_buf, 0, size); 792 } 793 794 if (!gelf_getshdr(s, &sec->sh)) { 795 WARN_ELF("gelf_getshdr"); 796 return NULL; 797 } 798 799 sec->sh.sh_size = size; 800 sec->sh.sh_entsize = entsize; 801 sec->sh.sh_type = SHT_PROGBITS; 802 sec->sh.sh_addralign = 1; 803 sec->sh.sh_flags = SHF_ALLOC | sh_flags; 804 805 /* Add section name to .shstrtab (or .strtab for Clang) */ 806 shstrtab = find_section_by_name(elf, ".shstrtab"); 807 if (!shstrtab) 808 shstrtab = find_section_by_name(elf, ".strtab"); 809 if (!shstrtab) { 810 WARN("can't find .shstrtab or .strtab section"); 811 return NULL; 812 } 813 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 814 if (sec->sh.sh_name == -1) 815 return NULL; 816 817 list_add_tail(&sec->list, &elf->sections); 818 elf_hash_add(section, &sec->hash, sec->idx); 819 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 820 821 elf->changed = true; 822 823 return sec; 824 } 825 826 static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base) 827 { 828 char *relocname; 829 struct section *sec; 830 831 relocname = malloc(strlen(base->name) + strlen(".rel") + 1); 832 if (!relocname) { 833 perror("malloc"); 834 return NULL; 835 } 836 strcpy(relocname, ".rel"); 837 strcat(relocname, base->name); 838 839 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rel), 0); 840 free(relocname); 841 if (!sec) 842 return NULL; 843 844 base->reloc = sec; 845 sec->base = base; 846 847 sec->sh.sh_type = SHT_REL; 848 sec->sh.sh_addralign = 8; 849 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 850 sec->sh.sh_info = base->idx; 851 sec->sh.sh_flags = SHF_INFO_LINK; 852 853 return sec; 854 } 855 856 static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base) 857 { 858 char *relocname; 859 struct section *sec; 860 861 relocname = malloc(strlen(base->name) + strlen(".rela") + 1); 862 if (!relocname) { 863 perror("malloc"); 864 return NULL; 865 } 866 strcpy(relocname, ".rela"); 867 strcat(relocname, base->name); 868 869 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rela), 0); 870 free(relocname); 871 if (!sec) 872 return NULL; 873 874 base->reloc = sec; 875 sec->base = base; 876 877 sec->sh.sh_type = SHT_RELA; 878 sec->sh.sh_addralign = 8; 879 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 880 sec->sh.sh_info = base->idx; 881 sec->sh.sh_flags = SHF_INFO_LINK; 882 883 return sec; 884 } 885 886 static struct section *elf_create_reloc_section(struct elf *elf, 887 struct section *base, 888 int reltype) 889 { 890 switch (reltype) { 891 case SHT_REL: return elf_create_rel_reloc_section(elf, base); 892 case SHT_RELA: return elf_create_rela_reloc_section(elf, base); 893 default: return NULL; 894 } 895 } 896 897 static int elf_rebuild_rel_reloc_section(struct section *sec) 898 { 899 struct reloc *reloc; 900 int idx = 0; 901 void *buf; 902 903 /* Allocate a buffer for relocations */ 904 buf = malloc(sec->sh.sh_size); 905 if (!buf) { 906 perror("malloc"); 907 return -1; 908 } 909 910 sec->data->d_buf = buf; 911 sec->data->d_size = sec->sh.sh_size; 912 sec->data->d_type = ELF_T_REL; 913 914 idx = 0; 915 list_for_each_entry(reloc, &sec->reloc_list, list) { 916 reloc->rel.r_offset = reloc->offset; 917 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 918 if (!gelf_update_rel(sec->data, idx, &reloc->rel)) { 919 WARN_ELF("gelf_update_rel"); 920 return -1; 921 } 922 idx++; 923 } 924 925 return 0; 926 } 927 928 static int elf_rebuild_rela_reloc_section(struct section *sec) 929 { 930 struct reloc *reloc; 931 int idx = 0; 932 void *buf; 933 934 /* Allocate a buffer for relocations with addends */ 935 buf = malloc(sec->sh.sh_size); 936 if (!buf) { 937 perror("malloc"); 938 return -1; 939 } 940 941 sec->data->d_buf = buf; 942 sec->data->d_size = sec->sh.sh_size; 943 sec->data->d_type = ELF_T_RELA; 944 945 idx = 0; 946 list_for_each_entry(reloc, &sec->reloc_list, list) { 947 reloc->rela.r_offset = reloc->offset; 948 reloc->rela.r_addend = reloc->addend; 949 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 950 if (!gelf_update_rela(sec->data, idx, &reloc->rela)) { 951 WARN_ELF("gelf_update_rela"); 952 return -1; 953 } 954 idx++; 955 } 956 957 return 0; 958 } 959 960 static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) 961 { 962 switch (sec->sh.sh_type) { 963 case SHT_REL: return elf_rebuild_rel_reloc_section(sec); 964 case SHT_RELA: return elf_rebuild_rela_reloc_section(sec); 965 default: return -1; 966 } 967 } 968 969 int elf_write_insn(struct elf *elf, struct section *sec, 970 unsigned long offset, unsigned int len, 971 const char *insn) 972 { 973 Elf_Data *data = sec->data; 974 975 if (data->d_type != ELF_T_BYTE || data->d_off) { 976 WARN("write to unexpected data for section: %s", sec->name); 977 return -1; 978 } 979 980 memcpy(data->d_buf + offset, insn, len); 981 elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY); 982 983 elf->changed = true; 984 985 return 0; 986 } 987 988 int elf_write_reloc(struct elf *elf, struct reloc *reloc) 989 { 990 struct section *sec = reloc->sec; 991 992 if (sec->sh.sh_type == SHT_REL) { 993 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 994 reloc->rel.r_offset = reloc->offset; 995 996 if (!gelf_update_rel(sec->data, reloc->idx, &reloc->rel)) { 997 WARN_ELF("gelf_update_rel"); 998 return -1; 999 } 1000 } else { 1001 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1002 reloc->rela.r_addend = reloc->addend; 1003 reloc->rela.r_offset = reloc->offset; 1004 1005 if (!gelf_update_rela(sec->data, reloc->idx, &reloc->rela)) { 1006 WARN_ELF("gelf_update_rela"); 1007 return -1; 1008 } 1009 } 1010 1011 elf->changed = true; 1012 1013 return 0; 1014 } 1015 1016 int elf_write(struct elf *elf) 1017 { 1018 struct section *sec; 1019 Elf_Scn *s; 1020 1021 /* Update changed relocation sections and section headers: */ 1022 list_for_each_entry(sec, &elf->sections, list) { 1023 if (sec->changed) { 1024 s = elf_getscn(elf->elf, sec->idx); 1025 if (!s) { 1026 WARN_ELF("elf_getscn"); 1027 return -1; 1028 } 1029 if (!gelf_update_shdr(s, &sec->sh)) { 1030 WARN_ELF("gelf_update_shdr"); 1031 return -1; 1032 } 1033 1034 if (sec->base && 1035 elf_rebuild_reloc_section(elf, sec)) { 1036 WARN("elf_rebuild_reloc_section"); 1037 return -1; 1038 } 1039 1040 sec->changed = false; 1041 elf->changed = true; 1042 } 1043 } 1044 1045 /* Make sure the new section header entries get updated properly. */ 1046 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); 1047 1048 /* Write all changes to the file. */ 1049 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { 1050 WARN_ELF("elf_update"); 1051 return -1; 1052 } 1053 1054 elf->changed = false; 1055 1056 return 0; 1057 } 1058 1059 void elf_close(struct elf *elf) 1060 { 1061 struct section *sec, *tmpsec; 1062 struct symbol *sym, *tmpsym; 1063 struct reloc *reloc, *tmpreloc; 1064 1065 if (elf->elf) 1066 elf_end(elf->elf); 1067 1068 if (elf->fd > 0) 1069 close(elf->fd); 1070 1071 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { 1072 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { 1073 list_del(&sym->list); 1074 hash_del(&sym->hash); 1075 free(sym); 1076 } 1077 list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) { 1078 list_del(&reloc->list); 1079 hash_del(&reloc->hash); 1080 free(reloc); 1081 } 1082 list_del(&sec->list); 1083 free(sec); 1084 } 1085 1086 free(elf); 1087 } 1088