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