1 /* Discard section not used at runtime from object files. 2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper (at) redhat.com>, 2000. 4 5 This program is Open Source software; you can redistribute it and/or 6 modify it under the terms of the Open Software License version 1.0 as 7 published by the Open Source Initiative. 8 9 You should have received a copy of the Open Software License along 10 with this program; if not, you may obtain a copy of the Open Software 11 License version 1.0 from http://www.opensource.org/licenses/osl.php or 12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13 3001 King Ranch Road, Ukiah, CA 95482. */ 14 15 #ifdef HAVE_CONFIG_H 16 # include <config.h> 17 #endif 18 19 #include <argp.h> 20 #include <assert.h> 21 #include <byteswap.h> 22 #include <endian.h> 23 #include <error.h> 24 #include <fcntl.h> 25 #include <gelf.h> 26 #include <libelf.h> 27 #include <libintl.h> 28 #include <locale.h> 29 #include <mcheck.h> 30 #include <stdbool.h> 31 #include <stdio.h> 32 #include <stdio_ext.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <unistd.h> 36 #include <sys/param.h> 37 #include <sys/time.h> 38 39 #include <elf-knowledge.h> 40 #include <libebl.h> 41 #include <system.h> 42 43 44 /* Name and version of program. */ 45 static void print_version (FILE *stream, struct argp_state *state); 46 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 47 48 49 /* Values for the parameters which have no short form. */ 50 #define OPT_REMOVE_COMMENT 0x100 51 #define OPT_PERMISSIVE 0x101 52 53 54 /* Definitions of arguments for argp functions. */ 55 static const struct argp_option options[] = 56 { 57 { NULL, 0, NULL, 0, N_("Output selection:") }, 58 { NULL, 'o', "FILE", 0, N_("Place stripped output into FILE") }, 59 { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE") }, 60 61 { NULL, 0, NULL, 0, N_("Output options:") }, 62 { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols") }, 63 { "preserve-dates", 'p', NULL, 0, 64 N_("Copy modified/access timestamps to the output") }, 65 { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0, 66 N_("Remove .comment section") }, 67 { "permissive", OPT_PERMISSIVE, NULL, 0, 68 N_("Relax a few rules to handle slightly broken ELF files") }, 69 { NULL, 0, NULL, 0, NULL } 70 }; 71 72 /* Short description of program. */ 73 static const char doc[] = N_("Discard symbols from object files."); 74 75 /* Strings for arguments in help texts. */ 76 static const char args_doc[] = N_("[FILE...]"); 77 78 /* Prototype for option handler. */ 79 static error_t parse_opt (int key, char *arg, struct argp_state *state); 80 81 /* Function to print some extra text in the help message. */ 82 static char *more_help (int key, const char *text, void *input); 83 84 /* Data structure to communicate with argp functions. */ 85 static struct argp argp = 86 { 87 options, parse_opt, args_doc, doc, NULL, more_help 88 }; 89 90 91 /* Print symbols in file named FNAME. */ 92 static int process_file (const char *fname); 93 94 /* Handle one ELF file. */ 95 static int handle_elf (int fd, Elf *elf, const char *prefix, 96 const char *fname, mode_t mode, struct timeval tvp[2]); 97 98 /* Handle all files contained in the archive. */ 99 static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 100 struct timeval tvp[2]); 101 102 #define INTERNAL_ERROR(fname) \ 103 error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"), \ 104 fname, __LINE__, VERSION, __DATE__, elf_errmsg (-1)) 105 106 107 /* Name of the output file. */ 108 static const char *output_fname; 109 110 /* Name of the debug output file. */ 111 static const char *debug_fname; 112 113 /* If true output files shall have same date as the input file. */ 114 static bool preserve_dates; 115 116 /* If true .comment sections will be removed. */ 117 static bool remove_comment; 118 119 /* If true remove all debug sections. */ 120 static bool remove_debug; 121 122 /* If true relax some ELF rules for input files. */ 123 static bool permissive; 124 125 126 int 127 main (int argc, char *argv[]) 128 { 129 int remaining; 130 int result = 0; 131 132 /* Make memory leak detection possible. */ 133 mtrace (); 134 135 /* We use no threads here which can interfere with handling a stream. */ 136 __fsetlocking (stdin, FSETLOCKING_BYCALLER); 137 __fsetlocking (stdout, FSETLOCKING_BYCALLER); 138 __fsetlocking (stderr, FSETLOCKING_BYCALLER); 139 140 /* Set locale. */ 141 setlocale (LC_ALL, ""); 142 143 /* Make sure the message catalog can be found. */ 144 bindtextdomain (PACKAGE, LOCALEDIR); 145 146 /* Initialize the message catalog. */ 147 textdomain (PACKAGE); 148 149 /* Parse and process arguments. */ 150 argp_parse (&argp, argc, argv, 0, &remaining, NULL); 151 152 /* Tell the library which version we are expecting. */ 153 elf_version (EV_CURRENT); 154 155 if (remaining == argc) 156 /* The user didn't specify a name so we use a.out. */ 157 result = process_file ("a.out"); 158 else 159 { 160 /* If we have seen the `-o' or '-f' option there must be exactly one 161 input file. */ 162 if ((output_fname != NULL || debug_fname != NULL) 163 && remaining + 1 < argc) 164 error (EXIT_FAILURE, 0, gettext ("\ 165 Only one input file allowed together with '-o' and '-f'")); 166 167 /* Process all the remaining files. */ 168 do 169 result |= process_file (argv[remaining]); 170 while (++remaining < argc); 171 } 172 173 return result; 174 } 175 176 177 /* Print the version information. */ 178 static void 179 print_version (FILE *stream, struct argp_state *state) 180 { 181 fprintf (stream, "strip (%s) %s\n", PACKAGE_NAME, VERSION); 182 fprintf (stream, gettext ("\ 183 Copyright (C) %s Red Hat, Inc.\n\ 184 This is free software; see the source for copying conditions. There is NO\n\ 185 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 186 "), "2004"); 187 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 188 } 189 190 191 /* Handle program arguments. */ 192 static error_t 193 parse_opt (int key, char *arg, struct argp_state *state) 194 { 195 switch (key) 196 { 197 case 'f': 198 debug_fname = arg; 199 break; 200 201 case 'o': 202 output_fname = arg; 203 break; 204 205 case 'p': 206 preserve_dates = true; 207 break; 208 209 case OPT_REMOVE_COMMENT: 210 remove_comment = true; 211 break; 212 213 case 'g': 214 remove_debug = true; 215 break; 216 217 case OPT_PERMISSIVE: 218 permissive = true; 219 break; 220 221 default: 222 return ARGP_ERR_UNKNOWN; 223 } 224 return 0; 225 } 226 227 228 static char * 229 more_help (int key, const char *text, void *input) 230 { 231 char *buf; 232 233 switch (key) 234 { 235 case ARGP_KEY_HELP_EXTRA: 236 /* We print some extra information. */ 237 if (asprintf (&buf, gettext ("Please report bugs to %s.\n"), 238 PACKAGE_BUGREPORT) < 0) 239 buf = NULL; 240 return buf; 241 242 default: 243 break; 244 } 245 return (char *) text; 246 } 247 248 249 static int 250 process_file (const char *fname) 251 { 252 /* If we have to preserve the modify and access timestamps get them 253 now. We cannot use fstat() after opening the file since the open 254 would change the access time. */ 255 struct stat64 pre_st; 256 struct timeval tv[2]; 257 again: 258 if (preserve_dates) 259 { 260 if (stat64 (fname, &pre_st) != 0) 261 { 262 error (0, errno, gettext ("cannot stat input file \"%s\""), fname); 263 return 1; 264 } 265 266 /* If we have to preserve the timestamp, we need it in the 267 format utimes() understands. */ 268 TIMESPEC_TO_TIMEVAL (&tv[0], &pre_st.st_atim); 269 TIMESPEC_TO_TIMEVAL (&tv[1], &pre_st.st_mtim); 270 } 271 272 /* Open the file. */ 273 int fd = open (fname, O_RDWR); 274 if (fd == -1) 275 { 276 error (0, errno, gettext ("while opening \"%s\""), fname); 277 return 1; 278 } 279 280 /* We always use fstat() even if we called stat() before. This is 281 done to make sure the information returned by stat() is for the 282 same file. */ 283 struct stat64 st; 284 if (fstat64 (fd, &st) != 0) 285 { 286 error (0, errno, gettext ("cannot stat input file \"%s\""), fname); 287 return 1; 288 } 289 /* Paranoid mode on. */ 290 if (preserve_dates 291 && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev)) 292 { 293 /* We detected a race. Try again. */ 294 close (fd); 295 goto again; 296 } 297 298 /* Now get the ELF descriptor. */ 299 Elf *elf = elf_begin (fd, ELF_C_RDWR, NULL); 300 int result; 301 switch (elf_kind (elf)) 302 { 303 case ELF_K_ELF: 304 result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS, 305 preserve_dates ? tv : NULL); 306 break; 307 308 case ELF_K_AR: 309 /* It is not possible to strip the content of an archive direct 310 the output to a specific file. */ 311 if (unlikely (output_fname != NULL)) 312 { 313 error (0, 0, gettext ("%s: cannot use -o when stripping archive"), 314 fname); 315 result = 1; 316 } 317 else 318 result = handle_ar (fd, elf, NULL, fname, preserve_dates ? tv : NULL); 319 break; 320 321 default: 322 error (0, 0, gettext ("%s: File format not recognized"), fname); 323 result = 1; 324 break; 325 } 326 327 if (unlikely (elf_end (elf) != 0)) 328 INTERNAL_ERROR (fname); 329 330 close (fd); 331 332 return result; 333 } 334 335 336 /* Maximum size of array allocated on stack. */ 337 #define MAX_STACK_ALLOC (400 * 1024) 338 339 340 static uint32_t 341 crc32_file (int fd, uint32_t *resp) 342 { 343 unsigned char buffer[1024 * 8]; 344 uint32_t crc = 0; 345 ssize_t count; 346 347 /* We have to rewind. */ 348 if (lseek (fd, 0, SEEK_SET) < 0) 349 return 1; 350 351 while ((count = TEMP_FAILURE_RETRY (read (fd, buffer, sizeof (buffer)))) > 0) 352 crc = crc32 (crc, buffer, count); 353 354 *resp = crc; 355 356 return count != 0; 357 } 358 359 360 static int 361 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname, 362 mode_t mode, struct timeval tvp[2]) 363 { 364 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 365 size_t fname_len = strlen (fname) + 1; 366 char *fullname = alloca (prefix_len + 1 + fname_len); 367 char *cp = fullname; 368 Elf *newelf; 369 Elf *debugelf = NULL; 370 char *tmp_debug_fname = NULL; 371 int result = 0; 372 GElf_Ehdr ehdr_mem; 373 GElf_Ehdr *ehdr; 374 size_t shstrndx; 375 size_t shnum; 376 struct shdr_info 377 { 378 Elf_Scn *scn; 379 GElf_Shdr shdr; 380 Elf_Data *data; 381 const char *name; 382 Elf32_Word idx; /* Index in new file. */ 383 Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */ 384 Elf32_Word symtab_idx; 385 Elf32_Word version_idx; 386 Elf32_Word group_idx; 387 Elf32_Word group_cnt; 388 Elf_Scn *newscn; 389 struct Ebl_Strent *se; 390 Elf32_Word *newsymidx; 391 } *shdr_info = NULL; 392 Elf_Scn *scn; 393 size_t cnt; 394 size_t idx; 395 bool changes; 396 GElf_Ehdr newehdr_mem; 397 GElf_Ehdr *newehdr; 398 GElf_Ehdr debugehdr_mem; 399 GElf_Ehdr *debugehdr; 400 struct Ebl_Strtab *shst = NULL; 401 uint32_t debug_crc; 402 bool any_symtab_changes = false; 403 Elf_Data *shstrtab_data = NULL; 404 405 /* Create the full name of the file. */ 406 if (prefix != NULL) 407 { 408 cp = mempcpy (cp, prefix, prefix_len); 409 *cp++ = ':'; 410 } 411 memcpy (cp, fname, fname_len); 412 413 /* If we are not replacing the input file open a new file here. */ 414 if (output_fname != NULL) 415 { 416 fd = open (output_fname, O_RDWR | O_CREAT, mode); 417 if (unlikely (fd == -1)) 418 { 419 error (0, errno, gettext ("cannot open `%s'"), output_fname); 420 return 1; 421 } 422 } 423 424 int debug_fd = -1; 425 426 /* Get the EBL handling. The -g option is currently the only reason 427 we need EBL so dont open the backend unless necessary. */ 428 Ebl *ebl = NULL; 429 if (remove_debug) 430 { 431 ebl = ebl_openbackend (elf); 432 if (ebl == NULL) 433 { 434 error (0, errno, gettext ("cannot open EBL backend")); 435 result = 1; 436 goto fail; 437 } 438 } 439 440 /* Open the additional file the debug information will be stored in. */ 441 if (debug_fname != NULL) 442 { 443 /* Create a temporary file name. We do not want to overwrite 444 the debug file if the file would not contain any 445 information. */ 446 size_t debug_fname_len = strlen (debug_fname); 447 tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX")); 448 strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len), 449 ".XXXXXX"); 450 451 debug_fd = mkstemp (tmp_debug_fname); 452 if (unlikely (debug_fd == -1)) 453 { 454 error (0, errno, gettext ("cannot open `%s'"), debug_fname); 455 result = 1; 456 goto fail; 457 } 458 } 459 460 /* Get the information from the old file. */ 461 ehdr = gelf_getehdr (elf, &ehdr_mem); 462 if (ehdr == NULL) 463 INTERNAL_ERROR (fname); 464 465 /* Get the section header string table index. */ 466 if (unlikely (elf_getshstrndx (elf, &shstrndx) < 0)) 467 error (EXIT_FAILURE, 0, 468 gettext ("cannot get section header string table index")); 469 470 /* We now create a new ELF descriptor for the same file. We 471 construct it almost exactly in the same way with some information 472 dropped. */ 473 if (output_fname != NULL) 474 newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL); 475 else 476 newelf = elf_clone (elf, ELF_C_EMPTY); 477 478 if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0) 479 || (ehdr->e_type != ET_REL 480 && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0))) 481 { 482 error (0, 0, gettext ("cannot create new file `%s': %s"), 483 output_fname, elf_errmsg (-1)); 484 goto fail; 485 } 486 487 /* Copy over the old program header if needed. */ 488 if (ehdr->e_type != ET_REL) 489 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) 490 { 491 GElf_Phdr phdr_mem; 492 GElf_Phdr *phdr; 493 494 phdr = gelf_getphdr (elf, cnt, &phdr_mem); 495 if (phdr == NULL 496 || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0)) 497 INTERNAL_ERROR (fname); 498 } 499 500 if (debug_fname != NULL) 501 { 502 /* Also create an ELF descriptor for the debug file */ 503 debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL); 504 if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0) 505 || (ehdr->e_type != ET_REL 506 && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0))) 507 { 508 error (0, 0, gettext ("cannot create new file `%s': %s"), 509 debug_fname, elf_errmsg (-1)); 510 goto fail_close; 511 } 512 513 /* Copy over the old program header if needed. */ 514 if (ehdr->e_type != ET_REL) 515 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) 516 { 517 GElf_Phdr phdr_mem; 518 GElf_Phdr *phdr; 519 520 phdr = gelf_getphdr (elf, cnt, &phdr_mem); 521 if (phdr == NULL 522 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0)) 523 INTERNAL_ERROR (fname); 524 } 525 } 526 527 /* Number of sections. */ 528 if (unlikely (elf_getshnum (elf, &shnum) < 0)) 529 { 530 error (0, 0, gettext ("cannot determine number of sections: %s"), 531 elf_errmsg (-1)); 532 goto fail_close; 533 } 534 535 /* Storage for section information. We leave room for two more 536 entries since we unconditionally create a section header string 537 table. Maybe some weird tool created an ELF file without one. 538 The other one is used for the debug link section. */ 539 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) 540 shdr_info = (struct shdr_info *) xcalloc (shnum + 2, 541 sizeof (struct shdr_info)); 542 else 543 { 544 shdr_info = (struct shdr_info *) alloca ((shnum + 2) 545 * sizeof (struct shdr_info)); 546 memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info)); 547 } 548 549 /* Prepare section information data structure. */ 550 scn = NULL; 551 cnt = 1; 552 while ((scn = elf_nextscn (elf, scn)) != NULL) 553 { 554 /* This should always be true (i.e., there should not be any 555 holes in the numbering). */ 556 assert (elf_ndxscn (scn) == cnt); 557 558 shdr_info[cnt].scn = scn; 559 560 /* Get the header. */ 561 if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL) 562 INTERNAL_ERROR (fname); 563 564 /* Get the name of the section. */ 565 shdr_info[cnt].name = elf_strptr (elf, shstrndx, 566 shdr_info[cnt].shdr.sh_name); 567 if (shdr_info[cnt].name == NULL) 568 { 569 error (0, 0, gettext ("illformed file `%s'"), fname); 570 goto fail_close; 571 } 572 573 /* Mark them as present but not yet investigated. */ 574 shdr_info[cnt].idx = 1; 575 576 /* Remember the shdr.sh_link value. */ 577 shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link; 578 579 /* Sections in files other than relocatable object files which 580 are not loaded can be freely moved by us. In relocatable 581 object files everything can be moved. */ 582 if (ehdr->e_type == ET_REL 583 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0) 584 shdr_info[cnt].shdr.sh_offset = 0; 585 586 /* If this is an extended section index table store an 587 appropriate reference. */ 588 if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX)) 589 { 590 assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0); 591 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt; 592 } 593 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP)) 594 { 595 Elf32_Word *grpref; 596 size_t inner; 597 598 /* Cross-reference the sections contained in the section 599 group. */ 600 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 601 if (shdr_info[cnt].data == NULL) 602 INTERNAL_ERROR (fname); 603 604 /* XXX Fix for unaligned access. */ 605 grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 606 for (inner = 1; 607 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 608 ++inner) 609 shdr_info[grpref[inner]].group_idx = cnt; 610 611 if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0)) 612 /* If the section group contains only one element and this 613 is n COMDAT section we can drop it right away. */ 614 shdr_info[cnt].idx = 0; 615 else 616 shdr_info[cnt].group_cnt = inner - 1; 617 } 618 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)) 619 { 620 assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0); 621 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt; 622 } 623 624 /* If this section is part of a group make sure it is not 625 discarded right away. */ 626 if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0) 627 { 628 assert (shdr_info[cnt].group_idx != 0); 629 630 if (shdr_info[shdr_info[cnt].group_idx].idx == 0) 631 { 632 /* The section group section will be removed. */ 633 shdr_info[cnt].group_idx = 0; 634 shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP; 635 } 636 } 637 638 /* Increment the counter. */ 639 ++cnt; 640 } 641 642 /* Now determine which sections can go away. The general rule is that 643 all sections which are not used at runtime are stripped out. But 644 there are a few exceptions: 645 646 - special sections named ".comment" and ".note" are kept 647 - OS or architecture specific sections are kept since we might not 648 know how to handle them 649 - if a section is referred to from a section which is not removed 650 in the sh_link or sh_info element it cannot be removed either 651 */ 652 for (cnt = 1; cnt < shnum; ++cnt) 653 /* Check whether the section can be removed. */ 654 if (SECTION_STRIP_P (ebl, elf, ehdr, &shdr_info[cnt].shdr, 655 shdr_info[cnt].name, remove_comment, remove_debug)) 656 { 657 /* For now assume this section will be removed. */ 658 shdr_info[cnt].idx = 0; 659 660 idx = shdr_info[cnt].group_idx; 661 while (idx != 0) 662 { 663 /* If the references section group is a normal section 664 group and has one element remaining, or if it is an 665 empty COMDAT section group it is removed. */ 666 bool is_comdat; 667 668 /* The section group data is already loaded. */ 669 assert (shdr_info[idx].data != NULL); 670 671 is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0] 672 & GRP_COMDAT) != 0; 673 674 --shdr_info[idx].group_cnt; 675 if ((!is_comdat && shdr_info[idx].group_cnt == 1) 676 || (is_comdat && shdr_info[idx].group_cnt == 0)) 677 { 678 shdr_info[idx].idx = 0; 679 /* Continue recursively. */ 680 idx = shdr_info[idx].group_idx; 681 } 682 else 683 break; 684 } 685 } 686 687 /* Mark the SHT_NULL section as handled. */ 688 shdr_info[0].idx = 2; 689 690 691 /* Handle exceptions: section groups and cross-references. We might 692 have to repeat this a few times since the resetting of the flag 693 might propagate. */ 694 do 695 { 696 changes = false; 697 698 for (cnt = 1; cnt < shnum; ++cnt) 699 { 700 if (shdr_info[cnt].idx == 0) 701 { 702 /* If a relocation section is marked as being removed make 703 sure the section it is relocating is removed, too. */ 704 if ((shdr_info[cnt].shdr.sh_type == SHT_REL 705 || shdr_info[cnt].shdr.sh_type == SHT_RELA) 706 && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) 707 shdr_info[cnt].idx = 1; 708 } 709 710 if (shdr_info[cnt].idx == 1) 711 { 712 /* The content of symbol tables we don't remove must not 713 reference any section which we do remove. Otherwise 714 we cannot remove the section. */ 715 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM 716 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) 717 { 718 Elf_Data *symdata; 719 Elf_Data *xndxdata; 720 size_t elsize; 721 722 /* Make sure the data is loaded. */ 723 if (shdr_info[cnt].data == NULL) 724 { 725 shdr_info[cnt].data 726 = elf_getdata (shdr_info[cnt].scn, NULL); 727 if (shdr_info[cnt].data == NULL) 728 INTERNAL_ERROR (fname); 729 } 730 symdata = shdr_info[cnt].data; 731 732 /* If there is an extended section index table load it 733 as well. */ 734 if (shdr_info[cnt].symtab_idx != 0 735 && shdr_info[shdr_info[cnt].symtab_idx].data == NULL) 736 { 737 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB); 738 739 shdr_info[shdr_info[cnt].symtab_idx].data 740 = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, 741 NULL); 742 if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL) 743 INTERNAL_ERROR (fname); 744 } 745 xndxdata = shdr_info[shdr_info[cnt].symtab_idx].data; 746 747 /* Go through all symbols and make sure the section they 748 reference is not removed. */ 749 elsize = gelf_fsize (elf, ELF_T_SYM, 1, ehdr->e_version); 750 751 for (size_t inner = 0; 752 inner < shdr_info[cnt].data->d_size / elsize; 753 ++inner) 754 { 755 GElf_Sym sym_mem; 756 Elf32_Word xndx; 757 GElf_Sym *sym; 758 size_t scnidx; 759 760 sym = gelf_getsymshndx (symdata, xndxdata, inner, 761 &sym_mem, &xndx); 762 if (sym == NULL) 763 INTERNAL_ERROR (fname); 764 765 scnidx = sym->st_shndx; 766 if (scnidx == SHN_UNDEF || scnidx >= shnum 767 || (scnidx >= SHN_LORESERVE 768 && scnidx <= SHN_HIRESERVE 769 && scnidx != SHN_XINDEX) 770 /* Don't count in the section symbols. */ 771 || GELF_ST_TYPE (sym->st_info) == STT_SECTION) 772 /* This is no section index, leave it alone. */ 773 continue; 774 else if (scnidx == SHN_XINDEX) 775 scnidx = xndx; 776 777 if (shdr_info[scnidx].idx == 0) 778 { 779 /* Mark this section as used. */ 780 shdr_info[scnidx].idx = 1; 781 changes |= scnidx < cnt; 782 } 783 } 784 } 785 786 /* Cross referencing happens: 787 - for the cases the ELF specification says. That are 788 + SHT_DYNAMIC in sh_link to string table 789 + SHT_HASH in sh_link to symbol table 790 + SHT_REL and SHT_RELA in sh_link to symbol table 791 + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table 792 + SHT_GROUP in sh_link to symbol table 793 + SHT_SYMTAB_SHNDX in sh_link to symbol table 794 Other (OS or architecture-specific) sections might as 795 well use this field so we process it unconditionally. 796 - references inside section groups 797 - specially marked references in sh_info if the SHF_INFO_LINK 798 flag is set 799 */ 800 801 if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0) 802 { 803 shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1; 804 changes |= shdr_info[cnt].shdr.sh_link < cnt; 805 } 806 807 /* Handle references through sh_info. */ 808 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr) 809 && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) 810 { 811 shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1; 812 changes |= shdr_info[cnt].shdr.sh_info < cnt; 813 } 814 815 /* Mark the section as investigated. */ 816 shdr_info[cnt].idx = 2; 817 } 818 } 819 } 820 while (changes); 821 822 /* Write out a copy of all the sections to the debug output file. 823 The ones that are not removed in the stripped file are SHT_NOBITS */ 824 if (debug_fname != NULL) 825 { 826 for (cnt = 1; cnt < shnum; ++cnt) 827 { 828 Elf_Data *debugdata; 829 GElf_Shdr debugshdr; 830 int discard_section; 831 832 scn = elf_newscn (debugelf); 833 if (scn == NULL) 834 error (EXIT_FAILURE, 0, 835 gettext ("while generating output file: %s"), 836 elf_errmsg (-1)); 837 838 discard_section = shdr_info[cnt].idx > 0 && cnt != ehdr->e_shstrndx; 839 840 /* Set the section header in the new file. */ 841 debugshdr = shdr_info[cnt].shdr; 842 if (discard_section) 843 debugshdr.sh_type = SHT_NOBITS; 844 845 if (unlikely (gelf_update_shdr (scn, &debugshdr)) == 0) 846 /* There cannot be any overflows. */ 847 INTERNAL_ERROR (fname); 848 849 /* Get the data from the old file if necessary. */ 850 if (shdr_info[cnt].data == NULL) 851 { 852 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 853 if (shdr_info[cnt].data == NULL) 854 INTERNAL_ERROR (fname); 855 } 856 857 /* Set the data. This is done by copying from the old file. */ 858 debugdata = elf_newdata (scn); 859 if (debugdata == NULL) 860 INTERNAL_ERROR (fname); 861 862 /* Copy the structure. */ 863 *debugdata = *shdr_info[cnt].data; 864 if (discard_section) 865 debugdata->d_buf = NULL; 866 } 867 868 /* Finish the ELF header. Fill in the fields not handled by 869 libelf from the old file. */ 870 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem); 871 if (debugehdr == NULL) 872 INTERNAL_ERROR (fname); 873 874 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT); 875 debugehdr->e_type = ehdr->e_type; 876 debugehdr->e_machine = ehdr->e_machine; 877 debugehdr->e_version = ehdr->e_version; 878 debugehdr->e_entry = ehdr->e_entry; 879 debugehdr->e_flags = ehdr->e_flags; 880 debugehdr->e_shstrndx = ehdr->e_shstrndx; 881 882 if (unlikely (gelf_update_ehdr (debugelf, debugehdr)) == 0) 883 { 884 error (0, 0, gettext ("%s: error while creating ELF header: %s"), 885 debug_fname, elf_errmsg (-1)); 886 result = 1; 887 goto fail_close; 888 } 889 890 /* Finally write the file. */ 891 if (unlikely (elf_update (debugelf, ELF_C_WRITE)) == -1) 892 { 893 error (0, 0, gettext ("while writing `%s': %s"), 894 debug_fname, elf_errmsg (-1)); 895 result = 1; 896 goto fail_close; 897 } 898 899 /* Create the real output file. First rename, then change the 900 mode. */ 901 if (rename (tmp_debug_fname, debug_fname) != 0 902 || fchmod (debug_fd, mode) != 0) 903 { 904 error (0, errno, gettext ("while creating '%s'"), debug_fname); 905 result = 1; 906 goto fail_close; 907 } 908 909 /* The temporary file does not exist anymore. */ 910 tmp_debug_fname = NULL; 911 912 /* Compute the checksum which we will add to the executable. */ 913 if (crc32_file (debug_fd, &debug_crc) != 0) 914 { 915 error (0, errno, 916 gettext ("while computing checksum for debug information")); 917 unlink (debug_fname); 918 result = 1; 919 goto fail_close; 920 } 921 922 } 923 924 /* Mark the section header string table as unused, we will create 925 a new one. */ 926 shdr_info[shstrndx].idx = 0; 927 928 /* We need a string table for the section headers. */ 929 shst = ebl_strtabinit (true); 930 if (shst == NULL) 931 error (EXIT_FAILURE, errno, gettext ("while preparing output for `%s'"), 932 output_fname ?: fname); 933 934 /* Assign new section numbers. */ 935 shdr_info[0].idx = 0; 936 for (cnt = idx = 1; cnt < shnum; ++cnt) 937 if (shdr_info[cnt].idx > 0) 938 { 939 shdr_info[cnt].idx = idx++; 940 941 /* Create a new section. */ 942 shdr_info[cnt].newscn = elf_newscn (newelf); 943 if (shdr_info[cnt].newscn == NULL) 944 error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"), 945 elf_errmsg (-1)); 946 947 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); 948 949 /* Add this name to the section header string table. */ 950 shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0); 951 } 952 953 /* Test whether we are doing anything at all. */ 954 if (cnt == idx) 955 /* Nope, all removable sections are already gone. */ 956 goto fail_close; 957 958 /* Create the reference to the file with the debug info. */ 959 if (debug_fname != NULL) 960 { 961 char *debug_basename; 962 off_t crc_offset; 963 964 /* Add the section header string table section name. */ 965 shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15); 966 shdr_info[cnt].idx = idx++; 967 968 /* Create the section header. */ 969 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS; 970 shdr_info[cnt].shdr.sh_flags = 0; 971 shdr_info[cnt].shdr.sh_addr = 0; 972 shdr_info[cnt].shdr.sh_link = SHN_UNDEF; 973 shdr_info[cnt].shdr.sh_info = SHN_UNDEF; 974 shdr_info[cnt].shdr.sh_entsize = 0; 975 shdr_info[cnt].shdr.sh_addralign = 4; 976 /* We set the offset to zero here. Before we write the ELF file the 977 field must have the correct value. This is done in the final 978 loop over all section. Then we have all the information needed. */ 979 shdr_info[cnt].shdr.sh_offset = 0; 980 981 /* Create the section. */ 982 shdr_info[cnt].newscn = elf_newscn (newelf); 983 if (shdr_info[cnt].newscn == NULL) 984 error (EXIT_FAILURE, 0, 985 gettext ("while create section header section: %s"), 986 elf_errmsg (-1)); 987 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); 988 989 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn); 990 if (shdr_info[cnt].data == NULL) 991 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"), 992 elf_errmsg (-1)); 993 994 debug_basename = basename (debug_fname); 995 crc_offset = strlen (debug_basename) + 1; 996 /* Align to 4 byte boundary */ 997 crc_offset = ((crc_offset - 1) & ~3) + 4; 998 999 shdr_info[cnt].data->d_align = 4; 1000 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size 1001 = crc_offset + 4; 1002 shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size); 1003 1004 strcpy (shdr_info[cnt].data->d_buf, debug_basename); 1005 /* Store the crc value in the correct byteorder */ 1006 if ((__BYTE_ORDER == __LITTLE_ENDIAN 1007 && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 1008 || (__BYTE_ORDER == __BIG_ENDIAN 1009 && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 1010 debug_crc = bswap_32 (debug_crc); 1011 memcpy ((char *)shdr_info[cnt].data->d_buf + crc_offset, 1012 (char *) &debug_crc, 4); 1013 1014 /* One more section done. */ 1015 ++cnt; 1016 } 1017 1018 /* Index of the section header table in the shdr_info array. */ 1019 size_t shdridx = cnt; 1020 1021 /* Add the section header string table section name. */ 1022 shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10); 1023 shdr_info[cnt].idx = idx; 1024 1025 /* Create the section header. */ 1026 shdr_info[cnt].shdr.sh_type = SHT_STRTAB; 1027 shdr_info[cnt].shdr.sh_flags = 0; 1028 shdr_info[cnt].shdr.sh_addr = 0; 1029 shdr_info[cnt].shdr.sh_link = SHN_UNDEF; 1030 shdr_info[cnt].shdr.sh_info = SHN_UNDEF; 1031 shdr_info[cnt].shdr.sh_entsize = 0; 1032 /* We set the offset to zero here. Before we write the ELF file the 1033 field must have the correct value. This is done in the final 1034 loop over all section. Then we have all the information needed. */ 1035 shdr_info[cnt].shdr.sh_offset = 0; 1036 shdr_info[cnt].shdr.sh_addralign = 1; 1037 1038 /* Create the section. */ 1039 shdr_info[cnt].newscn = elf_newscn (newelf); 1040 if (shdr_info[cnt].newscn == NULL) 1041 error (EXIT_FAILURE, 0, 1042 gettext ("while create section header section: %s"), 1043 elf_errmsg (-1)); 1044 assert (elf_ndxscn (shdr_info[cnt].newscn) == idx); 1045 1046 /* Finalize the string table and fill in the correct indices in the 1047 section headers. */ 1048 shstrtab_data = elf_newdata (shdr_info[cnt].newscn); 1049 if (shstrtab_data == NULL) 1050 error (EXIT_FAILURE, 0, 1051 gettext ("while create section header string table: %s"), 1052 elf_errmsg (-1)); 1053 ebl_strtabfinalize (shst, shstrtab_data); 1054 1055 /* We have to set the section size. */ 1056 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size; 1057 1058 /* Update the section information. */ 1059 GElf_Off lastoffset = 0; 1060 for (cnt = 1; cnt <= shdridx; ++cnt) 1061 if (shdr_info[cnt].idx > 0) 1062 { 1063 Elf_Data *newdata; 1064 1065 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1066 assert (scn != NULL); 1067 1068 /* Update the name. */ 1069 shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se); 1070 1071 /* Update the section header from the input file. Some fields 1072 might be section indeces which now have to be adjusted. */ 1073 if (shdr_info[cnt].shdr.sh_link != 0) 1074 shdr_info[cnt].shdr.sh_link = 1075 shdr_info[shdr_info[cnt].shdr.sh_link].idx; 1076 1077 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) 1078 { 1079 assert (shdr_info[cnt].data != NULL); 1080 1081 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 1082 for (size_t inner = 0; 1083 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 1084 ++inner) 1085 grpref[inner] = shdr_info[grpref[inner]].idx; 1086 } 1087 1088 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */ 1089 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) 1090 shdr_info[cnt].shdr.sh_info = 1091 shdr_info[shdr_info[cnt].shdr.sh_info].idx; 1092 1093 /* Get the data from the old file if necessary. We already 1094 created the data for the section header string table. */ 1095 if (cnt < shnum) 1096 { 1097 if (shdr_info[cnt].data == NULL) 1098 { 1099 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 1100 if (shdr_info[cnt].data == NULL) 1101 INTERNAL_ERROR (fname); 1102 } 1103 1104 /* Set the data. This is done by copying from the old file. */ 1105 newdata = elf_newdata (scn); 1106 if (newdata == NULL) 1107 INTERNAL_ERROR (fname); 1108 1109 /* Copy the structure. */ 1110 *newdata = *shdr_info[cnt].data; 1111 1112 /* We know the size. */ 1113 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size; 1114 1115 /* We have to adjust symtol tables. The st_shndx member might 1116 have to be updated. */ 1117 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM 1118 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) 1119 { 1120 Elf_Data *versiondata = NULL; 1121 Elf_Data *shndxdata = NULL; 1122 1123 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 1124 ehdr->e_version); 1125 1126 if (shdr_info[cnt].symtab_idx != 0) 1127 { 1128 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX); 1129 /* This section has extended section information. 1130 We have to modify that information, too. */ 1131 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, 1132 NULL); 1133 1134 assert ((versiondata->d_size / sizeof (Elf32_Word)) 1135 >= shdr_info[cnt].data->d_size / elsize); 1136 } 1137 1138 if (shdr_info[cnt].version_idx != 0) 1139 { 1140 assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM); 1141 /* This section has associated version 1142 information. We have to modify that 1143 information, too. */ 1144 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn, 1145 NULL); 1146 1147 assert ((versiondata->d_size / sizeof (GElf_Versym)) 1148 >= shdr_info[cnt].data->d_size / elsize); 1149 } 1150 1151 shdr_info[cnt].newsymidx 1152 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size 1153 / elsize, sizeof (Elf32_Word)); 1154 1155 bool last_was_local = true; 1156 size_t destidx; 1157 size_t inner; 1158 for (destidx = inner = 1; 1159 inner < shdr_info[cnt].data->d_size / elsize; 1160 ++inner) 1161 { 1162 Elf32_Word sec; 1163 GElf_Sym sym_mem; 1164 Elf32_Word xshndx; 1165 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data, 1166 shndxdata, inner, 1167 &sym_mem, &xshndx); 1168 if (sym == NULL) 1169 INTERNAL_ERROR (fname); 1170 1171 if (sym->st_shndx == SHN_UNDEF 1172 || (sym->st_shndx >= shnum 1173 && sym->st_shndx != SHN_XINDEX)) 1174 { 1175 /* This is no section index, leave it alone 1176 unless it is moved. */ 1177 if (destidx != inner 1178 && gelf_update_symshndx (shdr_info[cnt].data, 1179 shndxdata, 1180 destidx, sym, 1181 xshndx) == 0) 1182 INTERNAL_ERROR (fname); 1183 1184 shdr_info[cnt].newsymidx[inner] = destidx++; 1185 1186 if (last_was_local 1187 && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 1188 { 1189 last_was_local = false; 1190 shdr_info[cnt].shdr.sh_info = destidx - 1; 1191 } 1192 1193 continue; 1194 } 1195 1196 /* Get the full section index, if necessary from the 1197 XINDEX table. */ 1198 if (sym->st_shndx != SHN_XINDEX) 1199 sec = shdr_info[sym->st_shndx].idx; 1200 else 1201 { 1202 assert (shndxdata != NULL); 1203 1204 sec = shdr_info[xshndx].idx; 1205 } 1206 1207 if (sec != 0) 1208 { 1209 GElf_Section nshndx; 1210 Elf32_Word nxshndx; 1211 1212 if (sec < SHN_LORESERVE) 1213 { 1214 nshndx = sec; 1215 nxshndx = 0; 1216 } 1217 else 1218 { 1219 nshndx = SHN_XINDEX; 1220 nxshndx = sec; 1221 } 1222 1223 assert (sec < SHN_LORESERVE || shndxdata != NULL); 1224 1225 if ((inner != destidx || nshndx != sym->st_shndx 1226 || (shndxdata != NULL && nxshndx != xshndx)) 1227 && (sym->st_shndx = nshndx, 1228 gelf_update_symshndx (shdr_info[cnt].data, 1229 shndxdata, 1230 destidx, sym, 1231 nxshndx) == 0)) 1232 INTERNAL_ERROR (fname); 1233 1234 shdr_info[cnt].newsymidx[inner] = destidx++; 1235 1236 if (last_was_local 1237 && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 1238 { 1239 last_was_local = false; 1240 shdr_info[cnt].shdr.sh_info = destidx - 1; 1241 } 1242 } 1243 else 1244 /* This is a section symbol for a section which has 1245 been removed. */ 1246 assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION); 1247 } 1248 1249 if (destidx != inner) 1250 { 1251 /* The size of the symbol table changed. */ 1252 shdr_info[cnt].shdr.sh_size = newdata->d_size 1253 = destidx * elsize; 1254 any_symtab_changes = true; 1255 } 1256 else 1257 { 1258 /* The symbol table didn't really change. */ 1259 free (shdr_info[cnt].newsymidx); 1260 shdr_info[cnt].newsymidx = NULL; 1261 } 1262 } 1263 } 1264 1265 /* If we have to, compute the offset of the section. */ 1266 if (shdr_info[cnt].shdr.sh_offset == 0) 1267 shdr_info[cnt].shdr.sh_offset 1268 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1) 1269 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1))); 1270 1271 /* Set the section header in the new file. */ 1272 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0)) 1273 /* There cannot be any overflows. */ 1274 INTERNAL_ERROR (fname); 1275 1276 /* Remember the last section written so far. */ 1277 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS 1278 ? shdr_info[cnt].shdr.sh_size : 0); 1279 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz) 1280 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz; 1281 } 1282 1283 /* Adjust symbol references if symbol tables changed. */ 1284 if (any_symtab_changes) 1285 { 1286 /* Find all relocation sections which use this 1287 symbol table. */ 1288 for (cnt = 1; cnt <= shdridx; ++cnt) 1289 { 1290 if (shdr_info[cnt].idx == 0) 1291 /* Ignore sections which are discarded. */ 1292 continue; 1293 1294 if (shdr_info[cnt].shdr.sh_type == SHT_REL 1295 || shdr_info[cnt].shdr.sh_type == SHT_RELA) 1296 { 1297 /* If the symbol table hasn't changed, do not do anything. */ 1298 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL) 1299 continue; 1300 1301 Elf32_Word *newsymidx 1302 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx; 1303 Elf_Data *d = elf_getdata (elf_getscn (newelf, 1304 shdr_info[cnt].idx), 1305 NULL); 1306 assert (d != NULL); 1307 size_t nrels = (shdr_info[cnt].shdr.sh_size 1308 / shdr_info[cnt].shdr.sh_entsize); 1309 1310 if (shdr_info[cnt].shdr.sh_type == SHT_REL) 1311 for (size_t relidx = 0; relidx < nrels; ++relidx) 1312 { 1313 GElf_Rel rel_mem; 1314 if (gelf_getrel (d, relidx, &rel_mem) == NULL) 1315 INTERNAL_ERROR (fname); 1316 1317 size_t symidx = GELF_R_SYM (rel_mem.r_info); 1318 if (newsymidx[symidx] != symidx) 1319 { 1320 rel_mem.r_info 1321 = GELF_R_INFO (newsymidx[symidx], 1322 GELF_R_TYPE (rel_mem.r_info)); 1323 1324 if (gelf_update_rel (d, relidx, &rel_mem) == 0) 1325 INTERNAL_ERROR (fname); 1326 } 1327 } 1328 else 1329 for (size_t relidx = 0; relidx < nrels; ++relidx) 1330 { 1331 GElf_Rela rel_mem; 1332 if (gelf_getrela (d, relidx, &rel_mem) == NULL) 1333 INTERNAL_ERROR (fname); 1334 1335 size_t symidx = GELF_R_SYM (rel_mem.r_info); 1336 if (newsymidx[symidx] != symidx) 1337 { 1338 rel_mem.r_info 1339 = GELF_R_INFO (newsymidx[symidx], 1340 GELF_R_TYPE (rel_mem.r_info)); 1341 1342 if (gelf_update_rela (d, relidx, &rel_mem) == 0) 1343 INTERNAL_ERROR (fname); 1344 } 1345 } 1346 } 1347 else if (shdr_info[cnt].shdr.sh_type == SHT_HASH) 1348 { 1349 /* We have to recompute the hash table. */ 1350 Elf32_Word symtabidx = shdr_info[cnt].old_sh_link; 1351 1352 /* We do not have to do anything if the symbol table was 1353 not changed. */ 1354 if (shdr_info[symtabidx].newsymidx == NULL) 1355 continue; 1356 1357 /* The symbol version section in the new file. */ 1358 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1359 1360 /* The symbol table data. */ 1361 Elf_Data *symd = elf_getdata (elf_getscn (newelf, 1362 shdr_info[symtabidx].idx), 1363 NULL); 1364 assert (symd != NULL); 1365 1366 /* The hash table data. */ 1367 Elf_Data *hashd = elf_getdata (scn, NULL); 1368 assert (hashd != NULL); 1369 1370 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word)) 1371 { 1372 /* Sane arches first. */ 1373 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf; 1374 1375 size_t strshndx = shdr_info[symtabidx].old_sh_link; 1376 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 1377 ehdr->e_version); 1378 1379 /* Convert to the correct byte order. */ 1380 if (gelf_xlatetom (newelf, hashd, hashd, 1381 BYTE_ORDER == LITTLE_ENDIAN 1382 ? ELFDATA2LSB : ELFDATA2MSB) == NULL) 1383 INTERNAL_ERROR (fname); 1384 1385 /* Adjust the nchain value. The symbol table size 1386 changed. We keep the same size for the bucket array. */ 1387 bucket[1] = symd->d_size / elsize; 1388 Elf32_Word nbucket = bucket[0]; 1389 bucket += 2; 1390 Elf32_Word *chain = bucket + nbucket; 1391 1392 /* New size of the section. */ 1393 GElf_Shdr shdr_mem; 1394 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1395 shdr->sh_size = hashd->d_size 1396 = (2 + symd->d_size / elsize + nbucket) 1397 * sizeof (Elf32_Word); 1398 (void) gelf_update_shdr (scn, shdr); 1399 1400 /* Clear the arrays. */ 1401 memset (bucket, '\0', 1402 (symd->d_size / elsize + nbucket) 1403 * sizeof (Elf32_Word)); 1404 1405 for (size_t inner = shdr_info[symtabidx].shdr.sh_info; 1406 inner < symd->d_size / elsize; ++inner) 1407 { 1408 GElf_Sym sym_mem; 1409 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); 1410 assert (sym != NULL); 1411 1412 const char *name = elf_strptr (elf, strshndx, 1413 sym->st_name); 1414 assert (name != NULL); 1415 size_t hidx = elf_hash (name) % nbucket; 1416 1417 if (bucket[hidx] == 0) 1418 bucket[hidx] = inner; 1419 else 1420 { 1421 hidx = bucket[hidx]; 1422 1423 while (chain[hidx] != 0) 1424 hidx = chain[hidx]; 1425 1426 chain[hidx] = inner; 1427 } 1428 } 1429 } 1430 else 1431 { 1432 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */ 1433 assert (shdr_info[cnt].shdr.sh_entsize 1434 == sizeof (Elf64_Xword)); 1435 1436 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf; 1437 1438 size_t strshndx = shdr_info[symtabidx].old_sh_link; 1439 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 1440 ehdr->e_version); 1441 1442 /* Convert to the correct byte order. */ 1443 if (gelf_xlatetom (newelf, hashd, hashd, 1444 BYTE_ORDER == LITTLE_ENDIAN 1445 ? ELFDATA2LSB : ELFDATA2MSB) == NULL) 1446 INTERNAL_ERROR (fname); 1447 1448 /* Adjust the nchain value. The symbol table size 1449 changed. We keep the same size for the bucket array. */ 1450 bucket[1] = symd->d_size / elsize; 1451 Elf64_Xword nbucket = bucket[0]; 1452 bucket += 2; 1453 Elf64_Xword *chain = bucket + nbucket; 1454 1455 /* New size of the section. */ 1456 GElf_Shdr shdr_mem; 1457 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1458 shdr->sh_size = hashd->d_size 1459 = (2 + symd->d_size / elsize + nbucket) 1460 * sizeof (Elf64_Xword); 1461 (void) gelf_update_shdr (scn, shdr); 1462 1463 /* Clear the arrays. */ 1464 memset (bucket, '\0', 1465 (symd->d_size / elsize + nbucket) 1466 * sizeof (Elf64_Xword)); 1467 1468 for (size_t inner = shdr_info[symtabidx].shdr.sh_info; 1469 inner < symd->d_size / elsize; ++inner) 1470 { 1471 GElf_Sym sym_mem; 1472 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); 1473 assert (sym != NULL); 1474 1475 const char *name = elf_strptr (elf, strshndx, 1476 sym->st_name); 1477 assert (name != NULL); 1478 size_t hidx = elf_hash (name) % nbucket; 1479 1480 if (bucket[hidx] == 0) 1481 bucket[hidx] = inner; 1482 else 1483 { 1484 hidx = bucket[hidx]; 1485 1486 while (chain[hidx] != 0) 1487 hidx = chain[hidx]; 1488 1489 chain[hidx] = inner; 1490 } 1491 } 1492 } 1493 1494 /* Convert back to the file byte order. */ 1495 if (gelf_xlatetof (newelf, hashd, hashd, 1496 BYTE_ORDER == LITTLE_ENDIAN 1497 ? ELFDATA2LSB : ELFDATA2MSB) == NULL) 1498 INTERNAL_ERROR (fname); 1499 } 1500 else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym) 1501 { 1502 /* If the symbol table changed we have to adjust the 1503 entries. */ 1504 Elf32_Word symtabidx = shdr_info[cnt].old_sh_link; 1505 1506 /* We do not have to do anything if the symbol table was 1507 not changed. */ 1508 if (shdr_info[symtabidx].newsymidx == NULL) 1509 continue; 1510 1511 /* The symbol version section in the new file. */ 1512 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1513 1514 /* The symbol table data. */ 1515 Elf_Data *symd = elf_getdata (elf_getscn (newelf, 1516 shdr_info[symtabidx].idx), 1517 NULL); 1518 assert (symd != NULL); 1519 1520 /* The version symbol data. */ 1521 Elf_Data *verd = elf_getdata (scn, NULL); 1522 assert (verd != NULL); 1523 1524 /* Convert to the correct byte order. */ 1525 if (gelf_xlatetom (newelf, verd, verd, 1526 BYTE_ORDER == LITTLE_ENDIAN 1527 ? ELFDATA2LSB : ELFDATA2MSB) == NULL) 1528 INTERNAL_ERROR (fname); 1529 1530 /* The symbol version array. */ 1531 GElf_Half *verstab = (GElf_Half *) verd->d_buf; 1532 1533 /* New indices of the symbols. */ 1534 Elf32_Word *newsymidx = shdr_info[symtabidx].newsymidx; 1535 1536 /* Walk through the list and */ 1537 size_t elsize = gelf_fsize (elf, verd->d_type, 1, 1538 ehdr->e_version); 1539 for (size_t inner = 1; inner < verd->d_size / elsize; ++inner) 1540 if (newsymidx[inner] != 0) 1541 /* Overwriting the same array works since the 1542 reordering can only move entries to lower indices 1543 in the array. */ 1544 verstab[newsymidx[inner]] = verstab[inner]; 1545 1546 /* New size of the section. */ 1547 GElf_Shdr shdr_mem; 1548 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1549 shdr->sh_size = verd->d_size 1550 = gelf_fsize (newelf, verd->d_type, 1551 symd->d_size / gelf_fsize (elf, symd->d_type, 1, 1552 ehdr->e_version), 1553 ehdr->e_version); 1554 (void) gelf_update_shdr (scn, shdr); 1555 1556 /* Convert back to the file byte order. */ 1557 if (gelf_xlatetof (newelf, verd, verd, 1558 BYTE_ORDER == LITTLE_ENDIAN 1559 ? ELFDATA2LSB : ELFDATA2MSB) == NULL) 1560 INTERNAL_ERROR (fname); 1561 } 1562 else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) 1563 { 1564 /* Check whether the associated symbol table changed. */ 1565 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL) 1566 { 1567 /* Yes the symbol table changed. Update the section 1568 header of the section group. */ 1569 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1570 GElf_Shdr shdr_mem; 1571 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1572 assert (shdr != NULL); 1573 1574 size_t stabidx = shdr_info[cnt].old_sh_link; 1575 shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info]; 1576 1577 (void) gelf_update_shdr (scn, shdr); 1578 } 1579 } 1580 } 1581 } 1582 1583 /* Finally finish the ELF header. Fill in the fields not handled by 1584 libelf from the old file. */ 1585 newehdr = gelf_getehdr (newelf, &newehdr_mem); 1586 if (newehdr == NULL) 1587 INTERNAL_ERROR (fname); 1588 1589 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT); 1590 newehdr->e_type = ehdr->e_type; 1591 newehdr->e_machine = ehdr->e_machine; 1592 newehdr->e_version = ehdr->e_version; 1593 newehdr->e_entry = ehdr->e_entry; 1594 newehdr->e_flags = ehdr->e_flags; 1595 newehdr->e_phoff = ehdr->e_phoff; 1596 /* We need to position the section header table. */ 1597 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT); 1598 newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset 1599 + shdr_info[shdridx].shdr.sh_size + offsize - 1) 1600 & ~((GElf_Off) (offsize - 1))); 1601 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT); 1602 1603 /* The new section header string table index. */ 1604 if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX)) 1605 newehdr->e_shstrndx = idx; 1606 else 1607 { 1608 /* The index does not fit in the ELF header field. */ 1609 shdr_info[0].scn = elf_getscn (elf, 0); 1610 1611 if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL) 1612 INTERNAL_ERROR (fname); 1613 1614 shdr_info[0].shdr.sh_link = idx; 1615 (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr); 1616 1617 newehdr->e_shstrndx = SHN_XINDEX; 1618 } 1619 1620 if (gelf_update_ehdr (newelf, newehdr) == 0) 1621 { 1622 error (0, 0, gettext ("%s: error while creating ELF header: %s"), 1623 fname, elf_errmsg (-1)); 1624 return 1; 1625 } 1626 1627 /* We have everything from the old file. */ 1628 if (elf_cntl (elf, ELF_C_FDDONE) != 0) 1629 { 1630 error (0, 0, gettext ("%s: error while reading the file: %s"), 1631 fname, elf_errmsg (-1)); 1632 return 1; 1633 } 1634 1635 /* The ELF library better follows our layout when this is not a 1636 relocatable object file. */ 1637 elf_flagelf (newelf, ELF_C_SET, 1638 (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0) 1639 | (permissive ? ELF_F_PERMISSIVE : 0)); 1640 1641 /* Finally write the file. */ 1642 if (elf_update (newelf, ELF_C_WRITE) == -1) 1643 { 1644 error (0, 0, gettext ("while writing `%s': %s"), 1645 fname, elf_errmsg (-1)); 1646 result = 1; 1647 } 1648 1649 fail_close: 1650 if (shdr_info != NULL) 1651 { 1652 /* For some sections we might have created an table to map symbol 1653 table indices. */ 1654 if (any_symtab_changes) 1655 for (cnt = 1; cnt <= shdridx; ++cnt) 1656 free (shdr_info[cnt].newsymidx); 1657 1658 /* Free the memory. */ 1659 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) 1660 free (shdr_info); 1661 } 1662 1663 /* Free other resources. */ 1664 if (shstrtab_data != NULL) 1665 free (shstrtab_data->d_buf); 1666 if (shst != NULL) 1667 ebl_strtabfree (shst); 1668 1669 /* That was it. Close the descriptors. */ 1670 if (elf_end (newelf) != 0) 1671 { 1672 error (0, 0, gettext ("error while finishing `%s': %s"), fname, 1673 elf_errmsg (-1)); 1674 result = 1; 1675 } 1676 1677 if (debugelf != NULL && elf_end (debugelf) != 0) 1678 { 1679 error (0, 0, gettext ("error while finishing `%s': %s"), debug_fname, 1680 elf_errmsg (-1)); 1681 result = 1; 1682 } 1683 1684 fail: 1685 /* Close the EBL backend. */ 1686 if (ebl != NULL) 1687 ebl_closebackend (ebl); 1688 1689 /* Close debug file descriptor, if opened */ 1690 if (debug_fd >= 0) 1691 { 1692 if (tmp_debug_fname != NULL) 1693 unlink (tmp_debug_fname); 1694 close (debug_fd); 1695 } 1696 1697 /* If requested, preserve the timestamp. */ 1698 if (tvp != NULL) 1699 { 1700 if (futimes (fd, tvp) != 0) 1701 { 1702 error (0, errno, gettext ("\ 1703 cannot set access and modification date of \"%s\""), 1704 output_fname ?: fname); 1705 result = 1; 1706 } 1707 } 1708 1709 /* Close the file descriptor if we created a new file. */ 1710 if (output_fname != NULL) 1711 close (fd); 1712 1713 return result; 1714 } 1715 1716 1717 static int 1718 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 1719 struct timeval tvp[2]) 1720 { 1721 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 1722 size_t fname_len = strlen (fname) + 1; 1723 char new_prefix[prefix_len + 1 + fname_len]; 1724 char *cp = new_prefix; 1725 1726 /* Create the full name of the file. */ 1727 if (prefix != NULL) 1728 { 1729 cp = mempcpy (cp, prefix, prefix_len); 1730 *cp++ = ':'; 1731 } 1732 memcpy (cp, fname, fname_len); 1733 1734 1735 /* Process all the files contained in the archive. */ 1736 Elf *subelf; 1737 Elf_Cmd cmd = ELF_C_RDWR; 1738 int result = 0; 1739 while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 1740 { 1741 /* The the header for this element. */ 1742 Elf_Arhdr *arhdr = elf_getarhdr (subelf); 1743 1744 if (elf_kind (subelf) == ELF_K_ELF) 1745 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); 1746 else if (elf_kind (subelf) == ELF_K_AR) 1747 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL); 1748 1749 /* Get next archive element. */ 1750 cmd = elf_next (subelf); 1751 if (unlikely (elf_end (subelf) != 0)) 1752 INTERNAL_ERROR (fname); 1753 } 1754 1755 if (tvp != NULL) 1756 { 1757 if (unlikely (futimes (fd, tvp) != 0)) 1758 { 1759 error (0, errno, gettext ("\ 1760 cannot set access and modification date of \"%s\""), fname); 1761 result = 1; 1762 } 1763 } 1764 1765 if (unlikely (close (fd) != 0)) 1766 error (EXIT_FAILURE, errno, gettext ("while closing `%s'"), fname); 1767 1768 return result; 1769 } 1770