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