1 /* Discard section not used at runtime from object files.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5 This program is Open Source software; you can redistribute it and/or
6 modify it under the terms of the Open Software License version 1.0 as
7 published by the Open Source Initiative.
9 You should have received a copy of the Open Software License along
10 with this program; if not, you may obtain a copy of the Open Software
11 License version 1.0 from http://www.opensource.org/licenses/osl.php or
12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
13 3001 King Ranch Road, Ukiah, CA 95482. */
32 #include <stdio_ext.h>
36 #include <sys/param.h>
39 #include <elf-knowledge.h>
44 /* Name and version of program. */
45 static void print_version (FILE *stream, struct argp_state *state);
46 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
48 /* Bug report address. */
49 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
52 /* Values for the parameters which have no short form. */
53 #define OPT_REMOVE_COMMENT 0x100
54 #define OPT_PERMISSIVE 0x101
57 /* Definitions of arguments for argp functions. */
58 static const struct argp_option options[] =
60 { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
61 { NULL, 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 },
62 { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 },
63 { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
65 { NULL, 0, NULL, 0, N_("Output options:"), 0 },
66 { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
67 { "preserve-dates", 'p', NULL, 0,
68 N_("Copy modified/access timestamps to the output"), 0 },
69 { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
70 N_("Remove .comment section"), 0 },
71 { "permissive", OPT_PERMISSIVE, NULL, 0,
72 N_("Relax a few rules to handle slightly broken ELF files"), 0 },
73 { NULL, 0, NULL, 0, NULL, 0 }
76 /* Short description of program. */
77 static const char doc[] = N_("Discard symbols from object files.");
79 /* Strings for arguments in help texts. */
80 static const char args_doc[] = N_("[FILE...]");
82 /* Prototype for option handler. */
83 static error_t parse_opt (int key, char *arg, struct argp_state *state);
85 /* Data structure to communicate with argp functions. */
86 static struct argp argp =
88 options, parse_opt, args_doc, doc, NULL, NULL, NULL
92 /* Print symbols in file named FNAME. */
93 static int process_file (const char *fname);
95 /* Handle one ELF file. */
96 static int handle_elf (int fd, Elf *elf, const char *prefix,
97 const char *fname, mode_t mode, struct timeval tvp[2]);
99 /* Handle all files contained in the archive. */
100 static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
101 struct timeval tvp[2]);
103 #define INTERNAL_ERROR(fname) \
104 error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"), \
105 fname, __LINE__, VERSION, __DATE__, elf_errmsg (-1))
108 /* Name of the output file. */
109 static const char *output_fname;
111 /* Name of the debug output file. */
112 static const char *debug_fname;
114 /* Name to pretend the debug output file has. */
115 static const char *debug_fname_embed;
117 /* If true output files shall have same date as the input file. */
118 static bool preserve_dates;
120 /* If true .comment sections will be removed. */
121 static bool remove_comment;
123 /* If true remove all debug sections. */
124 static bool remove_debug;
126 /* If true relax some ELF rules for input files. */
127 static bool permissive;
131 main (int argc, char *argv[])
136 /* Make memory leak detection possible. */
139 /* We use no threads here which can interfere with handling a stream. */
140 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
141 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
142 __fsetlocking (stderr, FSETLOCKING_BYCALLER);
145 setlocale (LC_ALL, "");
147 /* Make sure the message catalog can be found. */
148 bindtextdomain (PACKAGE, LOCALEDIR);
150 /* Initialize the message catalog. */
151 textdomain (PACKAGE);
153 /* Parse and process arguments. */
154 if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
157 /* Tell the library which version we are expecting. */
158 elf_version (EV_CURRENT);
160 if (remaining == argc)
161 /* The user didn't specify a name so we use a.out. */
162 result = process_file ("a.out");
165 /* If we have seen the '-o' or '-f' option there must be exactly one
167 if ((output_fname != NULL || debug_fname != NULL)
168 && remaining + 1 < argc)
169 error (EXIT_FAILURE, 0, gettext ("\
170 Only one input file allowed together with '-o' and '-f'"));
172 /* Process all the remaining files. */
174 result |= process_file (argv[remaining]);
175 while (++remaining < argc);
182 /* Print the version information. */
184 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
186 fprintf (stream, "strip (%s) %s\n", PACKAGE_NAME, VERSION);
187 fprintf (stream, gettext ("\
188 Copyright (C) %s Red Hat, Inc.\n\
189 This is free software; see the source for copying conditions. There is NO\n\
190 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
192 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
196 /* Handle program arguments. */
198 parse_opt (int key, char *arg,
199 struct argp_state *state __attribute__ ((unused)))
204 if (debug_fname != NULL)
206 error (0, 0, gettext ("-f option specified twice"));
213 if (debug_fname_embed != NULL)
215 error (0, 0, gettext ("-F option specified twice"));
218 debug_fname_embed = arg;
222 if (output_fname != NULL)
224 error (0, 0, gettext ("-o option specified twice"));
231 preserve_dates = true;
234 case OPT_REMOVE_COMMENT:
235 remove_comment = true;
247 return ARGP_ERR_UNKNOWN;
254 process_file (const char *fname)
256 /* If we have to preserve the modify and access timestamps get them
257 now. We cannot use fstat() after opening the file since the open
258 would change the access time. */
259 struct stat64 pre_st;
260 struct timeval tv[2];
264 if (stat64 (fname, &pre_st) != 0)
266 error (0, errno, gettext ("cannot stat input file \"%s\""), fname);
270 /* If we have to preserve the timestamp, we need it in the
271 format utimes() understands. */
272 TIMESPEC_TO_TIMEVAL (&tv[0], &pre_st.st_atim);
273 TIMESPEC_TO_TIMEVAL (&tv[1], &pre_st.st_mtim);
277 int fd = open (fname, O_RDWR);
280 error (0, errno, gettext ("while opening \"%s\""), fname);
284 /* We always use fstat() even if we called stat() before. This is
285 done to make sure the information returned by stat() is for the
288 if (fstat64 (fd, &st) != 0)
290 error (0, errno, gettext ("cannot stat input file \"%s\""), fname);
293 /* Paranoid mode on. */
295 && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
297 /* We detected a race. Try again. */
302 /* Now get the ELF descriptor. */
303 Elf *elf = elf_begin (fd, ELF_C_RDWR, NULL);
305 switch (elf_kind (elf))
308 result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
309 preserve_dates ? tv : NULL);
313 /* It is not possible to strip the content of an archive direct
314 the output to a specific file. */
315 if (unlikely (output_fname != NULL))
317 error (0, 0, gettext ("%s: cannot use -o when stripping archive"),
322 result = handle_ar (fd, elf, NULL, fname, preserve_dates ? tv : NULL);
326 error (0, 0, gettext ("%s: File format not recognized"), fname);
331 if (unlikely (elf_end (elf) != 0))
332 INTERNAL_ERROR (fname);
340 /* Maximum size of array allocated on stack. */
341 #define MAX_STACK_ALLOC (400 * 1024)
344 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
345 mode_t mode, struct timeval tvp[2])
347 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
348 size_t fname_len = strlen (fname) + 1;
349 char *fullname = alloca (prefix_len + 1 + fname_len);
352 Elf *debugelf = NULL;
353 char *tmp_debug_fname = NULL;
365 Elf32_Word idx; /* Index in new file. */
366 Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */
367 Elf32_Word symtab_idx;
368 Elf32_Word version_idx;
369 Elf32_Word group_idx;
370 Elf32_Word group_cnt;
372 struct Ebl_Strent *se;
373 Elf32_Word *newsymidx;
379 GElf_Ehdr newehdr_mem;
381 GElf_Ehdr debugehdr_mem;
382 GElf_Ehdr *debugehdr;
383 struct Ebl_Strtab *shst = NULL;
384 Elf_Data debuglink_crc_data;
385 bool any_symtab_changes = false;
386 Elf_Data *shstrtab_data = NULL;
388 /* Create the full name of the file. */
391 cp = mempcpy (cp, prefix, prefix_len);
394 memcpy (cp, fname, fname_len);
396 /* If we are not replacing the input file open a new file here. */
397 if (output_fname != NULL)
399 fd = open (output_fname, O_RDWR | O_CREAT, mode);
400 if (unlikely (fd == -1))
402 error (0, errno, gettext ("cannot open '%s'"), output_fname);
409 /* Get the EBL handling. The -g option is currently the only reason
410 we need EBL so dont open the backend unless necessary. */
414 ebl = ebl_openbackend (elf);
417 error (0, errno, gettext ("cannot open EBL backend"));
423 /* Open the additional file the debug information will be stored in. */
424 if (debug_fname != NULL)
426 /* Create a temporary file name. We do not want to overwrite
427 the debug file if the file would not contain any
429 size_t debug_fname_len = strlen (debug_fname);
430 tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX"));
431 strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
434 debug_fd = mkstemp (tmp_debug_fname);
435 if (unlikely (debug_fd == -1))
437 error (0, errno, gettext ("cannot open '%s'"), debug_fname);
443 /* Get the information from the old file. */
444 ehdr = gelf_getehdr (elf, &ehdr_mem);
446 INTERNAL_ERROR (fname);
448 /* Get the section header string table index. */
449 if (unlikely (elf_getshstrndx (elf, &shstrndx) < 0))
450 error (EXIT_FAILURE, 0,
451 gettext ("cannot get section header string table index"));
453 /* We now create a new ELF descriptor for the same file. We
454 construct it almost exactly in the same way with some information
456 if (output_fname != NULL)
457 newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
459 newelf = elf_clone (elf, ELF_C_EMPTY);
461 if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
462 || (ehdr->e_type != ET_REL
463 && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0)))
465 error (0, 0, gettext ("cannot create new file '%s': %s"),
466 output_fname, elf_errmsg (-1));
470 /* Copy over the old program header if needed. */
471 if (ehdr->e_type != ET_REL)
472 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
477 phdr = gelf_getphdr (elf, cnt, &phdr_mem);
479 || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
480 INTERNAL_ERROR (fname);
483 if (debug_fname != NULL)
485 /* Also create an ELF descriptor for the debug file */
486 debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
487 if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
488 || (ehdr->e_type != ET_REL
489 && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0)))
491 error (0, 0, gettext ("cannot create new file '%s': %s"),
492 debug_fname, elf_errmsg (-1));
496 /* Copy over the old program header if needed. */
497 if (ehdr->e_type != ET_REL)
498 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
503 phdr = gelf_getphdr (elf, cnt, &phdr_mem);
505 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
506 INTERNAL_ERROR (fname);
510 /* Number of sections. */
511 if (unlikely (elf_getshnum (elf, &shnum) < 0))
513 error (0, 0, gettext ("cannot determine number of sections: %s"),
518 /* Storage for section information. We leave room for two more
519 entries since we unconditionally create a section header string
520 table. Maybe some weird tool created an ELF file without one.
521 The other one is used for the debug link section. */
522 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
523 shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
524 sizeof (struct shdr_info));
527 shdr_info = (struct shdr_info *) alloca ((shnum + 2)
528 * sizeof (struct shdr_info));
529 memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
532 /* Prepare section information data structure. */
535 while ((scn = elf_nextscn (elf, scn)) != NULL)
537 /* This should always be true (i.e., there should not be any
538 holes in the numbering). */
539 assert (elf_ndxscn (scn) == cnt);
541 shdr_info[cnt].scn = scn;
543 /* Get the header. */
544 if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
545 INTERNAL_ERROR (fname);
547 /* Get the name of the section. */
548 shdr_info[cnt].name = elf_strptr (elf, shstrndx,
549 shdr_info[cnt].shdr.sh_name);
550 if (shdr_info[cnt].name == NULL)
552 error (0, 0, gettext ("illformed file '%s'"), fname);
556 /* Mark them as present but not yet investigated. */
557 shdr_info[cnt].idx = 1;
559 /* Remember the shdr.sh_link value. */
560 shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
562 /* Sections in files other than relocatable object files which
563 are not loaded can be freely moved by us. In relocatable
564 object files everything can be moved. */
565 if (ehdr->e_type == ET_REL
566 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
567 shdr_info[cnt].shdr.sh_offset = 0;
569 /* If this is an extended section index table store an
570 appropriate reference. */
571 if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
573 assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
574 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
576 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
581 /* Cross-reference the sections contained in the section
583 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
584 if (shdr_info[cnt].data == NULL)
585 INTERNAL_ERROR (fname);
587 /* XXX Fix for unaligned access. */
588 grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
590 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
592 shdr_info[grpref[inner]].group_idx = cnt;
594 if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
595 /* If the section group contains only one element and this
596 is n COMDAT section we can drop it right away. */
597 shdr_info[cnt].idx = 0;
599 shdr_info[cnt].group_cnt = inner - 1;
601 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
603 assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
604 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
607 /* If this section is part of a group make sure it is not
608 discarded right away. */
609 if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
611 assert (shdr_info[cnt].group_idx != 0);
613 if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
615 /* The section group section will be removed. */
616 shdr_info[cnt].group_idx = 0;
617 shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP;
621 /* Increment the counter. */
625 /* Now determine which sections can go away. The general rule is that
626 all sections which are not used at runtime are stripped out. But
627 there are a few exceptions:
629 - special sections named ".comment" and ".note" are kept
630 - OS or architecture specific sections are kept since we might not
631 know how to handle them
632 - if a section is referred to from a section which is not removed
633 in the sh_link or sh_info element it cannot be removed either
635 for (cnt = 1; cnt < shnum; ++cnt)
636 /* Check whether the section can be removed. */
637 if (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr,
638 shdr_info[cnt].name, remove_comment,
641 /* For now assume this section will be removed. */
642 shdr_info[cnt].idx = 0;
644 idx = shdr_info[cnt].group_idx;
647 /* If the references section group is a normal section
648 group and has one element remaining, or if it is an
649 empty COMDAT section group it is removed. */
652 /* The section group data is already loaded. */
653 assert (shdr_info[idx].data != NULL);
655 is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
658 --shdr_info[idx].group_cnt;
659 if ((!is_comdat && shdr_info[idx].group_cnt == 1)
660 || (is_comdat && shdr_info[idx].group_cnt == 0))
662 shdr_info[idx].idx = 0;
663 /* Continue recursively. */
664 idx = shdr_info[idx].group_idx;
671 /* Mark the SHT_NULL section as handled. */
672 shdr_info[0].idx = 2;
675 /* Handle exceptions: section groups and cross-references. We might
676 have to repeat this a few times since the resetting of the flag
682 for (cnt = 1; cnt < shnum; ++cnt)
684 if (shdr_info[cnt].idx == 0)
686 /* If a relocation section is marked as being removed make
687 sure the section it is relocating is removed, too. */
688 if ((shdr_info[cnt].shdr.sh_type == SHT_REL
689 || shdr_info[cnt].shdr.sh_type == SHT_RELA)
690 && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
691 shdr_info[cnt].idx = 1;
694 if (shdr_info[cnt].idx == 1)
696 /* The content of symbol tables we don't remove must not
697 reference any section which we do remove. Otherwise
698 we cannot remove the section. */
699 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
700 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
706 /* Make sure the data is loaded. */
707 if (shdr_info[cnt].data == NULL)
710 = elf_getdata (shdr_info[cnt].scn, NULL);
711 if (shdr_info[cnt].data == NULL)
712 INTERNAL_ERROR (fname);
714 symdata = shdr_info[cnt].data;
716 /* If there is an extended section index table load it
718 if (shdr_info[cnt].symtab_idx != 0
719 && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
721 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
723 shdr_info[shdr_info[cnt].symtab_idx].data
724 = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
726 if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
727 INTERNAL_ERROR (fname);
729 xndxdata = shdr_info[shdr_info[cnt].symtab_idx].data;
731 /* Go through all symbols and make sure the section they
732 reference is not removed. */
733 elsize = gelf_fsize (elf, ELF_T_SYM, 1, ehdr->e_version);
735 for (size_t inner = 0;
736 inner < shdr_info[cnt].data->d_size / elsize;
744 sym = gelf_getsymshndx (symdata, xndxdata, inner,
747 INTERNAL_ERROR (fname);
749 scnidx = sym->st_shndx;
750 if (scnidx == SHN_UNDEF || scnidx >= shnum
751 || (scnidx >= SHN_LORESERVE
752 && scnidx <= SHN_HIRESERVE
753 && scnidx != SHN_XINDEX)
754 /* Don't count in the section symbols. */
755 || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
756 /* This is no section index, leave it alone. */
758 else if (scnidx == SHN_XINDEX)
761 if (shdr_info[scnidx].idx == 0)
763 /* Mark this section as used. */
764 shdr_info[scnidx].idx = 1;
765 changes |= scnidx < cnt;
770 /* Cross referencing happens:
771 - for the cases the ELF specification says. That are
772 + SHT_DYNAMIC in sh_link to string table
773 + SHT_HASH in sh_link to symbol table
774 + SHT_REL and SHT_RELA in sh_link to symbol table
775 + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
776 + SHT_GROUP in sh_link to symbol table
777 + SHT_SYMTAB_SHNDX in sh_link to symbol table
778 Other (OS or architecture-specific) sections might as
779 well use this field so we process it unconditionally.
780 - references inside section groups
781 - specially marked references in sh_info if the SHF_INFO_LINK
785 if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
787 shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
788 changes |= shdr_info[cnt].shdr.sh_link < cnt;
791 /* Handle references through sh_info. */
792 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)
793 && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
795 shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
796 changes |= shdr_info[cnt].shdr.sh_info < cnt;
799 /* Mark the section as investigated. */
800 shdr_info[cnt].idx = 2;
806 /* Copy the removed sections to the debug output file.
807 The ones that are not removed in the stripped file are SHT_NOBITS. */
808 if (debug_fname != NULL)
810 for (cnt = 1; cnt < shnum; ++cnt)
814 bool discard_section;
816 scn = elf_newscn (debugelf);
818 error (EXIT_FAILURE, 0,
819 gettext ("while generating output file: %s"),
822 discard_section = shdr_info[cnt].idx > 0 && cnt != ehdr->e_shstrndx;
824 /* Set the section header in the new file. */
825 debugshdr = shdr_info[cnt].shdr;
827 debugshdr.sh_type = SHT_NOBITS;
829 if (unlikely (gelf_update_shdr (scn, &debugshdr)) == 0)
830 /* There cannot be any overflows. */
831 INTERNAL_ERROR (fname);
833 /* Get the data from the old file if necessary. */
834 if (shdr_info[cnt].data == NULL)
836 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
837 if (shdr_info[cnt].data == NULL)
838 INTERNAL_ERROR (fname);
841 /* Set the data. This is done by copying from the old file. */
842 debugdata = elf_newdata (scn);
843 if (debugdata == NULL)
844 INTERNAL_ERROR (fname);
846 /* Copy the structure. This data may be modified in place
847 before we write out the file. */
848 *debugdata = *shdr_info[cnt].data;
850 debugdata->d_buf = NULL;
853 /* Finish the ELF header. Fill in the fields not handled by
854 libelf from the old file. */
855 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
856 if (debugehdr == NULL)
857 INTERNAL_ERROR (fname);
859 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
860 debugehdr->e_type = ehdr->e_type;
861 debugehdr->e_machine = ehdr->e_machine;
862 debugehdr->e_version = ehdr->e_version;
863 debugehdr->e_entry = ehdr->e_entry;
864 debugehdr->e_flags = ehdr->e_flags;
865 debugehdr->e_shstrndx = ehdr->e_shstrndx;
867 if (unlikely (gelf_update_ehdr (debugelf, debugehdr)) == 0)
869 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
870 debug_fname, elf_errmsg (-1));
876 /* Mark the section header string table as unused, we will create
878 shdr_info[shstrndx].idx = 0;
880 /* We need a string table for the section headers. */
881 shst = ebl_strtabinit (true);
883 error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
884 output_fname ?: fname);
886 /* Assign new section numbers. */
887 shdr_info[0].idx = 0;
888 for (cnt = idx = 1; cnt < shnum; ++cnt)
889 if (shdr_info[cnt].idx > 0)
891 shdr_info[cnt].idx = idx++;
893 /* Create a new section. */
894 shdr_info[cnt].newscn = elf_newscn (newelf);
895 if (shdr_info[cnt].newscn == NULL)
896 error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
899 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
901 /* Add this name to the section header string table. */
902 shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
905 /* Test whether we are doing anything at all. */
907 /* Nope, all removable sections are already gone. */
910 /* Create the reference to the file with the debug info. */
911 if (debug_fname != NULL)
913 char *debug_basename;
916 /* Add the section header string table section name. */
917 shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
918 shdr_info[cnt].idx = idx++;
920 /* Create the section header. */
921 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
922 shdr_info[cnt].shdr.sh_flags = 0;
923 shdr_info[cnt].shdr.sh_addr = 0;
924 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
925 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
926 shdr_info[cnt].shdr.sh_entsize = 0;
927 shdr_info[cnt].shdr.sh_addralign = 4;
928 /* We set the offset to zero here. Before we write the ELF file the
929 field must have the correct value. This is done in the final
930 loop over all section. Then we have all the information needed. */
931 shdr_info[cnt].shdr.sh_offset = 0;
933 /* Create the section. */
934 shdr_info[cnt].newscn = elf_newscn (newelf);
935 if (shdr_info[cnt].newscn == NULL)
936 error (EXIT_FAILURE, 0,
937 gettext ("while create section header section: %s"),
939 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
941 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
942 if (shdr_info[cnt].data == NULL)
943 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
946 debug_basename = basename (debug_fname_embed ?: debug_fname);
947 crc_offset = strlen (debug_basename) + 1;
948 /* Align to 4 byte boundary */
949 crc_offset = ((crc_offset - 1) & ~3) + 4;
951 shdr_info[cnt].data->d_align = 4;
952 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
954 shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size);
956 strcpy (shdr_info[cnt].data->d_buf, debug_basename);
958 /* Cache this Elf_Data describing the CRC32 word in the section.
959 We'll fill this in when we have written the debug file. */
960 debuglink_crc_data = *shdr_info[cnt].data;
961 debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
963 debuglink_crc_data.d_size = 4;
965 /* One more section done. */
969 /* Index of the section header table in the shdr_info array. */
970 size_t shdridx = cnt;
972 /* Add the section header string table section name. */
973 shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
974 shdr_info[cnt].idx = idx;
976 /* Create the section header. */
977 shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
978 shdr_info[cnt].shdr.sh_flags = 0;
979 shdr_info[cnt].shdr.sh_addr = 0;
980 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
981 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
982 shdr_info[cnt].shdr.sh_entsize = 0;
983 /* We set the offset to zero here. Before we write the ELF file the
984 field must have the correct value. This is done in the final
985 loop over all section. Then we have all the information needed. */
986 shdr_info[cnt].shdr.sh_offset = 0;
987 shdr_info[cnt].shdr.sh_addralign = 1;
989 /* Create the section. */
990 shdr_info[cnt].newscn = elf_newscn (newelf);
991 if (shdr_info[cnt].newscn == NULL)
992 error (EXIT_FAILURE, 0,
993 gettext ("while create section header section: %s"),
995 assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
997 /* Finalize the string table and fill in the correct indices in the
999 shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1000 if (shstrtab_data == NULL)
1001 error (EXIT_FAILURE, 0,
1002 gettext ("while create section header string table: %s"),
1004 ebl_strtabfinalize (shst, shstrtab_data);
1006 /* We have to set the section size. */
1007 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1009 /* Update the section information. */
1010 GElf_Off lastoffset = 0;
1011 for (cnt = 1; cnt <= shdridx; ++cnt)
1012 if (shdr_info[cnt].idx > 0)
1016 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1017 assert (scn != NULL);
1019 /* Update the name. */
1020 shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
1022 /* Update the section header from the input file. Some fields
1023 might be section indeces which now have to be adjusted. */
1024 if (shdr_info[cnt].shdr.sh_link != 0)
1025 shdr_info[cnt].shdr.sh_link =
1026 shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1028 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1030 assert (shdr_info[cnt].data != NULL);
1032 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1033 for (size_t inner = 0;
1034 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1036 grpref[inner] = shdr_info[grpref[inner]].idx;
1039 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */
1040 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1041 shdr_info[cnt].shdr.sh_info =
1042 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1044 /* Get the data from the old file if necessary. We already
1045 created the data for the section header string table. */
1048 if (shdr_info[cnt].data == NULL)
1050 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1051 if (shdr_info[cnt].data == NULL)
1052 INTERNAL_ERROR (fname);
1055 /* Set the data. This is done by copying from the old file. */
1056 newdata = elf_newdata (scn);
1057 if (newdata == NULL)
1058 INTERNAL_ERROR (fname);
1060 /* Copy the structure. */
1061 *newdata = *shdr_info[cnt].data;
1063 /* We know the size. */
1064 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1066 /* We have to adjust symtol tables. The st_shndx member might
1067 have to be updated. */
1068 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1069 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1071 Elf_Data *versiondata = NULL;
1072 Elf_Data *shndxdata = NULL;
1074 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1077 if (shdr_info[cnt].symtab_idx != 0)
1079 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1080 /* This section has extended section information.
1081 We have to modify that information, too. */
1082 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1085 assert ((versiondata->d_size / sizeof (Elf32_Word))
1086 >= shdr_info[cnt].data->d_size / elsize);
1089 if (shdr_info[cnt].version_idx != 0)
1091 assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1092 /* This section has associated version
1093 information. We have to modify that
1094 information, too. */
1095 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1098 assert ((versiondata->d_size / sizeof (GElf_Versym))
1099 >= shdr_info[cnt].data->d_size / elsize);
1102 shdr_info[cnt].newsymidx
1103 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1104 / elsize, sizeof (Elf32_Word));
1106 bool last_was_local = true;
1109 for (destidx = inner = 1;
1110 inner < shdr_info[cnt].data->d_size / elsize;
1116 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1120 INTERNAL_ERROR (fname);
1122 if (sym->st_shndx == SHN_UNDEF
1123 || (sym->st_shndx >= shnum
1124 && sym->st_shndx != SHN_XINDEX))
1126 /* This is no section index, leave it alone
1127 unless it is moved. */
1128 if (destidx != inner
1129 && gelf_update_symshndx (shdr_info[cnt].data,
1133 INTERNAL_ERROR (fname);
1135 shdr_info[cnt].newsymidx[inner] = destidx++;
1138 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1140 last_was_local = false;
1141 shdr_info[cnt].shdr.sh_info = destidx - 1;
1147 /* Get the full section index, if necessary from the
1149 if (sym->st_shndx != SHN_XINDEX)
1150 sec = shdr_info[sym->st_shndx].idx;
1153 assert (shndxdata != NULL);
1155 sec = shdr_info[xshndx].idx;
1160 GElf_Section nshndx;
1163 if (sec < SHN_LORESERVE)
1170 nshndx = SHN_XINDEX;
1174 assert (sec < SHN_LORESERVE || shndxdata != NULL);
1176 if ((inner != destidx || nshndx != sym->st_shndx
1177 || (shndxdata != NULL && nxshndx != xshndx))
1178 && (sym->st_shndx = nshndx,
1179 gelf_update_symshndx (shdr_info[cnt].data,
1183 INTERNAL_ERROR (fname);
1185 shdr_info[cnt].newsymidx[inner] = destidx++;
1188 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1190 last_was_local = false;
1191 shdr_info[cnt].shdr.sh_info = destidx - 1;
1195 /* This is a section symbol for a section which has
1197 assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
1200 if (destidx != inner)
1202 /* The size of the symbol table changed. */
1203 shdr_info[cnt].shdr.sh_size = newdata->d_size
1205 any_symtab_changes = true;
1209 /* The symbol table didn't really change. */
1210 free (shdr_info[cnt].newsymidx);
1211 shdr_info[cnt].newsymidx = NULL;
1216 /* If we have to, compute the offset of the section. */
1217 if (shdr_info[cnt].shdr.sh_offset == 0)
1218 shdr_info[cnt].shdr.sh_offset
1219 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1220 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1222 /* Set the section header in the new file. */
1223 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1224 /* There cannot be any overflows. */
1225 INTERNAL_ERROR (fname);
1227 /* Remember the last section written so far. */
1228 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1229 ? shdr_info[cnt].shdr.sh_size : 0);
1230 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1231 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1234 /* Adjust symbol references if symbol tables changed. */
1235 if (any_symtab_changes)
1237 /* Find all relocation sections which use this
1239 for (cnt = 1; cnt <= shdridx; ++cnt)
1241 if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
1242 /* Ignore sections which are discarded. When we are saving a
1243 relocation section in a separate debug file, we must fix up
1244 the symbol table references. */
1247 if (shdr_info[cnt].shdr.sh_type == SHT_REL
1248 || shdr_info[cnt].shdr.sh_type == SHT_RELA)
1250 /* If the symbol table hasn't changed, do not do anything. */
1251 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
1254 Elf32_Word *newsymidx
1255 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
1256 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
1257 ? elf_getscn (debugelf, cnt)
1258 : elf_getscn (newelf,
1259 shdr_info[cnt].idx),
1262 size_t nrels = (shdr_info[cnt].shdr.sh_size
1263 / shdr_info[cnt].shdr.sh_entsize);
1265 if (shdr_info[cnt].shdr.sh_type == SHT_REL)
1266 for (size_t relidx = 0; relidx < nrels; ++relidx)
1269 if (gelf_getrel (d, relidx, &rel_mem) == NULL)
1270 INTERNAL_ERROR (fname);
1272 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1273 if (newsymidx[symidx] != symidx)
1276 = GELF_R_INFO (newsymidx[symidx],
1277 GELF_R_TYPE (rel_mem.r_info));
1279 if (gelf_update_rel (d, relidx, &rel_mem) == 0)
1280 INTERNAL_ERROR (fname);
1284 for (size_t relidx = 0; relidx < nrels; ++relidx)
1287 if (gelf_getrela (d, relidx, &rel_mem) == NULL)
1288 INTERNAL_ERROR (fname);
1290 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1291 if (newsymidx[symidx] != symidx)
1294 = GELF_R_INFO (newsymidx[symidx],
1295 GELF_R_TYPE (rel_mem.r_info));
1297 if (gelf_update_rela (d, relidx, &rel_mem) == 0)
1298 INTERNAL_ERROR (fname);
1302 else if (shdr_info[cnt].shdr.sh_type == SHT_HASH)
1304 /* We have to recompute the hash table. */
1305 Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1307 /* We do not have to do anything if the symbol table was
1309 if (shdr_info[symtabidx].newsymidx == NULL)
1312 assert (shdr_info[cnt].idx > 0);
1314 /* The hash section in the new file. */
1315 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1317 /* The symbol table data. */
1318 Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1319 shdr_info[symtabidx].idx),
1321 assert (symd != NULL);
1323 /* The hash table data. */
1324 Elf_Data *hashd = elf_getdata (scn, NULL);
1325 assert (hashd != NULL);
1327 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
1329 /* Sane arches first. */
1330 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
1332 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1333 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1336 /* Adjust the nchain value. The symbol table size
1337 changed. We keep the same size for the bucket array. */
1338 bucket[1] = symd->d_size / elsize;
1339 Elf32_Word nbucket = bucket[0];
1341 Elf32_Word *chain = bucket + nbucket;
1343 /* New size of the section. */
1345 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1346 shdr->sh_size = hashd->d_size
1347 = (2 + symd->d_size / elsize + nbucket)
1348 * sizeof (Elf32_Word);
1349 (void) gelf_update_shdr (scn, shdr);
1351 /* Clear the arrays. */
1352 memset (bucket, '\0',
1353 (symd->d_size / elsize + nbucket)
1354 * sizeof (Elf32_Word));
1356 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1357 inner < symd->d_size / elsize; ++inner)
1360 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1361 assert (sym != NULL);
1363 const char *name = elf_strptr (elf, strshndx,
1365 assert (name != NULL);
1366 size_t hidx = elf_hash (name) % nbucket;
1368 if (bucket[hidx] == 0)
1369 bucket[hidx] = inner;
1372 hidx = bucket[hidx];
1374 while (chain[hidx] != 0)
1377 chain[hidx] = inner;
1383 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
1384 assert (shdr_info[cnt].shdr.sh_entsize
1385 == sizeof (Elf64_Xword));
1387 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
1389 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1390 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1393 /* Adjust the nchain value. The symbol table size
1394 changed. We keep the same size for the bucket array. */
1395 bucket[1] = symd->d_size / elsize;
1396 Elf64_Xword nbucket = bucket[0];
1398 Elf64_Xword *chain = bucket + nbucket;
1400 /* New size of the section. */
1402 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1403 shdr->sh_size = hashd->d_size
1404 = (2 + symd->d_size / elsize + nbucket)
1405 * sizeof (Elf64_Xword);
1406 (void) gelf_update_shdr (scn, shdr);
1408 /* Clear the arrays. */
1409 memset (bucket, '\0',
1410 (symd->d_size / elsize + nbucket)
1411 * sizeof (Elf64_Xword));
1413 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1414 inner < symd->d_size / elsize; ++inner)
1417 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1418 assert (sym != NULL);
1420 const char *name = elf_strptr (elf, strshndx,
1422 assert (name != NULL);
1423 size_t hidx = elf_hash (name) % nbucket;
1425 if (bucket[hidx] == 0)
1426 bucket[hidx] = inner;
1429 hidx = bucket[hidx];
1431 while (chain[hidx] != 0)
1434 chain[hidx] = inner;
1439 else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
1441 /* If the symbol table changed we have to adjust the
1443 Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1445 /* We do not have to do anything if the symbol table was
1447 if (shdr_info[symtabidx].newsymidx == NULL)
1450 assert (shdr_info[cnt].idx > 0);
1452 /* The symbol version section in the new file. */
1453 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1455 /* The symbol table data. */
1456 Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1457 shdr_info[symtabidx].idx),
1459 assert (symd != NULL);
1461 /* The version symbol data. */
1462 Elf_Data *verd = elf_getdata (scn, NULL);
1463 assert (verd != NULL);
1465 /* The symbol version array. */
1466 GElf_Half *verstab = (GElf_Half *) verd->d_buf;
1468 /* New indices of the symbols. */
1469 Elf32_Word *newsymidx = shdr_info[symtabidx].newsymidx;
1471 /* Walk through the list and */
1472 size_t elsize = gelf_fsize (elf, verd->d_type, 1,
1474 for (size_t inner = 1; inner < verd->d_size / elsize; ++inner)
1475 if (newsymidx[inner] != 0)
1476 /* Overwriting the same array works since the
1477 reordering can only move entries to lower indices
1479 verstab[newsymidx[inner]] = verstab[inner];
1481 /* New size of the section. */
1483 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1484 shdr->sh_size = verd->d_size
1485 = gelf_fsize (newelf, verd->d_type,
1486 symd->d_size / gelf_fsize (elf, symd->d_type, 1,
1489 (void) gelf_update_shdr (scn, shdr);
1491 else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1493 /* Check whether the associated symbol table changed. */
1494 if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
1496 /* Yes the symbol table changed. Update the section
1497 header of the section group. */
1498 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1500 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1501 assert (shdr != NULL);
1503 size_t stabidx = shdr_info[cnt].old_sh_link;
1504 shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
1506 (void) gelf_update_shdr (scn, shdr);
1512 /* Now that we have done all adjustments to the data,
1513 we can actually write out the debug file. */
1514 if (debug_fname != NULL)
1517 Elf_Data debug_crc_data =
1519 .d_type = ELF_T_WORD,
1520 .d_buf = &debug_crc,
1521 .d_size = sizeof (debug_crc),
1522 .d_version = EV_CURRENT
1525 /* Finally write the file. */
1526 if (unlikely (elf_update (debugelf, ELF_C_WRITE)) == -1)
1528 error (0, 0, gettext ("while writing '%s': %s"),
1529 debug_fname, elf_errmsg (-1));
1534 /* Create the real output file. First rename, then change the
1536 if (rename (tmp_debug_fname, debug_fname) != 0
1537 || fchmod (debug_fd, mode) != 0)
1539 error (0, errno, gettext ("while creating '%s'"), debug_fname);
1544 /* The temporary file does not exist anymore. */
1545 tmp_debug_fname = NULL;
1547 /* Compute the checksum which we will add to the executable. */
1548 if (crc32_file (debug_fd, &debug_crc) != 0)
1551 gettext ("while computing checksum for debug information"));
1552 unlink (debug_fname);
1557 /* Store it in the debuglink section data. */
1558 if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
1559 &debug_crc_data, ehdr->e_ident[EI_DATA])
1560 != &debuglink_crc_data))
1561 INTERNAL_ERROR (fname);
1564 /* Finally finish the ELF header. Fill in the fields not handled by
1565 libelf from the old file. */
1566 newehdr = gelf_getehdr (newelf, &newehdr_mem);
1567 if (newehdr == NULL)
1568 INTERNAL_ERROR (fname);
1570 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1571 newehdr->e_type = ehdr->e_type;
1572 newehdr->e_machine = ehdr->e_machine;
1573 newehdr->e_version = ehdr->e_version;
1574 newehdr->e_entry = ehdr->e_entry;
1575 newehdr->e_flags = ehdr->e_flags;
1576 newehdr->e_phoff = ehdr->e_phoff;
1577 /* We need to position the section header table. */
1578 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
1579 newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
1580 + shdr_info[shdridx].shdr.sh_size + offsize - 1)
1581 & ~((GElf_Off) (offsize - 1)));
1582 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
1584 /* The new section header string table index. */
1585 if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
1586 newehdr->e_shstrndx = idx;
1589 /* The index does not fit in the ELF header field. */
1590 shdr_info[0].scn = elf_getscn (elf, 0);
1592 if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
1593 INTERNAL_ERROR (fname);
1595 shdr_info[0].shdr.sh_link = idx;
1596 (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
1598 newehdr->e_shstrndx = SHN_XINDEX;
1601 if (gelf_update_ehdr (newelf, newehdr) == 0)
1603 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
1604 fname, elf_errmsg (-1));
1608 /* We have everything from the old file. */
1609 if (elf_cntl (elf, ELF_C_FDDONE) != 0)
1611 error (0, 0, gettext ("%s: error while reading the file: %s"),
1612 fname, elf_errmsg (-1));
1616 /* The ELF library better follows our layout when this is not a
1617 relocatable object file. */
1618 elf_flagelf (newelf, ELF_C_SET,
1619 (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
1620 | (permissive ? ELF_F_PERMISSIVE : 0));
1622 /* Finally write the file. */
1623 if (elf_update (newelf, ELF_C_WRITE) == -1)
1625 error (0, 0, gettext ("while writing '%s': %s"),
1626 fname, elf_errmsg (-1));
1631 if (shdr_info != NULL)
1633 /* For some sections we might have created an table to map symbol
1635 if (any_symtab_changes)
1636 for (cnt = 1; cnt <= shdridx; ++cnt)
1637 free (shdr_info[cnt].newsymidx);
1639 /* Free the memory. */
1640 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
1644 /* Free other resources. */
1645 if (shstrtab_data != NULL)
1646 free (shstrtab_data->d_buf);
1648 ebl_strtabfree (shst);
1650 /* That was it. Close the descriptors. */
1651 if (elf_end (newelf) != 0)
1653 error (0, 0, gettext ("error while finishing '%s': %s"), fname,
1658 if (debugelf != NULL && elf_end (debugelf) != 0)
1660 error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
1666 /* Close the EBL backend. */
1668 ebl_closebackend (ebl);
1670 /* Close debug file descriptor, if opened */
1673 if (tmp_debug_fname != NULL)
1674 unlink (tmp_debug_fname);
1678 /* If requested, preserve the timestamp. */
1681 if (futimes (fd, tvp) != 0)
1683 error (0, errno, gettext ("\
1684 cannot set access and modification date of '%s'"),
1685 output_fname ?: fname);
1690 /* Close the file descriptor if we created a new file. */
1691 if (output_fname != NULL)
1699 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
1700 struct timeval tvp[2])
1702 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
1703 size_t fname_len = strlen (fname) + 1;
1704 char new_prefix[prefix_len + 1 + fname_len];
1705 char *cp = new_prefix;
1707 /* Create the full name of the file. */
1710 cp = mempcpy (cp, prefix, prefix_len);
1713 memcpy (cp, fname, fname_len);
1716 /* Process all the files contained in the archive. */
1718 Elf_Cmd cmd = ELF_C_RDWR;
1720 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
1722 /* The the header for this element. */
1723 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
1725 if (elf_kind (subelf) == ELF_K_ELF)
1726 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
1727 else if (elf_kind (subelf) == ELF_K_AR)
1728 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
1730 /* Get next archive element. */
1731 cmd = elf_next (subelf);
1732 if (unlikely (elf_end (subelf) != 0))
1733 INTERNAL_ERROR (fname);
1738 if (unlikely (futimes (fd, tvp) != 0))
1740 error (0, errno, gettext ("\
1741 cannot set access and modification date of '%s'"), fname);
1746 if (unlikely (close (fd) != 0))
1747 error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);