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 coldstr[0] = '\0'; 307 pfunc = find_symbol_by_name(elf, sym->name); 308 coldstr[0] = '.'; 309 310 if (!pfunc) { 311 WARN("%s(): can't find parent function", 312 sym->name); 313 goto err; 314 } 315 316 sym->pfunc = pfunc; 317 pfunc->cfunc = sym; 318 } 319 } 320 } 321 322 return 0; 323 324 err: 325 free(sym); 326 return -1; 327 } 328 329 static int read_relas(struct elf *elf) 330 { 331 struct section *sec; 332 struct rela *rela; 333 int i; 334 unsigned int symndx; 335 336 list_for_each_entry(sec, &elf->sections, list) { 337 if (sec->sh.sh_type != SHT_RELA) 338 continue; 339 340 sec->base = find_section_by_name(elf, sec->name + 5); 341 if (!sec->base) { 342 WARN("can't find base section for rela section %s", 343 sec->name); 344 return -1; 345 } 346 347 sec->base->rela = sec; 348 349 for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) { 350 rela = malloc(sizeof(*rela)); 351 if (!rela) { 352 perror("malloc"); 353 return -1; 354 } 355 memset(rela, 0, sizeof(*rela)); 356 357 if (!gelf_getrela(sec->data, i, &rela->rela)) { 358 WARN_ELF("gelf_getrela"); 359 return -1; 360 } 361 362 rela->type = GELF_R_TYPE(rela->rela.r_info); 363 rela->addend = rela->rela.r_addend; 364 rela->offset = rela->rela.r_offset; 365 symndx = GELF_R_SYM(rela->rela.r_info); 366 rela->sym = find_symbol_by_index(elf, symndx); 367 if (!rela->sym) { 368 WARN("can't find rela entry symbol %d for %s", 369 symndx, sec->name); 370 return -1; 371 } 372 373 list_add_tail(&rela->list, &sec->rela_list); 374 hash_add(sec->rela_hash, &rela->hash, rela->offset); 375 376 } 377 } 378 379 return 0; 380 } 381 382 struct elf *elf_open(const char *name, int flags) 383 { 384 struct elf *elf; 385 Elf_Cmd cmd; 386 387 elf_version(EV_CURRENT); 388 389 elf = malloc(sizeof(*elf)); 390 if (!elf) { 391 perror("malloc"); 392 return NULL; 393 } 394 memset(elf, 0, sizeof(*elf)); 395 396 INIT_LIST_HEAD(&elf->sections); 397 398 elf->fd = open(name, flags); 399 if (elf->fd == -1) { 400 fprintf(stderr, "objtool: Can't open '%s': %s\n", 401 name, strerror(errno)); 402 goto err; 403 } 404 405 if ((flags & O_ACCMODE) == O_RDONLY) 406 cmd = ELF_C_READ_MMAP; 407 else if ((flags & O_ACCMODE) == O_RDWR) 408 cmd = ELF_C_RDWR; 409 else /* O_WRONLY */ 410 cmd = ELF_C_WRITE; 411 412 elf->elf = elf_begin(elf->fd, cmd, NULL); 413 if (!elf->elf) { 414 WARN_ELF("elf_begin"); 415 goto err; 416 } 417 418 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { 419 WARN_ELF("gelf_getehdr"); 420 goto err; 421 } 422 423 if (read_sections(elf)) 424 goto err; 425 426 if (read_symbols(elf)) 427 goto err; 428 429 if (read_relas(elf)) 430 goto err; 431 432 return elf; 433 434 err: 435 elf_close(elf); 436 return NULL; 437 } 438 439 struct section *elf_create_section(struct elf *elf, const char *name, 440 size_t entsize, int nr) 441 { 442 struct section *sec, *shstrtab; 443 size_t size = entsize * nr; 444 struct Elf_Scn *s; 445 Elf_Data *data; 446 447 sec = malloc(sizeof(*sec)); 448 if (!sec) { 449 perror("malloc"); 450 return NULL; 451 } 452 memset(sec, 0, sizeof(*sec)); 453 454 INIT_LIST_HEAD(&sec->symbol_list); 455 INIT_LIST_HEAD(&sec->rela_list); 456 hash_init(sec->rela_hash); 457 hash_init(sec->symbol_hash); 458 459 list_add_tail(&sec->list, &elf->sections); 460 461 s = elf_newscn(elf->elf); 462 if (!s) { 463 WARN_ELF("elf_newscn"); 464 return NULL; 465 } 466 467 sec->name = strdup(name); 468 if (!sec->name) { 469 perror("strdup"); 470 return NULL; 471 } 472 473 sec->idx = elf_ndxscn(s); 474 sec->len = size; 475 sec->changed = true; 476 477 sec->data = elf_newdata(s); 478 if (!sec->data) { 479 WARN_ELF("elf_newdata"); 480 return NULL; 481 } 482 483 sec->data->d_size = size; 484 sec->data->d_align = 1; 485 486 if (size) { 487 sec->data->d_buf = malloc(size); 488 if (!sec->data->d_buf) { 489 perror("malloc"); 490 return NULL; 491 } 492 memset(sec->data->d_buf, 0, size); 493 } 494 495 if (!gelf_getshdr(s, &sec->sh)) { 496 WARN_ELF("gelf_getshdr"); 497 return NULL; 498 } 499 500 sec->sh.sh_size = size; 501 sec->sh.sh_entsize = entsize; 502 sec->sh.sh_type = SHT_PROGBITS; 503 sec->sh.sh_addralign = 1; 504 sec->sh.sh_flags = SHF_ALLOC; 505 506 507 /* Add section name to .shstrtab */ 508 shstrtab = find_section_by_name(elf, ".shstrtab"); 509 if (!shstrtab) { 510 WARN("can't find .shstrtab section"); 511 return NULL; 512 } 513 514 s = elf_getscn(elf->elf, shstrtab->idx); 515 if (!s) { 516 WARN_ELF("elf_getscn"); 517 return NULL; 518 } 519 520 data = elf_newdata(s); 521 if (!data) { 522 WARN_ELF("elf_newdata"); 523 return NULL; 524 } 525 526 data->d_buf = sec->name; 527 data->d_size = strlen(name) + 1; 528 data->d_align = 1; 529 530 sec->sh.sh_name = shstrtab->len; 531 532 shstrtab->len += strlen(name) + 1; 533 shstrtab->changed = true; 534 535 return sec; 536 } 537 538 struct section *elf_create_rela_section(struct elf *elf, struct section *base) 539 { 540 char *relaname; 541 struct section *sec; 542 543 relaname = malloc(strlen(base->name) + strlen(".rela") + 1); 544 if (!relaname) { 545 perror("malloc"); 546 return NULL; 547 } 548 strcpy(relaname, ".rela"); 549 strcat(relaname, base->name); 550 551 sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0); 552 free(relaname); 553 if (!sec) 554 return NULL; 555 556 base->rela = sec; 557 sec->base = base; 558 559 sec->sh.sh_type = SHT_RELA; 560 sec->sh.sh_addralign = 8; 561 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 562 sec->sh.sh_info = base->idx; 563 sec->sh.sh_flags = SHF_INFO_LINK; 564 565 return sec; 566 } 567 568 int elf_rebuild_rela_section(struct section *sec) 569 { 570 struct rela *rela; 571 int nr, idx = 0, size; 572 GElf_Rela *relas; 573 574 nr = 0; 575 list_for_each_entry(rela, &sec->rela_list, list) 576 nr++; 577 578 size = nr * sizeof(*relas); 579 relas = malloc(size); 580 if (!relas) { 581 perror("malloc"); 582 return -1; 583 } 584 585 sec->data->d_buf = relas; 586 sec->data->d_size = size; 587 588 sec->sh.sh_size = size; 589 590 idx = 0; 591 list_for_each_entry(rela, &sec->rela_list, list) { 592 relas[idx].r_offset = rela->offset; 593 relas[idx].r_addend = rela->addend; 594 relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type); 595 idx++; 596 } 597 598 return 0; 599 } 600 601 int elf_write(struct elf *elf) 602 { 603 struct section *sec; 604 Elf_Scn *s; 605 606 /* Update section headers for changed sections: */ 607 list_for_each_entry(sec, &elf->sections, list) { 608 if (sec->changed) { 609 s = elf_getscn(elf->elf, sec->idx); 610 if (!s) { 611 WARN_ELF("elf_getscn"); 612 return -1; 613 } 614 if (!gelf_update_shdr(s, &sec->sh)) { 615 WARN_ELF("gelf_update_shdr"); 616 return -1; 617 } 618 } 619 } 620 621 /* Make sure the new section header entries get updated properly. */ 622 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); 623 624 /* Write all changes to the file. */ 625 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { 626 WARN_ELF("elf_update"); 627 return -1; 628 } 629 630 return 0; 631 } 632 633 void elf_close(struct elf *elf) 634 { 635 struct section *sec, *tmpsec; 636 struct symbol *sym, *tmpsym; 637 struct rela *rela, *tmprela; 638 639 if (elf->elf) 640 elf_end(elf->elf); 641 642 if (elf->fd > 0) 643 close(elf->fd); 644 645 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { 646 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { 647 list_del(&sym->list); 648 hash_del(&sym->hash); 649 free(sym); 650 } 651 list_for_each_entry_safe(rela, tmprela, &sec->rela_list, list) { 652 list_del(&rela->list); 653 hash_del(&rela->hash); 654 free(rela); 655 } 656 list_del(&sec->list); 657 free(sec); 658 } 659 660 free(elf); 661 } 662