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 3646 2018-10-27 02:25:39Z 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 void 883 resync_sections(struct elfcopy *ecp) 884 { 885 struct section *s, *ps; 886 GElf_Shdr osh; 887 uint64_t off; 888 int first; 889 890 ps = NULL; 891 first = 1; 892 off = 0; 893 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 894 if (first) { 895 off = s->off; 896 first = 0; 897 } 898 899 /* 900 * Ignore TLS sections with load address 0 and without 901 * content. We don't need to adjust their file offset or 902 * VMA, only the size matters. 903 */ 904 if (s->seg_tls != NULL && s->type == SHT_NOBITS && 905 s->off == 0) 906 continue; 907 908 /* Align section offset. */ 909 if (s->align == 0) 910 s->align = 1; 911 if (off <= s->off) { 912 if (!s->loadable || (ecp->flags & RELOCATABLE)) 913 s->off = roundup(off, s->align); 914 } else { 915 if (s->loadable && (ecp->flags & RELOCATABLE) == 0) 916 warnx("moving loadable section %s, " 917 "is this intentional?", s->name); 918 s->off = roundup(off, s->align); 919 } 920 921 /* Calculate next section offset. */ 922 off = s->off; 923 if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL)) 924 off += s->sz; 925 926 if (s->pseudo) { 927 ps = NULL; 928 continue; 929 } 930 931 /* Count padding bytes added through --pad-to. */ 932 if (s->pad_sz > 0) 933 off += s->pad_sz; 934 935 /* Update section header accordingly. */ 936 if (gelf_getshdr(s->os, &osh) == NULL) 937 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 938 elf_errmsg(-1)); 939 osh.sh_addr = s->vma; 940 osh.sh_offset = s->off; 941 osh.sh_size = s->sz; 942 if (!gelf_update_shdr(s->os, &osh)) 943 errx(EXIT_FAILURE, "elf_update_shdr failed: %s", 944 elf_errmsg(-1)); 945 946 /* Add padding for previous section, if need. */ 947 if (ps != NULL) { 948 if (ps->pad_sz > 0) { 949 /* Apply padding added by --pad-to. */ 950 pad_section(ecp, ps); 951 } else if ((ecp->flags & GAP_FILL) && 952 (ps->off + ps->sz < s->off)) { 953 /* 954 * Fill the gap between sections by padding 955 * the section with lower address. 956 */ 957 ps->pad_sz = s->off - (ps->off + ps->sz); 958 pad_section(ecp, ps); 959 } 960 } 961 962 ps = s; 963 } 964 965 /* Pad the last section, if need. */ 966 if (ps != NULL && ps->pad_sz > 0) 967 pad_section(ecp, ps); 968 } 969 970 static void 971 modify_section(struct elfcopy *ecp, struct section *s) 972 { 973 struct sec_action *sac; 974 size_t srcsz, dstsz, p, len; 975 char *b, *c, *d, *src, *end; 976 int dupe; 977 978 src = read_section(s, &srcsz); 979 if (src == NULL || srcsz == 0) { 980 /* For empty section, we proceed if we need to append. */ 981 if (!is_append_section(ecp, s->name)) 982 return; 983 } 984 985 /* Allocate buffer needed for new section data. */ 986 dstsz = srcsz; 987 if (is_append_section(ecp, s->name)) { 988 sac = lookup_sec_act(ecp, s->name, 0); 989 dstsz += strlen(sac->string) + 1; 990 } 991 if ((b = malloc(dstsz)) == NULL) 992 err(EXIT_FAILURE, "malloc failed"); 993 s->buf = b; 994 995 /* Compress section. */ 996 p = 0; 997 if (is_compress_section(ecp, s->name)) { 998 end = src + srcsz; 999 for(c = src; c < end;) { 1000 len = 0; 1001 while(c + len < end && c[len] != '\0') 1002 len++; 1003 if (c + len == end) { 1004 /* XXX should we warn here? */ 1005 strncpy(&b[p], c, len); 1006 p += len; 1007 break; 1008 } 1009 dupe = 0; 1010 for (d = b; d < b + p; ) { 1011 if (strcmp(d, c) == 0) { 1012 dupe = 1; 1013 break; 1014 } 1015 d += strlen(d) + 1; 1016 } 1017 if (!dupe) { 1018 strncpy(&b[p], c, len); 1019 b[p + len] = '\0'; 1020 p += len + 1; 1021 } 1022 c += len + 1; 1023 } 1024 } else { 1025 memcpy(b, src, srcsz); 1026 p += srcsz; 1027 } 1028 1029 /* Append section. */ 1030 if (is_append_section(ecp, s->name)) { 1031 sac = lookup_sec_act(ecp, s->name, 0); 1032 len = strlen(sac->string); 1033 strncpy(&b[p], sac->string, len); 1034 b[p + len] = '\0'; 1035 p += len + 1; 1036 } 1037 1038 s->sz = p; 1039 s->nocopy = 1; 1040 } 1041 1042 static void 1043 print_data(const char *d, size_t sz) 1044 { 1045 const char *c; 1046 1047 for (c = d; c < d + sz; c++) { 1048 if (*c == '\0') 1049 putchar('\n'); 1050 else 1051 putchar(*c); 1052 } 1053 } 1054 1055 static void 1056 print_section(struct section *s) 1057 { 1058 Elf_Data *id; 1059 int elferr; 1060 1061 if (s->buf != NULL && s->sz > 0) { 1062 print_data(s->buf, s->sz); 1063 } else { 1064 id = NULL; 1065 while ((id = elf_getdata(s->is, id)) != NULL || 1066 (id = elf_rawdata(s->is, id)) != NULL) { 1067 (void) elf_errno(); 1068 print_data(id->d_buf, id->d_size); 1069 } 1070 elferr = elf_errno(); 1071 if (elferr != 0) 1072 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 1073 elf_errmsg(elferr)); 1074 } 1075 putchar('\n'); 1076 } 1077 1078 static void * 1079 read_section(struct section *s, size_t *size) 1080 { 1081 Elf_Data *id; 1082 char *b; 1083 size_t sz; 1084 int elferr; 1085 1086 sz = 0; 1087 b = NULL; 1088 id = NULL; 1089 while ((id = elf_getdata(s->is, id)) != NULL || 1090 (id = elf_rawdata(s->is, id)) != NULL) { 1091 (void) elf_errno(); 1092 if (b == NULL) 1093 b = malloc(id->d_size); 1094 else 1095 b = malloc(sz + id->d_size); 1096 if (b == NULL) 1097 err(EXIT_FAILURE, "malloc or realloc failed"); 1098 1099 memcpy(&b[sz], id->d_buf, id->d_size); 1100 sz += id->d_size; 1101 } 1102 elferr = elf_errno(); 1103 if (elferr != 0) 1104 errx(EXIT_FAILURE, "elf_getdata() failed: %s", 1105 elf_errmsg(elferr)); 1106 1107 *size = sz; 1108 1109 return (b); 1110 } 1111 1112 void 1113 copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, 1114 int sec_flags) 1115 { 1116 GElf_Shdr ish, osh; 1117 1118 if (gelf_getshdr(s->is, &ish) == NULL) 1119 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1120 elf_errmsg(-1)); 1121 if (gelf_getshdr(s->os, &osh) == NULL) 1122 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1123 elf_errmsg(-1)); 1124 1125 if (copy) 1126 (void) memcpy(&osh, &ish, sizeof(ish)); 1127 else { 1128 osh.sh_type = s->type; 1129 osh.sh_addr = s->vma; 1130 osh.sh_offset = s->off; 1131 osh.sh_size = s->sz; 1132 osh.sh_link = ish.sh_link; 1133 osh.sh_info = ish.sh_info; 1134 osh.sh_addralign = s->align; 1135 osh.sh_entsize = ish.sh_entsize; 1136 1137 if (sec_flags) { 1138 osh.sh_flags = 0; 1139 if (sec_flags & SF_ALLOC) 1140 osh.sh_flags |= SHF_ALLOC; 1141 if ((sec_flags & SF_READONLY) == 0) 1142 osh.sh_flags |= SHF_WRITE; 1143 if (sec_flags & SF_CODE) 1144 osh.sh_flags |= SHF_EXECINSTR; 1145 if ((sec_flags & SF_CONTENTS) && 1146 s->type == SHT_NOBITS && s->sz > 0) { 1147 /* 1148 * Convert SHT_NOBITS section to section with 1149 * (zero'ed) content on file. 1150 */ 1151 osh.sh_type = s->type = SHT_PROGBITS; 1152 if ((s->buf = calloc(1, s->sz)) == NULL) 1153 err(EXIT_FAILURE, "malloc failed"); 1154 s->nocopy = 1; 1155 } 1156 } else { 1157 osh.sh_flags = ish.sh_flags; 1158 /* 1159 * Newer binutils as(1) emits the section flag 1160 * SHF_INFO_LINK for relocation sections. elfcopy 1161 * emits this flag in the output section if it's 1162 * missing in the input section, to remain compatible 1163 * with binutils. 1164 */ 1165 if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) 1166 osh.sh_flags |= SHF_INFO_LINK; 1167 } 1168 } 1169 1170 if (name == NULL) 1171 add_to_shstrtab(ecp, s->name); 1172 else 1173 add_to_shstrtab(ecp, name); 1174 1175 if (!gelf_update_shdr(s->os, &osh)) 1176 errx(EXIT_FAILURE, "elf_update_shdr failed: %s", 1177 elf_errmsg(-1)); 1178 } 1179 1180 void 1181 copy_data(struct section *s) 1182 { 1183 Elf_Data *id, *od; 1184 int elferr; 1185 1186 if (s->nocopy && s->buf == NULL) 1187 return; 1188 1189 if ((id = elf_getdata(s->is, NULL)) == NULL) { 1190 (void) elf_errno(); 1191 if ((id = elf_rawdata(s->is, NULL)) == NULL) { 1192 elferr = elf_errno(); 1193 if (elferr != 0) 1194 errx(EXIT_FAILURE, "failed to read section:" 1195 " %s", s->name); 1196 return; 1197 } 1198 } 1199 1200 if ((od = elf_newdata(s->os)) == NULL) 1201 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 1202 elf_errmsg(-1)); 1203 1204 if (s->nocopy) { 1205 /* Use s->buf as content if s->nocopy is set. */ 1206 od->d_align = id->d_align; 1207 od->d_off = 0; 1208 od->d_buf = s->buf; 1209 od->d_type = id->d_type; 1210 od->d_size = s->sz; 1211 od->d_version = id->d_version; 1212 } else { 1213 od->d_align = id->d_align; 1214 od->d_off = id->d_off; 1215 od->d_buf = id->d_buf; 1216 od->d_type = id->d_type; 1217 od->d_size = id->d_size; 1218 od->d_version = id->d_version; 1219 } 1220 1221 /* 1222 * Alignment Fixup. libelf does not allow the alignment for 1223 * Elf_Data descriptor to be set to 0. In this case we workaround 1224 * it by setting the alignment to 1. 1225 * 1226 * According to the ELF ABI, alignment 0 and 1 has the same 1227 * meaning: the section has no alignment constraints. 1228 */ 1229 if (od->d_align == 0) 1230 od->d_align = 1; 1231 } 1232 1233 struct section * 1234 create_external_section(struct elfcopy *ecp, const char *name, char *newname, 1235 void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype, 1236 uint64_t flags, uint64_t align, uint64_t vma, int loadable) 1237 { 1238 struct section *s; 1239 Elf_Scn *os; 1240 Elf_Data *od; 1241 GElf_Shdr osh; 1242 1243 if ((os = elf_newscn(ecp->eout)) == NULL) 1244 errx(EXIT_FAILURE, "elf_newscn() failed: %s", 1245 elf_errmsg(-1)); 1246 if ((s = calloc(1, sizeof(*s))) == NULL) 1247 err(EXIT_FAILURE, "calloc failed"); 1248 s->name = name; 1249 s->newname = newname; /* needs to be free()'ed */ 1250 s->off = off; 1251 s->sz = size; 1252 s->vma = vma; 1253 s->align = align; 1254 s->loadable = loadable; 1255 s->is = NULL; 1256 s->os = os; 1257 s->type = stype; 1258 s->nocopy = 1; 1259 insert_to_sec_list(ecp, s, 1); 1260 1261 if (gelf_getshdr(os, &osh) == NULL) 1262 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1263 elf_errmsg(-1)); 1264 osh.sh_flags = flags; 1265 osh.sh_type = s->type; 1266 osh.sh_addr = s->vma; 1267 osh.sh_addralign = s->align; 1268 if (!gelf_update_shdr(os, &osh)) 1269 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", 1270 elf_errmsg(-1)); 1271 add_to_shstrtab(ecp, name); 1272 1273 if (buf != NULL && size != 0) { 1274 if ((od = elf_newdata(os)) == NULL) 1275 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 1276 elf_errmsg(-1)); 1277 od->d_align = align; 1278 od->d_off = 0; 1279 od->d_buf = buf; 1280 od->d_size = size; 1281 od->d_type = dtype; 1282 od->d_version = EV_CURRENT; 1283 } 1284 1285 /* 1286 * Clear SYMTAB_INTACT, as we probably need to update/add new 1287 * STT_SECTION symbols into the symbol table. 1288 */ 1289 ecp->flags &= ~SYMTAB_INTACT; 1290 1291 return (s); 1292 } 1293 1294 /* 1295 * Insert sections specified by --add-section to the end of section list. 1296 */ 1297 static void 1298 insert_sections(struct elfcopy *ecp) 1299 { 1300 struct sec_add *sa; 1301 struct section *s; 1302 size_t off; 1303 uint64_t stype; 1304 1305 /* Put these sections in the end of current list. */ 1306 off = 0; 1307 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 1308 if (s->type != SHT_NOBITS && s->type != SHT_NULL) 1309 off = s->off + s->sz; 1310 else 1311 off = s->off; 1312 } 1313 1314 STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) { 1315 1316 /* TODO: Add section header vma/lma, flag changes here */ 1317 1318 /* 1319 * The default section type for user added section is 1320 * SHT_PROGBITS. If the section name match certain patterns, 1321 * elfcopy will try to set a more appropriate section type. 1322 * However, data type is always set to ELF_T_BYTE and no 1323 * translation is performed by libelf. 1324 */ 1325 stype = SHT_PROGBITS; 1326 if (strcmp(sa->name, ".note") == 0 || 1327 strncmp(sa->name, ".note.", strlen(".note.")) == 0) 1328 stype = SHT_NOTE; 1329 1330 (void) create_external_section(ecp, sa->name, NULL, sa->content, 1331 sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); 1332 } 1333 } 1334 1335 void 1336 add_to_shstrtab(struct elfcopy *ecp, const char *name) 1337 { 1338 1339 if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0) 1340 errx(EXIT_FAILURE, "elftc_string_table_insert failed"); 1341 } 1342 1343 void 1344 update_shdr(struct elfcopy *ecp, int update_link) 1345 { 1346 struct section *s; 1347 GElf_Shdr osh; 1348 int elferr; 1349 1350 /* Finalize the section name string table (.shstrtab). */ 1351 set_shstrtab(ecp); 1352 1353 TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { 1354 if (s->pseudo) 1355 continue; 1356 1357 if (gelf_getshdr(s->os, &osh) == NULL) 1358 errx(EXIT_FAILURE, "gelf_getshdr failed: %s", 1359 elf_errmsg(-1)); 1360 1361 /* Find section name in string table and set sh_name. */ 1362 osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab, 1363 s->name); 1364 1365 /* 1366 * sh_link needs to be updated, since the index of the 1367 * linked section might have changed. 1368 */ 1369 if (update_link && osh.sh_link != 0) 1370 osh.sh_link = ecp->secndx[osh.sh_link]; 1371 1372 /* 1373 * sh_info of relocation section links to the section to which 1374 * its relocation info applies. So it may need update as well. 1375 */ 1376 if ((s->type == SHT_REL || s->type == SHT_RELA) && 1377 osh.sh_info != 0) 1378 osh.sh_info = ecp->secndx[osh.sh_info]; 1379 1380 /* 1381 * sh_info of SHT_GROUP section needs to point to the correct 1382 * string in the symbol table. 1383 */ 1384 if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) && 1385 (ecp->flags & SYMTAB_INTACT) == 0) 1386 osh.sh_info = ecp->symndx[osh.sh_info]; 1387 1388 if (!gelf_update_shdr(s->os, &osh)) 1389 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", 1390 elf_errmsg(-1)); 1391 } 1392 elferr = elf_errno(); 1393 if (elferr != 0) 1394 errx(EXIT_FAILURE, "elf_nextscn failed: %s", 1395 elf_errmsg(elferr)); 1396 } 1397 1398 void 1399 init_shstrtab(struct elfcopy *ecp) 1400 { 1401 struct section *s; 1402 1403 if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL) 1404 err(EXIT_FAILURE, "calloc failed"); 1405 s = ecp->shstrtab; 1406 s->name = ".shstrtab"; 1407 s->is = NULL; 1408 s->sz = 0; 1409 s->align = 1; 1410 s->loadable = 0; 1411 s->type = SHT_STRTAB; 1412 s->vma = 0; 1413 s->strtab = elftc_string_table_create(0); 1414 1415 add_to_shstrtab(ecp, ""); 1416 add_to_shstrtab(ecp, ".symtab"); 1417 add_to_shstrtab(ecp, ".strtab"); 1418 add_to_shstrtab(ecp, ".shstrtab"); 1419 } 1420 1421 static void 1422 set_shstrtab(struct elfcopy *ecp) 1423 { 1424 struct section *s; 1425 Elf_Data *data; 1426 GElf_Shdr sh; 1427 const char *image; 1428 size_t sz; 1429 1430 s = ecp->shstrtab; 1431 1432 if (s->os == NULL) { 1433 /* Input object does not contain .shstrtab section */ 1434 if ((s->os = elf_newscn(ecp->eout)) == NULL) 1435 errx(EXIT_FAILURE, "elf_newscn failed: %s", 1436 elf_errmsg(-1)); 1437 insert_to_sec_list(ecp, s, 1); 1438 } 1439 1440 if (gelf_getshdr(s->os, &sh) == NULL) 1441 errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", 1442 elf_errmsg(-1)); 1443 sh.sh_addr = 0; 1444 sh.sh_addralign = 1; 1445 sh.sh_offset = s->off; 1446 sh.sh_type = SHT_STRTAB; 1447 sh.sh_flags = 0; 1448 sh.sh_entsize = 0; 1449 sh.sh_info = 0; 1450 sh.sh_link = 0; 1451 1452 if ((data = elf_newdata(s->os)) == NULL) 1453 errx(EXIT_FAILURE, "elf_newdata() failed: %s", 1454 elf_errmsg(-1)); 1455 1456 /* 1457 * If we don't have a symbol table, skip those a few bytes 1458 * which are reserved for this in the beginning of shstrtab. 1459 */ 1460 if (!(ecp->flags & SYMTAB_EXIST)) { 1461 elftc_string_table_remove(s->strtab, ".symtab"); 1462 elftc_string_table_remove(s->strtab, ".strtab"); 1463 } 1464 1465 image = elftc_string_table_image(s->strtab, &sz); 1466 s->sz = sz; 1467 1468 sh.sh_size = sz; 1469 if (!gelf_update_shdr(s->os, &sh)) 1470 errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", 1471 elf_errmsg(-1)); 1472 1473 data->d_align = 1; 1474 data->d_buf = (void *)(uintptr_t)image; 1475 data->d_size = sz; 1476 data->d_off = 0; 1477 data->d_type = ELF_T_BYTE; 1478 data->d_version = EV_CURRENT; 1479 1480 if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os))) 1481 errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s", 1482 elf_errmsg(-1)); 1483 } 1484 1485 void 1486 add_section(struct elfcopy *ecp, const char *arg) 1487 { 1488 struct sec_add *sa; 1489 struct stat sb; 1490 const char *s, *fn; 1491 FILE *fp; 1492 int len; 1493 1494 if ((s = strchr(arg, '=')) == NULL) 1495 errx(EXIT_FAILURE, 1496 "illegal format for --add-section option"); 1497 if ((sa = malloc(sizeof(*sa))) == NULL) 1498 err(EXIT_FAILURE, "malloc failed"); 1499 1500 len = s - arg; 1501 if ((sa->name = malloc(len + 1)) == NULL) 1502 err(EXIT_FAILURE, "malloc failed"); 1503 strncpy(sa->name, arg, len); 1504 sa->name[len] = '\0'; 1505 1506 fn = s + 1; 1507 if (stat(fn, &sb) == -1) 1508 err(EXIT_FAILURE, "stat failed"); 1509 sa->size = sb.st_size; 1510 if (sa->size > 0) { 1511 if ((sa->content = malloc(sa->size)) == NULL) 1512 err(EXIT_FAILURE, "malloc failed"); 1513 if ((fp = fopen(fn, "r")) == NULL) 1514 err(EXIT_FAILURE, "can not open %s", fn); 1515 if (fread(sa->content, 1, sa->size, fp) == 0 || 1516 ferror(fp)) 1517 err(EXIT_FAILURE, "fread failed"); 1518 fclose(fp); 1519 } else 1520 sa->content = NULL; 1521 1522 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); 1523 ecp->flags |= SEC_ADD; 1524 } 1525 1526 void 1527 free_sec_add(struct elfcopy *ecp) 1528 { 1529 struct sec_add *sa, *sa_temp; 1530 1531 STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) { 1532 STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list); 1533 free(sa->name); 1534 free(sa->content); 1535 free(sa); 1536 } 1537 } 1538 1539 static void 1540 add_gnu_debuglink(struct elfcopy *ecp) 1541 { 1542 struct sec_add *sa; 1543 struct stat sb; 1544 FILE *fp; 1545 char *fnbase, *buf; 1546 int crc_off; 1547 int crc; 1548 1549 if (ecp->debuglink == NULL) 1550 return; 1551 1552 /* Read debug file content. */ 1553 if ((sa = malloc(sizeof(*sa))) == NULL) 1554 err(EXIT_FAILURE, "malloc failed"); 1555 if ((sa->name = strdup(".gnu_debuglink")) == NULL) 1556 err(EXIT_FAILURE, "strdup failed"); 1557 if (stat(ecp->debuglink, &sb) == -1) 1558 err(EXIT_FAILURE, "stat failed"); 1559 if (sb.st_size == 0) 1560 errx(EXIT_FAILURE, "empty debug link target %s", 1561 ecp->debuglink); 1562 if ((buf = malloc(sb.st_size)) == NULL) 1563 err(EXIT_FAILURE, "malloc failed"); 1564 if ((fp = fopen(ecp->debuglink, "r")) == NULL) 1565 err(EXIT_FAILURE, "can not open %s", ecp->debuglink); 1566 if (fread(buf, 1, sb.st_size, fp) == 0 || 1567 ferror(fp)) 1568 err(EXIT_FAILURE, "fread failed"); 1569 fclose(fp); 1570 1571 /* Calculate crc checksum. */ 1572 crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF); 1573 free(buf); 1574 1575 /* Calculate section size and the offset to store crc checksum. */ 1576 if ((fnbase = basename(ecp->debuglink)) == NULL) 1577 err(EXIT_FAILURE, "basename failed"); 1578 crc_off = roundup(strlen(fnbase) + 1, 4); 1579 sa->size = crc_off + 4; 1580 1581 /* Section content. */ 1582 if ((sa->content = calloc(1, sa->size)) == NULL) 1583 err(EXIT_FAILURE, "malloc failed"); 1584 strncpy(sa->content, fnbase, strlen(fnbase)); 1585 if (ecp->oed == ELFDATA2LSB) { 1586 sa->content[crc_off] = crc & 0xFF; 1587 sa->content[crc_off + 1] = (crc >> 8) & 0xFF; 1588 sa->content[crc_off + 2] = (crc >> 16) & 0xFF; 1589 sa->content[crc_off + 3] = crc >> 24; 1590 } else { 1591 sa->content[crc_off] = crc >> 24; 1592 sa->content[crc_off + 1] = (crc >> 16) & 0xFF; 1593 sa->content[crc_off + 2] = (crc >> 8) & 0xFF; 1594 sa->content[crc_off + 3] = crc & 0xFF; 1595 } 1596 1597 STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); 1598 ecp->flags |= SEC_ADD; 1599 } 1600 1601 static uint32_t crctable[256] = 1602 { 1603 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 1604 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 1605 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 1606 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, 1607 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 1608 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, 1609 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 1610 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, 1611 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, 1612 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, 1613 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, 1614 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, 1615 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, 1616 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, 1617 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, 1618 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, 1619 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, 1620 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, 1621 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, 1622 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, 1623 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, 1624 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, 1625 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, 1626 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, 1627 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, 1628 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, 1629 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, 1630 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, 1631 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, 1632 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, 1633 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, 1634 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, 1635 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, 1636 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, 1637 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, 1638 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, 1639 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, 1640 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, 1641 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, 1642 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, 1643 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, 1644 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, 1645 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, 1646 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, 1647 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, 1648 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, 1649 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, 1650 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, 1651 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, 1652 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, 1653 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, 1654 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, 1655 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, 1656 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, 1657 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, 1658 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, 1659 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, 1660 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, 1661 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, 1662 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, 1663 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 1664 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 1665 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 1666 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL 1667 }; 1668 1669 static uint32_t 1670 calc_crc32(const char *p, size_t len, uint32_t crc) 1671 { 1672 uint32_t i; 1673 1674 for (i = 0; i < len; i++) { 1675 crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8); 1676 } 1677 1678 return (crc ^ 0xFFFFFFFF); 1679 } 1680