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