strip.c revision 3cbdd387c752999255aea91600b5cfdefbeac7d0
1/* Discard section not used at runtime from object files. 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. 3 This file is part of Red Hat elfutils. 4 Written by Ulrich Drepper <drepper@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. */ 57static void print_version (FILE *stream, struct argp_state *state); 58void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; 59 60/* Bug report address. */ 61const 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. */ 70static 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. */ 93static const char doc[] = N_("Discard symbols from object files."); 94 95/* Strings for arguments in help texts. */ 96static const char args_doc[] = N_("[FILE...]"); 97 98/* Prototype for option handler. */ 99static error_t parse_opt (int key, char *arg, struct argp_state *state); 100 101/* Data structure to communicate with argp functions. */ 102static struct argp argp = 103{ 104 options, parse_opt, args_doc, doc, NULL, NULL, NULL 105}; 106 107 108/* Print symbols in file named FNAME. */ 109static int process_file (const char *fname); 110 111/* Handle one ELF file. */ 112static 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. */ 116static 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. */ 125static const char *output_fname; 126 127/* Name of the debug output file. */ 128static const char *debug_fname; 129 130/* Name to pretend the debug output file has. */ 131static const char *debug_fname_embed; 132 133/* If true output files shall have same date as the input file. */ 134static bool preserve_dates; 135 136/* If true .comment sections will be removed. */ 137static bool remove_comment; 138 139/* If true remove all debug sections. */ 140static bool remove_debug; 141 142/* If true relax some ELF rules for input files. */ 143static bool permissive; 144 145 146int 147main (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 ("\ 186Only 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. */ 199static void 200print_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 ("\ 204Copyright (C) %s Red Hat, Inc.\n\ 205This is free software; see the source for copying conditions. There is NO\n\ 206warranty; 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. */ 213static error_t 214parse_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 284static int 285process_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 375static int 376handle_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 shstrndx; 387 struct shdr_info 388 { 389 Elf_Scn *scn; 390 GElf_Shdr shdr; 391 Elf_Data *data; 392 const char *name; 393 Elf32_Word idx; /* Index in new file. */ 394 Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */ 395 Elf32_Word symtab_idx; 396 Elf32_Word version_idx; 397 Elf32_Word group_idx; 398 Elf32_Word group_cnt; 399 Elf_Scn *newscn; 400 struct Ebl_Strent *se; 401 Elf32_Word *newsymidx; 402 } *shdr_info = NULL; 403 Elf_Scn *scn; 404 size_t cnt; 405 size_t idx; 406 bool changes; 407 GElf_Ehdr newehdr_mem; 408 GElf_Ehdr *newehdr; 409 GElf_Ehdr debugehdr_mem; 410 GElf_Ehdr *debugehdr; 411 struct Ebl_Strtab *shst = NULL; 412 Elf_Data debuglink_crc_data; 413 bool any_symtab_changes = false; 414 Elf_Data *shstrtab_data = NULL; 415 416 /* Create the full name of the file. */ 417 if (prefix != NULL) 418 { 419 cp = mempcpy (cp, prefix, prefix_len); 420 *cp++ = ':'; 421 } 422 memcpy (cp, fname, fname_len); 423 424 /* If we are not replacing the input file open a new file here. */ 425 if (output_fname != NULL) 426 { 427 fd = open (output_fname, O_RDWR | O_CREAT, mode); 428 if (unlikely (fd == -1)) 429 { 430 error (0, errno, gettext ("cannot open '%s'"), output_fname); 431 return 1; 432 } 433 } 434 435 int debug_fd = -1; 436 437 /* Get the EBL handling. The -g option is currently the only reason 438 we need EBL so dont open the backend unless necessary. */ 439 Ebl *ebl = NULL; 440 if (remove_debug) 441 { 442 ebl = ebl_openbackend (elf); 443 if (ebl == NULL) 444 { 445 error (0, errno, gettext ("cannot open EBL backend")); 446 result = 1; 447 goto fail; 448 } 449 } 450 451 /* Open the additional file the debug information will be stored in. */ 452 if (debug_fname != NULL) 453 { 454 /* Create a temporary file name. We do not want to overwrite 455 the debug file if the file would not contain any 456 information. */ 457 size_t debug_fname_len = strlen (debug_fname); 458 tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX")); 459 strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len), 460 ".XXXXXX"); 461 462 debug_fd = mkstemp (tmp_debug_fname); 463 if (unlikely (debug_fd == -1)) 464 { 465 error (0, errno, gettext ("cannot open '%s'"), debug_fname); 466 result = 1; 467 goto fail; 468 } 469 } 470 471 /* Get the information from the old file. */ 472 GElf_Ehdr ehdr_mem; 473 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 474 if (ehdr == NULL) 475 INTERNAL_ERROR (fname); 476 477 /* Get the section header string table index. */ 478 if (unlikely (elf_getshstrndx (elf, &shstrndx) < 0)) 479 error (EXIT_FAILURE, 0, 480 gettext ("cannot get section header string table index")); 481 482 /* We now create a new ELF descriptor for the same file. We 483 construct it almost exactly in the same way with some information 484 dropped. */ 485 Elf *newelf; 486 if (output_fname != NULL) 487 newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL); 488 else 489 newelf = elf_clone (elf, ELF_C_EMPTY); 490 491 if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0) 492 || (ehdr->e_type != ET_REL 493 && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0))) 494 { 495 error (0, 0, gettext ("cannot create new file '%s': %s"), 496 output_fname, elf_errmsg (-1)); 497 goto fail; 498 } 499 500 /* Copy over the old program header if needed. */ 501 if (ehdr->e_type != ET_REL) 502 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) 503 { 504 GElf_Phdr phdr_mem; 505 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); 506 if (phdr == NULL 507 || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0)) 508 INTERNAL_ERROR (fname); 509 } 510 511 if (debug_fname != NULL) 512 { 513 /* Also create an ELF descriptor for the debug file */ 514 debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL); 515 if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0) 516 || (ehdr->e_type != ET_REL 517 && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0))) 518 { 519 error (0, 0, gettext ("cannot create new file '%s': %s"), 520 debug_fname, elf_errmsg (-1)); 521 goto fail_close; 522 } 523 524 /* Copy over the old program header if needed. */ 525 if (ehdr->e_type != ET_REL) 526 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) 527 { 528 GElf_Phdr phdr_mem; 529 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem); 530 if (phdr == NULL 531 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0)) 532 INTERNAL_ERROR (fname); 533 } 534 } 535 536 /* Number of sections. */ 537 size_t shnum; 538 if (unlikely (elf_getshnum (elf, &shnum) < 0)) 539 { 540 error (0, 0, gettext ("cannot determine number of sections: %s"), 541 elf_errmsg (-1)); 542 goto fail_close; 543 } 544 545 /* Storage for section information. We leave room for two more 546 entries since we unconditionally create a section header string 547 table. Maybe some weird tool created an ELF file without one. 548 The other one is used for the debug link section. */ 549 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) 550 shdr_info = (struct shdr_info *) xcalloc (shnum + 2, 551 sizeof (struct shdr_info)); 552 else 553 { 554 shdr_info = (struct shdr_info *) alloca ((shnum + 2) 555 * sizeof (struct shdr_info)); 556 memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info)); 557 } 558 559 /* Prepare section information data structure. */ 560 scn = NULL; 561 cnt = 1; 562 while ((scn = elf_nextscn (elf, scn)) != NULL) 563 { 564 /* This should always be true (i.e., there should not be any 565 holes in the numbering). */ 566 assert (elf_ndxscn (scn) == cnt); 567 568 shdr_info[cnt].scn = scn; 569 570 /* Get the header. */ 571 if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL) 572 INTERNAL_ERROR (fname); 573 574 /* Get the name of the section. */ 575 shdr_info[cnt].name = elf_strptr (elf, shstrndx, 576 shdr_info[cnt].shdr.sh_name); 577 if (shdr_info[cnt].name == NULL) 578 { 579 error (0, 0, gettext ("illformed file '%s'"), fname); 580 goto fail_close; 581 } 582 583 /* Mark them as present but not yet investigated. */ 584 shdr_info[cnt].idx = 1; 585 586 /* Remember the shdr.sh_link value. */ 587 shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link; 588 589 /* Sections in files other than relocatable object files which 590 are not loaded can be freely moved by us. In relocatable 591 object files everything can be moved. */ 592 if (ehdr->e_type == ET_REL 593 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0) 594 shdr_info[cnt].shdr.sh_offset = 0; 595 596 /* If this is an extended section index table store an 597 appropriate reference. */ 598 if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX)) 599 { 600 assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0); 601 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt; 602 } 603 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP)) 604 { 605 /* Cross-reference the sections contained in the section 606 group. */ 607 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 608 if (shdr_info[cnt].data == NULL) 609 INTERNAL_ERROR (fname); 610 611 /* XXX Fix for unaligned access. */ 612 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 613 size_t inner; 614 for (inner = 1; 615 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 616 ++inner) 617 shdr_info[grpref[inner]].group_idx = cnt; 618 619 if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0)) 620 /* If the section group contains only one element and this 621 is n COMDAT section we can drop it right away. */ 622 shdr_info[cnt].idx = 0; 623 else 624 shdr_info[cnt].group_cnt = inner - 1; 625 } 626 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)) 627 { 628 assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0); 629 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt; 630 } 631 632 /* If this section is part of a group make sure it is not 633 discarded right away. */ 634 if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0) 635 { 636 assert (shdr_info[cnt].group_idx != 0); 637 638 if (shdr_info[shdr_info[cnt].group_idx].idx == 0) 639 { 640 /* The section group section will be removed. */ 641 shdr_info[cnt].group_idx = 0; 642 shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP; 643 } 644 } 645 646 /* Increment the counter. */ 647 ++cnt; 648 } 649 650 /* Now determine which sections can go away. The general rule is that 651 all sections which are not used at runtime are stripped out. But 652 there are a few exceptions: 653 654 - special sections named ".comment" and ".note" are kept 655 - OS or architecture specific sections are kept since we might not 656 know how to handle them 657 - if a section is referred to from a section which is not removed 658 in the sh_link or sh_info element it cannot be removed either 659 */ 660 for (cnt = 1; cnt < shnum; ++cnt) 661 /* Check whether the section can be removed. */ 662 if (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr, 663 shdr_info[cnt].name, remove_comment, 664 remove_debug)) 665 { 666 /* For now assume this section will be removed. */ 667 shdr_info[cnt].idx = 0; 668 669 idx = shdr_info[cnt].group_idx; 670 while (idx != 0) 671 { 672 /* The section group data is already loaded. */ 673 assert (shdr_info[idx].data != NULL); 674 675 /* If the references section group is a normal section 676 group and has one element remaining, or if it is an 677 empty COMDAT section group it is removed. */ 678 bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0] 679 & GRP_COMDAT) != 0; 680 681 --shdr_info[idx].group_cnt; 682 if ((!is_comdat && shdr_info[idx].group_cnt == 1) 683 || (is_comdat && shdr_info[idx].group_cnt == 0)) 684 { 685 shdr_info[idx].idx = 0; 686 /* Continue recursively. */ 687 idx = shdr_info[idx].group_idx; 688 } 689 else 690 break; 691 } 692 } 693 694 /* Mark the SHT_NULL section as handled. */ 695 shdr_info[0].idx = 2; 696 697 698 /* Handle exceptions: section groups and cross-references. We might 699 have to repeat this a few times since the resetting of the flag 700 might propagate. */ 701 do 702 { 703 changes = false; 704 705 for (cnt = 1; cnt < shnum; ++cnt) 706 { 707 if (shdr_info[cnt].idx == 0) 708 { 709 /* If a relocation section is marked as being removed make 710 sure the section it is relocating is removed, too. */ 711 if ((shdr_info[cnt].shdr.sh_type == SHT_REL 712 || shdr_info[cnt].shdr.sh_type == SHT_RELA) 713 && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0) 714 shdr_info[cnt].idx = 1; 715 } 716 717 if (shdr_info[cnt].idx == 1) 718 { 719 /* The content of symbol tables we don't remove must not 720 reference any section which we do remove. Otherwise 721 we cannot remove the section. */ 722 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM 723 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) 724 { 725 /* Make sure the data is loaded. */ 726 if (shdr_info[cnt].data == NULL) 727 { 728 shdr_info[cnt].data 729 = elf_getdata (shdr_info[cnt].scn, NULL); 730 if (shdr_info[cnt].data == NULL) 731 INTERNAL_ERROR (fname); 732 } 733 Elf_Data *symdata = shdr_info[cnt].data; 734 735 /* If there is an extended section index table load it 736 as well. */ 737 if (shdr_info[cnt].symtab_idx != 0 738 && shdr_info[shdr_info[cnt].symtab_idx].data == NULL) 739 { 740 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB); 741 742 shdr_info[shdr_info[cnt].symtab_idx].data 743 = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, 744 NULL); 745 if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL) 746 INTERNAL_ERROR (fname); 747 } 748 Elf_Data *xndxdata 749 = shdr_info[shdr_info[cnt].symtab_idx].data; 750 751 /* Go through all symbols and make sure the section they 752 reference is not removed. */ 753 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 754 ehdr->e_version); 755 756 for (size_t inner = 0; 757 inner < shdr_info[cnt].data->d_size / elsize; 758 ++inner) 759 { 760 GElf_Sym sym_mem; 761 Elf32_Word xndx; 762 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, 763 inner, &sym_mem, 764 &xndx); 765 if (sym == NULL) 766 INTERNAL_ERROR (fname); 767 768 size_t scnidx = sym->st_shndx; 769 if (scnidx == SHN_UNDEF || scnidx >= shnum 770 || (scnidx >= SHN_LORESERVE 771 && scnidx <= SHN_HIRESERVE 772 && scnidx != SHN_XINDEX) 773 /* Don't count in the section symbols. */ 774 || GELF_ST_TYPE (sym->st_info) == STT_SECTION) 775 /* This is no section index, leave it alone. */ 776 continue; 777 else if (scnidx == SHN_XINDEX) 778 scnidx = xndx; 779 780 if (shdr_info[scnidx].idx == 0) 781 { 782 /* Mark this section as used. */ 783 shdr_info[scnidx].idx = 1; 784 changes |= scnidx < cnt; 785 } 786 } 787 } 788 789 /* Cross referencing happens: 790 - for the cases the ELF specification says. That are 791 + SHT_DYNAMIC in sh_link to string table 792 + SHT_HASH in sh_link to symbol table 793 + SHT_REL and SHT_RELA in sh_link to symbol table 794 + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table 795 + SHT_GROUP in sh_link to symbol table 796 + SHT_SYMTAB_SHNDX in sh_link to symbol table 797 Other (OS or architecture-specific) sections might as 798 well use this field so we process it unconditionally. 799 - references inside section groups 800 - specially marked references in sh_info if the SHF_INFO_LINK 801 flag is set 802 */ 803 804 if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0) 805 { 806 shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1; 807 changes |= shdr_info[cnt].shdr.sh_link < cnt; 808 } 809 810 /* Handle references through sh_info. */ 811 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr) 812 && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0) 813 { 814 shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1; 815 changes |= shdr_info[cnt].shdr.sh_info < cnt; 816 } 817 818 /* Mark the section as investigated. */ 819 shdr_info[cnt].idx = 2; 820 } 821 } 822 } 823 while (changes); 824 825 /* Copy the removed sections to the debug output file. 826 The ones that are not removed in the stripped file are SHT_NOBITS. */ 827 if (debug_fname != NULL) 828 { 829 for (cnt = 1; cnt < shnum; ++cnt) 830 { 831 scn = elf_newscn (debugelf); 832 if (scn == NULL) 833 error (EXIT_FAILURE, 0, 834 gettext ("while generating output file: %s"), 835 elf_errmsg (-1)); 836 837 bool discard_section = (shdr_info[cnt].idx > 0 838 && shdr_info[cnt].shdr.sh_type != SHT_NOTE 839 && cnt != ehdr->e_shstrndx); 840 841 /* Set the section header in the new file. */ 842 GElf_Shdr debugshdr = shdr_info[cnt].shdr; 843 if (discard_section) 844 debugshdr.sh_type = SHT_NOBITS; 845 846 if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0)) 847 /* There cannot be any overflows. */ 848 INTERNAL_ERROR (fname); 849 850 /* Get the data from the old file if necessary. */ 851 if (shdr_info[cnt].data == NULL) 852 { 853 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 854 if (shdr_info[cnt].data == NULL) 855 INTERNAL_ERROR (fname); 856 } 857 858 /* Set the data. This is done by copying from the old file. */ 859 Elf_Data *debugdata = elf_newdata (scn); 860 if (debugdata == NULL) 861 INTERNAL_ERROR (fname); 862 863 /* Copy the structure. This data may be modified in place 864 before we write out the file. */ 865 *debugdata = *shdr_info[cnt].data; 866 if (discard_section) 867 debugdata->d_buf = NULL; 868 } 869 870 /* Finish the ELF header. Fill in the fields not handled by 871 libelf from the old file. */ 872 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem); 873 if (debugehdr == NULL) 874 INTERNAL_ERROR (fname); 875 876 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT); 877 debugehdr->e_type = ehdr->e_type; 878 debugehdr->e_machine = ehdr->e_machine; 879 debugehdr->e_version = ehdr->e_version; 880 debugehdr->e_entry = ehdr->e_entry; 881 debugehdr->e_flags = ehdr->e_flags; 882 debugehdr->e_shstrndx = ehdr->e_shstrndx; 883 884 if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0)) 885 { 886 error (0, 0, gettext ("%s: error while creating ELF header: %s"), 887 debug_fname, elf_errmsg (-1)); 888 result = 1; 889 goto fail_close; 890 } 891 } 892 893 /* Mark the section header string table as unused, we will create 894 a new one. */ 895 shdr_info[shstrndx].idx = 0; 896 897 /* We need a string table for the section headers. */ 898 shst = ebl_strtabinit (true); 899 if (shst == NULL) 900 error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"), 901 output_fname ?: fname); 902 903 /* Assign new section numbers. */ 904 shdr_info[0].idx = 0; 905 for (cnt = idx = 1; cnt < shnum; ++cnt) 906 if (shdr_info[cnt].idx > 0) 907 { 908 shdr_info[cnt].idx = idx++; 909 910 /* Create a new section. */ 911 shdr_info[cnt].newscn = elf_newscn (newelf); 912 if (shdr_info[cnt].newscn == NULL) 913 error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"), 914 elf_errmsg (-1)); 915 916 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); 917 918 /* Add this name to the section header string table. */ 919 shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0); 920 } 921 922 /* Test whether we are doing anything at all. */ 923 if (cnt == idx) 924 /* Nope, all removable sections are already gone. */ 925 goto fail_close; 926 927 /* Create the reference to the file with the debug info. */ 928 if (debug_fname != NULL) 929 { 930 /* Add the section header string table section name. */ 931 shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15); 932 shdr_info[cnt].idx = idx++; 933 934 /* Create the section header. */ 935 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS; 936 shdr_info[cnt].shdr.sh_flags = 0; 937 shdr_info[cnt].shdr.sh_addr = 0; 938 shdr_info[cnt].shdr.sh_link = SHN_UNDEF; 939 shdr_info[cnt].shdr.sh_info = SHN_UNDEF; 940 shdr_info[cnt].shdr.sh_entsize = 0; 941 shdr_info[cnt].shdr.sh_addralign = 4; 942 /* We set the offset to zero here. Before we write the ELF file the 943 field must have the correct value. This is done in the final 944 loop over all section. Then we have all the information needed. */ 945 shdr_info[cnt].shdr.sh_offset = 0; 946 947 /* Create the section. */ 948 shdr_info[cnt].newscn = elf_newscn (newelf); 949 if (shdr_info[cnt].newscn == NULL) 950 error (EXIT_FAILURE, 0, 951 gettext ("while create section header section: %s"), 952 elf_errmsg (-1)); 953 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx); 954 955 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn); 956 if (shdr_info[cnt].data == NULL) 957 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"), 958 elf_errmsg (-1)); 959 960 char *debug_basename = basename (debug_fname_embed ?: debug_fname); 961 off_t crc_offset = strlen (debug_basename) + 1; 962 /* Align to 4 byte boundary */ 963 crc_offset = ((crc_offset - 1) & ~3) + 4; 964 965 shdr_info[cnt].data->d_align = 4; 966 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size 967 = crc_offset + 4; 968 shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size); 969 970 strcpy (shdr_info[cnt].data->d_buf, debug_basename); 971 972 /* Cache this Elf_Data describing the CRC32 word in the section. 973 We'll fill this in when we have written the debug file. */ 974 debuglink_crc_data = *shdr_info[cnt].data; 975 debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf 976 + crc_offset); 977 debuglink_crc_data.d_size = 4; 978 979 /* One more section done. */ 980 ++cnt; 981 } 982 983 /* Index of the section header table in the shdr_info array. */ 984 size_t shdridx = cnt; 985 986 /* Add the section header string table section name. */ 987 shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10); 988 shdr_info[cnt].idx = idx; 989 990 /* Create the section header. */ 991 shdr_info[cnt].shdr.sh_type = SHT_STRTAB; 992 shdr_info[cnt].shdr.sh_flags = 0; 993 shdr_info[cnt].shdr.sh_addr = 0; 994 shdr_info[cnt].shdr.sh_link = SHN_UNDEF; 995 shdr_info[cnt].shdr.sh_info = SHN_UNDEF; 996 shdr_info[cnt].shdr.sh_entsize = 0; 997 /* We set the offset to zero here. Before we write the ELF file the 998 field must have the correct value. This is done in the final 999 loop over all section. Then we have all the information needed. */ 1000 shdr_info[cnt].shdr.sh_offset = 0; 1001 shdr_info[cnt].shdr.sh_addralign = 1; 1002 1003 /* Create the section. */ 1004 shdr_info[cnt].newscn = elf_newscn (newelf); 1005 if (shdr_info[cnt].newscn == NULL) 1006 error (EXIT_FAILURE, 0, 1007 gettext ("while create section header section: %s"), 1008 elf_errmsg (-1)); 1009 assert (elf_ndxscn (shdr_info[cnt].newscn) == idx); 1010 1011 /* Finalize the string table and fill in the correct indices in the 1012 section headers. */ 1013 shstrtab_data = elf_newdata (shdr_info[cnt].newscn); 1014 if (shstrtab_data == NULL) 1015 error (EXIT_FAILURE, 0, 1016 gettext ("while create section header string table: %s"), 1017 elf_errmsg (-1)); 1018 ebl_strtabfinalize (shst, shstrtab_data); 1019 1020 /* We have to set the section size. */ 1021 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size; 1022 1023 /* Update the section information. */ 1024 GElf_Off lastoffset = 0; 1025 for (cnt = 1; cnt <= shdridx; ++cnt) 1026 if (shdr_info[cnt].idx > 0) 1027 { 1028 Elf_Data *newdata; 1029 1030 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1031 assert (scn != NULL); 1032 1033 /* Update the name. */ 1034 shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se); 1035 1036 /* Update the section header from the input file. Some fields 1037 might be section indeces which now have to be adjusted. */ 1038 if (shdr_info[cnt].shdr.sh_link != 0) 1039 shdr_info[cnt].shdr.sh_link = 1040 shdr_info[shdr_info[cnt].shdr.sh_link].idx; 1041 1042 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) 1043 { 1044 assert (shdr_info[cnt].data != NULL); 1045 1046 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf; 1047 for (size_t inner = 0; 1048 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word); 1049 ++inner) 1050 grpref[inner] = shdr_info[grpref[inner]].idx; 1051 } 1052 1053 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */ 1054 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)) 1055 shdr_info[cnt].shdr.sh_info = 1056 shdr_info[shdr_info[cnt].shdr.sh_info].idx; 1057 1058 /* Get the data from the old file if necessary. We already 1059 created the data for the section header string table. */ 1060 if (cnt < shnum) 1061 { 1062 if (shdr_info[cnt].data == NULL) 1063 { 1064 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL); 1065 if (shdr_info[cnt].data == NULL) 1066 INTERNAL_ERROR (fname); 1067 } 1068 1069 /* Set the data. This is done by copying from the old file. */ 1070 newdata = elf_newdata (scn); 1071 if (newdata == NULL) 1072 INTERNAL_ERROR (fname); 1073 1074 /* Copy the structure. */ 1075 *newdata = *shdr_info[cnt].data; 1076 1077 /* We know the size. */ 1078 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size; 1079 1080 /* We have to adjust symtol tables. The st_shndx member might 1081 have to be updated. */ 1082 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM 1083 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB) 1084 { 1085 Elf_Data *versiondata = NULL; 1086 Elf_Data *shndxdata = NULL; 1087 1088 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 1089 ehdr->e_version); 1090 1091 if (shdr_info[cnt].symtab_idx != 0) 1092 { 1093 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX); 1094 /* This section has extended section information. 1095 We have to modify that information, too. */ 1096 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn, 1097 NULL); 1098 1099 assert ((versiondata->d_size / sizeof (Elf32_Word)) 1100 >= shdr_info[cnt].data->d_size / elsize); 1101 } 1102 1103 if (shdr_info[cnt].version_idx != 0) 1104 { 1105 assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM); 1106 /* This section has associated version 1107 information. We have to modify that 1108 information, too. */ 1109 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn, 1110 NULL); 1111 1112 assert ((versiondata->d_size / sizeof (GElf_Versym)) 1113 >= shdr_info[cnt].data->d_size / elsize); 1114 } 1115 1116 shdr_info[cnt].newsymidx 1117 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size 1118 / elsize, sizeof (Elf32_Word)); 1119 1120 bool last_was_local = true; 1121 size_t destidx; 1122 size_t inner; 1123 for (destidx = inner = 1; 1124 inner < shdr_info[cnt].data->d_size / elsize; 1125 ++inner) 1126 { 1127 Elf32_Word sec; 1128 GElf_Sym sym_mem; 1129 Elf32_Word xshndx; 1130 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data, 1131 shndxdata, inner, 1132 &sym_mem, &xshndx); 1133 if (sym == NULL) 1134 INTERNAL_ERROR (fname); 1135 1136 if (sym->st_shndx == SHN_UNDEF 1137 || (sym->st_shndx >= shnum 1138 && sym->st_shndx != SHN_XINDEX)) 1139 { 1140 /* This is no section index, leave it alone 1141 unless it is moved. */ 1142 if (destidx != inner 1143 && gelf_update_symshndx (shdr_info[cnt].data, 1144 shndxdata, 1145 destidx, sym, 1146 xshndx) == 0) 1147 INTERNAL_ERROR (fname); 1148 1149 shdr_info[cnt].newsymidx[inner] = destidx++; 1150 1151 if (last_was_local 1152 && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 1153 { 1154 last_was_local = false; 1155 shdr_info[cnt].shdr.sh_info = destidx - 1; 1156 } 1157 1158 continue; 1159 } 1160 1161 /* Get the full section index, if necessary from the 1162 XINDEX table. */ 1163 if (sym->st_shndx != SHN_XINDEX) 1164 sec = shdr_info[sym->st_shndx].idx; 1165 else 1166 { 1167 assert (shndxdata != NULL); 1168 1169 sec = shdr_info[xshndx].idx; 1170 } 1171 1172 if (sec != 0) 1173 { 1174 GElf_Section nshndx; 1175 Elf32_Word nxshndx; 1176 1177 if (sec < SHN_LORESERVE) 1178 { 1179 nshndx = sec; 1180 nxshndx = 0; 1181 } 1182 else 1183 { 1184 nshndx = SHN_XINDEX; 1185 nxshndx = sec; 1186 } 1187 1188 assert (sec < SHN_LORESERVE || shndxdata != NULL); 1189 1190 if ((inner != destidx || nshndx != sym->st_shndx 1191 || (shndxdata != NULL && nxshndx != xshndx)) 1192 && (sym->st_shndx = nshndx, 1193 gelf_update_symshndx (shdr_info[cnt].data, 1194 shndxdata, 1195 destidx, sym, 1196 nxshndx) == 0)) 1197 INTERNAL_ERROR (fname); 1198 1199 shdr_info[cnt].newsymidx[inner] = destidx++; 1200 1201 if (last_was_local 1202 && GELF_ST_BIND (sym->st_info) != STB_LOCAL) 1203 { 1204 last_was_local = false; 1205 shdr_info[cnt].shdr.sh_info = destidx - 1; 1206 } 1207 } 1208 else 1209 /* This is a section symbol for a section which has 1210 been removed. */ 1211 assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION); 1212 } 1213 1214 if (destidx != inner) 1215 { 1216 /* The size of the symbol table changed. */ 1217 shdr_info[cnt].shdr.sh_size = newdata->d_size 1218 = destidx * elsize; 1219 any_symtab_changes = true; 1220 } 1221 else 1222 { 1223 /* The symbol table didn't really change. */ 1224 free (shdr_info[cnt].newsymidx); 1225 shdr_info[cnt].newsymidx = NULL; 1226 } 1227 } 1228 } 1229 1230 /* If we have to, compute the offset of the section. */ 1231 if (shdr_info[cnt].shdr.sh_offset == 0) 1232 shdr_info[cnt].shdr.sh_offset 1233 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1) 1234 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1))); 1235 1236 /* Set the section header in the new file. */ 1237 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0)) 1238 /* There cannot be any overflows. */ 1239 INTERNAL_ERROR (fname); 1240 1241 /* Remember the last section written so far. */ 1242 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS 1243 ? shdr_info[cnt].shdr.sh_size : 0); 1244 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz) 1245 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz; 1246 } 1247 1248 /* Adjust symbol references if symbol tables changed. */ 1249 if (any_symtab_changes) 1250 { 1251 /* Find all relocation sections which use this 1252 symbol table. */ 1253 for (cnt = 1; cnt <= shdridx; ++cnt) 1254 { 1255 /* Update section headers when the data size has changed. 1256 We also update the SHT_NOBITS section in the debug 1257 file so that the section headers match in sh_size. */ 1258 inline void update_section_size (const Elf_Data *newdata) 1259 { 1260 GElf_Shdr shdr_mem; 1261 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1262 shdr->sh_size = newdata->d_size; 1263 (void) gelf_update_shdr (scn, shdr); 1264 if (debugelf != NULL) 1265 { 1266 /* libelf will use d_size to set sh_size. */ 1267 Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf, 1268 cnt), NULL); 1269 debugdata->d_size = newdata->d_size; 1270 } 1271 } 1272 1273 if (shdr_info[cnt].idx == 0 && debug_fname == NULL) 1274 /* Ignore sections which are discarded. When we are saving a 1275 relocation section in a separate debug file, we must fix up 1276 the symbol table references. */ 1277 continue; 1278 1279 if (shdr_info[cnt].shdr.sh_type == SHT_REL 1280 || shdr_info[cnt].shdr.sh_type == SHT_RELA) 1281 { 1282 /* If the symbol table hasn't changed, do not do anything. */ 1283 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL) 1284 continue; 1285 1286 Elf32_Word *newsymidx 1287 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx; 1288 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0 1289 ? elf_getscn (debugelf, cnt) 1290 : elf_getscn (newelf, 1291 shdr_info[cnt].idx), 1292 NULL); 1293 assert (d != NULL); 1294 size_t nrels = (shdr_info[cnt].shdr.sh_size 1295 / shdr_info[cnt].shdr.sh_entsize); 1296 1297 if (shdr_info[cnt].shdr.sh_type == SHT_REL) 1298 for (size_t relidx = 0; relidx < nrels; ++relidx) 1299 { 1300 GElf_Rel rel_mem; 1301 if (gelf_getrel (d, relidx, &rel_mem) == NULL) 1302 INTERNAL_ERROR (fname); 1303 1304 size_t symidx = GELF_R_SYM (rel_mem.r_info); 1305 if (newsymidx[symidx] != symidx) 1306 { 1307 rel_mem.r_info 1308 = GELF_R_INFO (newsymidx[symidx], 1309 GELF_R_TYPE (rel_mem.r_info)); 1310 1311 if (gelf_update_rel (d, relidx, &rel_mem) == 0) 1312 INTERNAL_ERROR (fname); 1313 } 1314 } 1315 else 1316 for (size_t relidx = 0; relidx < nrels; ++relidx) 1317 { 1318 GElf_Rela rel_mem; 1319 if (gelf_getrela (d, relidx, &rel_mem) == NULL) 1320 INTERNAL_ERROR (fname); 1321 1322 size_t symidx = GELF_R_SYM (rel_mem.r_info); 1323 if (newsymidx[symidx] != symidx) 1324 { 1325 rel_mem.r_info 1326 = GELF_R_INFO (newsymidx[symidx], 1327 GELF_R_TYPE (rel_mem.r_info)); 1328 1329 if (gelf_update_rela (d, relidx, &rel_mem) == 0) 1330 INTERNAL_ERROR (fname); 1331 } 1332 } 1333 } 1334 else if (shdr_info[cnt].shdr.sh_type == SHT_HASH) 1335 { 1336 /* We have to recompute the hash table. */ 1337 Elf32_Word symtabidx = shdr_info[cnt].old_sh_link; 1338 1339 /* We do not have to do anything if the symbol table was 1340 not changed. */ 1341 if (shdr_info[symtabidx].newsymidx == NULL) 1342 continue; 1343 1344 assert (shdr_info[cnt].idx > 0); 1345 1346 /* The hash section in the new file. */ 1347 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1348 1349 /* The symbol table data. */ 1350 Elf_Data *symd = elf_getdata (elf_getscn (newelf, 1351 shdr_info[symtabidx].idx), 1352 NULL); 1353 assert (symd != NULL); 1354 1355 /* The hash table data. */ 1356 Elf_Data *hashd = elf_getdata (scn, NULL); 1357 assert (hashd != NULL); 1358 1359 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word)) 1360 { 1361 /* Sane arches first. */ 1362 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf; 1363 1364 size_t strshndx = shdr_info[symtabidx].old_sh_link; 1365 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 1366 ehdr->e_version); 1367 1368 /* Adjust the nchain value. The symbol table size 1369 changed. We keep the same size for the bucket array. */ 1370 bucket[1] = symd->d_size / elsize; 1371 Elf32_Word nbucket = bucket[0]; 1372 bucket += 2; 1373 Elf32_Word *chain = bucket + nbucket; 1374 1375 /* New size of the section. */ 1376 hashd->d_size = ((2 + symd->d_size / elsize + nbucket) 1377 * sizeof (Elf32_Word)); 1378 update_section_size (hashd); 1379 1380 /* Clear the arrays. */ 1381 memset (bucket, '\0', 1382 (symd->d_size / elsize + nbucket) 1383 * sizeof (Elf32_Word)); 1384 1385 for (size_t inner = shdr_info[symtabidx].shdr.sh_info; 1386 inner < symd->d_size / elsize; ++inner) 1387 { 1388 GElf_Sym sym_mem; 1389 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); 1390 assert (sym != NULL); 1391 1392 const char *name = elf_strptr (elf, strshndx, 1393 sym->st_name); 1394 assert (name != NULL); 1395 size_t hidx = elf_hash (name) % nbucket; 1396 1397 if (bucket[hidx] == 0) 1398 bucket[hidx] = inner; 1399 else 1400 { 1401 hidx = bucket[hidx]; 1402 1403 while (chain[hidx] != 0) 1404 hidx = chain[hidx]; 1405 1406 chain[hidx] = inner; 1407 } 1408 } 1409 } 1410 else 1411 { 1412 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */ 1413 assert (shdr_info[cnt].shdr.sh_entsize 1414 == sizeof (Elf64_Xword)); 1415 1416 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf; 1417 1418 size_t strshndx = shdr_info[symtabidx].old_sh_link; 1419 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, 1420 ehdr->e_version); 1421 1422 /* Adjust the nchain value. The symbol table size 1423 changed. We keep the same size for the bucket array. */ 1424 bucket[1] = symd->d_size / elsize; 1425 Elf64_Xword nbucket = bucket[0]; 1426 bucket += 2; 1427 Elf64_Xword *chain = bucket + nbucket; 1428 1429 /* New size of the section. */ 1430 hashd->d_size = ((2 + symd->d_size / elsize + nbucket) 1431 * sizeof (Elf64_Xword)); 1432 update_section_size (hashd); 1433 1434 /* Clear the arrays. */ 1435 memset (bucket, '\0', 1436 (symd->d_size / elsize + nbucket) 1437 * sizeof (Elf64_Xword)); 1438 1439 for (size_t inner = shdr_info[symtabidx].shdr.sh_info; 1440 inner < symd->d_size / elsize; ++inner) 1441 { 1442 GElf_Sym sym_mem; 1443 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem); 1444 assert (sym != NULL); 1445 1446 const char *name = elf_strptr (elf, strshndx, 1447 sym->st_name); 1448 assert (name != NULL); 1449 size_t hidx = elf_hash (name) % nbucket; 1450 1451 if (bucket[hidx] == 0) 1452 bucket[hidx] = inner; 1453 else 1454 { 1455 hidx = bucket[hidx]; 1456 1457 while (chain[hidx] != 0) 1458 hidx = chain[hidx]; 1459 1460 chain[hidx] = inner; 1461 } 1462 } 1463 } 1464 } 1465 else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym) 1466 { 1467 /* If the symbol table changed we have to adjust the 1468 entries. */ 1469 Elf32_Word symtabidx = shdr_info[cnt].old_sh_link; 1470 1471 /* We do not have to do anything if the symbol table was 1472 not changed. */ 1473 if (shdr_info[symtabidx].newsymidx == NULL) 1474 continue; 1475 1476 assert (shdr_info[cnt].idx > 0); 1477 1478 /* The symbol version section in the new file. */ 1479 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1480 1481 /* The symbol table data. */ 1482 Elf_Data *symd = elf_getdata (elf_getscn (newelf, 1483 shdr_info[symtabidx].idx), 1484 NULL); 1485 assert (symd != NULL); 1486 1487 /* The version symbol data. */ 1488 Elf_Data *verd = elf_getdata (scn, NULL); 1489 assert (verd != NULL); 1490 1491 /* The symbol version array. */ 1492 GElf_Half *verstab = (GElf_Half *) verd->d_buf; 1493 1494 /* New indices of the symbols. */ 1495 Elf32_Word *newsymidx = shdr_info[symtabidx].newsymidx; 1496 1497 /* Walk through the list and */ 1498 size_t elsize = gelf_fsize (elf, verd->d_type, 1, 1499 ehdr->e_version); 1500 for (size_t inner = 1; inner < verd->d_size / elsize; ++inner) 1501 if (newsymidx[inner] != 0) 1502 /* Overwriting the same array works since the 1503 reordering can only move entries to lower indices 1504 in the array. */ 1505 verstab[newsymidx[inner]] = verstab[inner]; 1506 1507 /* New size of the section. */ 1508 verd->d_size = gelf_fsize (newelf, verd->d_type, 1509 symd->d_size 1510 / gelf_fsize (elf, symd->d_type, 1, 1511 ehdr->e_version), 1512 ehdr->e_version); 1513 update_section_size (verd); 1514 } 1515 else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP) 1516 { 1517 /* Check whether the associated symbol table changed. */ 1518 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL) 1519 { 1520 /* Yes the symbol table changed. Update the section 1521 header of the section group. */ 1522 scn = elf_getscn (newelf, shdr_info[cnt].idx); 1523 GElf_Shdr shdr_mem; 1524 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 1525 assert (shdr != NULL); 1526 1527 size_t stabidx = shdr_info[cnt].old_sh_link; 1528 shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info]; 1529 1530 (void) gelf_update_shdr (scn, shdr); 1531 } 1532 } 1533 } 1534 } 1535 1536 /* Now that we have done all adjustments to the data, 1537 we can actually write out the debug file. */ 1538 if (debug_fname != NULL) 1539 { 1540 uint32_t debug_crc; 1541 Elf_Data debug_crc_data = 1542 { 1543 .d_type = ELF_T_WORD, 1544 .d_buf = &debug_crc, 1545 .d_size = sizeof (debug_crc), 1546 .d_version = EV_CURRENT 1547 }; 1548 1549 /* Finally write the file. */ 1550 if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1)) 1551 { 1552 error (0, 0, gettext ("while writing '%s': %s"), 1553 debug_fname, elf_errmsg (-1)); 1554 result = 1; 1555 goto fail_close; 1556 } 1557 1558 /* Create the real output file. First rename, then change the 1559 mode. */ 1560 if (rename (tmp_debug_fname, debug_fname) != 0 1561 || fchmod (debug_fd, mode) != 0) 1562 { 1563 error (0, errno, gettext ("while creating '%s'"), debug_fname); 1564 result = 1; 1565 goto fail_close; 1566 } 1567 1568 /* The temporary file does not exist anymore. */ 1569 tmp_debug_fname = NULL; 1570 1571 /* Compute the checksum which we will add to the executable. */ 1572 if (crc32_file (debug_fd, &debug_crc) != 0) 1573 { 1574 error (0, errno, 1575 gettext ("while computing checksum for debug information")); 1576 unlink (debug_fname); 1577 result = 1; 1578 goto fail_close; 1579 } 1580 1581 /* Store it in the debuglink section data. */ 1582 if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data, 1583 &debug_crc_data, ehdr->e_ident[EI_DATA]) 1584 != &debuglink_crc_data)) 1585 INTERNAL_ERROR (fname); 1586 } 1587 1588 /* Finally finish the ELF header. Fill in the fields not handled by 1589 libelf from the old file. */ 1590 newehdr = gelf_getehdr (newelf, &newehdr_mem); 1591 if (newehdr == NULL) 1592 INTERNAL_ERROR (fname); 1593 1594 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT); 1595 newehdr->e_type = ehdr->e_type; 1596 newehdr->e_machine = ehdr->e_machine; 1597 newehdr->e_version = ehdr->e_version; 1598 newehdr->e_entry = ehdr->e_entry; 1599 newehdr->e_flags = ehdr->e_flags; 1600 newehdr->e_phoff = ehdr->e_phoff; 1601 /* We need to position the section header table. */ 1602 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT); 1603 newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset 1604 + shdr_info[shdridx].shdr.sh_size + offsize - 1) 1605 & ~((GElf_Off) (offsize - 1))); 1606 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT); 1607 1608 /* The new section header string table index. */ 1609 if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX)) 1610 newehdr->e_shstrndx = idx; 1611 else 1612 { 1613 /* The index does not fit in the ELF header field. */ 1614 shdr_info[0].scn = elf_getscn (elf, 0); 1615 1616 if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL) 1617 INTERNAL_ERROR (fname); 1618 1619 shdr_info[0].shdr.sh_link = idx; 1620 (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr); 1621 1622 newehdr->e_shstrndx = SHN_XINDEX; 1623 } 1624 1625 if (gelf_update_ehdr (newelf, newehdr) == 0) 1626 { 1627 error (0, 0, gettext ("%s: error while creating ELF header: %s"), 1628 fname, elf_errmsg (-1)); 1629 return 1; 1630 } 1631 1632 /* We have everything from the old file. */ 1633 if (elf_cntl (elf, ELF_C_FDDONE) != 0) 1634 { 1635 error (0, 0, gettext ("%s: error while reading the file: %s"), 1636 fname, elf_errmsg (-1)); 1637 return 1; 1638 } 1639 1640 /* The ELF library better follows our layout when this is not a 1641 relocatable object file. */ 1642 elf_flagelf (newelf, ELF_C_SET, 1643 (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0) 1644 | (permissive ? ELF_F_PERMISSIVE : 0)); 1645 1646 /* Finally write the file. */ 1647 if (elf_update (newelf, ELF_C_WRITE) == -1) 1648 { 1649 error (0, 0, gettext ("while writing '%s': %s"), 1650 fname, elf_errmsg (-1)); 1651 result = 1; 1652 } 1653 1654 fail_close: 1655 if (shdr_info != NULL) 1656 { 1657 /* For some sections we might have created an table to map symbol 1658 table indices. */ 1659 if (any_symtab_changes) 1660 for (cnt = 1; cnt <= shdridx; ++cnt) 1661 free (shdr_info[cnt].newsymidx); 1662 1663 /* Free the memory. */ 1664 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC) 1665 free (shdr_info); 1666 } 1667 1668 /* Free other resources. */ 1669 if (shstrtab_data != NULL) 1670 free (shstrtab_data->d_buf); 1671 if (shst != NULL) 1672 ebl_strtabfree (shst); 1673 1674 /* That was it. Close the descriptors. */ 1675 if (elf_end (newelf) != 0) 1676 { 1677 error (0, 0, gettext ("error while finishing '%s': %s"), fname, 1678 elf_errmsg (-1)); 1679 result = 1; 1680 } 1681 1682 if (debugelf != NULL && elf_end (debugelf) != 0) 1683 { 1684 error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname, 1685 elf_errmsg (-1)); 1686 result = 1; 1687 } 1688 1689 fail: 1690 /* Close the EBL backend. */ 1691 if (ebl != NULL) 1692 ebl_closebackend (ebl); 1693 1694 /* Close debug file descriptor, if opened */ 1695 if (debug_fd >= 0) 1696 { 1697 if (tmp_debug_fname != NULL) 1698 unlink (tmp_debug_fname); 1699 close (debug_fd); 1700 } 1701 1702 /* If requested, preserve the timestamp. */ 1703 if (tvp != NULL) 1704 { 1705 if (futimes (fd, tvp) != 0) 1706 { 1707 error (0, errno, gettext ("\ 1708cannot set access and modification date of '%s'"), 1709 output_fname ?: fname); 1710 result = 1; 1711 } 1712 } 1713 1714 /* Close the file descriptor if we created a new file. */ 1715 if (output_fname != NULL) 1716 close (fd); 1717 1718 return result; 1719} 1720 1721 1722static int 1723handle_ar (int fd, Elf *elf, const char *prefix, const char *fname, 1724 struct timeval tvp[2]) 1725{ 1726 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix); 1727 size_t fname_len = strlen (fname) + 1; 1728 char new_prefix[prefix_len + 1 + fname_len]; 1729 char *cp = new_prefix; 1730 1731 /* Create the full name of the file. */ 1732 if (prefix != NULL) 1733 { 1734 cp = mempcpy (cp, prefix, prefix_len); 1735 *cp++ = ':'; 1736 } 1737 memcpy (cp, fname, fname_len); 1738 1739 1740 /* Process all the files contained in the archive. */ 1741 Elf *subelf; 1742 Elf_Cmd cmd = ELF_C_RDWR; 1743 int result = 0; 1744 while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 1745 { 1746 /* The the header for this element. */ 1747 Elf_Arhdr *arhdr = elf_getarhdr (subelf); 1748 1749 if (elf_kind (subelf) == ELF_K_ELF) 1750 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL); 1751 else if (elf_kind (subelf) == ELF_K_AR) 1752 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL); 1753 1754 /* Get next archive element. */ 1755 cmd = elf_next (subelf); 1756 if (unlikely (elf_end (subelf) != 0)) 1757 INTERNAL_ERROR (fname); 1758 } 1759 1760 if (tvp != NULL) 1761 { 1762 if (unlikely (futimes (fd, tvp) != 0)) 1763 { 1764 error (0, errno, gettext ("\ 1765cannot set access and modification date of '%s'"), fname); 1766 result = 1; 1767 } 1768 } 1769 1770 if (unlikely (close (fd) != 0)) 1771 error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname); 1772 1773 return result; 1774} 1775 1776 1777#include "debugpred.h" 1778