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