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 INIT_LIST_HEAD(&sym->pv_target); 379 sym->alias = sym; 380 381 sym->idx = i; 382 383 if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, 384 &shndx)) { 385 WARN_ELF("gelf_getsymshndx"); 386 goto err; 387 } 388 389 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, 390 sym->sym.st_name); 391 if (!sym->name) { 392 WARN_ELF("elf_strptr"); 393 goto err; 394 } 395 396 if ((sym->sym.st_shndx > SHN_UNDEF && 397 sym->sym.st_shndx < SHN_LORESERVE) || 398 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { 399 if (sym->sym.st_shndx != SHN_XINDEX) 400 shndx = sym->sym.st_shndx; 401 402 sym->sec = find_section_by_index(elf, shndx); 403 if (!sym->sec) { 404 WARN("couldn't find section for symbol %s", 405 sym->name); 406 goto err; 407 } 408 if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { 409 sym->name = sym->sec->name; 410 sym->sec->sym = sym; 411 } 412 } else 413 sym->sec = find_section_by_index(elf, 0); 414 415 elf_add_symbol(elf, sym); 416 } 417 418 if (stats) { 419 printf("nr_symbols: %lu\n", (unsigned long)symbols_nr); 420 printf("symbol_bits: %d\n", elf->symbol_bits); 421 } 422 423 /* Create parent/child links for any cold subfunctions */ 424 list_for_each_entry(sec, &elf->sections, list) { 425 list_for_each_entry(sym, &sec->symbol_list, list) { 426 char pname[MAX_NAME_LEN + 1]; 427 size_t pnamelen; 428 if (sym->type != STT_FUNC) 429 continue; 430 431 if (sym->pfunc == NULL) 432 sym->pfunc = sym; 433 434 if (sym->cfunc == NULL) 435 sym->cfunc = sym; 436 437 coldstr = strstr(sym->name, ".cold"); 438 if (!coldstr) 439 continue; 440 441 pnamelen = coldstr - sym->name; 442 if (pnamelen > MAX_NAME_LEN) { 443 WARN("%s(): parent function name exceeds maximum length of %d characters", 444 sym->name, MAX_NAME_LEN); 445 return -1; 446 } 447 448 strncpy(pname, sym->name, pnamelen); 449 pname[pnamelen] = '\0'; 450 pfunc = find_symbol_by_name(elf, pname); 451 452 if (!pfunc) { 453 WARN("%s(): can't find parent function", 454 sym->name); 455 return -1; 456 } 457 458 sym->pfunc = pfunc; 459 pfunc->cfunc = sym; 460 461 /* 462 * Unfortunately, -fnoreorder-functions puts the child 463 * inside the parent. Remove the overlap so we can 464 * have sane assumptions. 465 * 466 * Note that pfunc->len now no longer matches 467 * pfunc->sym.st_size. 468 */ 469 if (sym->sec == pfunc->sec && 470 sym->offset >= pfunc->offset && 471 sym->offset + sym->len == pfunc->offset + pfunc->len) { 472 pfunc->len -= sym->len; 473 } 474 } 475 } 476 477 return 0; 478 479 err: 480 free(sym); 481 return -1; 482 } 483 484 static struct section *elf_create_reloc_section(struct elf *elf, 485 struct section *base, 486 int reltype); 487 488 int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, 489 unsigned int type, struct symbol *sym, int addend) 490 { 491 struct reloc *reloc; 492 493 if (!sec->reloc && !elf_create_reloc_section(elf, sec, SHT_RELA)) 494 return -1; 495 496 reloc = malloc(sizeof(*reloc)); 497 if (!reloc) { 498 perror("malloc"); 499 return -1; 500 } 501 memset(reloc, 0, sizeof(*reloc)); 502 503 reloc->sec = sec->reloc; 504 reloc->offset = offset; 505 reloc->type = type; 506 reloc->sym = sym; 507 reloc->addend = addend; 508 509 list_add_tail(&reloc->list, &sec->reloc->reloc_list); 510 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 511 512 sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize; 513 sec->reloc->changed = true; 514 515 return 0; 516 } 517 518 int elf_add_reloc_to_insn(struct elf *elf, struct section *sec, 519 unsigned long offset, unsigned int type, 520 struct section *insn_sec, unsigned long insn_off) 521 { 522 struct symbol *sym; 523 int addend; 524 525 if (insn_sec->sym) { 526 sym = insn_sec->sym; 527 addend = insn_off; 528 529 } else { 530 /* 531 * The Clang assembler strips section symbols, so we have to 532 * reference the function symbol instead: 533 */ 534 sym = find_symbol_containing(insn_sec, insn_off); 535 if (!sym) { 536 /* 537 * Hack alert. This happens when we need to reference 538 * the NOP pad insn immediately after the function. 539 */ 540 sym = find_symbol_containing(insn_sec, insn_off - 1); 541 } 542 543 if (!sym) { 544 WARN("can't find symbol containing %s+0x%lx", insn_sec->name, insn_off); 545 return -1; 546 } 547 548 addend = insn_off - sym->offset; 549 } 550 551 return elf_add_reloc(elf, sec, offset, type, sym, addend); 552 } 553 554 static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) 555 { 556 if (!gelf_getrel(sec->data, i, &reloc->rel)) { 557 WARN_ELF("gelf_getrel"); 558 return -1; 559 } 560 reloc->type = GELF_R_TYPE(reloc->rel.r_info); 561 reloc->addend = 0; 562 reloc->offset = reloc->rel.r_offset; 563 *symndx = GELF_R_SYM(reloc->rel.r_info); 564 return 0; 565 } 566 567 static int read_rela_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) 568 { 569 if (!gelf_getrela(sec->data, i, &reloc->rela)) { 570 WARN_ELF("gelf_getrela"); 571 return -1; 572 } 573 reloc->type = GELF_R_TYPE(reloc->rela.r_info); 574 reloc->addend = reloc->rela.r_addend; 575 reloc->offset = reloc->rela.r_offset; 576 *symndx = GELF_R_SYM(reloc->rela.r_info); 577 return 0; 578 } 579 580 static int read_relocs(struct elf *elf) 581 { 582 struct section *sec; 583 struct reloc *reloc; 584 int i; 585 unsigned int symndx; 586 unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0; 587 588 if (!elf_alloc_hash(reloc, elf->text_size / 16)) 589 return -1; 590 591 list_for_each_entry(sec, &elf->sections, list) { 592 if ((sec->sh.sh_type != SHT_RELA) && 593 (sec->sh.sh_type != SHT_REL)) 594 continue; 595 596 sec->base = find_section_by_index(elf, sec->sh.sh_info); 597 if (!sec->base) { 598 WARN("can't find base section for reloc section %s", 599 sec->name); 600 return -1; 601 } 602 603 sec->base->reloc = sec; 604 605 nr_reloc = 0; 606 for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) { 607 reloc = malloc(sizeof(*reloc)); 608 if (!reloc) { 609 perror("malloc"); 610 return -1; 611 } 612 memset(reloc, 0, sizeof(*reloc)); 613 switch (sec->sh.sh_type) { 614 case SHT_REL: 615 if (read_rel_reloc(sec, i, reloc, &symndx)) 616 return -1; 617 break; 618 case SHT_RELA: 619 if (read_rela_reloc(sec, i, reloc, &symndx)) 620 return -1; 621 break; 622 default: return -1; 623 } 624 625 reloc->sec = sec; 626 reloc->idx = i; 627 reloc->sym = find_symbol_by_index(elf, symndx); 628 if (!reloc->sym) { 629 WARN("can't find reloc entry symbol %d for %s", 630 symndx, sec->name); 631 return -1; 632 } 633 634 list_add_tail(&reloc->list, &sec->reloc_list); 635 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 636 637 nr_reloc++; 638 } 639 max_reloc = max(max_reloc, nr_reloc); 640 tot_reloc += nr_reloc; 641 } 642 643 if (stats) { 644 printf("max_reloc: %lu\n", max_reloc); 645 printf("tot_reloc: %lu\n", tot_reloc); 646 printf("reloc_bits: %d\n", elf->reloc_bits); 647 } 648 649 return 0; 650 } 651 652 struct elf *elf_open_read(const char *name, int flags) 653 { 654 struct elf *elf; 655 Elf_Cmd cmd; 656 657 elf_version(EV_CURRENT); 658 659 elf = malloc(sizeof(*elf)); 660 if (!elf) { 661 perror("malloc"); 662 return NULL; 663 } 664 memset(elf, 0, offsetof(struct elf, sections)); 665 666 INIT_LIST_HEAD(&elf->sections); 667 668 elf->fd = open(name, flags); 669 if (elf->fd == -1) { 670 fprintf(stderr, "objtool: Can't open '%s': %s\n", 671 name, strerror(errno)); 672 goto err; 673 } 674 675 if ((flags & O_ACCMODE) == O_RDONLY) 676 cmd = ELF_C_READ_MMAP; 677 else if ((flags & O_ACCMODE) == O_RDWR) 678 cmd = ELF_C_RDWR; 679 else /* O_WRONLY */ 680 cmd = ELF_C_WRITE; 681 682 elf->elf = elf_begin(elf->fd, cmd, NULL); 683 if (!elf->elf) { 684 WARN_ELF("elf_begin"); 685 goto err; 686 } 687 688 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { 689 WARN_ELF("gelf_getehdr"); 690 goto err; 691 } 692 693 if (read_sections(elf)) 694 goto err; 695 696 if (read_symbols(elf)) 697 goto err; 698 699 if (read_relocs(elf)) 700 goto err; 701 702 return elf; 703 704 err: 705 elf_close(elf); 706 return NULL; 707 } 708 709 static int elf_add_string(struct elf *elf, struct section *strtab, char *str) 710 { 711 Elf_Data *data; 712 Elf_Scn *s; 713 int len; 714 715 if (!strtab) 716 strtab = find_section_by_name(elf, ".strtab"); 717 if (!strtab) { 718 WARN("can't find .strtab section"); 719 return -1; 720 } 721 722 s = elf_getscn(elf->elf, strtab->idx); 723 if (!s) { 724 WARN_ELF("elf_getscn"); 725 return -1; 726 } 727 728 data = elf_newdata(s); 729 if (!data) { 730 WARN_ELF("elf_newdata"); 731 return -1; 732 } 733 734 data->d_buf = str; 735 data->d_size = strlen(str) + 1; 736 data->d_align = 1; 737 738 len = strtab->sh.sh_size; 739 strtab->sh.sh_size += data->d_size; 740 strtab->changed = true; 741 742 return len; 743 } 744 745 struct section *elf_create_section(struct elf *elf, const char *name, 746 unsigned int sh_flags, size_t entsize, int nr) 747 { 748 struct section *sec, *shstrtab; 749 size_t size = entsize * nr; 750 Elf_Scn *s; 751 752 sec = malloc(sizeof(*sec)); 753 if (!sec) { 754 perror("malloc"); 755 return NULL; 756 } 757 memset(sec, 0, sizeof(*sec)); 758 759 INIT_LIST_HEAD(&sec->symbol_list); 760 INIT_LIST_HEAD(&sec->reloc_list); 761 762 s = elf_newscn(elf->elf); 763 if (!s) { 764 WARN_ELF("elf_newscn"); 765 return NULL; 766 } 767 768 sec->name = strdup(name); 769 if (!sec->name) { 770 perror("strdup"); 771 return NULL; 772 } 773 774 sec->idx = elf_ndxscn(s); 775 sec->changed = true; 776 777 sec->data = elf_newdata(s); 778 if (!sec->data) { 779 WARN_ELF("elf_newdata"); 780 return NULL; 781 } 782 783 sec->data->d_size = size; 784 sec->data->d_align = 1; 785 786 if (size) { 787 sec->data->d_buf = malloc(size); 788 if (!sec->data->d_buf) { 789 perror("malloc"); 790 return NULL; 791 } 792 memset(sec->data->d_buf, 0, size); 793 } 794 795 if (!gelf_getshdr(s, &sec->sh)) { 796 WARN_ELF("gelf_getshdr"); 797 return NULL; 798 } 799 800 sec->sh.sh_size = size; 801 sec->sh.sh_entsize = entsize; 802 sec->sh.sh_type = SHT_PROGBITS; 803 sec->sh.sh_addralign = 1; 804 sec->sh.sh_flags = SHF_ALLOC | sh_flags; 805 806 /* Add section name to .shstrtab (or .strtab for Clang) */ 807 shstrtab = find_section_by_name(elf, ".shstrtab"); 808 if (!shstrtab) 809 shstrtab = find_section_by_name(elf, ".strtab"); 810 if (!shstrtab) { 811 WARN("can't find .shstrtab or .strtab section"); 812 return NULL; 813 } 814 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 815 if (sec->sh.sh_name == -1) 816 return NULL; 817 818 list_add_tail(&sec->list, &elf->sections); 819 elf_hash_add(section, &sec->hash, sec->idx); 820 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 821 822 elf->changed = true; 823 824 return sec; 825 } 826 827 static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base) 828 { 829 char *relocname; 830 struct section *sec; 831 832 relocname = malloc(strlen(base->name) + strlen(".rel") + 1); 833 if (!relocname) { 834 perror("malloc"); 835 return NULL; 836 } 837 strcpy(relocname, ".rel"); 838 strcat(relocname, base->name); 839 840 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rel), 0); 841 free(relocname); 842 if (!sec) 843 return NULL; 844 845 base->reloc = sec; 846 sec->base = base; 847 848 sec->sh.sh_type = SHT_REL; 849 sec->sh.sh_addralign = 8; 850 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 851 sec->sh.sh_info = base->idx; 852 sec->sh.sh_flags = SHF_INFO_LINK; 853 854 return sec; 855 } 856 857 static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base) 858 { 859 char *relocname; 860 struct section *sec; 861 862 relocname = malloc(strlen(base->name) + strlen(".rela") + 1); 863 if (!relocname) { 864 perror("malloc"); 865 return NULL; 866 } 867 strcpy(relocname, ".rela"); 868 strcat(relocname, base->name); 869 870 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rela), 0); 871 free(relocname); 872 if (!sec) 873 return NULL; 874 875 base->reloc = sec; 876 sec->base = base; 877 878 sec->sh.sh_type = SHT_RELA; 879 sec->sh.sh_addralign = 8; 880 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 881 sec->sh.sh_info = base->idx; 882 sec->sh.sh_flags = SHF_INFO_LINK; 883 884 return sec; 885 } 886 887 static struct section *elf_create_reloc_section(struct elf *elf, 888 struct section *base, 889 int reltype) 890 { 891 switch (reltype) { 892 case SHT_REL: return elf_create_rel_reloc_section(elf, base); 893 case SHT_RELA: return elf_create_rela_reloc_section(elf, base); 894 default: return NULL; 895 } 896 } 897 898 static int elf_rebuild_rel_reloc_section(struct section *sec) 899 { 900 struct reloc *reloc; 901 int idx = 0; 902 void *buf; 903 904 /* Allocate a buffer for relocations */ 905 buf = malloc(sec->sh.sh_size); 906 if (!buf) { 907 perror("malloc"); 908 return -1; 909 } 910 911 sec->data->d_buf = buf; 912 sec->data->d_size = sec->sh.sh_size; 913 sec->data->d_type = ELF_T_REL; 914 915 idx = 0; 916 list_for_each_entry(reloc, &sec->reloc_list, list) { 917 reloc->rel.r_offset = reloc->offset; 918 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 919 if (!gelf_update_rel(sec->data, idx, &reloc->rel)) { 920 WARN_ELF("gelf_update_rel"); 921 return -1; 922 } 923 idx++; 924 } 925 926 return 0; 927 } 928 929 static int elf_rebuild_rela_reloc_section(struct section *sec) 930 { 931 struct reloc *reloc; 932 int idx = 0; 933 void *buf; 934 935 /* Allocate a buffer for relocations with addends */ 936 buf = malloc(sec->sh.sh_size); 937 if (!buf) { 938 perror("malloc"); 939 return -1; 940 } 941 942 sec->data->d_buf = buf; 943 sec->data->d_size = sec->sh.sh_size; 944 sec->data->d_type = ELF_T_RELA; 945 946 idx = 0; 947 list_for_each_entry(reloc, &sec->reloc_list, list) { 948 reloc->rela.r_offset = reloc->offset; 949 reloc->rela.r_addend = reloc->addend; 950 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 951 if (!gelf_update_rela(sec->data, idx, &reloc->rela)) { 952 WARN_ELF("gelf_update_rela"); 953 return -1; 954 } 955 idx++; 956 } 957 958 return 0; 959 } 960 961 static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) 962 { 963 switch (sec->sh.sh_type) { 964 case SHT_REL: return elf_rebuild_rel_reloc_section(sec); 965 case SHT_RELA: return elf_rebuild_rela_reloc_section(sec); 966 default: return -1; 967 } 968 } 969 970 int elf_write_insn(struct elf *elf, struct section *sec, 971 unsigned long offset, unsigned int len, 972 const char *insn) 973 { 974 Elf_Data *data = sec->data; 975 976 if (data->d_type != ELF_T_BYTE || data->d_off) { 977 WARN("write to unexpected data for section: %s", sec->name); 978 return -1; 979 } 980 981 memcpy(data->d_buf + offset, insn, len); 982 elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY); 983 984 elf->changed = true; 985 986 return 0; 987 } 988 989 int elf_write_reloc(struct elf *elf, struct reloc *reloc) 990 { 991 struct section *sec = reloc->sec; 992 993 if (sec->sh.sh_type == SHT_REL) { 994 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 995 reloc->rel.r_offset = reloc->offset; 996 997 if (!gelf_update_rel(sec->data, reloc->idx, &reloc->rel)) { 998 WARN_ELF("gelf_update_rel"); 999 return -1; 1000 } 1001 } else { 1002 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1003 reloc->rela.r_addend = reloc->addend; 1004 reloc->rela.r_offset = reloc->offset; 1005 1006 if (!gelf_update_rela(sec->data, reloc->idx, &reloc->rela)) { 1007 WARN_ELF("gelf_update_rela"); 1008 return -1; 1009 } 1010 } 1011 1012 elf->changed = true; 1013 1014 return 0; 1015 } 1016 1017 int elf_write(struct elf *elf) 1018 { 1019 struct section *sec; 1020 Elf_Scn *s; 1021 1022 /* Update changed relocation sections and section headers: */ 1023 list_for_each_entry(sec, &elf->sections, list) { 1024 if (sec->changed) { 1025 s = elf_getscn(elf->elf, sec->idx); 1026 if (!s) { 1027 WARN_ELF("elf_getscn"); 1028 return -1; 1029 } 1030 if (!gelf_update_shdr(s, &sec->sh)) { 1031 WARN_ELF("gelf_update_shdr"); 1032 return -1; 1033 } 1034 1035 if (sec->base && 1036 elf_rebuild_reloc_section(elf, sec)) { 1037 WARN("elf_rebuild_reloc_section"); 1038 return -1; 1039 } 1040 1041 sec->changed = false; 1042 elf->changed = true; 1043 } 1044 } 1045 1046 /* Make sure the new section header entries get updated properly. */ 1047 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); 1048 1049 /* Write all changes to the file. */ 1050 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { 1051 WARN_ELF("elf_update"); 1052 return -1; 1053 } 1054 1055 elf->changed = false; 1056 1057 return 0; 1058 } 1059 1060 void elf_close(struct elf *elf) 1061 { 1062 struct section *sec, *tmpsec; 1063 struct symbol *sym, *tmpsym; 1064 struct reloc *reloc, *tmpreloc; 1065 1066 if (elf->elf) 1067 elf_end(elf->elf); 1068 1069 if (elf->fd > 0) 1070 close(elf->fd); 1071 1072 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { 1073 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { 1074 list_del(&sym->list); 1075 hash_del(&sym->hash); 1076 free(sym); 1077 } 1078 list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) { 1079 list_del(&reloc->list); 1080 hash_del(&reloc->hash); 1081 free(reloc); 1082 } 1083 list_del(&sec->list); 1084 free(sec); 1085 } 1086 1087 free(elf); 1088 } 1089