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