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