1 /* Discard section not used at runtime from object files.
2 Copyright (C) 2000-2008, 2009 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
6 Red Hat elfutils is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 2 of the License.
10 Red Hat elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with Red Hat elfutils; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
19 Red Hat elfutils is an included package of the Open Invention Network.
20 An included package of the Open Invention Network is a package for which
21 Open Invention Network licensees cross-license their patents. No patent
22 license is granted, either expressly or impliedly, by designation as an
23 included package. Should you wish to participate in the Open Invention
24 Network licensing program, please visit www.openinventionnetwork.com
25 <http://www.openinventionnetwork.com>. */
44 #include <stdio_ext.h>
48 #include <sys/param.h>
51 #include <elf-knowledge.h>
56 /* Name and version of program. */
57 static void print_version (FILE *stream, struct argp_state *state);
58 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
60 /* Bug report address. */
61 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
64 /* Values for the parameters which have no short form. */
65 #define OPT_REMOVE_COMMENT 0x100
66 #define OPT_PERMISSIVE 0x101
69 /* Definitions of arguments for argp functions. */
70 static const struct argp_option options[] =
72 { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
73 { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 },
74 { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 },
75 { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
77 { NULL, 0, NULL, 0, N_("Output options:"), 0 },
78 { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 },
79 { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
80 { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 },
81 { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 },
82 { "preserve-dates", 'p', NULL, 0,
83 N_("Copy modified/access timestamps to the output"), 0 },
84 { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
85 N_("Remove .comment section"), 0 },
86 { "remove-section", 'R', "SECTION", OPTION_HIDDEN, NULL, 0 },
87 { "permissive", OPT_PERMISSIVE, NULL, 0,
88 N_("Relax a few rules to handle slightly broken ELF files"), 0 },
89 { NULL, 0, NULL, 0, NULL, 0 }
92 /* Short description of program. */
93 static const char doc[] = N_("Discard symbols from object files.");
95 /* Strings for arguments in help texts. */
96 static const char args_doc[] = N_("[FILE...]");
98 /* Prototype for option handler. */
99 static error_t parse_opt (int key, char *arg, struct argp_state *state);
101 /* Data structure to communicate with argp functions. */
102 static struct argp argp =
104 options, parse_opt, args_doc, doc, NULL, NULL, NULL
108 /* Print symbols in file named FNAME. */
109 static int process_file (const char *fname);
111 /* Handle one ELF file. */
112 static int handle_elf (int fd, Elf *elf, const char *prefix,
113 const char *fname, mode_t mode, struct timeval tvp[2]);
115 /* Handle all files contained in the archive. */
116 static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
117 struct timeval tvp[2]);
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))
124 /* Name of the output file. */
125 static const char *output_fname;
127 /* Name of the debug output file. */
128 static const char *debug_fname;
130 /* Name to pretend the debug output file has. */
131 static const char *debug_fname_embed;
133 /* If true output files shall have same date as the input file. */
134 static bool preserve_dates;
136 /* If true .comment sections will be removed. */
137 static bool remove_comment;
139 /* If true remove all debug sections. */
140 static bool remove_debug;
142 /* If true relax some ELF rules for input files. */
143 static bool permissive;
147 main (int argc, char *argv[])
152 /* Make memory leak detection possible. */
155 /* We use no threads here which can interfere with handling a stream. */
156 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
157 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
158 __fsetlocking (stderr, FSETLOCKING_BYCALLER);
161 setlocale (LC_ALL, "");
163 /* Make sure the message catalog can be found. */
164 bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
166 /* Initialize the message catalog. */
167 textdomain (PACKAGE_TARNAME);
169 /* Parse and process arguments. */
170 if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
173 /* Tell the library which version we are expecting. */
174 elf_version (EV_CURRENT);
176 if (remaining == argc)
177 /* The user didn't specify a name so we use a.out. */
178 result = process_file ("a.out");
181 /* If we have seen the '-o' or '-f' option there must be exactly one
183 if ((output_fname != NULL || debug_fname != NULL)
184 && remaining + 1 < argc)
185 error (EXIT_FAILURE, 0, gettext ("\
186 Only one input file allowed together with '-o' and '-f'"));
188 /* Process all the remaining files. */
190 result |= process_file (argv[remaining]);
191 while (++remaining < argc);
198 /* Print the version information. */
200 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
202 fprintf (stream, "strip (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
203 fprintf (stream, gettext ("\
204 Copyright (C) %s Red Hat, Inc.\n\
205 This is free software; see the source for copying conditions. There is NO\n\
206 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
208 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
212 /* Handle program arguments. */
214 parse_opt (int key, char *arg, struct argp_state *state)
219 if (debug_fname != NULL)
221 error (0, 0, gettext ("-f option specified twice"));
228 if (debug_fname_embed != NULL)
230 error (0, 0, gettext ("-F option specified twice"));
233 debug_fname_embed = arg;
237 if (output_fname != NULL)
239 error (0, 0, gettext ("-o option specified twice"));
246 preserve_dates = true;
249 case OPT_REMOVE_COMMENT:
250 remove_comment = true;
254 if (!strcmp (arg, ".comment"))
255 remove_comment = true;
259 gettext ("-R option supports only .comment section"));
274 case 's': /* Ignored for compatibility. */
278 return ARGP_ERR_UNKNOWN;
285 process_file (const char *fname)
287 /* If we have to preserve the modify and access timestamps get them
288 now. We cannot use fstat() after opening the file since the open
289 would change the access time. */
290 struct stat64 pre_st;
291 struct timeval tv[2];
295 if (stat64 (fname, &pre_st) != 0)
297 error (0, errno, gettext ("cannot stat input file '%s'"), fname);
301 /* If we have to preserve the timestamp, we need it in the
302 format utimes() understands. */
303 TIMESPEC_TO_TIMEVAL (&tv[0], &pre_st.st_atim);
304 TIMESPEC_TO_TIMEVAL (&tv[1], &pre_st.st_mtim);
308 int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
311 error (0, errno, gettext ("while opening '%s'"), fname);
315 /* We always use fstat() even if we called stat() before. This is
316 done to make sure the information returned by stat() is for the
319 if (fstat64 (fd, &st) != 0)
321 error (0, errno, gettext ("cannot stat input file '%s'"), fname);
324 /* Paranoid mode on. */
326 && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
328 /* We detected a race. Try again. */
333 /* Now get the ELF descriptor. */
334 Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
337 switch (elf_kind (elf))
340 result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
341 preserve_dates ? tv : NULL);
345 /* It is not possible to strip the content of an archive direct
346 the output to a specific file. */
347 if (unlikely (output_fname != NULL || debug_fname != NULL))
349 error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"),
354 result = handle_ar (fd, elf, NULL, fname, preserve_dates ? tv : NULL);
358 error (0, 0, gettext ("%s: File format not recognized"), fname);
363 if (unlikely (elf_end (elf) != 0))
364 INTERNAL_ERROR (fname);
372 /* Maximum size of array allocated on stack. */
373 #define MAX_STACK_ALLOC (400 * 1024)
376 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
377 mode_t mode, struct timeval tvp[2])
379 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
380 size_t fname_len = strlen (fname) + 1;
381 char *fullname = alloca (prefix_len + 1 + fname_len);
383 Elf *debugelf = NULL;
384 char *tmp_debug_fname = NULL;
393 Elf_Data *debug_data;
395 Elf32_Word idx; /* Index in new file. */
396 Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */
397 Elf32_Word symtab_idx;
398 Elf32_Word version_idx;
399 Elf32_Word group_idx;
400 Elf32_Word group_cnt;
402 struct Ebl_Strent *se;
403 Elf32_Word *newsymidx;
409 GElf_Ehdr newehdr_mem;
411 GElf_Ehdr debugehdr_mem;
412 GElf_Ehdr *debugehdr;
413 struct Ebl_Strtab *shst = NULL;
414 Elf_Data debuglink_crc_data;
415 bool any_symtab_changes = false;
416 Elf_Data *shstrtab_data = NULL;
418 /* Create the full name of the file. */
421 cp = mempcpy (cp, prefix, prefix_len);
424 memcpy (cp, fname, fname_len);
426 /* If we are not replacing the input file open a new file here. */
427 if (output_fname != NULL)
429 fd = open (output_fname, O_RDWR | O_CREAT, mode);
430 if (unlikely (fd == -1))
432 error (0, errno, gettext ("cannot open '%s'"), output_fname);
439 /* Get the EBL handling. The -g option is currently the only reason
440 we need EBL so dont open the backend unless necessary. */
444 ebl = ebl_openbackend (elf);
447 error (0, errno, gettext ("cannot open EBL backend"));
453 /* Open the additional file the debug information will be stored in. */
454 if (debug_fname != NULL)
456 /* Create a temporary file name. We do not want to overwrite
457 the debug file if the file would not contain any
459 size_t debug_fname_len = strlen (debug_fname);
460 tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX"));
461 strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
464 debug_fd = mkstemp (tmp_debug_fname);
465 if (unlikely (debug_fd == -1))
467 error (0, errno, gettext ("cannot open '%s'"), debug_fname);
473 /* Get the information from the old file. */
475 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
477 INTERNAL_ERROR (fname);
479 /* Get the section header string table index. */
480 if (unlikely (elf_getshstrndx (elf, &shstrndx) < 0))
481 error (EXIT_FAILURE, 0,
482 gettext ("cannot get section header string table index"));
484 /* We now create a new ELF descriptor for the same file. We
485 construct it almost exactly in the same way with some information
488 if (output_fname != NULL)
489 newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
491 newelf = elf_clone (elf, ELF_C_EMPTY);
493 if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
494 || (ehdr->e_type != ET_REL
495 && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0)))
497 error (0, 0, gettext ("cannot create new file '%s': %s"),
498 output_fname, elf_errmsg (-1));
502 /* Copy over the old program header if needed. */
503 if (ehdr->e_type != ET_REL)
504 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
507 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
509 || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
510 INTERNAL_ERROR (fname);
513 if (debug_fname != NULL)
515 /* Also create an ELF descriptor for the debug file */
516 debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
517 if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
518 || (ehdr->e_type != ET_REL
519 && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0)))
521 error (0, 0, gettext ("cannot create new file '%s': %s"),
522 debug_fname, elf_errmsg (-1));
526 /* Copy over the old program header if needed. */
527 if (ehdr->e_type != ET_REL)
528 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
531 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
533 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
534 INTERNAL_ERROR (fname);
538 /* Number of sections. */
540 if (unlikely (elf_getshnum (elf, &shnum) < 0))
542 error (0, 0, gettext ("cannot determine number of sections: %s"),
547 /* Storage for section information. We leave room for two more
548 entries since we unconditionally create a section header string
549 table. Maybe some weird tool created an ELF file without one.
550 The other one is used for the debug link section. */
551 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
552 shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
553 sizeof (struct shdr_info));
556 shdr_info = (struct shdr_info *) alloca ((shnum + 2)
557 * sizeof (struct shdr_info));
558 memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
561 /* Prepare section information data structure. */
564 while ((scn = elf_nextscn (elf, scn)) != NULL)
566 /* This should always be true (i.e., there should not be any
567 holes in the numbering). */
568 assert (elf_ndxscn (scn) == cnt);
570 shdr_info[cnt].scn = scn;
572 /* Get the header. */
573 if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
574 INTERNAL_ERROR (fname);
576 /* Get the name of the section. */
577 shdr_info[cnt].name = elf_strptr (elf, shstrndx,
578 shdr_info[cnt].shdr.sh_name);
579 if (shdr_info[cnt].name == NULL)
581 error (0, 0, gettext ("illformed file '%s'"), fname);
585 /* Mark them as present but not yet investigated. */
586 shdr_info[cnt].idx = 1;
588 /* Remember the shdr.sh_link value. */
589 shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
591 /* Sections in files other than relocatable object files which
592 are not loaded can be freely moved by us. In relocatable
593 object files everything can be moved. */
594 if (ehdr->e_type == ET_REL
595 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
596 shdr_info[cnt].shdr.sh_offset = 0;
598 /* If this is an extended section index table store an
599 appropriate reference. */
600 if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
602 assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
603 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
605 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
607 /* Cross-reference the sections contained in the section
609 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
610 if (shdr_info[cnt].data == NULL)
611 INTERNAL_ERROR (fname);
613 /* XXX Fix for unaligned access. */
614 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
617 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
619 shdr_info[grpref[inner]].group_idx = cnt;
621 if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
622 /* If the section group contains only one element and this
623 is n COMDAT section we can drop it right away. */
624 shdr_info[cnt].idx = 0;
626 shdr_info[cnt].group_cnt = inner - 1;
628 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
630 assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
631 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
634 /* If this section is part of a group make sure it is not
635 discarded right away. */
636 if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
638 assert (shdr_info[cnt].group_idx != 0);
640 if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
642 /* The section group section will be removed. */
643 shdr_info[cnt].group_idx = 0;
644 shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP;
648 /* Increment the counter. */
652 /* Now determine which sections can go away. The general rule is that
653 all sections which are not used at runtime are stripped out. But
654 there are a few exceptions:
656 - special sections named ".comment" and ".note" are kept
657 - OS or architecture specific sections are kept since we might not
658 know how to handle them
659 - if a section is referred to from a section which is not removed
660 in the sh_link or sh_info element it cannot be removed either
662 for (cnt = 1; cnt < shnum; ++cnt)
663 /* Check whether the section can be removed. */
664 if (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr,
665 shdr_info[cnt].name, remove_comment,
668 /* For now assume this section will be removed. */
669 shdr_info[cnt].idx = 0;
671 idx = shdr_info[cnt].group_idx;
674 /* The section group data is already loaded. */
675 assert (shdr_info[idx].data != NULL);
677 /* If the references section group is a normal section
678 group and has one element remaining, or if it is an
679 empty COMDAT section group it is removed. */
680 bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
683 --shdr_info[idx].group_cnt;
684 if ((!is_comdat && shdr_info[idx].group_cnt == 1)
685 || (is_comdat && shdr_info[idx].group_cnt == 0))
687 shdr_info[idx].idx = 0;
688 /* Continue recursively. */
689 idx = shdr_info[idx].group_idx;
696 /* Mark the SHT_NULL section as handled. */
697 shdr_info[0].idx = 2;
700 /* Handle exceptions: section groups and cross-references. We might
701 have to repeat this a few times since the resetting of the flag
707 for (cnt = 1; cnt < shnum; ++cnt)
709 if (shdr_info[cnt].idx == 0)
711 /* If a relocation section is marked as being removed make
712 sure the section it is relocating is removed, too. */
713 if ((shdr_info[cnt].shdr.sh_type == SHT_REL
714 || shdr_info[cnt].shdr.sh_type == SHT_RELA)
715 && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
716 shdr_info[cnt].idx = 1;
719 if (shdr_info[cnt].idx == 1)
721 /* The content of symbol tables we don't remove must not
722 reference any section which we do remove. Otherwise
723 we cannot remove the section. */
724 if (debug_fname != NULL
725 && shdr_info[cnt].debug_data == NULL
726 && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
727 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB))
729 /* Make sure the data is loaded. */
730 if (shdr_info[cnt].data == NULL)
733 = elf_getdata (shdr_info[cnt].scn, NULL);
734 if (shdr_info[cnt].data == NULL)
735 INTERNAL_ERROR (fname);
737 Elf_Data *symdata = shdr_info[cnt].data;
739 /* If there is an extended section index table load it
741 if (shdr_info[cnt].symtab_idx != 0
742 && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
744 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
746 shdr_info[shdr_info[cnt].symtab_idx].data
747 = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
749 if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
750 INTERNAL_ERROR (fname);
753 = shdr_info[shdr_info[cnt].symtab_idx].data;
755 /* Go through all symbols and make sure the section they
756 reference is not removed. */
757 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
760 for (size_t inner = 0;
761 inner < shdr_info[cnt].data->d_size / elsize;
766 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
770 INTERNAL_ERROR (fname);
772 size_t scnidx = sym->st_shndx;
773 if (scnidx == SHN_UNDEF || scnidx >= shnum
774 || (scnidx >= SHN_LORESERVE
775 && scnidx <= SHN_HIRESERVE
776 && scnidx != SHN_XINDEX)
777 /* Don't count in the section symbols. */
778 || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
779 /* This is no section index, leave it alone. */
781 else if (scnidx == SHN_XINDEX)
784 if (shdr_info[scnidx].idx == 0)
785 /* This symbol table has a real symbol in
786 a discarded section. So preserve the
787 original table in the debug file. */
788 shdr_info[cnt].debug_data = symdata;
792 /* Cross referencing happens:
793 - for the cases the ELF specification says. That are
794 + SHT_DYNAMIC in sh_link to string table
795 + SHT_HASH in sh_link to symbol table
796 + SHT_REL and SHT_RELA in sh_link to symbol table
797 + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
798 + SHT_GROUP in sh_link to symbol table
799 + SHT_SYMTAB_SHNDX in sh_link to symbol table
800 Other (OS or architecture-specific) sections might as
801 well use this field so we process it unconditionally.
802 - references inside section groups
803 - specially marked references in sh_info if the SHF_INFO_LINK
807 if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
809 shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
810 changes |= shdr_info[cnt].shdr.sh_link < cnt;
813 /* Handle references through sh_info. */
814 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)
815 && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
817 shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
818 changes |= shdr_info[cnt].shdr.sh_info < cnt;
821 /* Mark the section as investigated. */
822 shdr_info[cnt].idx = 2;
825 if (debug_fname != NULL
826 && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL))
828 /* This section is being preserved in the debug file.
829 Sections it refers to must be preserved there too.
831 In this pass we mark sections to be preserved in both
832 files by setting the .debug_data pointer to the original
833 file's .data pointer. Below, we'll copy the section
836 inline void check_preserved (size_t i)
838 if (i != 0 && shdr_info[i].idx != 0)
840 if (shdr_info[i].data == NULL)
841 shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL);
842 if (shdr_info[i].data == NULL)
843 INTERNAL_ERROR (fname);
845 shdr_info[i].debug_data = shdr_info[i].data;
850 check_preserved (shdr_info[cnt].shdr.sh_link);
851 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
852 check_preserved (shdr_info[cnt].shdr.sh_info);
858 /* Copy the removed sections to the debug output file.
859 The ones that are not removed in the stripped file are SHT_NOBITS. */
860 if (debug_fname != NULL)
862 for (cnt = 1; cnt < shnum; ++cnt)
864 scn = elf_newscn (debugelf);
866 error (EXIT_FAILURE, 0,
867 gettext ("while generating output file: %s"),
870 bool discard_section = (shdr_info[cnt].idx > 0
871 && shdr_info[cnt].debug_data == NULL
872 && shdr_info[cnt].shdr.sh_type != SHT_NOTE
873 && cnt != ehdr->e_shstrndx);
875 /* Set the section header in the new file. */
876 GElf_Shdr debugshdr = shdr_info[cnt].shdr;
878 debugshdr.sh_type = SHT_NOBITS;
880 if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
881 /* There cannot be any overflows. */
882 INTERNAL_ERROR (fname);
884 /* Get the data from the old file if necessary. */
885 if (shdr_info[cnt].data == NULL)
887 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
888 if (shdr_info[cnt].data == NULL)
889 INTERNAL_ERROR (fname);
892 /* Set the data. This is done by copying from the old file. */
893 Elf_Data *debugdata = elf_newdata (scn);
894 if (debugdata == NULL)
895 INTERNAL_ERROR (fname);
897 /* Copy the structure. This data may be modified in place
898 before we write out the file. */
899 *debugdata = *shdr_info[cnt].data;
901 debugdata->d_buf = NULL;
902 else if (shdr_info[cnt].debug_data != NULL)
904 /* Copy the original data before it gets modified. */
905 shdr_info[cnt].debug_data = debugdata;
906 debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
907 debugdata->d_buf, debugdata->d_size);
911 /* Finish the ELF header. Fill in the fields not handled by
912 libelf from the old file. */
913 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
914 if (debugehdr == NULL)
915 INTERNAL_ERROR (fname);
917 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
918 debugehdr->e_type = ehdr->e_type;
919 debugehdr->e_machine = ehdr->e_machine;
920 debugehdr->e_version = ehdr->e_version;
921 debugehdr->e_entry = ehdr->e_entry;
922 debugehdr->e_flags = ehdr->e_flags;
923 debugehdr->e_shstrndx = ehdr->e_shstrndx;
925 if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
927 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
928 debug_fname, elf_errmsg (-1));
934 /* Mark the section header string table as unused, we will create
936 shdr_info[shstrndx].idx = 0;
938 /* We need a string table for the section headers. */
939 shst = ebl_strtabinit (true);
941 error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
942 output_fname ?: fname);
944 /* Assign new section numbers. */
945 shdr_info[0].idx = 0;
946 for (cnt = idx = 1; cnt < shnum; ++cnt)
947 if (shdr_info[cnt].idx > 0)
949 shdr_info[cnt].idx = idx++;
951 /* Create a new section. */
952 shdr_info[cnt].newscn = elf_newscn (newelf);
953 if (shdr_info[cnt].newscn == NULL)
954 error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
957 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
959 /* Add this name to the section header string table. */
960 shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
963 /* Test whether we are doing anything at all. */
965 /* Nope, all removable sections are already gone. */
968 /* Create the reference to the file with the debug info. */
969 if (debug_fname != NULL)
971 /* Add the section header string table section name. */
972 shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
973 shdr_info[cnt].idx = idx++;
975 /* Create the section header. */
976 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
977 shdr_info[cnt].shdr.sh_flags = 0;
978 shdr_info[cnt].shdr.sh_addr = 0;
979 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
980 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
981 shdr_info[cnt].shdr.sh_entsize = 0;
982 shdr_info[cnt].shdr.sh_addralign = 4;
983 /* We set the offset to zero here. Before we write the ELF file the
984 field must have the correct value. This is done in the final
985 loop over all section. Then we have all the information needed. */
986 shdr_info[cnt].shdr.sh_offset = 0;
988 /* Create the section. */
989 shdr_info[cnt].newscn = elf_newscn (newelf);
990 if (shdr_info[cnt].newscn == NULL)
991 error (EXIT_FAILURE, 0,
992 gettext ("while create section header section: %s"),
994 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
996 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
997 if (shdr_info[cnt].data == NULL)
998 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
1001 char *debug_basename = basename (debug_fname_embed ?: debug_fname);
1002 off_t crc_offset = strlen (debug_basename) + 1;
1003 /* Align to 4 byte boundary */
1004 crc_offset = ((crc_offset - 1) & ~3) + 4;
1006 shdr_info[cnt].data->d_align = 4;
1007 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
1009 shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size);
1011 strcpy (shdr_info[cnt].data->d_buf, debug_basename);
1013 /* Cache this Elf_Data describing the CRC32 word in the section.
1014 We'll fill this in when we have written the debug file. */
1015 debuglink_crc_data = *shdr_info[cnt].data;
1016 debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
1018 debuglink_crc_data.d_size = 4;
1020 /* One more section done. */
1024 /* Index of the section header table in the shdr_info array. */
1027 /* Add the section header string table section name. */
1028 shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
1029 shdr_info[cnt].idx = idx;
1031 /* Create the section header. */
1032 shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
1033 shdr_info[cnt].shdr.sh_flags = 0;
1034 shdr_info[cnt].shdr.sh_addr = 0;
1035 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1036 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1037 shdr_info[cnt].shdr.sh_entsize = 0;
1038 /* We set the offset to zero here. Before we write the ELF file the
1039 field must have the correct value. This is done in the final
1040 loop over all section. Then we have all the information needed. */
1041 shdr_info[cnt].shdr.sh_offset = 0;
1042 shdr_info[cnt].shdr.sh_addralign = 1;
1044 /* Create the section. */
1045 shdr_info[cnt].newscn = elf_newscn (newelf);
1046 if (shdr_info[cnt].newscn == NULL)
1047 error (EXIT_FAILURE, 0,
1048 gettext ("while create section header section: %s"),
1050 assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1052 /* Finalize the string table and fill in the correct indices in the
1054 shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1055 if (shstrtab_data == NULL)
1056 error (EXIT_FAILURE, 0,
1057 gettext ("while create section header string table: %s"),
1059 ebl_strtabfinalize (shst, shstrtab_data);
1061 /* We have to set the section size. */
1062 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1064 /* Update the section information. */
1065 GElf_Off lastoffset = 0;
1066 for (cnt = 1; cnt <= shdridx; ++cnt)
1067 if (shdr_info[cnt].idx > 0)
1071 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1072 assert (scn != NULL);
1074 /* Update the name. */
1075 shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
1077 /* Update the section header from the input file. Some fields
1078 might be section indeces which now have to be adjusted. */
1079 if (shdr_info[cnt].shdr.sh_link != 0)
1080 shdr_info[cnt].shdr.sh_link =
1081 shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1083 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1085 assert (shdr_info[cnt].data != NULL);
1087 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1088 for (size_t inner = 0;
1089 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1091 grpref[inner] = shdr_info[grpref[inner]].idx;
1094 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */
1095 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1096 shdr_info[cnt].shdr.sh_info =
1097 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1099 /* Get the data from the old file if necessary. We already
1100 created the data for the section header string table. */
1103 if (shdr_info[cnt].data == NULL)
1105 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1106 if (shdr_info[cnt].data == NULL)
1107 INTERNAL_ERROR (fname);
1110 /* Set the data. This is done by copying from the old file. */
1111 newdata = elf_newdata (scn);
1112 if (newdata == NULL)
1113 INTERNAL_ERROR (fname);
1115 /* Copy the structure. */
1116 *newdata = *shdr_info[cnt].data;
1118 /* We know the size. */
1119 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1121 /* We have to adjust symbol tables. The st_shndx member might
1122 have to be updated. */
1123 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1124 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1126 Elf_Data *versiondata = NULL;
1127 Elf_Data *shndxdata = NULL;
1129 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1132 if (shdr_info[cnt].symtab_idx != 0)
1134 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1135 /* This section has extended section information.
1136 We have to modify that information, too. */
1137 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1140 assert ((versiondata->d_size / sizeof (Elf32_Word))
1141 >= shdr_info[cnt].data->d_size / elsize);
1144 if (shdr_info[cnt].version_idx != 0)
1146 assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1147 /* This section has associated version
1148 information. We have to modify that
1149 information, too. */
1150 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1153 assert ((versiondata->d_size / sizeof (GElf_Versym))
1154 >= shdr_info[cnt].data->d_size / elsize);
1157 shdr_info[cnt].newsymidx
1158 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1159 / elsize, sizeof (Elf32_Word));
1161 bool last_was_local = true;
1164 for (destidx = inner = 1;
1165 inner < shdr_info[cnt].data->d_size / elsize;
1171 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1175 INTERNAL_ERROR (fname);
1177 if (sym->st_shndx == SHN_UNDEF
1178 || (sym->st_shndx >= shnum
1179 && sym->st_shndx != SHN_XINDEX))
1181 /* This is no section index, leave it alone
1182 unless it is moved. */
1183 if (destidx != inner
1184 && gelf_update_symshndx (shdr_info[cnt].data,
1188 INTERNAL_ERROR (fname);
1190 shdr_info[cnt].newsymidx[inner] = destidx++;
1193 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1195 last_was_local = false;
1196 shdr_info[cnt].shdr.sh_info = destidx - 1;
1202 /* Get the full section index, if necessary from the
1204 if (sym->st_shndx != SHN_XINDEX)
1205 sec = shdr_info[sym->st_shndx].idx;
1208 assert (shndxdata != NULL);
1210 sec = shdr_info[xshndx].idx;
1215 GElf_Section nshndx;
1218 if (sec < SHN_LORESERVE)
1225 nshndx = SHN_XINDEX;
1229 assert (sec < SHN_LORESERVE || shndxdata != NULL);
1231 if ((inner != destidx || nshndx != sym->st_shndx
1232 || (shndxdata != NULL && nxshndx != xshndx))
1233 && (sym->st_shndx = nshndx,
1234 gelf_update_symshndx (shdr_info[cnt].data,
1238 INTERNAL_ERROR (fname);
1240 shdr_info[cnt].newsymidx[inner] = destidx++;
1243 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1245 last_was_local = false;
1246 shdr_info[cnt].shdr.sh_info = destidx - 1;
1249 else if (debug_fname == NULL
1250 || shdr_info[cnt].debug_data == NULL)
1251 /* This is a section symbol for a section which has
1253 assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
1256 if (destidx != inner)
1258 /* The size of the symbol table changed. */
1259 shdr_info[cnt].shdr.sh_size = newdata->d_size
1261 any_symtab_changes = true;
1265 /* The symbol table didn't really change. */
1266 free (shdr_info[cnt].newsymidx);
1267 shdr_info[cnt].newsymidx = NULL;
1272 /* If we have to, compute the offset of the section. */
1273 if (shdr_info[cnt].shdr.sh_offset == 0)
1274 shdr_info[cnt].shdr.sh_offset
1275 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1276 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1278 /* Set the section header in the new file. */
1279 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1280 /* There cannot be any overflows. */
1281 INTERNAL_ERROR (fname);
1283 /* Remember the last section written so far. */
1284 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1285 ? shdr_info[cnt].shdr.sh_size : 0);
1286 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1287 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1290 /* Adjust symbol references if symbol tables changed. */
1291 if (any_symtab_changes)
1292 /* Find all relocation sections which use this symbol table. */
1293 for (cnt = 1; cnt <= shdridx; ++cnt)
1295 /* Update section headers when the data size has changed.
1296 We also update the SHT_NOBITS section in the debug
1297 file so that the section headers match in sh_size. */
1298 inline void update_section_size (const Elf_Data *newdata)
1301 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1302 shdr->sh_size = newdata->d_size;
1303 (void) gelf_update_shdr (scn, shdr);
1304 if (debugelf != NULL)
1306 /* libelf will use d_size to set sh_size. */
1307 Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
1309 debugdata->d_size = newdata->d_size;
1313 if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
1314 /* Ignore sections which are discarded. When we are saving a
1315 relocation section in a separate debug file, we must fix up
1316 the symbol table references. */
1319 const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1320 const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
1321 switch (shdr_info[cnt].shdr.sh_type)
1323 inline bool no_symtab_updates (void)
1325 /* If the symbol table hasn't changed, do not do anything. */
1326 if (shdr_info[symtabidx].newsymidx == NULL)
1329 /* If the symbol table is not discarded, but additionally
1330 duplicated in the separate debug file and this section
1331 is discarded, don't adjust anything. */
1332 return (shdr_info[cnt].idx == 0
1333 && shdr_info[symtabidx].debug_data != NULL);
1338 if (no_symtab_updates ())
1341 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
1342 ? elf_getscn (debugelf, cnt)
1343 : elf_getscn (newelf,
1344 shdr_info[cnt].idx),
1347 size_t nrels = (shdr_info[cnt].shdr.sh_size
1348 / shdr_info[cnt].shdr.sh_entsize);
1350 if (shdr_info[cnt].shdr.sh_type == SHT_REL)
1351 for (size_t relidx = 0; relidx < nrels; ++relidx)
1354 if (gelf_getrel (d, relidx, &rel_mem) == NULL)
1355 INTERNAL_ERROR (fname);
1357 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1358 if (newsymidx[symidx] != symidx)
1361 = GELF_R_INFO (newsymidx[symidx],
1362 GELF_R_TYPE (rel_mem.r_info));
1364 if (gelf_update_rel (d, relidx, &rel_mem) == 0)
1365 INTERNAL_ERROR (fname);
1369 for (size_t relidx = 0; relidx < nrels; ++relidx)
1372 if (gelf_getrela (d, relidx, &rel_mem) == NULL)
1373 INTERNAL_ERROR (fname);
1375 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1376 if (newsymidx[symidx] != symidx)
1379 = GELF_R_INFO (newsymidx[symidx],
1380 GELF_R_TYPE (rel_mem.r_info));
1382 if (gelf_update_rela (d, relidx, &rel_mem) == 0)
1383 INTERNAL_ERROR (fname);
1389 if (no_symtab_updates ())
1392 /* We have to recompute the hash table. */
1394 assert (shdr_info[cnt].idx > 0);
1396 /* The hash section in the new file. */
1397 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1399 /* The symbol table data. */
1400 Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1401 shdr_info[symtabidx].idx),
1403 assert (symd != NULL);
1405 /* The hash table data. */
1406 Elf_Data *hashd = elf_getdata (scn, NULL);
1407 assert (hashd != NULL);
1409 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
1411 /* Sane arches first. */
1412 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
1414 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1415 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1418 /* Adjust the nchain value. The symbol table size
1419 changed. We keep the same size for the bucket array. */
1420 bucket[1] = symd->d_size / elsize;
1421 Elf32_Word nbucket = bucket[0];
1423 Elf32_Word *chain = bucket + nbucket;
1425 /* New size of the section. */
1426 hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
1427 * sizeof (Elf32_Word));
1428 update_section_size (hashd);
1430 /* Clear the arrays. */
1431 memset (bucket, '\0',
1432 (symd->d_size / elsize + nbucket)
1433 * sizeof (Elf32_Word));
1435 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1436 inner < symd->d_size / elsize; ++inner)
1439 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1440 assert (sym != NULL);
1442 const char *name = elf_strptr (elf, strshndx,
1444 assert (name != NULL);
1445 size_t hidx = elf_hash (name) % nbucket;
1447 if (bucket[hidx] == 0)
1448 bucket[hidx] = inner;
1451 hidx = bucket[hidx];
1453 while (chain[hidx] != 0)
1456 chain[hidx] = inner;
1462 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
1463 assert (shdr_info[cnt].shdr.sh_entsize
1464 == sizeof (Elf64_Xword));
1466 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
1468 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1469 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1472 /* Adjust the nchain value. The symbol table size
1473 changed. We keep the same size for the bucket array. */
1474 bucket[1] = symd->d_size / elsize;
1475 Elf64_Xword nbucket = bucket[0];
1477 Elf64_Xword *chain = bucket + nbucket;
1479 /* New size of the section. */
1480 hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
1481 * sizeof (Elf64_Xword));
1482 update_section_size (hashd);
1484 /* Clear the arrays. */
1485 memset (bucket, '\0',
1486 (symd->d_size / elsize + nbucket)
1487 * sizeof (Elf64_Xword));
1489 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1490 inner < symd->d_size / elsize; ++inner)
1493 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1494 assert (sym != NULL);
1496 const char *name = elf_strptr (elf, strshndx,
1498 assert (name != NULL);
1499 size_t hidx = elf_hash (name) % nbucket;
1501 if (bucket[hidx] == 0)
1502 bucket[hidx] = inner;
1505 hidx = bucket[hidx];
1507 while (chain[hidx] != 0)
1510 chain[hidx] = inner;
1516 case SHT_GNU_versym:
1517 /* If the symbol table changed we have to adjust the entries. */
1518 if (no_symtab_updates ())
1521 assert (shdr_info[cnt].idx > 0);
1523 /* The symbol version section in the new file. */
1524 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1526 /* The symbol table data. */
1527 symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
1529 assert (symd != NULL);
1531 /* The version symbol data. */
1532 Elf_Data *verd = elf_getdata (scn, NULL);
1533 assert (verd != NULL);
1535 /* The symbol version array. */
1536 GElf_Half *verstab = (GElf_Half *) verd->d_buf;
1538 /* Walk through the list and */
1539 size_t elsize = gelf_fsize (elf, verd->d_type, 1,
1541 for (size_t inner = 1; inner < verd->d_size / elsize; ++inner)
1542 if (newsymidx[inner] != 0)
1543 /* Overwriting the same array works since the
1544 reordering can only move entries to lower indices
1546 verstab[newsymidx[inner]] = verstab[inner];
1548 /* New size of the section. */
1549 verd->d_size = gelf_fsize (newelf, verd->d_type,
1551 / gelf_fsize (elf, symd->d_type, 1,
1554 update_section_size (verd);
1558 if (no_symtab_updates ())
1561 /* Yes, the symbol table changed.
1562 Update the section header of the section group. */
1563 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1565 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1566 assert (shdr != NULL);
1568 shdr->sh_info = newsymidx[shdr->sh_info];
1570 (void) gelf_update_shdr (scn, shdr);
1575 /* Now that we have done all adjustments to the data,
1576 we can actually write out the debug file. */
1577 if (debug_fname != NULL)
1580 Elf_Data debug_crc_data =
1582 .d_type = ELF_T_WORD,
1583 .d_buf = &debug_crc,
1584 .d_size = sizeof (debug_crc),
1585 .d_version = EV_CURRENT
1588 /* Finally write the file. */
1589 if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
1591 error (0, 0, gettext ("while writing '%s': %s"),
1592 debug_fname, elf_errmsg (-1));
1597 /* Create the real output file. First rename, then change the
1599 if (rename (tmp_debug_fname, debug_fname) != 0
1600 || fchmod (debug_fd, mode) != 0)
1602 error (0, errno, gettext ("while creating '%s'"), debug_fname);
1607 /* The temporary file does not exist anymore. */
1608 tmp_debug_fname = NULL;
1610 /* Compute the checksum which we will add to the executable. */
1611 if (crc32_file (debug_fd, &debug_crc) != 0)
1614 gettext ("while computing checksum for debug information"));
1615 unlink (debug_fname);
1620 /* Store it in the debuglink section data. */
1621 if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
1622 &debug_crc_data, ehdr->e_ident[EI_DATA])
1623 != &debuglink_crc_data))
1624 INTERNAL_ERROR (fname);
1627 /* Finally finish the ELF header. Fill in the fields not handled by
1628 libelf from the old file. */
1629 newehdr = gelf_getehdr (newelf, &newehdr_mem);
1630 if (newehdr == NULL)
1631 INTERNAL_ERROR (fname);
1633 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1634 newehdr->e_type = ehdr->e_type;
1635 newehdr->e_machine = ehdr->e_machine;
1636 newehdr->e_version = ehdr->e_version;
1637 newehdr->e_entry = ehdr->e_entry;
1638 newehdr->e_flags = ehdr->e_flags;
1639 newehdr->e_phoff = ehdr->e_phoff;
1640 /* We need to position the section header table. */
1641 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
1642 newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
1643 + shdr_info[shdridx].shdr.sh_size + offsize - 1)
1644 & ~((GElf_Off) (offsize - 1)));
1645 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
1647 /* The new section header string table index. */
1648 if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
1649 newehdr->e_shstrndx = idx;
1652 /* The index does not fit in the ELF header field. */
1653 shdr_info[0].scn = elf_getscn (elf, 0);
1655 if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
1656 INTERNAL_ERROR (fname);
1658 shdr_info[0].shdr.sh_link = idx;
1659 (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
1661 newehdr->e_shstrndx = SHN_XINDEX;
1664 if (gelf_update_ehdr (newelf, newehdr) == 0)
1666 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
1667 fname, elf_errmsg (-1));
1671 /* We have everything from the old file. */
1672 if (elf_cntl (elf, ELF_C_FDDONE) != 0)
1674 error (0, 0, gettext ("%s: error while reading the file: %s"),
1675 fname, elf_errmsg (-1));
1679 /* The ELF library better follows our layout when this is not a
1680 relocatable object file. */
1681 elf_flagelf (newelf, ELF_C_SET,
1682 (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
1683 | (permissive ? ELF_F_PERMISSIVE : 0));
1685 /* Finally write the file. */
1686 if (elf_update (newelf, ELF_C_WRITE) == -1)
1688 error (0, 0, gettext ("while writing '%s': %s"),
1689 fname, elf_errmsg (-1));
1694 if (shdr_info != NULL)
1696 /* For some sections we might have created an table to map symbol
1698 if (any_symtab_changes)
1699 for (cnt = 1; cnt <= shdridx; ++cnt)
1701 free (shdr_info[cnt].newsymidx);
1702 if (shdr_info[cnt].debug_data != NULL)
1703 free (shdr_info[cnt].debug_data->d_buf);
1706 /* Free the memory. */
1707 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
1711 /* Free other resources. */
1712 if (shstrtab_data != NULL)
1713 free (shstrtab_data->d_buf);
1715 ebl_strtabfree (shst);
1717 /* That was it. Close the descriptors. */
1718 if (elf_end (newelf) != 0)
1720 error (0, 0, gettext ("error while finishing '%s': %s"), fname,
1725 if (debugelf != NULL && elf_end (debugelf) != 0)
1727 error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
1733 /* Close the EBL backend. */
1735 ebl_closebackend (ebl);
1737 /* Close debug file descriptor, if opened */
1740 if (tmp_debug_fname != NULL)
1741 unlink (tmp_debug_fname);
1745 /* If requested, preserve the timestamp. */
1748 if (futimes (fd, tvp) != 0)
1750 error (0, errno, gettext ("\
1751 cannot set access and modification date of '%s'"),
1752 output_fname ?: fname);
1757 /* Close the file descriptor if we created a new file. */
1758 if (output_fname != NULL)
1766 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
1767 struct timeval tvp[2])
1769 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
1770 size_t fname_len = strlen (fname) + 1;
1771 char new_prefix[prefix_len + 1 + fname_len];
1772 char *cp = new_prefix;
1774 /* Create the full name of the file. */
1777 cp = mempcpy (cp, prefix, prefix_len);
1780 memcpy (cp, fname, fname_len);
1783 /* Process all the files contained in the archive. */
1785 Elf_Cmd cmd = ELF_C_RDWR;
1787 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
1789 /* The the header for this element. */
1790 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
1792 if (elf_kind (subelf) == ELF_K_ELF)
1793 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
1794 else if (elf_kind (subelf) == ELF_K_AR)
1795 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
1797 /* Get next archive element. */
1798 cmd = elf_next (subelf);
1799 if (unlikely (elf_end (subelf) != 0))
1800 INTERNAL_ERROR (fname);
1805 if (unlikely (futimes (fd, tvp) != 0))
1807 error (0, errno, gettext ("\
1808 cannot set access and modification date of '%s'"), fname);
1813 if (unlikely (close (fd) != 0))
1814 error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
1820 #include "debugpred.h"