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 <linux/interval_tree_generic.h> 20 #include <objtool/builtin.h> 21 22 #include <objtool/elf.h> 23 #include <objtool/warn.h> 24 25 static inline u32 str_hash(const char *str) 26 { 27 return jhash(str, strlen(str), 0); 28 } 29 30 #define __elf_table(name) (elf->name##_hash) 31 #define __elf_bits(name) (elf->name##_bits) 32 33 #define __elf_table_entry(name, key) \ 34 __elf_table(name)[hash_min(key, __elf_bits(name))] 35 36 #define elf_hash_add(name, node, key) \ 37 ({ \ 38 struct elf_hash_node *__node = node; \ 39 __node->next = __elf_table_entry(name, key); \ 40 __elf_table_entry(name, key) = __node; \ 41 }) 42 43 static inline void __elf_hash_del(struct elf_hash_node *node, 44 struct elf_hash_node **head) 45 { 46 struct elf_hash_node *cur, *prev; 47 48 if (node == *head) { 49 *head = node->next; 50 return; 51 } 52 53 for (prev = NULL, cur = *head; cur; prev = cur, cur = cur->next) { 54 if (cur == node) { 55 prev->next = cur->next; 56 break; 57 } 58 } 59 } 60 61 #define elf_hash_del(name, node, key) \ 62 __elf_hash_del(node, &__elf_table_entry(name, key)) 63 64 #define elf_list_entry(ptr, type, member) \ 65 ({ \ 66 typeof(ptr) __ptr = (ptr); \ 67 __ptr ? container_of(__ptr, type, member) : NULL; \ 68 }) 69 70 #define elf_hash_for_each_possible(name, obj, member, key) \ 71 for (obj = elf_list_entry(__elf_table_entry(name, key), typeof(*obj), member); \ 72 obj; \ 73 obj = elf_list_entry(obj->member.next, typeof(*(obj)), member)) 74 75 #define elf_alloc_hash(name, size) \ 76 ({ \ 77 __elf_bits(name) = max(10, ilog2(size)); \ 78 __elf_table(name) = mmap(NULL, sizeof(struct elf_hash_node *) << __elf_bits(name), \ 79 PROT_READ|PROT_WRITE, \ 80 MAP_PRIVATE|MAP_ANON, -1, 0); \ 81 if (__elf_table(name) == (void *)-1L) { \ 82 WARN("mmap fail " #name); \ 83 __elf_table(name) = NULL; \ 84 } \ 85 __elf_table(name); \ 86 }) 87 88 static inline unsigned long __sym_start(struct symbol *s) 89 { 90 return s->offset; 91 } 92 93 static inline unsigned long __sym_last(struct symbol *s) 94 { 95 return s->offset + s->len - 1; 96 } 97 98 INTERVAL_TREE_DEFINE(struct symbol, node, unsigned long, __subtree_last, 99 __sym_start, __sym_last, static, __sym) 100 101 #define __sym_for_each(_iter, _tree, _start, _end) \ 102 for (_iter = __sym_iter_first((_tree), (_start), (_end)); \ 103 _iter; _iter = __sym_iter_next(_iter, (_start), (_end))) 104 105 struct symbol_hole { 106 unsigned long key; 107 const struct symbol *sym; 108 }; 109 110 /* 111 * Find !section symbol where @offset is after it. 112 */ 113 static int symbol_hole_by_offset(const void *key, const struct rb_node *node) 114 { 115 const struct symbol *s = rb_entry(node, struct symbol, node); 116 struct symbol_hole *sh = (void *)key; 117 118 if (sh->key < s->offset) 119 return -1; 120 121 if (sh->key >= s->offset + s->len) { 122 if (s->type != STT_SECTION) 123 sh->sym = s; 124 return 1; 125 } 126 127 return 0; 128 } 129 130 struct section *find_section_by_name(const struct elf *elf, const char *name) 131 { 132 struct section *sec; 133 134 elf_hash_for_each_possible(section_name, sec, name_hash, str_hash(name)) { 135 if (!strcmp(sec->name, name)) 136 return sec; 137 } 138 139 return NULL; 140 } 141 142 static struct section *find_section_by_index(struct elf *elf, 143 unsigned int idx) 144 { 145 struct section *sec; 146 147 elf_hash_for_each_possible(section, sec, hash, idx) { 148 if (sec->idx == idx) 149 return sec; 150 } 151 152 return NULL; 153 } 154 155 static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx) 156 { 157 struct symbol *sym; 158 159 elf_hash_for_each_possible(symbol, sym, hash, idx) { 160 if (sym->idx == idx) 161 return sym; 162 } 163 164 return NULL; 165 } 166 167 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) 168 { 169 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; 170 struct symbol *iter; 171 172 __sym_for_each(iter, tree, offset, offset) { 173 if (iter->offset == offset && iter->type != STT_SECTION) 174 return iter; 175 } 176 177 return NULL; 178 } 179 180 struct symbol *find_func_by_offset(struct section *sec, unsigned long offset) 181 { 182 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; 183 struct symbol *iter; 184 185 __sym_for_each(iter, tree, offset, offset) { 186 if (iter->offset == offset && iter->type == STT_FUNC) 187 return iter; 188 } 189 190 return NULL; 191 } 192 193 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset) 194 { 195 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; 196 struct symbol *iter; 197 198 __sym_for_each(iter, tree, offset, offset) { 199 if (iter->type != STT_SECTION) 200 return iter; 201 } 202 203 return NULL; 204 } 205 206 /* 207 * Returns size of hole starting at @offset. 208 */ 209 int find_symbol_hole_containing(const struct section *sec, unsigned long offset) 210 { 211 struct symbol_hole hole = { 212 .key = offset, 213 .sym = NULL, 214 }; 215 struct rb_node *n; 216 struct symbol *s; 217 218 /* 219 * Find the rightmost symbol for which @offset is after it. 220 */ 221 n = rb_find(&hole, &sec->symbol_tree.rb_root, symbol_hole_by_offset); 222 223 /* found a symbol that contains @offset */ 224 if (n) 225 return 0; /* not a hole */ 226 227 /* didn't find a symbol for which @offset is after it */ 228 if (!hole.sym) 229 return 0; /* not a hole */ 230 231 /* @offset >= sym->offset + sym->len, find symbol after it */ 232 n = rb_next(&hole.sym->node); 233 if (!n) 234 return -1; /* until end of address space */ 235 236 /* hole until start of next symbol */ 237 s = rb_entry(n, struct symbol, node); 238 return s->offset - offset; 239 } 240 241 struct symbol *find_func_containing(struct section *sec, unsigned long offset) 242 { 243 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; 244 struct symbol *iter; 245 246 __sym_for_each(iter, tree, offset, offset) { 247 if (iter->type == STT_FUNC) 248 return iter; 249 } 250 251 return NULL; 252 } 253 254 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name) 255 { 256 struct symbol *sym; 257 258 elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { 259 if (!strcmp(sym->name, name)) 260 return sym; 261 } 262 263 return NULL; 264 } 265 266 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, 267 unsigned long offset, unsigned int len) 268 { 269 struct reloc *reloc, *r = NULL; 270 struct section *rsec; 271 unsigned long o; 272 273 rsec = sec->rsec; 274 if (!rsec) 275 return NULL; 276 277 for_offset_range(o, offset, offset + len) { 278 elf_hash_for_each_possible(reloc, reloc, hash, 279 sec_offset_hash(rsec, o)) { 280 if (reloc->sec != rsec) 281 continue; 282 283 if (reloc_offset(reloc) >= offset && 284 reloc_offset(reloc) < offset + len) { 285 if (!r || reloc_offset(reloc) < reloc_offset(r)) 286 r = reloc; 287 } 288 } 289 if (r) 290 return r; 291 } 292 293 return NULL; 294 } 295 296 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) 297 { 298 return find_reloc_by_dest_range(elf, sec, offset, 1); 299 } 300 301 static bool is_dwarf_section(struct section *sec) 302 { 303 return !strncmp(sec->name, ".debug_", 7); 304 } 305 306 static int read_sections(struct elf *elf) 307 { 308 Elf_Scn *s = NULL; 309 struct section *sec; 310 size_t shstrndx, sections_nr; 311 int i; 312 313 if (elf_getshdrnum(elf->elf, §ions_nr)) { 314 WARN_ELF("elf_getshdrnum"); 315 return -1; 316 } 317 318 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { 319 WARN_ELF("elf_getshdrstrndx"); 320 return -1; 321 } 322 323 if (!elf_alloc_hash(section, sections_nr) || 324 !elf_alloc_hash(section_name, sections_nr)) 325 return -1; 326 327 elf->section_data = calloc(sections_nr, sizeof(*sec)); 328 if (!elf->section_data) { 329 perror("calloc"); 330 return -1; 331 } 332 for (i = 0; i < sections_nr; i++) { 333 sec = &elf->section_data[i]; 334 335 INIT_LIST_HEAD(&sec->symbol_list); 336 337 s = elf_getscn(elf->elf, i); 338 if (!s) { 339 WARN_ELF("elf_getscn"); 340 return -1; 341 } 342 343 sec->idx = elf_ndxscn(s); 344 345 if (!gelf_getshdr(s, &sec->sh)) { 346 WARN_ELF("gelf_getshdr"); 347 return -1; 348 } 349 350 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); 351 if (!sec->name) { 352 WARN_ELF("elf_strptr"); 353 return -1; 354 } 355 356 if (sec->sh.sh_size != 0 && !is_dwarf_section(sec)) { 357 sec->data = elf_getdata(s, NULL); 358 if (!sec->data) { 359 WARN_ELF("elf_getdata"); 360 return -1; 361 } 362 if (sec->data->d_off != 0 || 363 sec->data->d_size != sec->sh.sh_size) { 364 WARN("unexpected data attributes for %s", 365 sec->name); 366 return -1; 367 } 368 } 369 370 list_add_tail(&sec->list, &elf->sections); 371 elf_hash_add(section, &sec->hash, sec->idx); 372 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 373 374 if (is_reloc_sec(sec)) 375 elf->num_relocs += sec_num_entries(sec); 376 } 377 378 if (opts.stats) { 379 printf("nr_sections: %lu\n", (unsigned long)sections_nr); 380 printf("section_bits: %d\n", elf->section_bits); 381 } 382 383 /* sanity check, one more call to elf_nextscn() should return NULL */ 384 if (elf_nextscn(elf->elf, s)) { 385 WARN("section entry mismatch"); 386 return -1; 387 } 388 389 return 0; 390 } 391 392 static void elf_add_symbol(struct elf *elf, struct symbol *sym) 393 { 394 struct list_head *entry; 395 struct rb_node *pnode; 396 struct symbol *iter; 397 398 INIT_LIST_HEAD(&sym->pv_target); 399 sym->alias = sym; 400 401 sym->type = GELF_ST_TYPE(sym->sym.st_info); 402 sym->bind = GELF_ST_BIND(sym->sym.st_info); 403 404 if (sym->type == STT_FILE) 405 elf->num_files++; 406 407 sym->offset = sym->sym.st_value; 408 sym->len = sym->sym.st_size; 409 410 __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { 411 if (iter->offset == sym->offset && iter->type == sym->type) 412 iter->alias = sym; 413 } 414 415 __sym_insert(sym, &sym->sec->symbol_tree); 416 pnode = rb_prev(&sym->node); 417 if (pnode) 418 entry = &rb_entry(pnode, struct symbol, node)->list; 419 else 420 entry = &sym->sec->symbol_list; 421 list_add(&sym->list, entry); 422 elf_hash_add(symbol, &sym->hash, sym->idx); 423 elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); 424 425 /* 426 * Don't store empty STT_NOTYPE symbols in the rbtree. They 427 * can exist within a function, confusing the sorting. 428 */ 429 if (!sym->len) 430 __sym_remove(sym, &sym->sec->symbol_tree); 431 } 432 433 static int read_symbols(struct elf *elf) 434 { 435 struct section *symtab, *symtab_shndx, *sec; 436 struct symbol *sym, *pfunc; 437 int symbols_nr, i; 438 char *coldstr; 439 Elf_Data *shndx_data = NULL; 440 Elf32_Word shndx; 441 442 symtab = find_section_by_name(elf, ".symtab"); 443 if (symtab) { 444 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 445 if (symtab_shndx) 446 shndx_data = symtab_shndx->data; 447 448 symbols_nr = sec_num_entries(symtab); 449 } else { 450 /* 451 * A missing symbol table is actually possible if it's an empty 452 * .o file. This can happen for thunk_64.o. Make sure to at 453 * least allocate the symbol hash tables so we can do symbol 454 * lookups without crashing. 455 */ 456 symbols_nr = 0; 457 } 458 459 if (!elf_alloc_hash(symbol, symbols_nr) || 460 !elf_alloc_hash(symbol_name, symbols_nr)) 461 return -1; 462 463 elf->symbol_data = calloc(symbols_nr, sizeof(*sym)); 464 if (!elf->symbol_data) { 465 perror("calloc"); 466 return -1; 467 } 468 for (i = 0; i < symbols_nr; i++) { 469 sym = &elf->symbol_data[i]; 470 471 sym->idx = i; 472 473 if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, 474 &shndx)) { 475 WARN_ELF("gelf_getsymshndx"); 476 goto err; 477 } 478 479 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, 480 sym->sym.st_name); 481 if (!sym->name) { 482 WARN_ELF("elf_strptr"); 483 goto err; 484 } 485 486 if ((sym->sym.st_shndx > SHN_UNDEF && 487 sym->sym.st_shndx < SHN_LORESERVE) || 488 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { 489 if (sym->sym.st_shndx != SHN_XINDEX) 490 shndx = sym->sym.st_shndx; 491 492 sym->sec = find_section_by_index(elf, shndx); 493 if (!sym->sec) { 494 WARN("couldn't find section for symbol %s", 495 sym->name); 496 goto err; 497 } 498 if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { 499 sym->name = sym->sec->name; 500 sym->sec->sym = sym; 501 } 502 } else 503 sym->sec = find_section_by_index(elf, 0); 504 505 elf_add_symbol(elf, sym); 506 } 507 508 if (opts.stats) { 509 printf("nr_symbols: %lu\n", (unsigned long)symbols_nr); 510 printf("symbol_bits: %d\n", elf->symbol_bits); 511 } 512 513 /* Create parent/child links for any cold subfunctions */ 514 list_for_each_entry(sec, &elf->sections, list) { 515 sec_for_each_sym(sec, sym) { 516 char *pname; 517 size_t pnamelen; 518 if (sym->type != STT_FUNC) 519 continue; 520 521 if (sym->pfunc == NULL) 522 sym->pfunc = sym; 523 524 if (sym->cfunc == NULL) 525 sym->cfunc = sym; 526 527 coldstr = strstr(sym->name, ".cold"); 528 if (!coldstr) 529 continue; 530 531 pnamelen = coldstr - sym->name; 532 pname = strndup(sym->name, pnamelen); 533 if (!pname) { 534 WARN("%s(): failed to allocate memory", 535 sym->name); 536 return -1; 537 } 538 539 pfunc = find_symbol_by_name(elf, pname); 540 free(pname); 541 542 if (!pfunc) { 543 WARN("%s(): can't find parent function", 544 sym->name); 545 return -1; 546 } 547 548 sym->pfunc = pfunc; 549 pfunc->cfunc = sym; 550 551 /* 552 * Unfortunately, -fnoreorder-functions puts the child 553 * inside the parent. Remove the overlap so we can 554 * have sane assumptions. 555 * 556 * Note that pfunc->len now no longer matches 557 * pfunc->sym.st_size. 558 */ 559 if (sym->sec == pfunc->sec && 560 sym->offset >= pfunc->offset && 561 sym->offset + sym->len == pfunc->offset + pfunc->len) { 562 pfunc->len -= sym->len; 563 } 564 } 565 } 566 567 return 0; 568 569 err: 570 free(sym); 571 return -1; 572 } 573 574 /* 575 * @sym's idx has changed. Update the relocs which reference it. 576 */ 577 static int elf_update_sym_relocs(struct elf *elf, struct symbol *sym) 578 { 579 struct reloc *reloc; 580 581 for (reloc = sym->relocs; reloc; reloc = reloc->sym_next_reloc) 582 set_reloc_sym(elf, reloc, reloc->sym->idx); 583 584 return 0; 585 } 586 587 /* 588 * The libelf API is terrible; gelf_update_sym*() takes a data block relative 589 * index value, *NOT* the symbol index. As such, iterate the data blocks and 590 * adjust index until it fits. 591 * 592 * If no data block is found, allow adding a new data block provided the index 593 * is only one past the end. 594 */ 595 static int elf_update_symbol(struct elf *elf, struct section *symtab, 596 struct section *symtab_shndx, struct symbol *sym) 597 { 598 Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF; 599 Elf_Data *symtab_data = NULL, *shndx_data = NULL; 600 Elf64_Xword entsize = symtab->sh.sh_entsize; 601 int max_idx, idx = sym->idx; 602 Elf_Scn *s, *t = NULL; 603 bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE && 604 sym->sym.st_shndx != SHN_XINDEX; 605 606 if (is_special_shndx) 607 shndx = sym->sym.st_shndx; 608 609 s = elf_getscn(elf->elf, symtab->idx); 610 if (!s) { 611 WARN_ELF("elf_getscn"); 612 return -1; 613 } 614 615 if (symtab_shndx) { 616 t = elf_getscn(elf->elf, symtab_shndx->idx); 617 if (!t) { 618 WARN_ELF("elf_getscn"); 619 return -1; 620 } 621 } 622 623 for (;;) { 624 /* get next data descriptor for the relevant sections */ 625 symtab_data = elf_getdata(s, symtab_data); 626 if (t) 627 shndx_data = elf_getdata(t, shndx_data); 628 629 /* end-of-list */ 630 if (!symtab_data) { 631 /* 632 * Over-allocate to avoid O(n^2) symbol creation 633 * behaviour. The down side is that libelf doesn't 634 * like this; see elf_truncate_section() for the fixup. 635 */ 636 int num = max(1U, sym->idx/3); 637 void *buf; 638 639 if (idx) { 640 /* we don't do holes in symbol tables */ 641 WARN("index out of range"); 642 return -1; 643 } 644 645 /* if @idx == 0, it's the next contiguous entry, create it */ 646 symtab_data = elf_newdata(s); 647 if (t) 648 shndx_data = elf_newdata(t); 649 650 buf = calloc(num, entsize); 651 if (!buf) { 652 WARN("malloc"); 653 return -1; 654 } 655 656 symtab_data->d_buf = buf; 657 symtab_data->d_size = num * entsize; 658 symtab_data->d_align = 1; 659 symtab_data->d_type = ELF_T_SYM; 660 661 mark_sec_changed(elf, symtab, true); 662 symtab->truncate = true; 663 664 if (t) { 665 buf = calloc(num, sizeof(Elf32_Word)); 666 if (!buf) { 667 WARN("malloc"); 668 return -1; 669 } 670 671 shndx_data->d_buf = buf; 672 shndx_data->d_size = num * sizeof(Elf32_Word); 673 shndx_data->d_align = sizeof(Elf32_Word); 674 shndx_data->d_type = ELF_T_WORD; 675 676 mark_sec_changed(elf, symtab_shndx, true); 677 symtab_shndx->truncate = true; 678 } 679 680 break; 681 } 682 683 /* empty blocks should not happen */ 684 if (!symtab_data->d_size) { 685 WARN("zero size data"); 686 return -1; 687 } 688 689 /* is this the right block? */ 690 max_idx = symtab_data->d_size / entsize; 691 if (idx < max_idx) 692 break; 693 694 /* adjust index and try again */ 695 idx -= max_idx; 696 } 697 698 /* something went side-ways */ 699 if (idx < 0) { 700 WARN("negative index"); 701 return -1; 702 } 703 704 /* setup extended section index magic and write the symbol */ 705 if ((shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) || is_special_shndx) { 706 sym->sym.st_shndx = shndx; 707 if (!shndx_data) 708 shndx = 0; 709 } else { 710 sym->sym.st_shndx = SHN_XINDEX; 711 if (!shndx_data) { 712 WARN("no .symtab_shndx"); 713 return -1; 714 } 715 } 716 717 if (!gelf_update_symshndx(symtab_data, shndx_data, idx, &sym->sym, shndx)) { 718 WARN_ELF("gelf_update_symshndx"); 719 return -1; 720 } 721 722 return 0; 723 } 724 725 static struct symbol * 726 __elf_create_symbol(struct elf *elf, struct symbol *sym) 727 { 728 struct section *symtab, *symtab_shndx; 729 Elf32_Word first_non_local, new_idx; 730 struct symbol *old; 731 732 symtab = find_section_by_name(elf, ".symtab"); 733 if (symtab) { 734 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 735 } else { 736 WARN("no .symtab"); 737 return NULL; 738 } 739 740 new_idx = sec_num_entries(symtab); 741 742 if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL) 743 goto non_local; 744 745 /* 746 * Move the first global symbol, as per sh_info, into a new, higher 747 * symbol index. This fees up a spot for a new local symbol. 748 */ 749 first_non_local = symtab->sh.sh_info; 750 old = find_symbol_by_index(elf, first_non_local); 751 if (old) { 752 753 elf_hash_del(symbol, &old->hash, old->idx); 754 elf_hash_add(symbol, &old->hash, new_idx); 755 old->idx = new_idx; 756 757 if (elf_update_symbol(elf, symtab, symtab_shndx, old)) { 758 WARN("elf_update_symbol move"); 759 return NULL; 760 } 761 762 if (elf_update_sym_relocs(elf, old)) 763 return NULL; 764 765 new_idx = first_non_local; 766 } 767 768 /* 769 * Either way, we will add a LOCAL symbol. 770 */ 771 symtab->sh.sh_info += 1; 772 773 non_local: 774 sym->idx = new_idx; 775 if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) { 776 WARN("elf_update_symbol"); 777 return NULL; 778 } 779 780 symtab->sh.sh_size += symtab->sh.sh_entsize; 781 mark_sec_changed(elf, symtab, true); 782 783 if (symtab_shndx) { 784 symtab_shndx->sh.sh_size += sizeof(Elf32_Word); 785 mark_sec_changed(elf, symtab_shndx, true); 786 } 787 788 return sym; 789 } 790 791 static struct symbol * 792 elf_create_section_symbol(struct elf *elf, struct section *sec) 793 { 794 struct symbol *sym = calloc(1, sizeof(*sym)); 795 796 if (!sym) { 797 perror("malloc"); 798 return NULL; 799 } 800 801 sym->name = sec->name; 802 sym->sec = sec; 803 804 // st_name 0 805 sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION); 806 // st_other 0 807 // st_value 0 808 // st_size 0 809 810 sym = __elf_create_symbol(elf, sym); 811 if (sym) 812 elf_add_symbol(elf, sym); 813 814 return sym; 815 } 816 817 static int elf_add_string(struct elf *elf, struct section *strtab, char *str); 818 819 struct symbol * 820 elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size) 821 { 822 struct symbol *sym = calloc(1, sizeof(*sym)); 823 size_t namelen = strlen(orig->name) + sizeof("__pfx_"); 824 char *name = malloc(namelen); 825 826 if (!sym || !name) { 827 perror("malloc"); 828 return NULL; 829 } 830 831 snprintf(name, namelen, "__pfx_%s", orig->name); 832 833 sym->name = name; 834 sym->sec = orig->sec; 835 836 sym->sym.st_name = elf_add_string(elf, NULL, name); 837 sym->sym.st_info = orig->sym.st_info; 838 sym->sym.st_value = orig->sym.st_value - size; 839 sym->sym.st_size = size; 840 841 sym = __elf_create_symbol(elf, sym); 842 if (sym) 843 elf_add_symbol(elf, sym); 844 845 return sym; 846 } 847 848 static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, 849 unsigned int reloc_idx, 850 unsigned long offset, struct symbol *sym, 851 s64 addend, unsigned int type) 852 { 853 struct reloc *reloc, empty = { 0 }; 854 855 if (reloc_idx >= sec_num_entries(rsec)) { 856 WARN("%s: bad reloc_idx %u for %s with %d relocs", 857 __func__, reloc_idx, rsec->name, sec_num_entries(rsec)); 858 return NULL; 859 } 860 861 reloc = &rsec->relocs[reloc_idx]; 862 863 if (memcmp(reloc, &empty, sizeof(empty))) { 864 WARN("%s: %s: reloc %d already initialized!", 865 __func__, rsec->name, reloc_idx); 866 return NULL; 867 } 868 869 reloc->sec = rsec; 870 reloc->sym = sym; 871 872 set_reloc_offset(elf, reloc, offset); 873 set_reloc_sym(elf, reloc, sym->idx); 874 set_reloc_type(elf, reloc, type); 875 set_reloc_addend(elf, reloc, addend); 876 877 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 878 reloc->sym_next_reloc = sym->relocs; 879 sym->relocs = reloc; 880 881 return reloc; 882 } 883 884 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, 885 unsigned long offset, 886 unsigned int reloc_idx, 887 struct section *insn_sec, 888 unsigned long insn_off) 889 { 890 struct symbol *sym = insn_sec->sym; 891 int addend = insn_off; 892 893 if (!(insn_sec->sh.sh_flags & SHF_EXECINSTR)) { 894 WARN("bad call to %s() for data symbol %s", 895 __func__, sym->name); 896 return NULL; 897 } 898 899 if (!sym) { 900 /* 901 * Due to how weak functions work, we must use section based 902 * relocations. Symbol based relocations would result in the 903 * weak and non-weak function annotations being overlaid on the 904 * non-weak function after linking. 905 */ 906 sym = elf_create_section_symbol(elf, insn_sec); 907 if (!sym) 908 return NULL; 909 910 insn_sec->sym = sym; 911 } 912 913 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, 914 elf_text_rela_type(elf)); 915 } 916 917 struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec, 918 unsigned long offset, 919 unsigned int reloc_idx, 920 struct symbol *sym, 921 s64 addend) 922 { 923 if (sym->sec && (sec->sh.sh_flags & SHF_EXECINSTR)) { 924 WARN("bad call to %s() for text symbol %s", 925 __func__, sym->name); 926 return NULL; 927 } 928 929 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, 930 elf_data_rela_type(elf)); 931 } 932 933 static int read_relocs(struct elf *elf) 934 { 935 unsigned long nr_reloc, max_reloc = 0; 936 struct section *rsec; 937 struct reloc *reloc; 938 unsigned int symndx; 939 struct symbol *sym; 940 int i; 941 942 if (!elf_alloc_hash(reloc, elf->num_relocs)) 943 return -1; 944 945 list_for_each_entry(rsec, &elf->sections, list) { 946 if (!is_reloc_sec(rsec)) 947 continue; 948 949 rsec->base = find_section_by_index(elf, rsec->sh.sh_info); 950 if (!rsec->base) { 951 WARN("can't find base section for reloc section %s", 952 rsec->name); 953 return -1; 954 } 955 956 rsec->base->rsec = rsec; 957 958 nr_reloc = 0; 959 rsec->relocs = calloc(sec_num_entries(rsec), sizeof(*reloc)); 960 if (!rsec->relocs) { 961 perror("calloc"); 962 return -1; 963 } 964 for (i = 0; i < sec_num_entries(rsec); i++) { 965 reloc = &rsec->relocs[i]; 966 967 reloc->sec = rsec; 968 symndx = reloc_sym(reloc); 969 reloc->sym = sym = find_symbol_by_index(elf, symndx); 970 if (!reloc->sym) { 971 WARN("can't find reloc entry symbol %d for %s", 972 symndx, rsec->name); 973 return -1; 974 } 975 976 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 977 reloc->sym_next_reloc = sym->relocs; 978 sym->relocs = reloc; 979 980 nr_reloc++; 981 } 982 max_reloc = max(max_reloc, nr_reloc); 983 } 984 985 if (opts.stats) { 986 printf("max_reloc: %lu\n", max_reloc); 987 printf("num_relocs: %lu\n", elf->num_relocs); 988 printf("reloc_bits: %d\n", elf->reloc_bits); 989 } 990 991 return 0; 992 } 993 994 struct elf *elf_open_read(const char *name, int flags) 995 { 996 struct elf *elf; 997 Elf_Cmd cmd; 998 999 elf_version(EV_CURRENT); 1000 1001 elf = malloc(sizeof(*elf)); 1002 if (!elf) { 1003 perror("malloc"); 1004 return NULL; 1005 } 1006 memset(elf, 0, sizeof(*elf)); 1007 1008 INIT_LIST_HEAD(&elf->sections); 1009 1010 elf->fd = open(name, flags); 1011 if (elf->fd == -1) { 1012 fprintf(stderr, "objtool: Can't open '%s': %s\n", 1013 name, strerror(errno)); 1014 goto err; 1015 } 1016 1017 if ((flags & O_ACCMODE) == O_RDONLY) 1018 cmd = ELF_C_READ_MMAP; 1019 else if ((flags & O_ACCMODE) == O_RDWR) 1020 cmd = ELF_C_RDWR; 1021 else /* O_WRONLY */ 1022 cmd = ELF_C_WRITE; 1023 1024 elf->elf = elf_begin(elf->fd, cmd, NULL); 1025 if (!elf->elf) { 1026 WARN_ELF("elf_begin"); 1027 goto err; 1028 } 1029 1030 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { 1031 WARN_ELF("gelf_getehdr"); 1032 goto err; 1033 } 1034 1035 if (read_sections(elf)) 1036 goto err; 1037 1038 if (read_symbols(elf)) 1039 goto err; 1040 1041 if (read_relocs(elf)) 1042 goto err; 1043 1044 return elf; 1045 1046 err: 1047 elf_close(elf); 1048 return NULL; 1049 } 1050 1051 static int elf_add_string(struct elf *elf, struct section *strtab, char *str) 1052 { 1053 Elf_Data *data; 1054 Elf_Scn *s; 1055 int len; 1056 1057 if (!strtab) 1058 strtab = find_section_by_name(elf, ".strtab"); 1059 if (!strtab) { 1060 WARN("can't find .strtab section"); 1061 return -1; 1062 } 1063 1064 s = elf_getscn(elf->elf, strtab->idx); 1065 if (!s) { 1066 WARN_ELF("elf_getscn"); 1067 return -1; 1068 } 1069 1070 data = elf_newdata(s); 1071 if (!data) { 1072 WARN_ELF("elf_newdata"); 1073 return -1; 1074 } 1075 1076 data->d_buf = str; 1077 data->d_size = strlen(str) + 1; 1078 data->d_align = 1; 1079 1080 len = strtab->sh.sh_size; 1081 strtab->sh.sh_size += data->d_size; 1082 1083 mark_sec_changed(elf, strtab, true); 1084 1085 return len; 1086 } 1087 1088 struct section *elf_create_section(struct elf *elf, const char *name, 1089 size_t entsize, unsigned int nr) 1090 { 1091 struct section *sec, *shstrtab; 1092 size_t size = entsize * nr; 1093 Elf_Scn *s; 1094 1095 sec = malloc(sizeof(*sec)); 1096 if (!sec) { 1097 perror("malloc"); 1098 return NULL; 1099 } 1100 memset(sec, 0, sizeof(*sec)); 1101 1102 INIT_LIST_HEAD(&sec->symbol_list); 1103 1104 s = elf_newscn(elf->elf); 1105 if (!s) { 1106 WARN_ELF("elf_newscn"); 1107 return NULL; 1108 } 1109 1110 sec->name = strdup(name); 1111 if (!sec->name) { 1112 perror("strdup"); 1113 return NULL; 1114 } 1115 1116 sec->idx = elf_ndxscn(s); 1117 1118 sec->data = elf_newdata(s); 1119 if (!sec->data) { 1120 WARN_ELF("elf_newdata"); 1121 return NULL; 1122 } 1123 1124 sec->data->d_size = size; 1125 sec->data->d_align = 1; 1126 1127 if (size) { 1128 sec->data->d_buf = malloc(size); 1129 if (!sec->data->d_buf) { 1130 perror("malloc"); 1131 return NULL; 1132 } 1133 memset(sec->data->d_buf, 0, size); 1134 } 1135 1136 if (!gelf_getshdr(s, &sec->sh)) { 1137 WARN_ELF("gelf_getshdr"); 1138 return NULL; 1139 } 1140 1141 sec->sh.sh_size = size; 1142 sec->sh.sh_entsize = entsize; 1143 sec->sh.sh_type = SHT_PROGBITS; 1144 sec->sh.sh_addralign = 1; 1145 sec->sh.sh_flags = SHF_ALLOC; 1146 1147 /* Add section name to .shstrtab (or .strtab for Clang) */ 1148 shstrtab = find_section_by_name(elf, ".shstrtab"); 1149 if (!shstrtab) 1150 shstrtab = find_section_by_name(elf, ".strtab"); 1151 if (!shstrtab) { 1152 WARN("can't find .shstrtab or .strtab section"); 1153 return NULL; 1154 } 1155 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 1156 if (sec->sh.sh_name == -1) 1157 return NULL; 1158 1159 list_add_tail(&sec->list, &elf->sections); 1160 elf_hash_add(section, &sec->hash, sec->idx); 1161 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 1162 1163 mark_sec_changed(elf, sec, true); 1164 1165 return sec; 1166 } 1167 1168 static struct section *elf_create_rela_section(struct elf *elf, 1169 struct section *sec, 1170 unsigned int reloc_nr) 1171 { 1172 struct section *rsec; 1173 char *rsec_name; 1174 1175 rsec_name = malloc(strlen(sec->name) + strlen(".rela") + 1); 1176 if (!rsec_name) { 1177 perror("malloc"); 1178 return NULL; 1179 } 1180 strcpy(rsec_name, ".rela"); 1181 strcat(rsec_name, sec->name); 1182 1183 rsec = elf_create_section(elf, rsec_name, elf_rela_size(elf), reloc_nr); 1184 free(rsec_name); 1185 if (!rsec) 1186 return NULL; 1187 1188 rsec->data->d_type = ELF_T_RELA; 1189 rsec->sh.sh_type = SHT_RELA; 1190 rsec->sh.sh_addralign = elf_addr_size(elf); 1191 rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 1192 rsec->sh.sh_info = sec->idx; 1193 rsec->sh.sh_flags = SHF_INFO_LINK; 1194 1195 rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc)); 1196 if (!rsec->relocs) { 1197 perror("calloc"); 1198 return NULL; 1199 } 1200 1201 sec->rsec = rsec; 1202 rsec->base = sec; 1203 1204 return rsec; 1205 } 1206 1207 struct section *elf_create_section_pair(struct elf *elf, const char *name, 1208 size_t entsize, unsigned int nr, 1209 unsigned int reloc_nr) 1210 { 1211 struct section *sec; 1212 1213 sec = elf_create_section(elf, name, entsize, nr); 1214 if (!sec) 1215 return NULL; 1216 1217 if (!elf_create_rela_section(elf, sec, reloc_nr)) 1218 return NULL; 1219 1220 return sec; 1221 } 1222 1223 int elf_write_insn(struct elf *elf, struct section *sec, 1224 unsigned long offset, unsigned int len, 1225 const char *insn) 1226 { 1227 Elf_Data *data = sec->data; 1228 1229 if (data->d_type != ELF_T_BYTE || data->d_off) { 1230 WARN("write to unexpected data for section: %s", sec->name); 1231 return -1; 1232 } 1233 1234 memcpy(data->d_buf + offset, insn, len); 1235 1236 mark_sec_changed(elf, sec, true); 1237 1238 return 0; 1239 } 1240 1241 /* 1242 * When Elf_Scn::sh_size is smaller than the combined Elf_Data::d_size 1243 * do you: 1244 * 1245 * A) adhere to the section header and truncate the data, or 1246 * B) ignore the section header and write out all the data you've got? 1247 * 1248 * Yes, libelf sucks and we need to manually truncate if we over-allocate data. 1249 */ 1250 static int elf_truncate_section(struct elf *elf, struct section *sec) 1251 { 1252 u64 size = sec->sh.sh_size; 1253 bool truncated = false; 1254 Elf_Data *data = NULL; 1255 Elf_Scn *s; 1256 1257 s = elf_getscn(elf->elf, sec->idx); 1258 if (!s) { 1259 WARN_ELF("elf_getscn"); 1260 return -1; 1261 } 1262 1263 for (;;) { 1264 /* get next data descriptor for the relevant section */ 1265 data = elf_getdata(s, data); 1266 1267 if (!data) { 1268 if (size) { 1269 WARN("end of section data but non-zero size left\n"); 1270 return -1; 1271 } 1272 return 0; 1273 } 1274 1275 if (truncated) { 1276 /* when we remove symbols */ 1277 WARN("truncated; but more data\n"); 1278 return -1; 1279 } 1280 1281 if (!data->d_size) { 1282 WARN("zero size data"); 1283 return -1; 1284 } 1285 1286 if (data->d_size > size) { 1287 truncated = true; 1288 data->d_size = size; 1289 } 1290 1291 size -= data->d_size; 1292 } 1293 } 1294 1295 int elf_write(struct elf *elf) 1296 { 1297 struct section *sec; 1298 Elf_Scn *s; 1299 1300 if (opts.dryrun) 1301 return 0; 1302 1303 /* Update changed relocation sections and section headers: */ 1304 list_for_each_entry(sec, &elf->sections, list) { 1305 if (sec->truncate) 1306 elf_truncate_section(elf, sec); 1307 1308 if (sec_changed(sec)) { 1309 s = elf_getscn(elf->elf, sec->idx); 1310 if (!s) { 1311 WARN_ELF("elf_getscn"); 1312 return -1; 1313 } 1314 1315 /* Note this also flags the section dirty */ 1316 if (!gelf_update_shdr(s, &sec->sh)) { 1317 WARN_ELF("gelf_update_shdr"); 1318 return -1; 1319 } 1320 1321 mark_sec_changed(elf, sec, false); 1322 } 1323 } 1324 1325 /* Make sure the new section header entries get updated properly. */ 1326 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); 1327 1328 /* Write all changes to the file. */ 1329 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { 1330 WARN_ELF("elf_update"); 1331 return -1; 1332 } 1333 1334 elf->changed = false; 1335 1336 return 0; 1337 } 1338 1339 void elf_close(struct elf *elf) 1340 { 1341 if (elf->elf) 1342 elf_end(elf->elf); 1343 1344 if (elf->fd > 0) 1345 close(elf->fd); 1346 1347 /* 1348 * NOTE: All remaining allocations are leaked on purpose. Objtool is 1349 * about to exit anyway. 1350 */ 1351 } 1352
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.