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 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
60 /* Bug report address. */
61 ARGP_PROGRAM_BUG_ADDRESS_DEF = 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 don't 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
839 && shdr_info[i].debug_data == NULL)
841 if (shdr_info[i].data == NULL)
842 shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL);
843 if (shdr_info[i].data == NULL)
844 INTERNAL_ERROR (fname);
846 shdr_info[i].debug_data = shdr_info[i].data;
851 check_preserved (shdr_info[cnt].shdr.sh_link);
852 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
853 check_preserved (shdr_info[cnt].shdr.sh_info);
859 /* Copy the removed sections to the debug output file.
860 The ones that are not removed in the stripped file are SHT_NOBITS. */
861 if (debug_fname != NULL)
863 for (cnt = 1; cnt < shnum; ++cnt)
865 scn = elf_newscn (debugelf);
867 error (EXIT_FAILURE, 0,
868 gettext ("while generating output file: %s"),
871 bool discard_section = (shdr_info[cnt].idx > 0
872 && shdr_info[cnt].debug_data == NULL
873 && shdr_info[cnt].shdr.sh_type != SHT_NOTE
874 && cnt != ehdr->e_shstrndx);
876 /* Set the section header in the new file. */
877 GElf_Shdr debugshdr = shdr_info[cnt].shdr;
879 debugshdr.sh_type = SHT_NOBITS;
881 if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
882 /* There cannot be any overflows. */
883 INTERNAL_ERROR (fname);
885 /* Get the data from the old file if necessary. */
886 if (shdr_info[cnt].data == NULL)
888 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
889 if (shdr_info[cnt].data == NULL)
890 INTERNAL_ERROR (fname);
893 /* Set the data. This is done by copying from the old file. */
894 Elf_Data *debugdata = elf_newdata (scn);
895 if (debugdata == NULL)
896 INTERNAL_ERROR (fname);
898 /* Copy the structure. This data may be modified in place
899 before we write out the file. */
900 *debugdata = *shdr_info[cnt].data;
902 debugdata->d_buf = NULL;
903 else if (shdr_info[cnt].debug_data != NULL)
905 /* Copy the original data before it gets modified. */
906 shdr_info[cnt].debug_data = debugdata;
907 debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
908 debugdata->d_buf, debugdata->d_size);
912 /* Finish the ELF header. Fill in the fields not handled by
913 libelf from the old file. */
914 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
915 if (debugehdr == NULL)
916 INTERNAL_ERROR (fname);
918 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
919 debugehdr->e_type = ehdr->e_type;
920 debugehdr->e_machine = ehdr->e_machine;
921 debugehdr->e_version = ehdr->e_version;
922 debugehdr->e_entry = ehdr->e_entry;
923 debugehdr->e_flags = ehdr->e_flags;
924 debugehdr->e_shstrndx = ehdr->e_shstrndx;
926 if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
928 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
929 debug_fname, elf_errmsg (-1));
935 /* Mark the section header string table as unused, we will create
937 shdr_info[shstrndx].idx = 0;
939 /* We need a string table for the section headers. */
940 shst = ebl_strtabinit (true);
942 error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
943 output_fname ?: fname);
945 /* Assign new section numbers. */
946 shdr_info[0].idx = 0;
947 for (cnt = idx = 1; cnt < shnum; ++cnt)
948 if (shdr_info[cnt].idx > 0)
950 shdr_info[cnt].idx = idx++;
952 /* Create a new section. */
953 shdr_info[cnt].newscn = elf_newscn (newelf);
954 if (shdr_info[cnt].newscn == NULL)
955 error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
958 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
960 /* Add this name to the section header string table. */
961 shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
964 /* Test whether we are doing anything at all. */
966 /* Nope, all removable sections are already gone. */
969 /* Create the reference to the file with the debug info. */
970 if (debug_fname != NULL)
972 /* Add the section header string table section name. */
973 shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
974 shdr_info[cnt].idx = idx++;
976 /* Create the section header. */
977 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
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 shdr_info[cnt].shdr.sh_addralign = 4;
984 /* We set the offset to zero here. Before we write the ELF file the
985 field must have the correct value. This is done in the final
986 loop over all section. Then we have all the information needed. */
987 shdr_info[cnt].shdr.sh_offset = 0;
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) == shdr_info[cnt].idx);
997 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
998 if (shdr_info[cnt].data == NULL)
999 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
1002 char *debug_basename = basename (debug_fname_embed ?: debug_fname);
1003 off_t crc_offset = strlen (debug_basename) + 1;
1004 /* Align to 4 byte boundary */
1005 crc_offset = ((crc_offset - 1) & ~3) + 4;
1007 shdr_info[cnt].data->d_align = 4;
1008 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
1010 shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size);
1012 strcpy (shdr_info[cnt].data->d_buf, debug_basename);
1014 /* Cache this Elf_Data describing the CRC32 word in the section.
1015 We'll fill this in when we have written the debug file. */
1016 debuglink_crc_data = *shdr_info[cnt].data;
1017 debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
1019 debuglink_crc_data.d_size = 4;
1021 /* One more section done. */
1025 /* Index of the section header table in the shdr_info array. */
1028 /* Add the section header string table section name. */
1029 shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
1030 shdr_info[cnt].idx = idx;
1032 /* Create the section header. */
1033 shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
1034 shdr_info[cnt].shdr.sh_flags = 0;
1035 shdr_info[cnt].shdr.sh_addr = 0;
1036 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1037 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1038 shdr_info[cnt].shdr.sh_entsize = 0;
1039 /* We set the offset to zero here. Before we write the ELF file the
1040 field must have the correct value. This is done in the final
1041 loop over all section. Then we have all the information needed. */
1042 shdr_info[cnt].shdr.sh_offset = 0;
1043 shdr_info[cnt].shdr.sh_addralign = 1;
1045 /* Create the section. */
1046 shdr_info[cnt].newscn = elf_newscn (newelf);
1047 if (shdr_info[cnt].newscn == NULL)
1048 error (EXIT_FAILURE, 0,
1049 gettext ("while create section header section: %s"),
1051 assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1053 /* Finalize the string table and fill in the correct indices in the
1055 shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1056 if (shstrtab_data == NULL)
1057 error (EXIT_FAILURE, 0,
1058 gettext ("while create section header string table: %s"),
1060 ebl_strtabfinalize (shst, shstrtab_data);
1062 /* We have to set the section size. */
1063 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1065 /* Update the section information. */
1066 GElf_Off lastoffset = 0;
1067 for (cnt = 1; cnt <= shdridx; ++cnt)
1068 if (shdr_info[cnt].idx > 0)
1072 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1073 assert (scn != NULL);
1075 /* Update the name. */
1076 shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
1078 /* Update the section header from the input file. Some fields
1079 might be section indeces which now have to be adjusted. */
1080 if (shdr_info[cnt].shdr.sh_link != 0)
1081 shdr_info[cnt].shdr.sh_link =
1082 shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1084 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1086 assert (shdr_info[cnt].data != NULL);
1088 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1089 for (size_t inner = 0;
1090 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1092 grpref[inner] = shdr_info[grpref[inner]].idx;
1095 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */
1096 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1097 shdr_info[cnt].shdr.sh_info =
1098 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1100 /* Get the data from the old file if necessary. We already
1101 created the data for the section header string table. */
1104 if (shdr_info[cnt].data == NULL)
1106 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1107 if (shdr_info[cnt].data == NULL)
1108 INTERNAL_ERROR (fname);
1111 /* Set the data. This is done by copying from the old file. */
1112 newdata = elf_newdata (scn);
1113 if (newdata == NULL)
1114 INTERNAL_ERROR (fname);
1116 /* Copy the structure. */
1117 *newdata = *shdr_info[cnt].data;
1119 /* We know the size. */
1120 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1122 /* We have to adjust symbol tables. The st_shndx member might
1123 have to be updated. */
1124 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1125 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1127 Elf_Data *versiondata = NULL;
1128 Elf_Data *shndxdata = NULL;
1130 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1133 if (shdr_info[cnt].symtab_idx != 0)
1135 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1136 /* This section has extended section information.
1137 We have to modify that information, too. */
1138 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1141 assert ((versiondata->d_size / sizeof (Elf32_Word))
1142 >= shdr_info[cnt].data->d_size / elsize);
1145 if (shdr_info[cnt].version_idx != 0)
1147 assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1148 /* This section has associated version
1149 information. We have to modify that
1150 information, too. */
1151 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1154 assert ((versiondata->d_size / sizeof (GElf_Versym))
1155 >= shdr_info[cnt].data->d_size / elsize);
1158 shdr_info[cnt].newsymidx
1159 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1160 / elsize, sizeof (Elf32_Word));
1162 bool last_was_local = true;
1165 for (destidx = inner = 1;
1166 inner < shdr_info[cnt].data->d_size / elsize;
1172 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1176 INTERNAL_ERROR (fname);
1178 if (sym->st_shndx == SHN_UNDEF
1179 || (sym->st_shndx >= shnum
1180 && sym->st_shndx != SHN_XINDEX))
1182 /* This is no section index, leave it alone
1183 unless it is moved. */
1184 if (destidx != inner
1185 && gelf_update_symshndx (shdr_info[cnt].data,
1189 INTERNAL_ERROR (fname);
1191 shdr_info[cnt].newsymidx[inner] = destidx++;
1194 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1196 last_was_local = false;
1197 shdr_info[cnt].shdr.sh_info = destidx - 1;
1203 /* Get the full section index, if necessary from the
1205 if (sym->st_shndx != SHN_XINDEX)
1206 sec = shdr_info[sym->st_shndx].idx;
1209 assert (shndxdata != NULL);
1211 sec = shdr_info[xshndx].idx;
1216 GElf_Section nshndx;
1219 if (sec < SHN_LORESERVE)
1226 nshndx = SHN_XINDEX;
1230 assert (sec < SHN_LORESERVE || shndxdata != NULL);
1232 if ((inner != destidx || nshndx != sym->st_shndx
1233 || (shndxdata != NULL && nxshndx != xshndx))
1234 && (sym->st_shndx = nshndx,
1235 gelf_update_symshndx (shdr_info[cnt].data,
1239 INTERNAL_ERROR (fname);
1241 shdr_info[cnt].newsymidx[inner] = destidx++;
1244 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1246 last_was_local = false;
1247 shdr_info[cnt].shdr.sh_info = destidx - 1;
1250 else if (debug_fname == NULL
1251 || shdr_info[cnt].debug_data == NULL)
1252 /* This is a section symbol for a section which has
1254 assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
1257 if (destidx != inner)
1259 /* The size of the symbol table changed. */
1260 shdr_info[cnt].shdr.sh_size = newdata->d_size
1262 any_symtab_changes = true;
1266 /* The symbol table didn't really change. */
1267 free (shdr_info[cnt].newsymidx);
1268 shdr_info[cnt].newsymidx = NULL;
1273 /* If we have to, compute the offset of the section. */
1274 if (shdr_info[cnt].shdr.sh_offset == 0)
1275 shdr_info[cnt].shdr.sh_offset
1276 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1277 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1279 /* Set the section header in the new file. */
1280 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1281 /* There cannot be any overflows. */
1282 INTERNAL_ERROR (fname);
1284 /* Remember the last section written so far. */
1285 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1286 ? shdr_info[cnt].shdr.sh_size : 0);
1287 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1288 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1291 /* Adjust symbol references if symbol tables changed. */
1292 if (any_symtab_changes)
1293 /* Find all relocation sections which use this symbol table. */
1294 for (cnt = 1; cnt <= shdridx; ++cnt)
1296 /* Update section headers when the data size has changed.
1297 We also update the SHT_NOBITS section in the debug
1298 file so that the section headers match in sh_size. */
1299 inline void update_section_size (const Elf_Data *newdata)
1302 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1303 shdr->sh_size = newdata->d_size;
1304 (void) gelf_update_shdr (scn, shdr);
1305 if (debugelf != NULL)
1307 /* libelf will use d_size to set sh_size. */
1308 Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
1310 debugdata->d_size = newdata->d_size;
1314 if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
1315 /* Ignore sections which are discarded. When we are saving a
1316 relocation section in a separate debug file, we must fix up
1317 the symbol table references. */
1320 const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1321 const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
1322 switch (shdr_info[cnt].shdr.sh_type)
1324 inline bool no_symtab_updates (void)
1326 /* If the symbol table hasn't changed, do not do anything. */
1327 if (shdr_info[symtabidx].newsymidx == NULL)
1330 /* If the symbol table is not discarded, but additionally
1331 duplicated in the separate debug file and this section
1332 is discarded, don't adjust anything. */
1333 return (shdr_info[cnt].idx == 0
1334 && shdr_info[symtabidx].debug_data != NULL);
1339 if (no_symtab_updates ())
1342 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
1343 ? elf_getscn (debugelf, cnt)
1344 : elf_getscn (newelf,
1345 shdr_info[cnt].idx),
1348 size_t nrels = (shdr_info[cnt].shdr.sh_size
1349 / shdr_info[cnt].shdr.sh_entsize);
1351 if (shdr_info[cnt].shdr.sh_type == SHT_REL)
1352 for (size_t relidx = 0; relidx < nrels; ++relidx)
1355 if (gelf_getrel (d, relidx, &rel_mem) == NULL)
1356 INTERNAL_ERROR (fname);
1358 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1359 if (newsymidx[symidx] != symidx)
1362 = GELF_R_INFO (newsymidx[symidx],
1363 GELF_R_TYPE (rel_mem.r_info));
1365 if (gelf_update_rel (d, relidx, &rel_mem) == 0)
1366 INTERNAL_ERROR (fname);
1370 for (size_t relidx = 0; relidx < nrels; ++relidx)
1373 if (gelf_getrela (d, relidx, &rel_mem) == NULL)
1374 INTERNAL_ERROR (fname);
1376 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1377 if (newsymidx[symidx] != symidx)
1380 = GELF_R_INFO (newsymidx[symidx],
1381 GELF_R_TYPE (rel_mem.r_info));
1383 if (gelf_update_rela (d, relidx, &rel_mem) == 0)
1384 INTERNAL_ERROR (fname);
1390 if (no_symtab_updates ())
1393 /* We have to recompute the hash table. */
1395 assert (shdr_info[cnt].idx > 0);
1397 /* The hash section in the new file. */
1398 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1400 /* The symbol table data. */
1401 Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1402 shdr_info[symtabidx].idx),
1404 assert (symd != NULL);
1406 /* The hash table data. */
1407 Elf_Data *hashd = elf_getdata (scn, NULL);
1408 assert (hashd != NULL);
1410 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
1412 /* Sane arches first. */
1413 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
1415 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1416 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1419 /* Adjust the nchain value. The symbol table size
1420 changed. We keep the same size for the bucket array. */
1421 bucket[1] = symd->d_size / elsize;
1422 Elf32_Word nbucket = bucket[0];
1424 Elf32_Word *chain = bucket + nbucket;
1426 /* New size of the section. */
1427 hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
1428 * sizeof (Elf32_Word));
1429 update_section_size (hashd);
1431 /* Clear the arrays. */
1432 memset (bucket, '\0',
1433 (symd->d_size / elsize + nbucket)
1434 * sizeof (Elf32_Word));
1436 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1437 inner < symd->d_size / elsize; ++inner)
1440 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1441 assert (sym != NULL);
1443 const char *name = elf_strptr (elf, strshndx,
1445 assert (name != NULL);
1446 size_t hidx = elf_hash (name) % nbucket;
1448 if (bucket[hidx] == 0)
1449 bucket[hidx] = inner;
1452 hidx = bucket[hidx];
1454 while (chain[hidx] != 0)
1457 chain[hidx] = inner;
1463 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
1464 assert (shdr_info[cnt].shdr.sh_entsize
1465 == sizeof (Elf64_Xword));
1467 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
1469 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1470 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1473 /* Adjust the nchain value. The symbol table size
1474 changed. We keep the same size for the bucket array. */
1475 bucket[1] = symd->d_size / elsize;
1476 Elf64_Xword nbucket = bucket[0];
1478 Elf64_Xword *chain = bucket + nbucket;
1480 /* New size of the section. */
1481 hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
1482 * sizeof (Elf64_Xword));
1483 update_section_size (hashd);
1485 /* Clear the arrays. */
1486 memset (bucket, '\0',
1487 (symd->d_size / elsize + nbucket)
1488 * sizeof (Elf64_Xword));
1490 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1491 inner < symd->d_size / elsize; ++inner)
1494 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1495 assert (sym != NULL);
1497 const char *name = elf_strptr (elf, strshndx,
1499 assert (name != NULL);
1500 size_t hidx = elf_hash (name) % nbucket;
1502 if (bucket[hidx] == 0)
1503 bucket[hidx] = inner;
1506 hidx = bucket[hidx];
1508 while (chain[hidx] != 0)
1511 chain[hidx] = inner;
1517 case SHT_GNU_versym:
1518 /* If the symbol table changed we have to adjust the entries. */
1519 if (no_symtab_updates ())
1522 assert (shdr_info[cnt].idx > 0);
1524 /* The symbol version section in the new file. */
1525 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1527 /* The symbol table data. */
1528 symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
1530 assert (symd != NULL);
1532 /* The version symbol data. */
1533 Elf_Data *verd = elf_getdata (scn, NULL);
1534 assert (verd != NULL);
1536 /* The symbol version array. */
1537 GElf_Half *verstab = (GElf_Half *) verd->d_buf;
1539 /* Walk through the list and */
1540 size_t elsize = gelf_fsize (elf, verd->d_type, 1,
1542 for (size_t inner = 1; inner < verd->d_size / elsize; ++inner)
1543 if (newsymidx[inner] != 0)
1544 /* Overwriting the same array works since the
1545 reordering can only move entries to lower indices
1547 verstab[newsymidx[inner]] = verstab[inner];
1549 /* New size of the section. */
1550 verd->d_size = gelf_fsize (newelf, verd->d_type,
1552 / gelf_fsize (elf, symd->d_type, 1,
1555 update_section_size (verd);
1559 if (no_symtab_updates ())
1562 /* Yes, the symbol table changed.
1563 Update the section header of the section group. */
1564 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1566 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1567 assert (shdr != NULL);
1569 shdr->sh_info = newsymidx[shdr->sh_info];
1571 (void) gelf_update_shdr (scn, shdr);
1576 /* Now that we have done all adjustments to the data,
1577 we can actually write out the debug file. */
1578 if (debug_fname != NULL)
1581 Elf_Data debug_crc_data =
1583 .d_type = ELF_T_WORD,
1584 .d_buf = &debug_crc,
1585 .d_size = sizeof (debug_crc),
1586 .d_version = EV_CURRENT
1589 /* Finally write the file. */
1590 if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
1592 error (0, 0, gettext ("while writing '%s': %s"),
1593 debug_fname, elf_errmsg (-1));
1598 /* Create the real output file. First rename, then change the
1600 if (rename (tmp_debug_fname, debug_fname) != 0
1601 || fchmod (debug_fd, mode) != 0)
1603 error (0, errno, gettext ("while creating '%s'"), debug_fname);
1608 /* The temporary file does not exist anymore. */
1609 tmp_debug_fname = NULL;
1611 /* Compute the checksum which we will add to the executable. */
1612 if (crc32_file (debug_fd, &debug_crc) != 0)
1615 gettext ("while computing checksum for debug information"));
1616 unlink (debug_fname);
1621 /* Store it in the debuglink section data. */
1622 if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
1623 &debug_crc_data, ehdr->e_ident[EI_DATA])
1624 != &debuglink_crc_data))
1625 INTERNAL_ERROR (fname);
1628 /* Finally finish the ELF header. Fill in the fields not handled by
1629 libelf from the old file. */
1630 newehdr = gelf_getehdr (newelf, &newehdr_mem);
1631 if (newehdr == NULL)
1632 INTERNAL_ERROR (fname);
1634 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1635 newehdr->e_type = ehdr->e_type;
1636 newehdr->e_machine = ehdr->e_machine;
1637 newehdr->e_version = ehdr->e_version;
1638 newehdr->e_entry = ehdr->e_entry;
1639 newehdr->e_flags = ehdr->e_flags;
1640 newehdr->e_phoff = ehdr->e_phoff;
1641 /* We need to position the section header table. */
1642 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
1643 newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
1644 + shdr_info[shdridx].shdr.sh_size + offsize - 1)
1645 & ~((GElf_Off) (offsize - 1)));
1646 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
1648 /* The new section header string table index. */
1649 if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
1650 newehdr->e_shstrndx = idx;
1653 /* The index does not fit in the ELF header field. */
1654 shdr_info[0].scn = elf_getscn (elf, 0);
1656 if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
1657 INTERNAL_ERROR (fname);
1659 shdr_info[0].shdr.sh_link = idx;
1660 (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
1662 newehdr->e_shstrndx = SHN_XINDEX;
1665 if (gelf_update_ehdr (newelf, newehdr) == 0)
1667 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
1668 fname, elf_errmsg (-1));
1672 /* We have everything from the old file. */
1673 if (elf_cntl (elf, ELF_C_FDDONE) != 0)
1675 error (0, 0, gettext ("%s: error while reading the file: %s"),
1676 fname, elf_errmsg (-1));
1680 /* The ELF library better follows our layout when this is not a
1681 relocatable object file. */
1682 elf_flagelf (newelf, ELF_C_SET,
1683 (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
1684 | (permissive ? ELF_F_PERMISSIVE : 0));
1686 /* Finally write the file. */
1687 if (elf_update (newelf, ELF_C_WRITE) == -1)
1689 error (0, 0, gettext ("while writing '%s': %s"),
1690 fname, elf_errmsg (-1));
1695 if (shdr_info != NULL)
1697 /* For some sections we might have created an table to map symbol
1699 if (any_symtab_changes)
1700 for (cnt = 1; cnt <= shdridx; ++cnt)
1702 free (shdr_info[cnt].newsymidx);
1703 if (shdr_info[cnt].debug_data != NULL)
1704 free (shdr_info[cnt].debug_data->d_buf);
1707 /* Free the memory. */
1708 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
1712 /* Free other resources. */
1713 if (shstrtab_data != NULL)
1714 free (shstrtab_data->d_buf);
1716 ebl_strtabfree (shst);
1718 /* That was it. Close the descriptors. */
1719 if (elf_end (newelf) != 0)
1721 error (0, 0, gettext ("error while finishing '%s': %s"), fname,
1726 if (debugelf != NULL && elf_end (debugelf) != 0)
1728 error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
1734 /* Close the EBL backend. */
1736 ebl_closebackend (ebl);
1738 /* Close debug file descriptor, if opened */
1741 if (tmp_debug_fname != NULL)
1742 unlink (tmp_debug_fname);
1746 /* If requested, preserve the timestamp. */
1749 if (futimes (fd, tvp) != 0)
1751 error (0, errno, gettext ("\
1752 cannot set access and modification date of '%s'"),
1753 output_fname ?: fname);
1758 /* Close the file descriptor if we created a new file. */
1759 if (output_fname != NULL)
1767 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
1768 struct timeval tvp[2])
1770 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
1771 size_t fname_len = strlen (fname) + 1;
1772 char new_prefix[prefix_len + 1 + fname_len];
1773 char *cp = new_prefix;
1775 /* Create the full name of the file. */
1778 cp = mempcpy (cp, prefix, prefix_len);
1781 memcpy (cp, fname, fname_len);
1784 /* Process all the files contained in the archive. */
1786 Elf_Cmd cmd = ELF_C_RDWR;
1788 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
1790 /* The the header for this element. */
1791 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
1793 if (elf_kind (subelf) == ELF_K_ELF)
1794 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
1795 else if (elf_kind (subelf) == ELF_K_AR)
1796 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
1798 /* Get next archive element. */
1799 cmd = elf_next (subelf);
1800 if (unlikely (elf_end (subelf) != 0))
1801 INTERNAL_ERROR (fname);
1806 if (unlikely (futimes (fd, tvp) != 0))
1808 error (0, errno, gettext ("\
1809 cannot set access and modification date of '%s'"), fname);
1814 if (unlikely (close (fd) != 0))
1815 error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
1821 #include "debugpred.h"