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