1 /*- 2 * Copyright (c) 2007-2011,2014 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/stat.h> 29 #include <err.h> 30 #include <libgen.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include "elfcopy.h" 36 37 ELFTC_VCSID("$Id: sections.c 3443 2016-04-15 18:57:54Z kaiwang27 $"); 38 39 static void add_gnu_debuglink(struct elfcopy *ecp); 40 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); 41 static void check_section_rename(struct elfcopy *ecp, struct section *s); 42 static void filter_reloc(struct elfcopy *ecp, struct section *s); 43 static int get_section_flags(struct elfcopy *ecp, const char *name); 44 static void insert_sections(struct elfcopy *ecp); 45 static void insert_to_strtab(struct section *t, const char *s); 46 static int is_append_section(struct elfcopy *ecp, const char *name); 47 static int is_compress_section(struct elfcopy *ecp, const char *name); 48 static int is_debug_section(const char *name); 49 static int is_dwo_section(const char *name); 50 static int is_modify_section(struct elfcopy *ecp, const char *name); 51 static int is_print_section(struct elfcopy *ecp, const char *name); 52 static int lookup_string(struct section *t, const char *s); 53 static void modify_section(struct elfcopy *ecp, struct section *s); 54 static void pad_section(struct elfcopy *ecp, struct section *s); 55 static void print_data(const char *d, size_t sz); 56 static void print_section(struct section *s); 57 static void *read_section(struct section *s, size_t *size); 58 static void update_reloc(struct elfcopy *ecp, struct section *s); 59 static void update_section_group(struct elfcopy *ecp, struct section *s); 60 61 int 62 is_remove_section(struct elfcopy *ecp, const char *name) 63 { 64 65 /* Always keep section name table */ 66 if (strcmp(name, ".shstrtab") == 0) 67 return 0; 68 if (strcmp(name, ".symtab") == 0 || 69 strcmp(name, ".strtab") == 0) { 70 if (ecp->strip == STRIP_ALL && lookup_symop_list( 71 ecp, NULL, SYMOP_KEEP) == NULL) 72 return (1); 73 else 74 return (0); 75 } 76 77 if (ecp->strip == STRIP_DWO && is_dwo_section(name)) 78 return (1); 79 if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name)) 80 return (1); 81 82 if (is_debug_section(name)) { 83 if (ecp->strip == STRIP_ALL || 84 ecp->strip == STRIP_DEBUG || 85 ecp->strip == STRIP_UNNEEDED || 86 (ecp->flags & DISCARD_LOCAL)) 87 return (1); 88 if (ecp->strip == STRIP_NONDEBUG) 89 return (0); 90 } 91 92 if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) { 93 struct sec_action *sac; 94 95 sac = lookup_sec_act(ecp, name, 0); 96 if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove) 97 return (1); 98 if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy)) 99 return (1); 100 } 101 102 return (0); 103 } 104 105 /* 106 * Relocation section needs to be removed if the section it applies to 107 * will be removed. 108 */ 109 int 110 is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info) 111 { 112 const char *name; 113 GElf_Shdr ish; 114 Elf_Scn *is; 115 size_t indx; 116 int elferr; 117 118 if (elf_getshstrndx(ecp->ein, &indx) == 0) 119 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", 120 elf_errmsg(-1)); 121 122 is = NULL; 123 while ((is = elf_nextscn(ecp->ein, is)) != NULL) { 124 if (sh_info == elf_ndxscn(is)) { 125 if (gelf_getshdr(is, &ish) == NULL) 126 errx(EXIT_FAILURE, "gelf_getshdr failed: %s", 127 elf_errmsg(-1)); 128 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == 129 NULL) 130 errx(EXIT_FAILURE, "elf_strptr failed: %s", 131 elf_errmsg(-1)); 132 if (is_remove_section(ecp, name)) 133 return (1); 134 else 135 return (0); 136 } 137 } 138 elferr = elf_errno(); 139 if (elferr != 0) 140 errx(EXIT_FAILURE, "elf_nextscn failed: %s", 141 elf_errmsg(elferr)); 142 143 /* Remove reloc section if we can't find the target section. */ 144 return (1); 145 } 146 147 static int 148 is_append_section(struct elfcopy *ecp, const char *name) 149 { 150 struct sec_action *sac; 151 152 sac = lookup_sec_act(ecp, name, 0); 153 if (sac != NULL && sac->append != 0 && sac->string != NULL) 154 return (1); 155 156 return (0); 157 } 158 159 static int 160 is_compress_section(struct elfcopy *ecp, const char *name) 161 { 162 struct sec_action *sac; 163 164 sac = lookup_sec_act(ecp, name, 0); 165 if (sac != NULL && sac->compress != 0) 166 return (1); 167 168 return (0); 169 } 170 171 static void 172 check_section_rename(struct elfcopy *ecp, struct section *s) 173 { 174 struct sec_action *sac; 175 char *prefix; 176 size_t namelen; 177 178 if (s->pseudo) 179 return; 180 181 sac = lookup_sec_act(ecp, s->name, 0); 182 if (sac != NULL && sac->rename) 183 s->name = sac->newname; 184 185 if (!strcmp(s->name, ".symtab") || 186 !strcmp(s->name, ".strtab") || 187 !strcmp(s->name, ".shstrtab")) 188 return; 189 190 prefix = NULL; 191 if (s->loadable && ecp->prefix_alloc != NULL) 192 prefix = ecp->prefix_alloc; 193 else if (ecp->prefix_sec != NULL) 194 prefix = ecp->prefix_sec; 195 196 if (prefix != NULL) { 197 namelen = strlen(s->name) + strlen(prefix) + 1; 198 if ((s->newname = malloc(namelen)) == NULL) 199 err(EXIT_FAILURE, "malloc failed"); 200 snprintf(s->newname, namelen, "%s%s", prefix, s->name); 201 s->name = s->newname; 202 } 203 } 204 205 static int 206 get_section_flags(struct elfcopy *ecp, const char *name) 207 { 208 struct sec_action *sac; 209 210 sac = lookup_sec_act(ecp, name, 0); 211 if (sac != NULL && sac->flags) 212 return sac->flags; 213 214 return (0); 215 } 216 217 /* 218 * Determine whether the section are debugging section. 219 * According to libbfd, debugging sections are recognized 220 * only by name. 221 */ 222 static int 223 is_debug_section(const char *name) 224 { 225 const char *dbg_sec[] = { 226 ".apple_", 227 ".debug", 228 ".gnu.linkonce.wi.", 229 ".line", 230 ".stab", 231 NULL 232 }; 233 const char **p; 234 235 for(p = dbg_sec; *p; p++) { 236 if (strncmp(name, *p, strlen(*p)) == 0) 237 return (1); 238 } 239 240 return (0); 241 } 242 243 static int 244 is_dwo_section(const char *name) 245 { 246 size_t len; 247 248 if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0) 249 return (1); 250 return (0); 251 } 252 253 static int 254 is_print_section(struct elfcopy *ecp, const char *name) 255 { 256 struct sec_action *sac; 257 258 sac = lookup_sec_act(ecp, name, 0); 259 if (sac != NULL && sac->print != 0) 260 return (1); 261 262 return (0); 263 } 264 265 static int 266 is_modify_section(struct elfcopy *ecp, const char *name) 267 { 268 269 if (is_append_section(ecp, name) || 270 is_compress_section(ecp, name)) 271 return (1); 272 273 return (0); 274 } 275 276 struct sec_action* 277 lookup_sec_act(struct elfcopy *ecp, const char *name, int add) 278 { 279 struct sec_action *sac; 280 281 if (name == NULL) 282 return NULL; 283 284 STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { 285 if (strcmp(name, sac->name) == 0) 286 return sac; 287 } 288 289 if (add == 0) 290 return NULL; 291 292 if ((sac = malloc(sizeof(*sac))) == NULL) 293 errx(EXIT_FAILURE, "not enough memory"); 294 memset(sac, 0, sizeof(*sac)); 295 sac->name = name; 296 STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list); 297 298 return (sac); 299 } 300 301 void 302 free_sec_act(struct elfcopy *ecp) 303 { 304 struct sec_action *sac, *sac_temp; 305 306 STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) { 307 STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list); 308 free(sac); 309 } 310 } 311 312 void 313 insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail) 314 { 315 struct section *s; 316 317 if (!tail) { 318 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 319 if (sec->off < s->off) { 320 TAILQ_INSERT_BEFORE(s, sec, sec_list); 321 goto inc_nos; 322 } 323 } 324 } 325 326 TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list); 327 328 inc_nos: 329 if (sec->pseudo == 0) 330 ecp->nos++; 331 } 332 333 /* 334 * First step of section creation: create scn and internal section 335 * structure, discard sections to be removed. 336 */ 337 void 338 create_scn(struct elfcopy *ecp) 339 { 340 struct section *s; 341 const char *name; 342 Elf_Scn *is; 343 GElf_Shdr ish; 344 size_t indx; 345 uint64_t oldndx, newndx; 346 int elferr, sec_flags, reorder; 347 348 /* 349 * Insert a pseudo section that contains the ELF header 350 * and program header. Used as reference for section offset 351 * or load address adjustment. 352 */ 353 if ((s = calloc(1, sizeof(*s))) == NULL) 354 err(EXIT_FAILURE, "calloc failed"); 355 s->off = 0; 356 s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) + 357 gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT); 358 s->align = 1; 359 s->pseudo = 1; 360 s->loadable = add_to_inseg_list(ecp, s); 361 insert_to_sec_list(ecp, s, 0); 362 363 /* Create internal .shstrtab section. */ 364 init_shstrtab(ecp); 365 366 if (elf_getshstrndx(ecp->ein, &indx) == 0) 367 errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", 368 elf_errmsg(-1)); 369 370 reorder = 0; 371 is = NULL; 372 while ((is = elf_nextscn(ecp->ein, is)) != NULL) { 373 if (gelf_getshdr(is, &ish) == NULL) 374 errx(EXIT_FAILURE, "gelf_getshdr failed: %s", 375 elf_errmsg(-1)); 376 if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL) 377 errx(EXIT_FAILURE, "elf_strptr failed: %s", 378 elf_errmsg(-1)); 379 380 /* Skip sections to be removed. */ 381 if (is_remove_section(ecp, name)) 382 continue; 383 384 /* 385 * Relocation section need to be remove if the section 386 * it applies will be removed. 387 */ 388 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) 389 if (ish.sh_info != 0 && 390 is_remove_reloc_sec(ecp, ish.sh_info)) 391 continue; 392 393 /* 394 * Section groups should be removed if symbol table will 395 * be removed. (section group's signature stored in symbol 396 * table) 397 */ 398 if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL) 399 continue; 400 401 /* Get section flags set by user. */ 402 sec_flags = get_section_flags(ecp, name); 403 404 /* Create internal section object. */ 405 if (strcmp(name, ".shstrtab") != 0) { 406 if ((s = calloc(1, sizeof(*s))) == NULL) 407 err(EXIT_FAILURE, "calloc failed"); 408 s->name = name; 409 s->is = is; 410 s->off = ish.sh_offset; 411 s->sz = ish.sh_size; 412 s->align = ish.sh_addralign; 413 s->type = ish.sh_type; 414 s->flags = ish.sh_flags; 415 s->vma = ish.sh_addr; 416 417 /* 418 * Search program headers to determine whether section 419 * is loadable, but if user explicitly set section flags 420 * while neither "load" nor "alloc" is set, we make the 421 * section unloadable. 422 * 423 * Sections in relocatable object is loadable if 424 * section flag SHF_ALLOC is set. 425 */ 426 if (sec_flags && 427 (sec_flags & (SF_LOAD | SF_ALLOC)) == 0) 428 s->loadable = 0; 429 else { 430 s->loadable = add_to_inseg_list(ecp, s); 431 if ((ecp->flags & RELOCATABLE) && 432 (ish.sh_flags & SHF_ALLOC)) 433 s->loadable = 1; 434 } 435 } else { 436 /* Assuming .shstrtab is "unloadable". */ 437 s = ecp->shstrtab; 438 s->off = ish.sh_offset; 439 } 440 441 oldndx = newndx = SHN_UNDEF; 442 if (strcmp(name, ".symtab") != 0 && 443 strcmp(name, ".strtab") != 0) { 444 if (!strcmp(name, ".shstrtab")) { 445 /* 446 * Add sections specified by --add-section and 447 * gnu debuglink. we want these sections have 448 * smaller index than .shstrtab section. 449 */ 450 if (ecp->debuglink != NULL) 451 add_gnu_debuglink(ecp); 452 if (ecp->flags & SEC_ADD) 453 insert_sections(ecp); 454 } 455 if ((s->os = elf_newscn(ecp->eout)) == NULL) 456 errx(EXIT_FAILURE, "elf_newscn failed: %s", 457 elf_errmsg(-1)); 458 if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF) 459 errx(EXIT_FAILURE, "elf_ndxscn failed: %s", 460 elf_errmsg(-1)); 461 } 462 if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF) 463 errx(EXIT_FAILURE, "elf_ndxscn failed: %s", 464 elf_errmsg(-1)); 465 if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF) 466 ecp->secndx[oldndx] = newndx; 467 468 /* 469 * If strip action is STRIP_NONDEBUG(only keep debug), 470 * change sections type of loadable sections and section 471 * groups to SHT_NOBITS, and the content of those sections 472 * will be discarded. However, SHT_NOTE sections should 473 * be kept. 474 */ 475 if (ecp->strip == STRIP_NONDEBUG) { 476 if (((ish.sh_flags & SHF_ALLOC) || 477 (ish.sh_flags & SHF_GROUP)) && 478 ish.sh_type != SHT_NOTE) 479 s->type = SHT_NOBITS; 480 } 481 482 check_section_rename(ecp, s); 483 484 /* create section header based on input object. */ 485 if (strcmp(name, ".symtab") != 0 && 486 strcmp(name, ".strtab") != 0 && 487 strcmp(name, ".shstrtab") != 0) { 488 copy_shdr(ecp, s, NULL, 0, sec_flags); 489 /* 490 * elfcopy puts .symtab, .strtab and .shstrtab 491 * sections in the end of the output object. 492 * If the input objects have more sections 493 * after any of these 3 sections, the section 494 * table will be reordered. section symbols 495 * should be regenerated for relocations. 496 */ 497 if (reorder) 498 ecp->flags &= ~SYMTAB_INTACT; 499 } else 500 reorder = 1; 501 502 if (strcmp(name, ".symtab") == 0) { 503 ecp->flags |= SYMTAB_EXIST; 504 ecp->symtab = s; 505 } 506 if (strcmp(name, ".strtab") == 0) 507 ecp->strtab = s; 508 509 insert_to_sec_list(ecp, s, 0); 510 } 511 elferr = elf_errno(); 512 if (elferr != 0) 513 errx(EXIT_FAILURE, "elf_nextscn failed: %s", 514 elf_errmsg(elferr)); 515 } 516 517 struct section * 518 insert_shtab(struct elfcopy *ecp, int tail) 519 { 520 struct section *s, *shtab; 521 GElf_Ehdr ieh; 522 int nsecs; 523 524 /* 525 * Treat section header table as a "pseudo" section, insert it 526 * into section list, so later it will get sorted and resynced 527 * just as normal sections. 528 */ 529 if ((shtab = calloc(1, sizeof(*shtab))) == NULL) 530 errx(EXIT_FAILURE, "calloc failed"); 531 if (!tail) { 532 /* 533 * "shoff" of input object is used as a hint for section 534 * resync later. 535 */ 536 if (gelf_getehdr(ecp->ein, &ieh) == NULL) 537 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", 538 elf_errmsg(-1)); 539 shtab->off = ieh.e_shoff; 540 } else 541 shtab->off = 0; 542 /* Calculate number of sections in the output object. */ 543 nsecs = 0; 544 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 545 if (!s->pseudo) 546 nsecs++; 547 } 548 /* Remember there is always a null section, so we +1 here. */ 549 shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT); 550 if (shtab->sz == 0) 551 errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); 552 shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8); 553 shtab->loadable = 0; 554 shtab->pseudo = 1; 555 insert_to_sec_list(ecp, shtab, tail); 556 557 return (shtab); 558 } 559 560 void 561 copy_content(struct elfcopy *ecp) 562 { 563 struct section *s; 564 565 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 566 /* Skip pseudo section. */ 567 if (s->pseudo) 568 continue; 569 570 /* Skip special sections. */ 571 if (strcmp(s->name, ".symtab") == 0 || 572 strcmp(s->name, ".strtab") == 0 || 573 strcmp(s->name, ".shstrtab") == 0) 574 continue; 575 576 /* 577 * If strip action is STRIP_ALL, relocation info need 578 * to be stripped. Skip filtering otherwisw. 579 */ 580 if (ecp->strip == STRIP_ALL && 581 (s->type == SHT_REL || s->type == SHT_RELA)) 582 filter_reloc(ecp, s); 583 584 /* 585 * The section indices in the SHT_GROUP section needs 586 * to be updated since we might have stripped some 587 * sections and changed section numbering. 588 */ 589 if (s->type == SHT_GROUP) 590 update_section_group(ecp, s); 591 592 if (is_modify_section(ecp, s->name)) 593 modify_section(ecp, s); 594 595 copy_data(s); 596 597 /* 598 * If symbol table is modified, relocation info might 599 * need update, as symbol index may have changed. 600 */ 601 if ((ecp->flags & SYMTAB_INTACT) == 0 && 602 (ecp->flags & SYMTAB_EXIST) && 603 (s->type == SHT_REL || s->type == SHT_RELA)) 604 update_reloc(ecp, s); 605 606 if (is_print_section(ecp, s->name)) 607 print_section(s); 608 } 609 } 610 611 612 /* 613 * Update section group section. The section indices in the SHT_GROUP 614 * section need update after section numbering changed. 615 */ 616 static void 617 update_section_group(struct elfcopy *ecp, struct section *s) 618 { 619 GElf_Shdr ish; 620 Elf_Data *id; 621 uint32_t *ws, *wd; 622 uint64_t n; 623 size_t ishnum; 624 int i, j; 625 626 if (!elf_getshnum(ecp->ein, &ishnum)) 627 errx(EXIT_FAILURE, "elf_getshnum failed: %s", 628 elf_errmsg(-1)); 629 630 if (gelf_getshdr(s->is, &ish) == NULL) 631 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", 632 elf_errmsg(-1)); 633 634 if ((id = elf_getdata(s->is, NULL)) == NULL) 635 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 636 elf_errmsg(-1)); 637 638 if (ish.sh_size == 0) 639 return; 640 641 if (ish.sh_entsize == 0) 642 ish.sh_entsize = 4; 643 644 ws = id->d_buf; 645 646 /* We only support COMDAT section. */ 647 #ifndef GRP_COMDAT 648 #define GRP_COMDAT 0x1 649 #endif 650 if ((*ws & GRP_COMDAT) == 0) 651 return; 652 653 if ((s->buf = malloc(ish.sh_size)) == NULL) 654 err(EXIT_FAILURE, "malloc failed"); 655 656 s->sz = ish.sh_size; 657 658 wd = s->buf; 659 660 /* Copy the flag word as-is. */ 661 *wd = *ws; 662 663 /* Update the section indices. */ 664 n = ish.sh_size / ish.sh_entsize; 665 for(i = 1, j = 1; (uint64_t)i < n; i++) { 666 if (ws[i] != SHN_UNDEF && ws[i] < ishnum && 667 ecp->secndx[ws[i]] != 0) 668 wd[j++] = ecp->secndx[ws[i]]; 669 else 670 s->sz -= 4; 671 } 672 673 s->nocopy = 1; 674 } 675 676 /* 677 * Filter relocation entries, only keep those entries whose 678 * symbol is in the keep list. 679 */ 680 static void 681 filter_reloc(struct elfcopy *ecp, struct section *s) 682 { 683 const char *name; 684 GElf_Shdr ish; 685 GElf_Rel rel; 686 GElf_Rela rela; 687 Elf32_Rel *rel32; 688 Elf64_Rel *rel64; 689 Elf32_Rela *rela32; 690 Elf64_Rela *rela64; 691 Elf_Data *id; 692 uint64_t cap, n, nrels; 693 int elferr, i; 694 695 if (gelf_getshdr(s->is, &ish) == NULL) 696 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", 697 elf_errmsg(-1)); 698 699 /* We don't want to touch relocation info for dynamic symbols. */ 700 if ((ecp->flags & SYMTAB_EXIST) == 0) { 701 if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0) { 702 /* 703 * This reloc section applies to the symbol table 704 * that was stripped, so discard whole section. 705 */ 706 s->nocopy = 1; 707 s->sz = 0; 708 } 709 return; 710 } else { 711 /* Symbol table exist, check if index equals. */ 712 if (ish.sh_link != elf_ndxscn(ecp->symtab->is)) 713 return; 714 } 715 716 #define COPYREL(REL, SZ) do { \ 717 if (nrels == 0) { \ 718 if ((REL##SZ = malloc(cap * \ 719 sizeof(Elf##SZ##_Rel))) == NULL) \ 720 err(EXIT_FAILURE, "malloc failed"); \ 721 } \ 722 if (nrels >= cap) { \ 723 cap *= 2; \ 724 if ((REL##SZ = realloc(REL##SZ, cap * \ 725 sizeof(Elf##SZ##_Rel))) == NULL) \ 726 err(EXIT_FAILURE, "realloc failed"); \ 727 } \ 728 REL##SZ[nrels].r_offset = REL.r_offset; \ 729 REL##SZ[nrels].r_info = REL.r_info; \ 730 if (s->type == SHT_RELA) \ 731 rela##SZ[nrels].r_addend = rela.r_addend; \ 732 nrels++; \ 733 } while (0) 734 735 nrels = 0; 736 cap = 4; /* keep list is usually small. */ 737 rel32 = NULL; 738 rel64 = NULL; 739 rela32 = NULL; 740 rela64 = NULL; 741 if ((id = elf_getdata(s->is, NULL)) == NULL) 742 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 743 elf_errmsg(-1)); 744 n = ish.sh_size / ish.sh_entsize; 745 for(i = 0; (uint64_t)i < n; i++) { 746 if (s->type == SHT_REL) { 747 if (gelf_getrel(id, i, &rel) != &rel) 748 errx(EXIT_FAILURE, "gelf_getrel failed: %s", 749 elf_errmsg(-1)); 750 } else { 751 if (gelf_getrela(id, i, &rela) != &rela) 752 errx(EXIT_FAILURE, "gelf_getrel failed: %s", 753 elf_errmsg(-1)); 754 } 755 name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is), 756 GELF_R_SYM(rel.r_info)); 757 if (name == NULL) 758 errx(EXIT_FAILURE, "elf_strptr failed: %s", 759 elf_errmsg(-1)); 760 if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL) { 761 if (ecp->oec == ELFCLASS32) { 762 if (s->type == SHT_REL) 763 COPYREL(rel, 32); 764 else 765 COPYREL(rela, 32); 766 } else { 767 if (s->type == SHT_REL) 768 COPYREL(rel, 64); 769 else 770 COPYREL(rela, 64); 771 } 772 } 773 } 774 elferr = elf_errno(); 775 if (elferr != 0) 776 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 777 elf_errmsg(elferr)); 778 779 if (ecp->oec == ELFCLASS32) { 780 if (s->type == SHT_REL) 781 s->buf = rel32; 782 else 783 s->buf = rela32; 784 } else { 785 if (s->type == SHT_REL) 786 s->buf = rel64; 787 else 788 s->buf = rela64; 789 } 790 s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL : 791 ELF_T_RELA), nrels, EV_CURRENT); 792 s->nocopy = 1; 793 } 794 795 static void 796 update_reloc(struct elfcopy *ecp, struct section *s) 797 { 798 GElf_Shdr osh; 799 GElf_Rel rel; 800 GElf_Rela rela; 801 Elf_Data *od; 802 uint64_t n; 803 int i; 804 805 #define UPDATEREL(REL) do { \ 806 if (gelf_get##REL(od, i, &REL) != &REL) \ 807 errx(EXIT_FAILURE, "gelf_get##REL failed: %s", \ 808 elf_errmsg(-1)); \ 809 REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)], \ 810 GELF_R_TYPE(REL.r_info)); \ 811 if (!gelf_update_##REL(od, i, &REL)) \ 812 errx(EXIT_FAILURE, "gelf_update_##REL failed: %s", \ 813 elf_errmsg(-1)); \ 814 } while(0) 815 816 if (s->sz == 0) 817 return; 818 if (gelf_getshdr(s->os, &osh) == NULL) 819 errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", 820 elf_errmsg(-1)); 821 /* Only process .symtab reloc info. */ 822 if (osh.sh_link != elf_ndxscn(ecp->symtab->is)) 823 return; 824 if ((od = elf_getdata(s->os, NULL)) == NULL) 825 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 826 elf_errmsg(-1)); 827 n = osh.sh_size / osh.sh_entsize; 828 for(i = 0; (uint64_t)i < n; i++) { 829 if (s->type == SHT_REL) 830 UPDATEREL(rel); 831 else 832 UPDATEREL(rela); 833 } 834 } 835 836 static void 837 pad_section(struct elfcopy *ecp, struct section *s) 838 { 839 GElf_Shdr osh; 840 Elf_Data *od; 841 842 if (s == NULL || s->pad_sz == 0) 843 return; 844 845 if ((s->pad = malloc(s->pad_sz)) == NULL) 846 err(EXIT_FAILURE, "malloc failed"); 847 memset(s->pad, ecp->fill, s->pad_sz); 848 849 /* Create a new Elf_Data to contain the padding bytes. */ 850 if ((od = elf_newdata(s->os)) == NULL) 851 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 852 elf_errmsg(-1)); 853 od->d_align = 1; 854 od->d_off = s->sz; 855 od->d_buf = s->pad; 856 od->d_type = ELF_T_BYTE; 857 od->d_size = s->pad_sz; 858 od->d_version = EV_CURRENT; 859 860 /* Update section header. */ 861 if (gelf_getshdr(s->os, &osh) == NULL) 862 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 863 elf_errmsg(-1)); 864 osh.sh_size = s->sz + s->pad_sz; 865 if (!gelf_update_shdr(s->os, &osh)) 866 errx(EXIT_FAILURE, "elf_update_shdr failed: %s", 867 elf_errmsg(-1)); 868 } 869 870 void 871 resync_sections(struct elfcopy *ecp) 872 { 873 struct section *s, *ps; 874 GElf_Shdr osh; 875 uint64_t off; 876 int first; 877 878 ps = NULL; 879 first = 1; 880 off = 0; 881 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 882 if (first) { 883 off = s->off; 884 first = 0; 885 } 886 887 /* 888 * Ignore TLS sections with load address 0 and without 889 * content. We don't need to adjust their file offset or 890 * VMA, only the size matters. 891 */ 892 if (s->seg_tls != NULL && s->type == SHT_NOBITS && 893 s->off == 0) 894 continue; 895 896 /* Align section offset. */ 897 if (s->align == 0) 898 s->align = 1; 899 if (off <= s->off) { 900 if (!s->loadable || (ecp->flags & RELOCATABLE)) 901 s->off = roundup(off, s->align); 902 } else { 903 if (s->loadable && (ecp->flags & RELOCATABLE) == 0) 904 warnx("moving loadable section %s, " 905 "is this intentional?", s->name); 906 s->off = roundup(off, s->align); 907 } 908 909 /* Calculate next section offset. */ 910 off = s->off; 911 if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL)) 912 off += s->sz; 913 914 if (s->pseudo) { 915 ps = NULL; 916 continue; 917 } 918 919 /* Count padding bytes added through --pad-to. */ 920 if (s->pad_sz > 0) 921 off += s->pad_sz; 922 923 /* Update section header accordingly. */ 924 if (gelf_getshdr(s->os, &osh) == NULL) 925 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 926 elf_errmsg(-1)); 927 osh.sh_addr = s->vma; 928 osh.sh_offset = s->off; 929 osh.sh_size = s->sz; 930 if (!gelf_update_shdr(s->os, &osh)) 931 errx(EXIT_FAILURE, "elf_update_shdr failed: %s", 932 elf_errmsg(-1)); 933 934 /* Add padding for previous section, if need. */ 935 if (ps != NULL) { 936 if (ps->pad_sz > 0) { 937 /* Apply padding added by --pad-to. */ 938 pad_section(ecp, ps); 939 } else if ((ecp->flags & GAP_FILL) && 940 (ps->off + ps->sz < s->off)) { 941 /* 942 * Fill the gap between sections by padding 943 * the section with lower address. 944 */ 945 ps->pad_sz = s->off - (ps->off + ps->sz); 946 pad_section(ecp, ps); 947 } 948 } 949 950 ps = s; 951 } 952 953 /* Pad the last section, if need. */ 954 if (ps != NULL && ps->pad_sz > 0) 955 pad_section(ecp, ps); 956 } 957 958 static void 959 modify_section(struct elfcopy *ecp, struct section *s) 960 { 961 struct sec_action *sac; 962 size_t srcsz, dstsz, p, len; 963 char *b, *c, *d, *src, *end; 964 int dupe; 965 966 src = read_section(s, &srcsz); 967 if (src == NULL || srcsz == 0) { 968 /* For empty section, we proceed if we need to append. */ 969 if (!is_append_section(ecp, s->name)) 970 return; 971 } 972 973 /* Allocate buffer needed for new section data. */ 974 dstsz = srcsz; 975 if (is_append_section(ecp, s->name)) { 976 sac = lookup_sec_act(ecp, s->name, 0); 977 dstsz += strlen(sac->string) + 1; 978 } 979 if ((b = malloc(dstsz)) == NULL) 980 err(EXIT_FAILURE, "malloc failed"); 981 s->buf = b; 982 983 /* Compress section. */ 984 p = 0; 985 if (is_compress_section(ecp, s->name)) { 986 end = src + srcsz; 987 for(c = src; c < end;) { 988 len = 0; 989 while(c + len < end && c[len] != '\0') 990 len++; 991 if (c + len == end) { 992 /* XXX should we warn here? */ 993 strncpy(&b[p], c, len); 994 p += len; 995 break; 996 } 997 dupe = 0; 998 for (d = b; d < b + p; ) { 999 if (strcmp(d, c) == 0) { 1000 dupe = 1; 1001 break; 1002 } 1003 d += strlen(d) + 1; 1004 } 1005 if (!dupe) { 1006 strncpy(&b[p], c, len); 1007 b[p + len] = '\0'; 1008 p += len + 1; 1009 } 1010 c += len + 1; 1011 } 1012 } else { 1013 memcpy(b, src, srcsz); 1014 p += srcsz; 1015 } 1016 1017 /* Append section. */ 1018 if (is_append_section(ecp, s->name)) { 1019 sac = lookup_sec_act(ecp, s->name, 0); 1020 len = strlen(sac->string); 1021 strncpy(&b[p], sac->string, len); 1022 b[p + len] = '\0'; 1023 p += len + 1; 1024 } 1025 1026 s->sz = p; 1027 s->nocopy = 1; 1028 } 1029 1030 static void 1031 print_data(const char *d, size_t sz) 1032 { 1033 const char *c; 1034 1035 for (c = d; c < d + sz; c++) { 1036 if (*c == '\0') 1037 putchar('\n'); 1038 else 1039 putchar(*c); 1040 } 1041 } 1042 1043 static void 1044 print_section(struct section *s) 1045 { 1046 Elf_Data *id; 1047 int elferr; 1048 1049 if (s->buf != NULL && s->sz > 0) { 1050 print_data(s->buf, s->sz); 1051 } else { 1052 id = NULL; 1053 while ((id = elf_getdata(s->is, id)) != NULL || 1054 (id = elf_rawdata(s->is, id)) != NULL) { 1055 (void) elf_errno(); 1056 print_data(id->d_buf, id->d_size); 1057 } 1058 elferr = elf_errno(); 1059 if (elferr != 0) 1060 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 1061 elf_errmsg(elferr)); 1062 } 1063 putchar('\n'); 1064 } 1065 1066 static void * 1067 read_section(struct section *s, size_t *size) 1068 { 1069 Elf_Data *id; 1070 char *b; 1071 size_t sz; 1072 int elferr; 1073 1074 sz = 0; 1075 b = NULL; 1076 id = NULL; 1077 while ((id = elf_getdata(s->is, id)) != NULL || 1078 (id = elf_rawdata(s->is, id)) != NULL) { 1079 (void) elf_errno(); 1080 if (b == NULL) 1081 b = malloc(id->d_size); 1082 else 1083 b = malloc(sz + id->d_size); 1084 if (b == NULL) 1085 err(EXIT_FAILURE, "malloc or realloc failed"); 1086 1087 memcpy(&b[sz], id->d_buf, id->d_size); 1088 sz += id->d_size; 1089 } 1090 elferr = elf_errno(); 1091 if (elferr != 0) 1092 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 1093 elf_errmsg(elferr)); 1094 1095 *size = sz; 1096 1097 return (b); 1098 } 1099 1100 void 1101 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, 1102 int sec_flags) 1103 { 1104 GElf_Shdr ish, osh; 1105 1106 if (gelf_getshdr(s->is, &ish) == NULL) 1107 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1108 elf_errmsg(-1)); 1109 if (gelf_getshdr(s->os, &osh) == NULL) 1110 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1111 elf_errmsg(-1)); 1112 1113 if (copy) 1114 (void) memcpy(&osh, &ish, sizeof(ish)); 1115 else { 1116 osh.sh_type = s->type; 1117 osh.sh_addr = s->vma; 1118 osh.sh_offset = s->off; 1119 osh.sh_size = s->sz; 1120 osh.sh_link = ish.sh_link; 1121 osh.sh_info = ish.sh_info; 1122 osh.sh_addralign = s->align; 1123 osh.sh_entsize = ish.sh_entsize; 1124 1125 if (sec_flags) { 1126 osh.sh_flags = 0; 1127 if (sec_flags & SF_ALLOC) 1128 osh.sh_flags |= SHF_ALLOC; 1129 if ((sec_flags & SF_READONLY) == 0) 1130 osh.sh_flags |= SHF_WRITE; 1131 if (sec_flags & SF_CODE) 1132 osh.sh_flags |= SHF_EXECINSTR; 1133 if ((sec_flags & SF_CONTENTS) && 1134 s->type == SHT_NOBITS && s->sz > 0) { 1135 /* 1136 * Convert SHT_NOBITS section to section with 1137 * (zero'ed) content on file. 1138 */ 1139 osh.sh_type = s->type = SHT_PROGBITS; 1140 if ((s->buf = calloc(1, s->sz)) == NULL) 1141 err(EXIT_FAILURE, "malloc failed"); 1142 s->nocopy = 1; 1143 } 1144 } else { 1145 osh.sh_flags = ish.sh_flags; 1146 /* 1147 * Newer binutils as(1) emits the section flag 1148 * SHF_INFO_LINK for relocation sections. elfcopy 1149 * emits this flag in the output section if it's 1150 * missing in the input section, to remain compatible 1151 * with binutils. 1152 */ 1153 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) 1154 osh.sh_flags |= SHF_INFO_LINK; 1155 } 1156 } 1157 1158 if (name == NULL) 1159 add_to_shstrtab(ecp, s->name); 1160 else 1161 add_to_shstrtab(ecp, name); 1162 1163 if (!gelf_update_shdr(s->os, &osh)) 1164 errx(EXIT_FAILURE, "elf_update_shdr failed: %s", 1165 elf_errmsg(-1)); 1166 } 1167 1168 void 1169 copy_data(struct section *s) 1170 { 1171 Elf_Data *id, *od; 1172 int elferr; 1173 1174 if (s->nocopy && s->buf == NULL) 1175 return; 1176 1177 if ((id = elf_getdata(s->is, NULL)) == NULL) { 1178 (void) elf_errno(); 1179 if ((id = elf_rawdata(s->is, NULL)) == NULL) { 1180 elferr = elf_errno(); 1181 if (elferr != 0) 1182 errx(EXIT_FAILURE, "failed to read section:" 1183 " %s", s->name); 1184 return; 1185 } 1186 } 1187 1188 if ((od = elf_newdata(s->os)) == NULL) 1189 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 1190 elf_errmsg(-1)); 1191 1192 if (s->nocopy) { 1193 /* Use s->buf as content if s->nocopy is set. */ 1194 od->d_align = id->d_align; 1195 od->d_off = 0; 1196 od->d_buf = s->buf; 1197 od->d_type = id->d_type; 1198 od->d_size = s->sz; 1199 od->d_version = id->d_version; 1200 } else { 1201 od->d_align = id->d_align; 1202 od->d_off = id->d_off; 1203 od->d_buf = id->d_buf; 1204 od->d_type = id->d_type; 1205 od->d_size = id->d_size; 1206 od->d_version = id->d_version; 1207 } 1208 1209 /* 1210 * Alignment Fixup. libelf does not allow the alignment for 1211 * Elf_Data descriptor to be set to 0. In this case we workaround 1212 * it by setting the alignment to 1. 1213 * 1214 * According to the ELF ABI, alignment 0 and 1 has the same 1215 * meaning: the section has no alignment constraints. 1216 */ 1217 if (od->d_align == 0) 1218 od->d_align = 1; 1219 } 1220 1221 struct section * 1222 create_external_section(struct elfcopy *ecp, const char *name, char *newname, 1223 void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype, 1224 uint64_t flags, uint64_t align, uint64_t vma, int loadable) 1225 { 1226 struct section *s; 1227 Elf_Scn *os; 1228 Elf_Data *od; 1229 GElf_Shdr osh; 1230 1231 if ((os = elf_newscn(ecp->eout)) == NULL) 1232 errx(EXIT_FAILURE, "elf_newscn() failed: %s", 1233 elf_errmsg(-1)); 1234 if ((s = calloc(1, sizeof(*s))) == NULL) 1235 err(EXIT_FAILURE, "calloc failed"); 1236 s->name = name; 1237 s->newname = newname; /* needs to be free()'ed */ 1238 s->off = off; 1239 s->sz = size; 1240 s->vma = vma; 1241 s->align = align; 1242 s->loadable = loadable; 1243 s->is = NULL; 1244 s->os = os; 1245 s->type = stype; 1246 s->nocopy = 1; 1247 insert_to_sec_list(ecp, s, 1); 1248 1249 if (gelf_getshdr(os, &osh) == NULL) 1250 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1251 elf_errmsg(-1)); 1252 osh.sh_flags = flags; 1253 osh.sh_type = s->type; 1254 osh.sh_addr = s->vma; 1255 osh.sh_addralign = s->align; 1256 if (!gelf_update_shdr(os, &osh)) 1257 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", 1258 elf_errmsg(-1)); 1259 add_to_shstrtab(ecp, name); 1260 1261 if (buf != NULL && size != 0) { 1262 if ((od = elf_newdata(os)) == NULL) 1263 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 1264 elf_errmsg(-1)); 1265 od->d_align = align; 1266 od->d_off = 0; 1267 od->d_buf = buf; 1268 od->d_size = size; 1269 od->d_type = dtype; 1270 od->d_version = EV_CURRENT; 1271 } 1272 1273 /* 1274 * Clear SYMTAB_INTACT, as we probably need to update/add new 1275 * STT_SECTION symbols into the symbol table. 1276 */ 1277 ecp->flags &= ~SYMTAB_INTACT; 1278 1279 return (s); 1280 } 1281 1282 /* 1283 * Insert sections specified by --add-section to the end of section list. 1284 */ 1285 static void 1286 insert_sections(struct elfcopy *ecp) 1287 { 1288 struct sec_add *sa; 1289 struct section *s; 1290 size_t off; 1291 uint64_t stype; 1292 1293 /* Put these sections in the end of current list. */ 1294 off = 0; 1295 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 1296 if (s->type != SHT_NOBITS && s->type != SHT_NULL) 1297 off = s->off + s->sz; 1298 else 1299 off = s->off; 1300 } 1301 1302 STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) { 1303 1304 /* TODO: Add section header vma/lma, flag changes here */ 1305 1306 /* 1307 * The default section type for user added section is 1308 * SHT_PROGBITS. If the section name match certain patterns, 1309 * elfcopy will try to set a more appropriate section type. 1310 * However, data type is always set to ELF_T_BYTE and no 1311 * translation is performed by libelf. 1312 */ 1313 stype = SHT_PROGBITS; 1314 if (strcmp(sa->name, ".note") == 0 || 1315 strncmp(sa->name, ".note.", strlen(".note.")) == 0) 1316 stype = SHT_NOTE; 1317 1318 (void) create_external_section(ecp, sa->name, NULL, sa->content, 1319 sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); 1320 } 1321 } 1322 1323 void 1324 add_to_shstrtab(struct elfcopy *ecp, const char *name) 1325 { 1326 struct section *s; 1327 1328 s = ecp->shstrtab; 1329 insert_to_strtab(s, name); 1330 } 1331 1332 void 1333 update_shdr(struct elfcopy *ecp, int update_link) 1334 { 1335 struct section *s; 1336 GElf_Shdr osh; 1337 int elferr; 1338 1339 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 1340 if (s->pseudo) 1341 continue; 1342 1343 if (gelf_getshdr(s->os, &osh) == NULL) 1344 errx(EXIT_FAILURE, "gelf_getshdr failed: %s", 1345 elf_errmsg(-1)); 1346 1347 /* Find section name in string table and set sh_name. */ 1348 osh.sh_name = lookup_string(ecp->shstrtab, s->name); 1349 1350 /* 1351 * sh_link needs to be updated, since the index of the 1352 * linked section might have changed. 1353 */ 1354 if (update_link && osh.sh_link != 0) 1355 osh.sh_link = ecp->secndx[osh.sh_link]; 1356 1357 /* 1358 * sh_info of relocation section links to the section to which 1359 * its relocation info applies. So it may need update as well. 1360 */ 1361 if ((s->type == SHT_REL || s->type == SHT_RELA) && 1362 osh.sh_info != 0) 1363 osh.sh_info = ecp->secndx[osh.sh_info]; 1364 1365 /* 1366 * sh_info of SHT_GROUP section needs to point to the correct 1367 * string in the symbol table. 1368 */ 1369 if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) && 1370 (ecp->flags & SYMTAB_INTACT) == 0) 1371 osh.sh_info = ecp->symndx[osh.sh_info]; 1372 1373 if (!gelf_update_shdr(s->os, &osh)) 1374 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", 1375 elf_errmsg(-1)); 1376 } 1377 elferr = elf_errno(); 1378 if (elferr != 0) 1379 errx(EXIT_FAILURE, "elf_nextscn failed: %s", 1380 elf_errmsg(elferr)); 1381 } 1382 1383 void 1384 init_shstrtab(struct elfcopy *ecp) 1385 { 1386 struct section *s; 1387 1388 if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL) 1389 err(EXIT_FAILURE, "calloc failed"); 1390 s = ecp->shstrtab; 1391 s->name = ".shstrtab"; 1392 s->is = NULL; 1393 s->sz = 0; 1394 s->align = 1; 1395 s->loadable = 0; 1396 s->type = SHT_STRTAB; 1397 s->vma = 0; 1398 1399 insert_to_strtab(s, ""); 1400 insert_to_strtab(s, ".symtab"); 1401 insert_to_strtab(s, ".strtab"); 1402 insert_to_strtab(s, ".shstrtab"); 1403 } 1404 1405 void 1406 set_shstrtab(struct elfcopy *ecp) 1407 { 1408 struct section *s; 1409 Elf_Data *data; 1410 GElf_Shdr sh; 1411 1412 s = ecp->shstrtab; 1413 1414 if (s->os == NULL) { 1415 /* Input object does not contain .shstrtab section */ 1416 if ((s->os = elf_newscn(ecp->eout)) == NULL) 1417 errx(EXIT_FAILURE, "elf_newscn failed: %s", 1418 elf_errmsg(-1)); 1419 insert_to_sec_list(ecp, s, 1); 1420 } 1421 1422 if (gelf_getshdr(s->os, &sh) == NULL) 1423 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1424 elf_errmsg(-1)); 1425 sh.sh_addr = 0; 1426 sh.sh_addralign = 1; 1427 sh.sh_offset = s->off; 1428 sh.sh_type = SHT_STRTAB; 1429 sh.sh_flags = 0; 1430 sh.sh_entsize = 0; 1431 sh.sh_info = 0; 1432 sh.sh_link = 0; 1433 1434 if ((data = elf_newdata(s->os)) == NULL) 1435 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 1436 elf_errmsg(-1)); 1437 1438 /* 1439 * If we don't have a symbol table, skip those a few bytes 1440 * which are reserved for this in the beginning of shstrtab. 1441 */ 1442 if (!(ecp->flags & SYMTAB_EXIST)) { 1443 s->sz -= sizeof(".symtab\0.strtab"); 1444 memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"), 1445 s->sz); 1446 } 1447 1448 sh.sh_size = s->sz; 1449 if (!gelf_update_shdr(s->os, &sh)) 1450 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", 1451 elf_errmsg(-1)); 1452 1453 data->d_align = 1; 1454 data->d_buf = s->buf; 1455 data->d_size = s->sz; 1456 data->d_off = 0; 1457 data->d_type = ELF_T_BYTE; 1458 data->d_version = EV_CURRENT; 1459 1460 if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os))) 1461 errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s", 1462 elf_errmsg(-1)); 1463 } 1464 1465 void 1466 add_section(struct elfcopy *ecp, const char *arg) 1467 { 1468 struct sec_add *sa; 1469 struct stat sb; 1470 const char *s, *fn; 1471 FILE *fp; 1472 int len; 1473 1474 if ((s = strchr(arg, '=')) == NULL) 1475 errx(EXIT_FAILURE, 1476 "illegal format for --add-section option"); 1477 if ((sa = malloc(sizeof(*sa))) == NULL) 1478 err(EXIT_FAILURE, "malloc failed"); 1479 1480 len = s - arg; 1481 if ((sa->name = malloc(len + 1)) == NULL) 1482 err(EXIT_FAILURE, "malloc failed"); 1483 strncpy(sa->name, arg, len); 1484 sa->name[len] = '\0'; 1485 1486 fn = s + 1; 1487 if (stat(fn, &sb) == -1) 1488 err(EXIT_FAILURE, "stat failed"); 1489 sa->size = sb.st_size; 1490 if (sa->size > 0) { 1491 if ((sa->content = malloc(sa->size)) == NULL) 1492 err(EXIT_FAILURE, "malloc failed"); 1493 if ((fp = fopen(fn, "r")) == NULL) 1494 err(EXIT_FAILURE, "can not open %s", fn); 1495 if (fread(sa->content, 1, sa->size, fp) == 0 || 1496 ferror(fp)) 1497 err(EXIT_FAILURE, "fread failed"); 1498 fclose(fp); 1499 } else 1500 sa->content = NULL; 1501 1502 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); 1503 ecp->flags |= SEC_ADD; 1504 } 1505 1506 void 1507 free_sec_add(struct elfcopy *ecp) 1508 { 1509 struct sec_add *sa, *sa_temp; 1510 1511 STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) { 1512 STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list); 1513 free(sa->name); 1514 free(sa->content); 1515 free(sa); 1516 } 1517 } 1518 1519 static void 1520 add_gnu_debuglink(struct elfcopy *ecp) 1521 { 1522 struct sec_add *sa; 1523 struct stat sb; 1524 FILE *fp; 1525 char *fnbase, *buf; 1526 int crc_off; 1527 int crc; 1528 1529 if (ecp->debuglink == NULL) 1530 return; 1531 1532 /* Read debug file content. */ 1533 if ((sa = malloc(sizeof(*sa))) == NULL) 1534 err(EXIT_FAILURE, "malloc failed"); 1535 if ((sa->name = strdup(".gnu_debuglink")) == NULL) 1536 err(EXIT_FAILURE, "strdup failed"); 1537 if (stat(ecp->debuglink, &sb) == -1) 1538 err(EXIT_FAILURE, "stat failed"); 1539 if (sb.st_size == 0) 1540 errx(EXIT_FAILURE, "empty debug link target %s", 1541 ecp->debuglink); 1542 if ((buf = malloc(sb.st_size)) == NULL) 1543 err(EXIT_FAILURE, "malloc failed"); 1544 if ((fp = fopen(ecp->debuglink, "r")) == NULL) 1545 err(EXIT_FAILURE, "can not open %s", ecp->debuglink); 1546 if (fread(buf, 1, sb.st_size, fp) == 0 || 1547 ferror(fp)) 1548 err(EXIT_FAILURE, "fread failed"); 1549 fclose(fp); 1550 1551 /* Calculate crc checksum. */ 1552 crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF); 1553 free(buf); 1554 1555 /* Calculate section size and the offset to store crc checksum. */ 1556 if ((fnbase = basename(ecp->debuglink)) == NULL) 1557 err(EXIT_FAILURE, "basename failed"); 1558 crc_off = roundup(strlen(fnbase) + 1, 4); 1559 sa->size = crc_off + 4; 1560 1561 /* Section content. */ 1562 if ((sa->content = calloc(1, sa->size)) == NULL) 1563 err(EXIT_FAILURE, "malloc failed"); 1564 strncpy(sa->content, fnbase, strlen(fnbase)); 1565 if (ecp->oed == ELFDATA2LSB) { 1566 sa->content[crc_off] = crc & 0xFF; 1567 sa->content[crc_off + 1] = (crc >> 8) & 0xFF; 1568 sa->content[crc_off + 2] = (crc >> 16) & 0xFF; 1569 sa->content[crc_off + 3] = crc >> 24; 1570 } else { 1571 sa->content[crc_off] = crc >> 24; 1572 sa->content[crc_off + 1] = (crc >> 16) & 0xFF; 1573 sa->content[crc_off + 2] = (crc >> 8) & 0xFF; 1574 sa->content[crc_off + 3] = crc & 0xFF; 1575 } 1576 1577 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); 1578 ecp->flags |= SEC_ADD; 1579 } 1580 1581 static void 1582 insert_to_strtab(struct section *t, const char *s) 1583 { 1584 const char *r; 1585 char *b, *c; 1586 size_t len, slen; 1587 int append; 1588 1589 if (t->sz == 0) { 1590 t->cap = 512; 1591 if ((t->buf = malloc(t->cap)) == NULL) 1592 err(EXIT_FAILURE, "malloc failed"); 1593 } 1594 1595 slen = strlen(s); 1596 append = 0; 1597 b = t->buf; 1598 for (c = b; c < b + t->sz;) { 1599 len = strlen(c); 1600 if (!append && len >= slen) { 1601 r = c + (len - slen); 1602 if (strcmp(r, s) == 0) 1603 return; 1604 } else if (len < slen && len != 0) { 1605 r = s + (slen - len); 1606 if (strcmp(c, r) == 0) { 1607 t->sz -= len + 1; 1608 memmove(c, c + len + 1, t->sz - (c - b)); 1609 append = 1; 1610 continue; 1611 } 1612 } 1613 c += len + 1; 1614 } 1615 1616 while (t->sz + slen + 1 >= t->cap) { 1617 t->cap *= 2; 1618 if ((t->buf = realloc(t->buf, t->cap)) == NULL) 1619 err(EXIT_FAILURE, "realloc failed"); 1620 } 1621 b = t->buf; 1622 strncpy(&b[t->sz], s, slen); 1623 b[t->sz + slen] = '\0'; 1624 t->sz += slen + 1; 1625 } 1626 1627 static int 1628 lookup_string(struct section *t, const char *s) 1629 { 1630 const char *b, *c, *r; 1631 size_t len, slen; 1632 1633 slen = strlen(s); 1634 b = t->buf; 1635 for (c = b; c < b + t->sz;) { 1636 len = strlen(c); 1637 if (len >= slen) { 1638 r = c + (len - slen); 1639 if (strcmp(r, s) == 0) 1640 return (r - b); 1641 } 1642 c += len + 1; 1643 } 1644 1645 return (-1); 1646 } 1647 1648 static uint32_t crctable[256] = 1649 { 1650 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 1651 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 1652 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 1653 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, 1654 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 1655 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, 1656 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 1657 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, 1658 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, 1659 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, 1660 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, 1661 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, 1662 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, 1663 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, 1664 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, 1665 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, 1666 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, 1667 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, 1668 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, 1669 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, 1670 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, 1671 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, 1672 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, 1673 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, 1674 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, 1675 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, 1676 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, 1677 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, 1678 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, 1679 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, 1680 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, 1681 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, 1682 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, 1683 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, 1684 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, 1685 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, 1686 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, 1687 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, 1688 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, 1689 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, 1690 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, 1691 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, 1692 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, 1693 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, 1694 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, 1695 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, 1696 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, 1697 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, 1698 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, 1699 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, 1700 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, 1701 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, 1702 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, 1703 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, 1704 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, 1705 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, 1706 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, 1707 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, 1708 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, 1709 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, 1710 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 1711 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 1712 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 1713 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL 1714 }; 1715 1716 static uint32_t 1717 calc_crc32(const char *p, size_t len, uint32_t crc) 1718 { 1719 uint32_t i; 1720 1721 for (i = 0; i < len; i++) { 1722 crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8); 1723 } 1724 1725 return (crc ^ 0xFFFFFFFF); 1726 } 1727