1 /* 2 * elf.c - ELF access library 3 * 4 * Adapted from kpatch (https://github.com/dynup/kpatch): 5 * Copyright (C) 2013-2015 Josh Poimboeuf <jpoimboe@redhat.com> 6 * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include <sys/types.h> 23 #include <sys/stat.h> 24 #include <fcntl.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 #include <errno.h> 30 31 #include "elf.h" 32 #include "warn.h" 33 34 struct section *find_section_by_name(struct elf *elf, const char *name) 35 { 36 struct section *sec; 37 38 list_for_each_entry(sec, &elf->sections, list) 39 if (!strcmp(sec->name, name)) 40 return sec; 41 42 return NULL; 43 } 44 45 static struct section *find_section_by_index(struct elf *elf, 46 unsigned int idx) 47 { 48 struct section *sec; 49 50 list_for_each_entry(sec, &elf->sections, list) 51 if (sec->idx == idx) 52 return sec; 53 54 return NULL; 55 } 56 57 static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx) 58 { 59 struct section *sec; 60 struct symbol *sym; 61 62 list_for_each_entry(sec, &elf->sections, list) 63 hash_for_each_possible(sec->symbol_hash, sym, hash, idx) 64 if (sym->idx == idx) 65 return sym; 66 67 return NULL; 68 } 69 70 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) 71 { 72 struct symbol *sym; 73 74 list_for_each_entry(sym, &sec->symbol_list, list) 75 if (sym->type != STT_SECTION && 76 sym->offset == offset) 77 return sym; 78 79 return NULL; 80 } 81 82 struct symbol *find_symbol_by_name(struct elf *elf, const char *name) 83 { 84 struct section *sec; 85 struct symbol *sym; 86 87 list_for_each_entry(sec, &elf->sections, list) 88 list_for_each_entry(sym, &sec->symbol_list, list) 89 if (!strcmp(sym->name, name)) 90 return sym; 91 92 return NULL; 93 } 94 95 struct symbol *find_symbol_containing(struct section *sec, unsigned long offset) 96 { 97 struct symbol *sym; 98 99 list_for_each_entry(sym, &sec->symbol_list, list) 100 if (sym->type != STT_SECTION && 101 offset >= sym->offset && offset < sym->offset + sym->len) 102 return sym; 103 104 return NULL; 105 } 106 107 struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, 108 unsigned int len) 109 { 110 struct rela *rela; 111 unsigned long o; 112 113 if (!sec->rela) 114 return NULL; 115 116 for (o = offset; o < offset + len; o++) 117 hash_for_each_possible(sec->rela->rela_hash, rela, hash, o) 118 if (rela->offset == o) 119 return rela; 120 121 return NULL; 122 } 123 124 struct rela *find_rela_by_dest(struct section *sec, unsigned long offset) 125 { 126 return find_rela_by_dest_range(sec, offset, 1); 127 } 128 129 struct symbol *find_containing_func(struct section *sec, unsigned long offset) 130 { 131 struct symbol *func; 132 133 list_for_each_entry(func, &sec->symbol_list, list) 134 if (func->type == STT_FUNC && offset >= func->offset && 135 offset < func->offset + func->len) 136 return func; 137 138 return NULL; 139 } 140 141 static int read_sections(struct elf *elf) 142 { 143 Elf_Scn *s = NULL; 144 struct section *sec; 145 size_t shstrndx, sections_nr; 146 int i; 147 148 if (elf_getshdrnum(elf->elf, §ions_nr)) { 149 WARN_ELF("elf_getshdrnum"); 150 return -1; 151 } 152 153 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { 154 WARN_ELF("elf_getshdrstrndx"); 155 return -1; 156 } 157 158 for (i = 0; i < sections_nr; i++) { 159 sec = malloc(sizeof(*sec)); 160 if (!sec) { 161 perror("malloc"); 162 return -1; 163 } 164 memset(sec, 0, sizeof(*sec)); 165 166 INIT_LIST_HEAD(&sec->symbol_list); 167 INIT_LIST_HEAD(&sec->rela_list); 168 hash_init(sec->rela_hash); 169 hash_init(sec->symbol_hash); 170 171 list_add_tail(&sec->list, &elf->sections); 172 173 s = elf_getscn(elf->elf, i); 174 if (!s) { 175 WARN_ELF("elf_getscn"); 176 return -1; 177 } 178 179 sec->idx = elf_ndxscn(s); 180 181 if (!gelf_getshdr(s, &sec->sh)) { 182 WARN_ELF("gelf_getshdr"); 183 return -1; 184 } 185 186 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); 187 if (!sec->name) { 188 WARN_ELF("elf_strptr"); 189 return -1; 190 } 191 192 if (sec->sh.sh_size != 0) { 193 sec->data = elf_getdata(s, NULL); 194 if (!sec->data) { 195 WARN_ELF("elf_getdata"); 196 return -1; 197 } 198 if (sec->data->d_off != 0 || 199 sec->data->d_size != sec->sh.sh_size) { 200 WARN("unexpected data attributes for %s", 201 sec->name); 202 return -1; 203 } 204 } 205 sec->len = sec->sh.sh_size; 206 } 207 208 /* sanity check, one more call to elf_nextscn() should return NULL */ 209 if (elf_nextscn(elf->elf, s)) { 210 WARN("section entry mismatch"); 211 return -1; 212 } 213 214 return 0; 215 } 216 217 static int read_symbols(struct elf *elf) 218 { 219 struct section *symtab, *sec; 220 struct symbol *sym, *pfunc; 221 struct list_head *entry, *tmp; 222 int symbols_nr, i; 223 char *coldstr; 224 225 symtab = find_section_by_name(elf, ".symtab"); 226 if (!symtab) { 227 WARN("missing symbol table"); 228 return -1; 229 } 230 231 symbols_nr = symtab->sh.sh_size / symtab->sh.sh_entsize; 232 233 for (i = 0; i < symbols_nr; i++) { 234 sym = malloc(sizeof(*sym)); 235 if (!sym) { 236 perror("malloc"); 237 return -1; 238 } 239 memset(sym, 0, sizeof(*sym)); 240 241 sym->idx = i; 242 243 if (!gelf_getsym(symtab->data, i, &sym->sym)) { 244 WARN_ELF("gelf_getsym"); 245 goto err; 246 } 247 248 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, 249 sym->sym.st_name); 250 if (!sym->name) { 251 WARN_ELF("elf_strptr"); 252 goto err; 253 } 254 255 sym->type = GELF_ST_TYPE(sym->sym.st_info); 256 sym->bind = GELF_ST_BIND(sym->sym.st_info); 257 258 if (sym->sym.st_shndx > SHN_UNDEF && 259 sym->sym.st_shndx < SHN_LORESERVE) { 260 sym->sec = find_section_by_index(elf, 261 sym->sym.st_shndx); 262 if (!sym->sec) { 263 WARN("couldn't find section for symbol %s", 264 sym->name); 265 goto err; 266 } 267 if (sym->type == STT_SECTION) { 268 sym->name = sym->sec->name; 269 sym->sec->sym = sym; 270 } 271 } else 272 sym->sec = find_section_by_index(elf, 0); 273 274 sym->offset = sym->sym.st_value; 275 sym->len = sym->sym.st_size; 276 277 /* sorted insert into a per-section list */ 278 entry = &sym->sec->symbol_list; 279 list_for_each_prev(tmp, &sym->sec->symbol_list) { 280 struct symbol *s; 281 282 s = list_entry(tmp, struct symbol, list); 283 284 if (sym->offset > s->offset) { 285 entry = tmp; 286 break; 287 } 288 289 if (sym->offset == s->offset && sym->len >= s->len) { 290 entry = tmp; 291 break; 292 } 293 } 294 list_add(&sym->list, entry); 295 hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx); 296 } 297 298 /* Create parent/child links for any cold subfunctions */ 299 list_for_each_entry(sec, &elf->sections, list) { 300 list_for_each_entry(sym, &sec->symbol_list, list) { 301 if (sym->type != STT_FUNC) 302 continue; 303 sym->pfunc = sym->cfunc = sym; 304 coldstr = strstr(sym->name, ".cold"); 305 if (!coldstr) 306 continue; 307 308 coldstr[0] = '\0'; 309 pfunc = find_symbol_by_name(elf, sym->name); 310 coldstr[0] = '.'; 311 312 if (!pfunc) { 313 WARN("%s(): can't find parent function", 314 sym->name); 315 goto err; 316 } 317 318 sym->pfunc = pfunc; 319 pfunc->cfunc = sym; 320 321 /* 322 * Unfortunately, -fnoreorder-functions puts the child 323 * inside the parent. Remove the overlap so we can 324 * have sane assumptions. 325 * 326 * Note that pfunc->len now no longer matches 327 * pfunc->sym.st_size. 328 */ 329 if (sym->sec == pfunc->sec && 330 sym->offset >= pfunc->offset && 331 sym->offset + sym->len == pfunc->offset + pfunc->len) { 332 pfunc->len -= sym->len; 333 } 334 } 335 } 336 337 return 0; 338 339 err: 340 free(sym); 341 return -1; 342 } 343 344 static int read_relas(struct elf *elf) 345 { 346 struct section *sec; 347 struct rela *rela; 348 int i; 349 unsigned int symndx; 350 351 list_for_each_entry(sec, &elf->sections, list) { 352 if (sec->sh.sh_type != SHT_RELA) 353 continue; 354 355 sec->base = find_section_by_name(elf, sec->name + 5); 356 if (!sec->base) { 357 WARN("can't find base section for rela section %s", 358 sec->name); 359 return -1; 360 } 361 362 sec->base->rela = sec; 363 364 for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) { 365 rela = malloc(sizeof(*rela)); 366 if (!rela) { 367 perror("malloc"); 368 return -1; 369 } 370 memset(rela, 0, sizeof(*rela)); 371 372 if (!gelf_getrela(sec->data, i, &rela->rela)) { 373 WARN_ELF("gelf_getrela"); 374 return -1; 375 } 376 377 rela->type = GELF_R_TYPE(rela->rela.r_info); 378 rela->addend = rela->rela.r_addend; 379 rela->offset = rela->rela.r_offset; 380 symndx = GELF_R_SYM(rela->rela.r_info); 381 rela->sym = find_symbol_by_index(elf, symndx); 382 rela->rela_sec = sec; 383 if (!rela->sym) { 384 WARN("can't find rela entry symbol %d for %s", 385 symndx, sec->name); 386 return -1; 387 } 388 389 list_add_tail(&rela->list, &sec->rela_list); 390 hash_add(sec->rela_hash, &rela->hash, rela->offset); 391 392 } 393 } 394 395 return 0; 396 } 397 398 struct elf *elf_open(const char *name, int flags) 399 { 400 struct elf *elf; 401 Elf_Cmd cmd; 402 403 elf_version(EV_CURRENT); 404 405 elf = malloc(sizeof(*elf)); 406 if (!elf) { 407 perror("malloc"); 408 return NULL; 409 } 410 memset(elf, 0, sizeof(*elf)); 411 412 INIT_LIST_HEAD(&elf->sections); 413 414 elf->fd = open(name, flags); 415 if (elf->fd == -1) { 416 fprintf(stderr, "objtool: Can't open '%s': %s\n", 417 name, strerror(errno)); 418 goto err; 419 } 420 421 if ((flags & O_ACCMODE) == O_RDONLY) 422 cmd = ELF_C_READ_MMAP; 423 else if ((flags & O_ACCMODE) == O_RDWR) 424 cmd = ELF_C_RDWR; 425 else /* O_WRONLY */ 426 cmd = ELF_C_WRITE; 427 428 elf->elf = elf_begin(elf->fd, cmd, NULL); 429 if (!elf->elf) { 430 WARN_ELF("elf_begin"); 431 goto err; 432 } 433 434 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { 435 WARN_ELF("gelf_getehdr"); 436 goto err; 437 } 438 439 if (read_sections(elf)) 440 goto err; 441 442 if (read_symbols(elf)) 443 goto err; 444 445 if (read_relas(elf)) 446 goto err; 447 448 return elf; 449 450 err: 451 elf_close(elf); 452 return NULL; 453 } 454 455 struct section *elf_create_section(struct elf *elf, const char *name, 456 size_t entsize, int nr) 457 { 458 struct section *sec, *shstrtab; 459 size_t size = entsize * nr; 460 struct Elf_Scn *s; 461 Elf_Data *data; 462 463 sec = malloc(sizeof(*sec)); 464 if (!sec) { 465 perror("malloc"); 466 return NULL; 467 } 468 memset(sec, 0, sizeof(*sec)); 469 470 INIT_LIST_HEAD(&sec->symbol_list); 471 INIT_LIST_HEAD(&sec->rela_list); 472 hash_init(sec->rela_hash); 473 hash_init(sec->symbol_hash); 474 475 list_add_tail(&sec->list, &elf->sections); 476 477 s = elf_newscn(elf->elf); 478 if (!s) { 479 WARN_ELF("elf_newscn"); 480 return NULL; 481 } 482 483 sec->name = strdup(name); 484 if (!sec->name) { 485 perror("strdup"); 486 return NULL; 487 } 488 489 sec->idx = elf_ndxscn(s); 490 sec->len = size; 491 sec->changed = true; 492 493 sec->data = elf_newdata(s); 494 if (!sec->data) { 495 WARN_ELF("elf_newdata"); 496 return NULL; 497 } 498 499 sec->data->d_size = size; 500 sec->data->d_align = 1; 501 502 if (size) { 503 sec->data->d_buf = malloc(size); 504 if (!sec->data->d_buf) { 505 perror("malloc"); 506 return NULL; 507 } 508 memset(sec->data->d_buf, 0, size); 509 } 510 511 if (!gelf_getshdr(s, &sec->sh)) { 512 WARN_ELF("gelf_getshdr"); 513 return NULL; 514 } 515 516 sec->sh.sh_size = size; 517 sec->sh.sh_entsize = entsize; 518 sec->sh.sh_type = SHT_PROGBITS; 519 sec->sh.sh_addralign = 1; 520 sec->sh.sh_flags = SHF_ALLOC; 521 522 523 /* Add section name to .shstrtab (or .strtab for Clang) */ 524 shstrtab = find_section_by_name(elf, ".shstrtab"); 525 if (!shstrtab) 526 shstrtab = find_section_by_name(elf, ".strtab"); 527 if (!shstrtab) { 528 WARN("can't find .shstrtab or .strtab section"); 529 return NULL; 530 } 531 532 s = elf_getscn(elf->elf, shstrtab->idx); 533 if (!s) { 534 WARN_ELF("elf_getscn"); 535 return NULL; 536 } 537 538 data = elf_newdata(s); 539 if (!data) { 540 WARN_ELF("elf_newdata"); 541 return NULL; 542 } 543 544 data->d_buf = sec->name; 545 data->d_size = strlen(name) + 1; 546 data->d_align = 1; 547 548 sec->sh.sh_name = shstrtab->len; 549 550 shstrtab->len += strlen(name) + 1; 551 shstrtab->changed = true; 552 553 return sec; 554 } 555 556 struct section *elf_create_rela_section(struct elf *elf, struct section *base) 557 { 558 char *relaname; 559 struct section *sec; 560 561 relaname = malloc(strlen(base->name) + strlen(".rela") + 1); 562 if (!relaname) { 563 perror("malloc"); 564 return NULL; 565 } 566 strcpy(relaname, ".rela"); 567 strcat(relaname, base->name); 568 569 sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0); 570 free(relaname); 571 if (!sec) 572 return NULL; 573 574 base->rela = sec; 575 sec->base = base; 576 577 sec->sh.sh_type = SHT_RELA; 578 sec->sh.sh_addralign = 8; 579 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 580 sec->sh.sh_info = base->idx; 581 sec->sh.sh_flags = SHF_INFO_LINK; 582 583 return sec; 584 } 585 586 int elf_rebuild_rela_section(struct section *sec) 587 { 588 struct rela *rela; 589 int nr, idx = 0, size; 590 GElf_Rela *relas; 591 592 nr = 0; 593 list_for_each_entry(rela, &sec->rela_list, list) 594 nr++; 595 596 size = nr * sizeof(*relas); 597 relas = malloc(size); 598 if (!relas) { 599 perror("malloc"); 600 return -1; 601 } 602 603 sec->data->d_buf = relas; 604 sec->data->d_size = size; 605 606 sec->sh.sh_size = size; 607 608 idx = 0; 609 list_for_each_entry(rela, &sec->rela_list, list) { 610 relas[idx].r_offset = rela->offset; 611 relas[idx].r_addend = rela->addend; 612 relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type); 613 idx++; 614 } 615 616 return 0; 617 } 618 619 int elf_write(struct elf *elf) 620 { 621 struct section *sec; 622 Elf_Scn *s; 623 624 /* Update section headers for changed sections: */ 625 list_for_each_entry(sec, &elf->sections, list) { 626 if (sec->changed) { 627 s = elf_getscn(elf->elf, sec->idx); 628 if (!s) { 629 WARN_ELF("elf_getscn"); 630 return -1; 631 } 632 if (!gelf_update_shdr(s, &sec->sh)) { 633 WARN_ELF("gelf_update_shdr"); 634 return -1; 635 } 636 } 637 } 638 639 /* Make sure the new section header entries get updated properly. */ 640 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); 641 642 /* Write all changes to the file. */ 643 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { 644 WARN_ELF("elf_update"); 645 return -1; 646 } 647 648 return 0; 649 } 650 651 void elf_close(struct elf *elf) 652 { 653 struct section *sec, *tmpsec; 654 struct symbol *sym, *tmpsym; 655 struct rela *rela, *tmprela; 656 657 if (elf->elf) 658 elf_end(elf->elf); 659 660 if (elf->fd > 0) 661 close(elf->fd); 662 663 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { 664 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { 665 list_del(&sym->list); 666 hash_del(&sym->hash); 667 free(sym); 668 } 669 list_for_each_entry_safe(rela, tmprela, &sec->rela_list, list) { 670 list_del(&rela->list); 671 hash_del(&rela->hash); 672 free(rela); 673 } 674 list_del(&sec->list); 675 free(sec); 676 } 677 678 free(elf); 679 } 680