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