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 sec->len = sec->sh.sh_size; 290 291 if (sec->sh.sh_flags & SHF_EXECINSTR) 292 elf->text_size += sec->len; 293 294 list_add_tail(&sec->list, &elf->sections); 295 elf_hash_add(section, &sec->hash, sec->idx); 296 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 297 } 298 299 if (stats) { 300 printf("nr_sections: %lu\n", (unsigned long)sections_nr); 301 printf("section_bits: %d\n", elf->section_bits); 302 } 303 304 /* sanity check, one more call to elf_nextscn() should return NULL */ 305 if (elf_nextscn(elf->elf, s)) { 306 WARN("section entry mismatch"); 307 return -1; 308 } 309 310 return 0; 311 } 312 313 static void elf_add_symbol(struct elf *elf, struct symbol *sym) 314 { 315 struct list_head *entry; 316 struct rb_node *pnode; 317 318 sym->type = GELF_ST_TYPE(sym->sym.st_info); 319 sym->bind = GELF_ST_BIND(sym->sym.st_info); 320 321 sym->offset = sym->sym.st_value; 322 sym->len = sym->sym.st_size; 323 324 rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset); 325 pnode = rb_prev(&sym->node); 326 if (pnode) 327 entry = &rb_entry(pnode, struct symbol, node)->list; 328 else 329 entry = &sym->sec->symbol_list; 330 list_add(&sym->list, entry); 331 elf_hash_add(symbol, &sym->hash, sym->idx); 332 elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); 333 334 /* 335 * Don't store empty STT_NOTYPE symbols in the rbtree. They 336 * can exist within a function, confusing the sorting. 337 */ 338 if (!sym->len) 339 rb_erase(&sym->node, &sym->sec->symbol_tree); 340 } 341 342 static int read_symbols(struct elf *elf) 343 { 344 struct section *symtab, *symtab_shndx, *sec; 345 struct symbol *sym, *pfunc; 346 int symbols_nr, i; 347 char *coldstr; 348 Elf_Data *shndx_data = NULL; 349 Elf32_Word shndx; 350 351 symtab = find_section_by_name(elf, ".symtab"); 352 if (symtab) { 353 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 354 if (symtab_shndx) 355 shndx_data = symtab_shndx->data; 356 357 symbols_nr = symtab->sh.sh_size / symtab->sh.sh_entsize; 358 } else { 359 /* 360 * A missing symbol table is actually possible if it's an empty 361 * .o file. This can happen for thunk_64.o. Make sure to at 362 * least allocate the symbol hash tables so we can do symbol 363 * lookups without crashing. 364 */ 365 symbols_nr = 0; 366 } 367 368 if (!elf_alloc_hash(symbol, symbols_nr) || 369 !elf_alloc_hash(symbol_name, symbols_nr)) 370 return -1; 371 372 for (i = 0; i < symbols_nr; i++) { 373 sym = malloc(sizeof(*sym)); 374 if (!sym) { 375 perror("malloc"); 376 return -1; 377 } 378 memset(sym, 0, sizeof(*sym)); 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->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->len; 738 strtab->len += data->d_size; 739 strtab->changed = true; 740 741 return len; 742 } 743 744 struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name) 745 { 746 struct section *symtab, *symtab_shndx; 747 struct symbol *sym; 748 Elf_Data *data; 749 Elf_Scn *s; 750 751 sym = malloc(sizeof(*sym)); 752 if (!sym) { 753 perror("malloc"); 754 return NULL; 755 } 756 memset(sym, 0, sizeof(*sym)); 757 758 sym->name = strdup(name); 759 760 sym->sym.st_name = elf_add_string(elf, NULL, sym->name); 761 if (sym->sym.st_name == -1) 762 return NULL; 763 764 sym->sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 765 // st_other 0 766 // st_shndx 0 767 // st_value 0 768 // st_size 0 769 770 symtab = find_section_by_name(elf, ".symtab"); 771 if (!symtab) { 772 WARN("can't find .symtab"); 773 return NULL; 774 } 775 776 s = elf_getscn(elf->elf, symtab->idx); 777 if (!s) { 778 WARN_ELF("elf_getscn"); 779 return NULL; 780 } 781 782 data = elf_newdata(s); 783 if (!data) { 784 WARN_ELF("elf_newdata"); 785 return NULL; 786 } 787 788 data->d_buf = &sym->sym; 789 data->d_size = sizeof(sym->sym); 790 data->d_align = 1; 791 data->d_type = ELF_T_SYM; 792 793 sym->idx = symtab->len / sizeof(sym->sym); 794 795 symtab->len += data->d_size; 796 symtab->changed = true; 797 798 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 799 if (symtab_shndx) { 800 s = elf_getscn(elf->elf, symtab_shndx->idx); 801 if (!s) { 802 WARN_ELF("elf_getscn"); 803 return NULL; 804 } 805 806 data = elf_newdata(s); 807 if (!data) { 808 WARN_ELF("elf_newdata"); 809 return NULL; 810 } 811 812 data->d_buf = &sym->sym.st_size; /* conveniently 0 */ 813 data->d_size = sizeof(Elf32_Word); 814 data->d_align = 4; 815 data->d_type = ELF_T_WORD; 816 817 symtab_shndx->len += 4; 818 symtab_shndx->changed = true; 819 } 820 821 sym->sec = find_section_by_index(elf, 0); 822 823 elf_add_symbol(elf, sym); 824 825 return sym; 826 } 827 828 struct section *elf_create_section(struct elf *elf, const char *name, 829 unsigned int sh_flags, size_t entsize, int nr) 830 { 831 struct section *sec, *shstrtab; 832 size_t size = entsize * nr; 833 Elf_Scn *s; 834 835 sec = malloc(sizeof(*sec)); 836 if (!sec) { 837 perror("malloc"); 838 return NULL; 839 } 840 memset(sec, 0, sizeof(*sec)); 841 842 INIT_LIST_HEAD(&sec->symbol_list); 843 INIT_LIST_HEAD(&sec->reloc_list); 844 845 s = elf_newscn(elf->elf); 846 if (!s) { 847 WARN_ELF("elf_newscn"); 848 return NULL; 849 } 850 851 sec->name = strdup(name); 852 if (!sec->name) { 853 perror("strdup"); 854 return NULL; 855 } 856 857 sec->idx = elf_ndxscn(s); 858 sec->len = size; 859 sec->changed = true; 860 861 sec->data = elf_newdata(s); 862 if (!sec->data) { 863 WARN_ELF("elf_newdata"); 864 return NULL; 865 } 866 867 sec->data->d_size = size; 868 sec->data->d_align = 1; 869 870 if (size) { 871 sec->data->d_buf = malloc(size); 872 if (!sec->data->d_buf) { 873 perror("malloc"); 874 return NULL; 875 } 876 memset(sec->data->d_buf, 0, size); 877 } 878 879 if (!gelf_getshdr(s, &sec->sh)) { 880 WARN_ELF("gelf_getshdr"); 881 return NULL; 882 } 883 884 sec->sh.sh_size = size; 885 sec->sh.sh_entsize = entsize; 886 sec->sh.sh_type = SHT_PROGBITS; 887 sec->sh.sh_addralign = 1; 888 sec->sh.sh_flags = SHF_ALLOC | sh_flags; 889 890 /* Add section name to .shstrtab (or .strtab for Clang) */ 891 shstrtab = find_section_by_name(elf, ".shstrtab"); 892 if (!shstrtab) 893 shstrtab = find_section_by_name(elf, ".strtab"); 894 if (!shstrtab) { 895 WARN("can't find .shstrtab or .strtab section"); 896 return NULL; 897 } 898 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 899 if (sec->sh.sh_name == -1) 900 return NULL; 901 902 list_add_tail(&sec->list, &elf->sections); 903 elf_hash_add(section, &sec->hash, sec->idx); 904 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 905 906 elf->changed = true; 907 908 return sec; 909 } 910 911 static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base) 912 { 913 char *relocname; 914 struct section *sec; 915 916 relocname = malloc(strlen(base->name) + strlen(".rel") + 1); 917 if (!relocname) { 918 perror("malloc"); 919 return NULL; 920 } 921 strcpy(relocname, ".rel"); 922 strcat(relocname, base->name); 923 924 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rel), 0); 925 free(relocname); 926 if (!sec) 927 return NULL; 928 929 base->reloc = sec; 930 sec->base = base; 931 932 sec->sh.sh_type = SHT_REL; 933 sec->sh.sh_addralign = 8; 934 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 935 sec->sh.sh_info = base->idx; 936 sec->sh.sh_flags = SHF_INFO_LINK; 937 938 return sec; 939 } 940 941 static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base) 942 { 943 char *relocname; 944 struct section *sec; 945 946 relocname = malloc(strlen(base->name) + strlen(".rela") + 1); 947 if (!relocname) { 948 perror("malloc"); 949 return NULL; 950 } 951 strcpy(relocname, ".rela"); 952 strcat(relocname, base->name); 953 954 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rela), 0); 955 free(relocname); 956 if (!sec) 957 return NULL; 958 959 base->reloc = sec; 960 sec->base = base; 961 962 sec->sh.sh_type = SHT_RELA; 963 sec->sh.sh_addralign = 8; 964 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 965 sec->sh.sh_info = base->idx; 966 sec->sh.sh_flags = SHF_INFO_LINK; 967 968 return sec; 969 } 970 971 static struct section *elf_create_reloc_section(struct elf *elf, 972 struct section *base, 973 int reltype) 974 { 975 switch (reltype) { 976 case SHT_REL: return elf_create_rel_reloc_section(elf, base); 977 case SHT_RELA: return elf_create_rela_reloc_section(elf, base); 978 default: return NULL; 979 } 980 } 981 982 static int elf_rebuild_rel_reloc_section(struct section *sec, int nr) 983 { 984 struct reloc *reloc; 985 int idx = 0, size; 986 void *buf; 987 988 /* Allocate a buffer for relocations */ 989 size = nr * sizeof(GElf_Rel); 990 buf = malloc(size); 991 if (!buf) { 992 perror("malloc"); 993 return -1; 994 } 995 996 sec->data->d_buf = buf; 997 sec->data->d_size = size; 998 sec->data->d_type = ELF_T_REL; 999 1000 sec->sh.sh_size = size; 1001 1002 idx = 0; 1003 list_for_each_entry(reloc, &sec->reloc_list, list) { 1004 reloc->rel.r_offset = reloc->offset; 1005 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1006 gelf_update_rel(sec->data, idx, &reloc->rel); 1007 idx++; 1008 } 1009 1010 return 0; 1011 } 1012 1013 static int elf_rebuild_rela_reloc_section(struct section *sec, int nr) 1014 { 1015 struct reloc *reloc; 1016 int idx = 0, size; 1017 void *buf; 1018 1019 /* Allocate a buffer for relocations with addends */ 1020 size = nr * sizeof(GElf_Rela); 1021 buf = malloc(size); 1022 if (!buf) { 1023 perror("malloc"); 1024 return -1; 1025 } 1026 1027 sec->data->d_buf = buf; 1028 sec->data->d_size = size; 1029 sec->data->d_type = ELF_T_RELA; 1030 1031 sec->sh.sh_size = size; 1032 1033 idx = 0; 1034 list_for_each_entry(reloc, &sec->reloc_list, list) { 1035 reloc->rela.r_offset = reloc->offset; 1036 reloc->rela.r_addend = reloc->addend; 1037 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1038 gelf_update_rela(sec->data, idx, &reloc->rela); 1039 idx++; 1040 } 1041 1042 return 0; 1043 } 1044 1045 static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) 1046 { 1047 struct reloc *reloc; 1048 int nr; 1049 1050 nr = 0; 1051 list_for_each_entry(reloc, &sec->reloc_list, list) 1052 nr++; 1053 1054 switch (sec->sh.sh_type) { 1055 case SHT_REL: return elf_rebuild_rel_reloc_section(sec, nr); 1056 case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr); 1057 default: return -1; 1058 } 1059 } 1060 1061 int elf_write_insn(struct elf *elf, struct section *sec, 1062 unsigned long offset, unsigned int len, 1063 const char *insn) 1064 { 1065 Elf_Data *data = sec->data; 1066 1067 if (data->d_type != ELF_T_BYTE || data->d_off) { 1068 WARN("write to unexpected data for section: %s", sec->name); 1069 return -1; 1070 } 1071 1072 memcpy(data->d_buf + offset, insn, len); 1073 elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY); 1074 1075 elf->changed = true; 1076 1077 return 0; 1078 } 1079 1080 int elf_write_reloc(struct elf *elf, struct reloc *reloc) 1081 { 1082 struct section *sec = reloc->sec; 1083 1084 if (sec->sh.sh_type == SHT_REL) { 1085 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1086 reloc->rel.r_offset = reloc->offset; 1087 1088 if (!gelf_update_rel(sec->data, reloc->idx, &reloc->rel)) { 1089 WARN_ELF("gelf_update_rel"); 1090 return -1; 1091 } 1092 } else { 1093 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1094 reloc->rela.r_addend = reloc->addend; 1095 reloc->rela.r_offset = reloc->offset; 1096 1097 if (!gelf_update_rela(sec->data, reloc->idx, &reloc->rela)) { 1098 WARN_ELF("gelf_update_rela"); 1099 return -1; 1100 } 1101 } 1102 1103 elf->changed = true; 1104 1105 return 0; 1106 } 1107 1108 int elf_write(struct elf *elf) 1109 { 1110 struct section *sec; 1111 Elf_Scn *s; 1112 1113 /* Update changed relocation sections and section headers: */ 1114 list_for_each_entry(sec, &elf->sections, list) { 1115 if (sec->changed) { 1116 if (sec->base && 1117 elf_rebuild_reloc_section(elf, sec)) { 1118 WARN("elf_rebuild_reloc_section"); 1119 return -1; 1120 } 1121 1122 s = elf_getscn(elf->elf, sec->idx); 1123 if (!s) { 1124 WARN_ELF("elf_getscn"); 1125 return -1; 1126 } 1127 if (!gelf_update_shdr(s, &sec->sh)) { 1128 WARN_ELF("gelf_update_shdr"); 1129 return -1; 1130 } 1131 1132 sec->changed = false; 1133 elf->changed = true; 1134 } 1135 } 1136 1137 /* Make sure the new section header entries get updated properly. */ 1138 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); 1139 1140 /* Write all changes to the file. */ 1141 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { 1142 WARN_ELF("elf_update"); 1143 return -1; 1144 } 1145 1146 elf->changed = false; 1147 1148 return 0; 1149 } 1150 1151 void elf_close(struct elf *elf) 1152 { 1153 struct section *sec, *tmpsec; 1154 struct symbol *sym, *tmpsym; 1155 struct reloc *reloc, *tmpreloc; 1156 1157 if (elf->elf) 1158 elf_end(elf->elf); 1159 1160 if (elf->fd > 0) 1161 close(elf->fd); 1162 1163 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { 1164 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { 1165 list_del(&sym->list); 1166 hash_del(&sym->hash); 1167 free(sym); 1168 } 1169 list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) { 1170 list_del(&reloc->list); 1171 hash_del(&reloc->hash); 1172 free(reloc); 1173 } 1174 list_del(&sec->list); 1175 free(sec); 1176 } 1177 1178 free(elf); 1179 } 1180