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