1 /* Discard section not used at runtime from object files.
2 Copyright (C) 2000-2012, 2014, 2015, 2016, 2017, 2018 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
35 #include <stdio_ext.h>
42 #include <elf-knowledge.h>
47 #include <printversion.h>
49 typedef uint8_t GElf_Byte;
51 /* Name and version of program. */
52 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
54 /* Bug report address. */
55 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
58 /* Values for the parameters which have no short form. */
59 #define OPT_REMOVE_COMMENT 0x100
60 #define OPT_PERMISSIVE 0x101
61 #define OPT_STRIP_SECTIONS 0x102
62 #define OPT_RELOC_DEBUG 0x103
63 #define OPT_KEEP_SECTION 0x104
64 #define OPT_RELOC_DEBUG_ONLY 0x105
67 /* Definitions of arguments for argp functions. */
68 static const struct argp_option options[] =
70 { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
71 { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 },
72 { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 },
73 { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
75 { NULL, 0, NULL, 0, N_("Output options:"), 0 },
76 { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 },
77 { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
78 { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 },
79 { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 },
80 { "strip-sections", OPT_STRIP_SECTIONS, NULL, 0,
81 N_("Remove section headers (not recommended)"), 0 },
82 { "preserve-dates", 'p', NULL, 0,
83 N_("Copy modified/access timestamps to the output"), 0 },
84 { "reloc-debug-sections", OPT_RELOC_DEBUG, NULL, 0,
85 N_("Resolve all trivial relocations between debug sections if the removed sections are placed in a debug file (only relevant for ET_REL files, operation is not reversable, needs -f)"), 0 },
86 { "reloc-debug-sections-only", OPT_RELOC_DEBUG_ONLY, NULL, 0,
87 N_("Similar to --reloc-debug-sections, but resolve all trivial relocations between debug sections in place. No other stripping is performed (operation is not reversable, incompatible with -f, -g, --remove-comment and --remove-section)"), 0 },
88 { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
89 N_("Remove .comment section"), 0 },
90 { "remove-section", 'R', "SECTION", 0, N_("Remove the named section. SECTION is an extended wildcard pattern. May be given more than once. Only non-allocated sections can be removed."), 0 },
91 { "keep-section", OPT_KEEP_SECTION, "SECTION", 0, N_("Keep the named section. SECTION is an extended wildcard pattern. May be given more than once."), 0 },
92 { "permissive", OPT_PERMISSIVE, NULL, 0,
93 N_("Relax a few rules to handle slightly broken ELF files"), 0 },
94 { NULL, 0, NULL, 0, NULL, 0 }
97 /* Short description of program. */
98 static const char doc[] = N_("Discard symbols from object files.");
100 /* Strings for arguments in help texts. */
101 static const char args_doc[] = N_("[FILE...]");
103 /* Prototype for option handler. */
104 static error_t parse_opt (int key, char *arg, struct argp_state *state);
106 /* Data structure to communicate with argp functions. */
107 static struct argp argp =
109 options, parse_opt, args_doc, doc, NULL, NULL, NULL
113 /* Print symbols in file named FNAME. */
114 static int process_file (const char *fname);
116 /* Handle one ELF file. */
117 static int handle_elf (int fd, Elf *elf, const char *prefix,
118 const char *fname, mode_t mode, struct timespec tvp[2]);
120 /* Handle all files contained in the archive. */
121 static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
122 struct timespec tvp[2]) __attribute__ ((unused));
124 static int debug_fd = -1;
125 static char *tmp_debug_fname = NULL;
127 /* Close debug file descriptor, if opened. And remove temporary debug file. */
128 static void cleanup_debug (void);
130 #define INTERNAL_ERROR(fname) \
133 error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"), \
134 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \
138 /* Name of the output file. */
139 static const char *output_fname;
141 /* Name of the debug output file. */
142 static const char *debug_fname;
144 /* Name to pretend the debug output file has. */
145 static const char *debug_fname_embed;
147 /* If true output files shall have same date as the input file. */
148 static bool preserve_dates;
150 /* If true .comment sections will be removed. */
151 static bool remove_comment;
153 /* If true remove all debug sections. */
154 static bool remove_debug;
156 /* If true remove all section headers. */
157 static bool remove_shdrs;
159 /* If true relax some ELF rules for input files. */
160 static bool permissive;
162 /* If true perform relocations between debug sections. */
163 static bool reloc_debug;
165 /* If true perform relocations between debug sections only. */
166 static bool reloc_debug_only;
168 /* Sections the user explicitly wants to keep or remove. */
169 struct section_pattern
172 struct section_pattern *next;
175 static struct section_pattern *keep_secs = NULL;
176 static struct section_pattern *remove_secs = NULL;
179 add_pattern (struct section_pattern **patterns, const char *pattern)
181 struct section_pattern *p = xmalloc (sizeof *p);
182 p->pattern = xstrdup (pattern);
188 free_sec_patterns (struct section_pattern *patterns)
190 struct section_pattern *pattern = patterns;
191 while (pattern != NULL)
193 struct section_pattern *p = pattern;
203 free_sec_patterns (keep_secs);
204 free_sec_patterns (remove_secs);
208 section_name_matches (struct section_pattern *patterns, const char *name)
210 struct section_pattern *pattern = patterns;
211 while (pattern != NULL)
213 if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0)
215 pattern = pattern->next;
222 main (int argc, char *argv[])
227 /* We use no threads here which can interfere with handling a stream. */
228 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
229 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
230 __fsetlocking (stderr, FSETLOCKING_BYCALLER);
233 setlocale (LC_ALL, "");
235 /* Make sure the message catalog can be found. */
236 bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
238 /* Initialize the message catalog. */
239 textdomain (PACKAGE_TARNAME);
241 /* Parse and process arguments. */
242 if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
245 if (reloc_debug && debug_fname == NULL)
246 error (EXIT_FAILURE, 0,
247 gettext ("--reloc-debug-sections used without -f"));
249 if (reloc_debug_only &&
250 (debug_fname != NULL || remove_secs != NULL
251 || remove_comment == true || remove_debug == true))
252 error (EXIT_FAILURE, 0,
253 gettext ("--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --remove-section"));
255 /* Tell the library which version we are expecting. */
256 elf_version (EV_CURRENT);
258 if (remaining == argc)
259 /* The user didn't specify a name so we use a.out. */
260 result = process_file ("a.out");
263 /* If we have seen the '-o' or '-f' option there must be exactly one
265 if ((output_fname != NULL || debug_fname != NULL)
266 && remaining + 1 < argc)
267 error (EXIT_FAILURE, 0, gettext ("\
268 Only one input file allowed together with '-o' and '-f'"));
270 /* Process all the remaining files. */
272 result |= process_file (argv[remaining]);
273 while (++remaining < argc);
281 /* Handle program arguments. */
283 parse_opt (int key, char *arg, struct argp_state *state)
288 if (debug_fname != NULL)
290 error (0, 0, gettext ("-f option specified twice"));
297 if (debug_fname_embed != NULL)
299 error (0, 0, gettext ("-F option specified twice"));
302 debug_fname_embed = arg;
306 if (output_fname != NULL)
308 error (0, 0, gettext ("-o option specified twice"));
315 preserve_dates = true;
318 case OPT_RELOC_DEBUG:
322 case OPT_RELOC_DEBUG_ONLY:
323 reloc_debug_only = true;
326 case OPT_REMOVE_COMMENT:
327 remove_comment = true;
331 if (fnmatch (arg, ".comment", FNM_EXTMATCH) == 0)
332 remove_comment = true;
333 add_pattern (&remove_secs, arg);
336 case OPT_KEEP_SECTION:
337 add_pattern (&keep_secs, arg);
346 case OPT_STRIP_SECTIONS:
354 case 's': /* Ignored for compatibility. */
357 case ARGP_KEY_SUCCESS:
358 if (remove_comment == true
359 && section_name_matches (keep_secs, ".comment"))
362 gettext ("cannot both keep and remove .comment section"));
368 return ARGP_ERR_UNKNOWN;
374 secndx_name (Elf *elf, size_t ndx)
378 Elf_Scn *sec = elf_getscn (elf, ndx);
379 GElf_Shdr *shdr = gelf_getshdr (sec, &mem);
380 if (shdr == NULL || elf_getshdrstrndx (elf, &shstrndx) < 0)
382 return elf_strptr (elf, shstrndx, shdr->sh_name) ?: "???";
385 /* Get the extended section index table data for a symbol table section. */
387 get_xndxdata (Elf *elf, Elf_Scn *symscn)
389 Elf_Data *xndxdata = NULL;
391 GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
392 if (shdr != NULL && shdr->sh_type == SHT_SYMTAB)
394 size_t scnndx = elf_ndxscn (symscn);
395 Elf_Scn *xndxscn = NULL;
396 while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL)
398 GElf_Shdr xndxshdr_mem;
399 GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
402 && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
403 && xndxshdr->sh_link == scnndx)
405 xndxdata = elf_getdata (xndxscn, NULL);
414 /* Updates the shdrstrndx for the given Elf by updating the Ehdr and
415 possibly the section zero extension field. Returns zero on success. */
417 update_shdrstrndx (Elf *elf, size_t shdrstrndx)
420 if (gelf_getehdr (elf, &ehdr) == 0)
423 if (shdrstrndx < SHN_LORESERVE)
424 ehdr.e_shstrndx = shdrstrndx;
427 ehdr.e_shstrndx = SHN_XINDEX;
428 Elf_Scn *scn0 = elf_getscn (elf, 0);
430 GElf_Shdr *shdr0 = gelf_getshdr (scn0, &shdr0_mem);
434 shdr0->sh_link = shdrstrndx;
435 if (gelf_update_shdr (scn0, shdr0) == 0)
439 if (unlikely (gelf_update_ehdr (elf, &ehdr) == 0))
445 /* Remove any relocations between debug sections in ET_REL
446 for the debug file when requested. These relocations are always
447 zero based between the unallocated sections. */
449 remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr,
450 const char *fname, size_t shstrndx)
453 while ((scn = elf_nextscn (elf, scn)) != NULL)
455 /* We need the actual section and header from the elf
456 not just the cached original in shdr_info because we
457 might want to change the size. */
459 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
460 if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
462 /* Make sure that this relocation section points to a
463 section to relocate with contents, that isn't
464 allocated and that is a debug section. */
465 Elf_Scn *tscn = elf_getscn (elf, shdr->sh_info);
467 GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
468 if (tshdr->sh_type == SHT_NOBITS
469 || tshdr->sh_size == 0
470 || (tshdr->sh_flags & SHF_ALLOC) != 0)
473 const char *tname = elf_strptr (elf, shstrndx,
475 if (! tname || ! ebl_debugscn_p (ebl, tname))
478 /* OK, lets relocate all trivial cross debug section
480 Elf_Data *reldata = elf_getdata (scn, NULL);
481 if (reldata == NULL || reldata->d_buf == NULL)
482 INTERNAL_ERROR (fname);
484 /* Make sure we adjust the uncompressed debug data
485 (and recompress if necessary at the end). */
487 int tcompress_type = 0;
488 bool is_gnu_compressed = false;
489 if (strncmp (tname, ".zdebug", strlen ("zdebug")) == 0)
491 is_gnu_compressed = true;
492 if (elf_compress_gnu (tscn, 0, 0) != 1)
493 INTERNAL_ERROR (fname);
497 if (gelf_getchdr (tscn, &tchdr) != NULL)
499 tcompress_type = tchdr.ch_type;
500 if (elf_compress (tscn, 0, 0) != 1)
501 INTERNAL_ERROR (fname);
505 Elf_Data *tdata = elf_getdata (tscn, NULL);
506 if (tdata == NULL || tdata->d_buf == NULL
507 || tdata->d_type != ELF_T_BYTE)
508 INTERNAL_ERROR (fname);
510 /* Pick up the symbol table and shndx table to
511 resolve relocation symbol indexes. */
512 Elf64_Word symt = shdr->sh_link;
513 Elf_Data *symdata, *xndxdata;
514 Elf_Scn * symscn = elf_getscn (elf, symt);
515 symdata = elf_getdata (symscn, NULL);
516 xndxdata = get_xndxdata (elf, symscn);
518 INTERNAL_ERROR (fname);
520 /* Apply one relocation. Returns true when trivial
521 relocation actually done. */
522 bool relocate (GElf_Addr offset, const GElf_Sxword addend,
523 bool is_rela, int rtype, int symndx)
525 /* R_*_NONE relocs can always just be removed. */
529 /* We only do simple absolute relocations. */
531 Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub);
532 if (type == ELF_T_NUM)
535 /* These are the types we can relocate. */
536 #define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \
537 DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \
538 DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
540 /* And only for relocations against other debug sections. */
543 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
546 Elf32_Word sec = (sym->st_shndx == SHN_XINDEX
547 ? xndx : sym->st_shndx);
549 if (ebl_debugscn_p (ebl, secndx_name (elf, sec)))
553 #define DO_TYPE(NAME, Name) GElf_##Name Name;
554 union { TYPES; } tmpbuf;
559 #define DO_TYPE(NAME, Name) \
561 size = sizeof (GElf_##Name); \
570 if (offset > tdata->d_size
571 || tdata->d_size - offset < size)
574 error (EXIT_FAILURE, 0, gettext ("bad relocation"));
577 /* When the symbol value is zero then for SHT_REL
578 sections this is all that needs to be checked.
579 The addend is contained in the original data at
580 the offset already. So if the (section) symbol
581 address is zero and the given addend is zero
582 just remove the relocation, it isn't needed
584 if (addend == 0 && sym->st_value == 0)
592 .d_version = EV_CURRENT,
597 .d_buf = tdata->d_buf + offset,
599 .d_version = EV_CURRENT,
602 GElf_Addr value = sym->st_value;
605 /* For SHT_RELA sections we just take the
606 given addend and add it to the value. */
608 /* For ADD/SUB relocations we need to fetch the
609 current section contents. */
612 Elf_Data *d = gelf_xlatetom (elf, &tmpdata,
614 ehdr->e_ident[EI_DATA]);
616 INTERNAL_ERROR (fname);
617 assert (d == &tmpdata);
622 /* For SHT_REL sections we have to peek at
623 what is already in the section at the given
624 offset to get the addend. */
625 Elf_Data *d = gelf_xlatetom (elf, &tmpdata,
627 ehdr->e_ident[EI_DATA]);
629 INTERNAL_ERROR (fname);
630 assert (d == &tmpdata);
635 #define DO_TYPE(NAME, Name) \
638 tmpbuf.Name -= (GElf_##Name) value; \
640 tmpbuf.Name += (GElf_##Name) value; \
648 /* Now finally put in the new value. */
649 Elf_Data *s = gelf_xlatetof (elf, &rdata,
651 ehdr->e_ident[EI_DATA]);
653 INTERNAL_ERROR (fname);
654 assert (s == &rdata);
661 if (shdr->sh_entsize == 0)
662 INTERNAL_ERROR (fname);
664 size_t nrels = shdr->sh_size / shdr->sh_entsize;
666 if (shdr->sh_type == SHT_REL)
667 for (size_t relidx = 0; relidx < nrels; ++relidx)
670 GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
671 if (! relocate (r->r_offset, 0, false,
672 GELF_R_TYPE (r->r_info),
673 GELF_R_SYM (r->r_info)))
676 gelf_update_rel (reldata, next, r);
681 for (size_t relidx = 0; relidx < nrels; ++relidx)
684 GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
685 if (! relocate (r->r_offset, r->r_addend, true,
686 GELF_R_TYPE (r->r_info),
687 GELF_R_SYM (r->r_info)))
690 gelf_update_rela (reldata, next, r);
696 shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
697 gelf_update_shdr (scn, shdr);
699 if (is_gnu_compressed)
701 if (elf_compress_gnu (tscn, 1, ELF_CHF_FORCE) != 1)
702 INTERNAL_ERROR (fname);
704 else if (tcompress_type != 0)
706 if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1)
707 INTERNAL_ERROR (fname);
714 process_file (const char *fname)
716 /* If we have to preserve the modify and access timestamps get them
717 now. We cannot use fstat() after opening the file since the open
718 would change the access time. */
720 struct timespec tv[2];
724 if (stat (fname, &pre_st) != 0)
726 error (0, errno, gettext ("cannot stat input file '%s'"), fname);
730 /* If we have to preserve the timestamp, we need it in the
731 format utimes() understands. */
732 tv[0] = pre_st.st_atim;
733 tv[1] = pre_st.st_mtim;
737 int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
740 error (0, errno, gettext ("while opening '%s'"), fname);
744 /* We always use fstat() even if we called stat() before. This is
745 done to make sure the information returned by stat() is for the
748 if (fstat (fd, &st) != 0)
750 error (0, errno, gettext ("cannot stat input file '%s'"), fname);
753 /* Paranoid mode on. */
755 && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
757 /* We detected a race. Try again. */
762 /* Now get the ELF descriptor. */
763 Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
766 switch (elf_kind (elf))
769 result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
770 preserve_dates ? tv : NULL);
774 /* It is not possible to strip the content of an archive direct
775 the output to a specific file. */
776 if (unlikely (output_fname != NULL || debug_fname != NULL))
778 error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"),
784 /* We would like to support ar archives, but currently it just
785 doesn't work at all since we call elf_clone on the members
786 which doesn't really support ar members.
787 result = handle_ar (fd, elf, NULL, fname,
788 preserve_dates ? tv : NULL);
790 error (0, 0, gettext ("%s: no support for stripping archive"),
797 error (0, 0, gettext ("%s: File format not recognized"), fname);
802 if (unlikely (elf_end (elf) != 0))
803 INTERNAL_ERROR (fname);
810 /* Processing for --reloc-debug-sections-only. */
812 handle_debug_relocs (Elf *elf, Ebl *ebl, Elf *new_elf,
813 GElf_Ehdr *ehdr, const char *fname, size_t shstrndx,
814 GElf_Off *last_offset, GElf_Xword *last_size)
817 /* Copy over the ELF header. */
818 if (gelf_update_ehdr (new_elf, ehdr) == 0)
820 error (0, 0, "couldn't update new ehdr: %s", elf_errmsg (-1));
824 /* Copy over sections and record end of allocated sections. */
825 GElf_Off lastoffset = 0;
827 while ((scn = elf_nextscn (elf, scn)) != NULL)
829 /* Get the header. */
831 if (gelf_getshdr (scn, &shdr) == NULL)
833 error (0, 0, "couldn't get shdr: %s", elf_errmsg (-1));
837 /* Create new section. */
838 Elf_Scn *new_scn = elf_newscn (new_elf);
841 error (0, 0, "couldn't create new section: %s", elf_errmsg (-1));
845 if (gelf_update_shdr (new_scn, &shdr) == 0)
847 error (0, 0, "couldn't update shdr: %s", elf_errmsg (-1));
851 /* Copy over section data. */
852 Elf_Data *data = NULL;
853 while ((data = elf_getdata (scn, data)) != NULL)
855 Elf_Data *new_data = elf_newdata (new_scn);
856 if (new_data == NULL)
858 error (0, 0, "couldn't create new section data: %s",
865 /* Record last offset of allocated section. */
866 if ((shdr.sh_flags & SHF_ALLOC) != 0)
868 GElf_Off filesz = (shdr.sh_type != SHT_NOBITS
870 if (lastoffset < shdr.sh_offset + filesz)
871 lastoffset = shdr.sh_offset + filesz;
875 /* Make sure section header name table is setup correctly, we'll
876 need it to determine whether to relocate sections. */
877 if (update_shdrstrndx (new_elf, shstrndx) != 0)
879 error (0, 0, "error updating shdrstrndx: %s", elf_errmsg (-1));
883 /* Adjust the relocation sections. */
884 remove_debug_relocations (ebl, new_elf, ehdr, fname, shstrndx);
886 /* Adjust the offsets of the non-allocated sections, so they come after
887 the allocated sections. */
889 while ((scn = elf_nextscn (new_elf, scn)) != NULL)
891 /* Get the header. */
893 if (gelf_getshdr (scn, &shdr) == NULL)
895 error (0, 0, "couldn't get shdr: %s", elf_errmsg (-1));
899 /* Adjust non-allocated section offsets to be after any allocated. */
900 if ((shdr.sh_flags & SHF_ALLOC) == 0)
902 shdr.sh_offset = ((lastoffset + shdr.sh_addralign - 1)
903 & ~((GElf_Off) (shdr.sh_addralign - 1)));
904 if (gelf_update_shdr (scn, &shdr) == 0)
906 error (0, 0, "couldn't update shdr: %s", elf_errmsg (-1));
910 GElf_Off filesz = (shdr.sh_type != SHT_NOBITS
912 lastoffset = shdr.sh_offset + filesz;
913 *last_offset = shdr.sh_offset;
921 /* Maximum size of array allocated on stack. */
922 #define MAX_STACK_ALLOC (400 * 1024)
925 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
926 mode_t mode, struct timespec tvp[2])
928 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
929 size_t fname_len = strlen (fname) + 1;
930 char *fullname = alloca (prefix_len + 1 + fname_len);
932 Elf *debugelf = NULL;
933 tmp_debug_fname = NULL;
936 GElf_Off lastsec_offset = 0;
937 Elf64_Xword lastsec_size = 0;
944 Elf_Data *debug_data;
946 Elf32_Word idx; /* Index in new file. */
947 Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */
948 Elf32_Word symtab_idx;
949 Elf32_Word version_idx;
950 Elf32_Word group_idx;
951 Elf32_Word group_cnt;
954 Elf32_Word *newsymidx;
960 GElf_Ehdr newehdr_mem;
962 GElf_Ehdr debugehdr_mem;
963 GElf_Ehdr *debugehdr;
964 Dwelf_Strtab *shst = NULL;
965 Elf_Data debuglink_crc_data;
966 bool any_symtab_changes = false;
967 Elf_Data *shstrtab_data = NULL;
968 void *debuglink_buf = NULL;
970 /* Create the full name of the file. */
973 cp = mempcpy (cp, prefix, prefix_len);
976 memcpy (cp, fname, fname_len);
978 /* If we are not replacing the input file open a new file here. */
979 if (output_fname != NULL)
981 fd = open (output_fname, O_RDWR | O_CREAT, mode);
982 if (unlikely (fd == -1))
984 error (0, errno, gettext ("cannot open '%s'"), output_fname);
991 /* Get the EBL handling. Removing all debugging symbols with the -g
992 option or resolving all relocations between debug sections with
993 the --reloc-debug-sections option are currently the only reasons
994 we need EBL so don't open the backend unless necessary. */
996 if (remove_debug || reloc_debug || reloc_debug_only)
998 ebl = ebl_openbackend (elf);
1001 error (0, errno, gettext ("cannot open EBL backend"));
1007 /* Open the additional file the debug information will be stored in. */
1008 if (debug_fname != NULL)
1010 /* Create a temporary file name. We do not want to overwrite
1011 the debug file if the file would not contain any
1013 size_t debug_fname_len = strlen (debug_fname);
1014 tmp_debug_fname = (char *) xmalloc (debug_fname_len + sizeof (".XXXXXX"));
1015 strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
1018 debug_fd = mkstemp (tmp_debug_fname);
1019 if (unlikely (debug_fd == -1))
1021 error (0, errno, gettext ("cannot open '%s'"), debug_fname);
1027 /* Get the information from the old file. */
1029 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
1031 INTERNAL_ERROR (fname);
1033 /* Get the section header string table index. */
1034 if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
1037 error (EXIT_FAILURE, 0,
1038 gettext ("cannot get section header string table index"));
1041 /* Get the number of phdrs in the old file. */
1043 if (elf_getphdrnum (elf, &phnum) != 0)
1046 error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs"));
1049 /* We now create a new ELF descriptor for the same file. We
1050 construct it almost exactly in the same way with some information
1053 if (output_fname != NULL)
1054 newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
1056 newelf = elf_clone (elf, ELF_C_EMPTY);
1058 if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0))
1060 error (0, 0, gettext ("cannot create new ehdr for file '%s': %s"),
1061 output_fname ?: fname, elf_errmsg (-1));
1065 /* Copy over the old program header if needed. */
1068 if (unlikely (gelf_newphdr (newelf, phnum) == 0))
1070 error (0, 0, gettext ("cannot create new phdr for file '%s': %s"),
1071 output_fname ?: fname, elf_errmsg (-1));
1075 for (cnt = 0; cnt < phnum; ++cnt)
1078 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
1080 || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
1081 INTERNAL_ERROR (fname);
1085 if (reloc_debug_only)
1087 if (handle_debug_relocs (elf, ebl, newelf, ehdr, fname, shstrndx,
1088 &lastsec_offset, &lastsec_size) != 0)
1094 goto done; /* Skip all actual stripping operations. */
1097 if (debug_fname != NULL)
1099 /* Also create an ELF descriptor for the debug file */
1100 debugelf = elf_begin (debug_fd, ELF_C_WRITE, NULL);
1101 if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0))
1103 error (0, 0, gettext ("cannot create new ehdr for file '%s': %s"),
1104 debug_fname, elf_errmsg (-1));
1108 /* Copy over the old program header if needed. */
1111 if (unlikely (gelf_newphdr (debugelf, phnum) == 0))
1113 error (0, 0, gettext ("cannot create new phdr for file '%s': %s"),
1114 debug_fname, elf_errmsg (-1));
1118 for (cnt = 0; cnt < phnum; ++cnt)
1121 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
1123 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
1124 INTERNAL_ERROR (fname);
1129 /* Number of sections. */
1131 if (unlikely (elf_getshdrnum (elf, &shnum) < 0))
1133 error (0, 0, gettext ("cannot determine number of sections: %s"),
1138 if (shstrndx >= shnum)
1141 #define elf_assert(test) do { if (!(test)) goto illformed; } while (0)
1143 /* Storage for section information. We leave room for two more
1144 entries since we unconditionally create a section header string
1145 table. Maybe some weird tool created an ELF file without one.
1146 The other one is used for the debug link section. */
1147 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
1148 shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
1149 sizeof (struct shdr_info));
1152 shdr_info = (struct shdr_info *) alloca ((shnum + 2)
1153 * sizeof (struct shdr_info));
1154 memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
1157 /* Track whether allocated sections all come before non-allocated ones. */
1158 bool seen_allocated = false;
1159 bool seen_unallocated = false;
1160 bool mixed_allocated_unallocated = false;
1162 /* Prepare section information data structure. */
1165 while ((scn = elf_nextscn (elf, scn)) != NULL)
1167 /* This should always be true (i.e., there should not be any
1168 holes in the numbering). */
1169 elf_assert (elf_ndxscn (scn) == cnt);
1171 shdr_info[cnt].scn = scn;
1173 /* Get the header. */
1174 if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
1175 INTERNAL_ERROR (fname);
1177 /* Normally (in non-ET_REL files) we see all allocated sections first,
1178 then all non-allocated. */
1179 if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
1180 seen_unallocated = true;
1183 if (seen_unallocated && seen_allocated)
1184 mixed_allocated_unallocated = true;
1185 seen_allocated = true;
1188 /* Get the name of the section. */
1189 shdr_info[cnt].name = elf_strptr (elf, shstrndx,
1190 shdr_info[cnt].shdr.sh_name);
1191 if (shdr_info[cnt].name == NULL)
1194 error (0, 0, gettext ("illformed file '%s'"), fname);
1198 /* Sanity check the user. */
1199 if (section_name_matches (remove_secs, shdr_info[cnt].name))
1201 if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0)
1204 gettext ("Cannot remove allocated section '%s'"),
1205 shdr_info[cnt].name);
1210 if (section_name_matches (keep_secs, shdr_info[cnt].name))
1213 gettext ("Cannot both keep and remove section '%s'"),
1214 shdr_info[cnt].name);
1220 /* Mark them as present but not yet investigated. */
1221 shdr_info[cnt].idx = 1;
1223 /* Remember the shdr.sh_link value. */
1224 shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
1225 if (shdr_info[cnt].old_sh_link >= shnum)
1228 /* Sections in files other than relocatable object files which
1229 not loaded can be freely moved by us. In theory we can also
1230 freely move around allocated nobits sections. But we don't
1231 to keep the layout of all allocated sections as similar as
1232 possible to the original file. In relocatable object files
1233 everything can be moved. */
1235 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
1236 shdr_info[cnt].shdr.sh_offset = 0;
1238 /* If this is an extended section index table store an
1239 appropriate reference. */
1240 if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
1242 elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
1243 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
1245 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
1247 /* Cross-reference the sections contained in the section
1249 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1250 if (shdr_info[cnt].data == NULL
1251 || shdr_info[cnt].data->d_size < sizeof (Elf32_Word))
1252 INTERNAL_ERROR (fname);
1254 /* XXX Fix for unaligned access. */
1255 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1258 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1261 if (grpref[inner] < shnum)
1262 shdr_info[grpref[inner]].group_idx = cnt;
1267 if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
1268 /* If the section group contains only one element and this
1269 is n COMDAT section we can drop it right away. */
1270 shdr_info[cnt].idx = 0;
1272 shdr_info[cnt].group_cnt = inner - 1;
1274 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
1276 elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
1277 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
1280 /* If this section is part of a group make sure it is not
1281 discarded right away. */
1282 if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
1284 elf_assert (shdr_info[cnt].group_idx != 0);
1286 if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
1288 /* The section group section might be removed.
1289 Don't remove the SHF_GROUP flag. The section is
1290 either also removed, in which case the flag doesn't matter.
1291 Or it moves with the group into the debug file, then
1292 it will be reconnected with the new group and should
1293 still have the flag set. */
1294 shdr_info[cnt].group_idx = 0;
1298 /* Increment the counter. */
1302 /* Now determine which sections can go away. The general rule is that
1303 all sections which are not used at runtime are stripped out. But
1304 there are a few exceptions:
1306 - special sections named ".comment" and ".note" are kept
1307 - OS or architecture specific sections are kept since we might not
1308 know how to handle them
1309 - if a section is referred to from a section which is not removed
1310 in the sh_link or sh_info element it cannot be removed either
1311 - the user might have explicitly said to remove or keep a section
1313 for (cnt = 1; cnt < shnum; ++cnt)
1314 /* Check whether the section can be removed. Since we will create
1315 a new .shstrtab assume it will be removed too. */
1316 if (remove_shdrs ? !(shdr_info[cnt].shdr.sh_flags & SHF_ALLOC)
1317 : (ebl_section_strip_p (ebl, &shdr_info[cnt].shdr,
1318 shdr_info[cnt].name, remove_comment,
1321 || section_name_matches (remove_secs, shdr_info[cnt].name)))
1323 /* The user might want to explicitly keep this one. */
1324 if (section_name_matches (keep_secs, shdr_info[cnt].name))
1327 /* For now assume this section will be removed. */
1328 shdr_info[cnt].idx = 0;
1330 idx = shdr_info[cnt].group_idx;
1333 /* The section group data is already loaded. */
1334 elf_assert (shdr_info[idx].data != NULL
1335 && shdr_info[idx].data->d_buf != NULL
1336 && shdr_info[idx].data->d_size >= sizeof (Elf32_Word));
1338 /* If the references section group is a normal section
1339 group and has one element remaining, or if it is an
1340 empty COMDAT section group it is removed. */
1341 bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
1344 --shdr_info[idx].group_cnt;
1345 if ((!is_comdat && shdr_info[idx].group_cnt == 1)
1346 || (is_comdat && shdr_info[idx].group_cnt == 0))
1348 shdr_info[idx].idx = 0;
1349 /* Continue recursively. */
1350 idx = shdr_info[idx].group_idx;
1357 /* Mark the SHT_NULL section as handled. */
1358 shdr_info[0].idx = 2;
1361 /* Handle exceptions: section groups and cross-references. We might
1362 have to repeat this a few times since the resetting of the flag
1368 for (cnt = 1; cnt < shnum; ++cnt)
1370 if (shdr_info[cnt].idx == 0)
1372 /* If a relocation section is marked as being removed make
1373 sure the section it is relocating is removed, too. */
1374 if (shdr_info[cnt].shdr.sh_type == SHT_REL
1375 || shdr_info[cnt].shdr.sh_type == SHT_RELA)
1377 if (shdr_info[cnt].shdr.sh_info >= shnum)
1379 else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
1380 shdr_info[cnt].idx = 1;
1383 /* If a group section is marked as being removed make
1384 sure all the sections it contains are being removed, too. */
1385 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1388 grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1390 in < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1392 if (grpref[in] < shnum)
1394 if (shdr_info[grpref[in]].idx != 0)
1396 shdr_info[cnt].idx = 1;
1405 if (shdr_info[cnt].idx == 1)
1407 /* The content of symbol tables we don't remove must not
1408 reference any section which we do remove. Otherwise
1409 we cannot remove the section. */
1410 if (debug_fname != NULL
1411 && shdr_info[cnt].debug_data == NULL
1412 && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1413 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB))
1415 /* Make sure the data is loaded. */
1416 if (shdr_info[cnt].data == NULL)
1419 = elf_getdata (shdr_info[cnt].scn, NULL);
1420 if (shdr_info[cnt].data == NULL)
1421 INTERNAL_ERROR (fname);
1423 Elf_Data *symdata = shdr_info[cnt].data;
1425 /* If there is an extended section index table load it
1427 if (shdr_info[cnt].symtab_idx != 0
1428 && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
1430 elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
1432 shdr_info[shdr_info[cnt].symtab_idx].data
1433 = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1435 if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
1436 INTERNAL_ERROR (fname);
1439 = shdr_info[shdr_info[cnt].symtab_idx].data;
1441 /* Go through all symbols and make sure the section they
1442 reference is not removed. */
1443 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
1445 for (size_t inner = 0;
1446 inner < shdr_info[cnt].data->d_size / elsize;
1451 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1455 INTERNAL_ERROR (fname);
1457 size_t scnidx = sym->st_shndx;
1458 if (scnidx == SHN_UNDEF || scnidx >= shnum
1459 || (scnidx >= SHN_LORESERVE
1460 && scnidx <= SHN_HIRESERVE
1461 && scnidx != SHN_XINDEX)
1462 /* Don't count in the section symbols. */
1463 || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
1464 /* This is no section index, leave it alone. */
1466 else if (scnidx == SHN_XINDEX)
1469 if (scnidx >= shnum)
1472 if (shdr_info[scnidx].idx == 0)
1473 /* This symbol table has a real symbol in
1474 a discarded section. So preserve the
1475 original table in the debug file. Unless
1476 it is a redundant data marker to a debug
1477 (data only) section. */
1478 if (! (ebl_section_strip_p (ebl,
1479 &shdr_info[scnidx].shdr,
1480 shdr_info[scnidx].name,
1483 && ebl_data_marker_symbol (ebl, sym,
1485 shdr_info[cnt].shdr.sh_link,
1487 shdr_info[cnt].debug_data = symdata;
1491 /* Cross referencing happens:
1492 - for the cases the ELF specification says. That are
1493 + SHT_DYNAMIC in sh_link to string table
1494 + SHT_HASH in sh_link to symbol table
1495 + SHT_REL and SHT_RELA in sh_link to symbol table
1496 + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
1497 + SHT_GROUP in sh_link to symbol table
1498 + SHT_SYMTAB_SHNDX in sh_link to symbol table
1499 Other (OS or architecture-specific) sections might as
1500 well use this field so we process it unconditionally.
1501 - references inside section groups
1502 - specially marked references in sh_info if the SHF_INFO_LINK
1506 if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
1508 shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
1509 changes |= shdr_info[cnt].shdr.sh_link < cnt;
1512 /* Handle references through sh_info. */
1513 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1515 if (shdr_info[cnt].shdr.sh_info >= shnum)
1517 else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
1519 shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
1520 changes |= shdr_info[cnt].shdr.sh_info < cnt;
1524 /* Mark the section as investigated. */
1525 shdr_info[cnt].idx = 2;
1528 if (debug_fname != NULL
1529 && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL))
1531 /* This section is being preserved in the debug file.
1532 Sections it refers to must be preserved there too.
1534 In this pass we mark sections to be preserved in both
1535 files by setting the .debug_data pointer to the original
1536 file's .data pointer. Below, we'll copy the section
1539 inline void check_preserved (size_t i)
1541 if (i != 0 && i < shnum + 2 && shdr_info[i].idx != 0
1542 && shdr_info[i].debug_data == NULL)
1544 if (shdr_info[i].data == NULL)
1545 shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL);
1546 if (shdr_info[i].data == NULL)
1547 INTERNAL_ERROR (fname);
1549 shdr_info[i].debug_data = shdr_info[i].data;
1554 check_preserved (shdr_info[cnt].shdr.sh_link);
1555 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1556 check_preserved (shdr_info[cnt].shdr.sh_info);
1562 /* Copy the removed sections to the debug output file.
1563 The ones that are not removed in the stripped file are SHT_NOBITS. */
1564 if (debug_fname != NULL)
1566 for (cnt = 1; cnt < shnum; ++cnt)
1568 scn = elf_newscn (debugelf);
1572 error (EXIT_FAILURE, 0,
1573 gettext ("while generating output file: %s"),
1577 bool discard_section = (shdr_info[cnt].idx > 0
1578 && shdr_info[cnt].debug_data == NULL
1579 && shdr_info[cnt].shdr.sh_type != SHT_NOTE
1580 && shdr_info[cnt].shdr.sh_type != SHT_GROUP
1581 && cnt != shstrndx);
1583 /* Set the section header in the new file. */
1584 GElf_Shdr debugshdr = shdr_info[cnt].shdr;
1585 if (discard_section)
1586 debugshdr.sh_type = SHT_NOBITS;
1588 if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
1589 /* There cannot be any overflows. */
1590 INTERNAL_ERROR (fname);
1592 /* Get the data from the old file if necessary. */
1593 if (shdr_info[cnt].data == NULL)
1595 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1596 if (shdr_info[cnt].data == NULL)
1597 INTERNAL_ERROR (fname);
1600 /* Set the data. This is done by copying from the old file. */
1601 Elf_Data *debugdata = elf_newdata (scn);
1602 if (debugdata == NULL)
1603 INTERNAL_ERROR (fname);
1605 /* Copy the structure. This data may be modified in place
1606 before we write out the file. */
1607 *debugdata = *shdr_info[cnt].data;
1608 if (discard_section)
1609 debugdata->d_buf = NULL;
1610 else if (shdr_info[cnt].debug_data != NULL
1611 || shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1613 /* Copy the original data before it gets modified. */
1614 shdr_info[cnt].debug_data = debugdata;
1615 if (debugdata->d_buf == NULL)
1616 INTERNAL_ERROR (fname);
1617 debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
1618 debugdata->d_buf, debugdata->d_size);
1622 /* Finish the ELF header. Fill in the fields not handled by
1623 libelf from the old file. */
1624 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
1625 if (debugehdr == NULL)
1626 INTERNAL_ERROR (fname);
1628 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1629 debugehdr->e_type = ehdr->e_type;
1630 debugehdr->e_machine = ehdr->e_machine;
1631 debugehdr->e_version = ehdr->e_version;
1632 debugehdr->e_entry = ehdr->e_entry;
1633 debugehdr->e_flags = ehdr->e_flags;
1635 if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
1637 error (0, 0, gettext ("%s: error while updating ELF header: %s"),
1638 debug_fname, elf_errmsg (-1));
1644 if (elf_getshdrstrndx (elf, &shdrstrndx) < 0)
1646 error (0, 0, gettext ("%s: error while getting shdrstrndx: %s"),
1647 fname, elf_errmsg (-1));
1652 if (update_shdrstrndx (debugelf, shdrstrndx) != 0)
1654 error (0, 0, gettext ("%s: error updating shdrstrndx: %s"),
1655 debug_fname, elf_errmsg (-1));
1661 /* Although we always create a new section header string table we
1662 don't explicitly mark the existing one as unused. It can still
1663 be used through a symbol table section we are keeping. If not it
1664 will already be marked as unused. */
1666 /* We need a string table for the section headers. */
1667 shst = dwelf_strtab_init (true);
1671 error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
1672 output_fname ?: fname);
1675 /* Assign new section numbers. */
1676 shdr_info[0].idx = 0;
1677 for (cnt = idx = 1; cnt < shnum; ++cnt)
1678 if (shdr_info[cnt].idx > 0)
1680 shdr_info[cnt].idx = idx++;
1682 /* Create a new section. */
1683 shdr_info[cnt].newscn = elf_newscn (newelf);
1684 if (shdr_info[cnt].newscn == NULL)
1687 error (EXIT_FAILURE, 0,
1688 gettext ("while generating output file: %s"),
1692 elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1694 /* Add this name to the section header string table. */
1695 shdr_info[cnt].se = dwelf_strtab_add (shst, shdr_info[cnt].name);
1698 /* Test whether we are doing anything at all. Either all removable
1699 sections are already gone. Or the only section we would remove is
1700 the .shstrtab section which we would add again. */
1701 bool removing_sections = !(cnt == idx
1703 && shdr_info[shstrndx].idx == 0));
1704 if (output_fname == NULL && !removing_sections)
1707 /* Create the reference to the file with the debug info (if any). */
1708 if (debug_fname != NULL && !remove_shdrs && removing_sections)
1710 /* Add the section header string table section name. */
1711 shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".gnu_debuglink", 15);
1712 shdr_info[cnt].idx = idx++;
1714 /* Create the section header. */
1715 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
1716 shdr_info[cnt].shdr.sh_flags = 0;
1717 shdr_info[cnt].shdr.sh_addr = 0;
1718 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1719 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1720 shdr_info[cnt].shdr.sh_entsize = 0;
1721 shdr_info[cnt].shdr.sh_addralign = 4;
1722 /* We set the offset to zero here. Before we write the ELF file the
1723 field must have the correct value. This is done in the final
1724 loop over all section. Then we have all the information needed. */
1725 shdr_info[cnt].shdr.sh_offset = 0;
1727 /* Create the section. */
1728 shdr_info[cnt].newscn = elf_newscn (newelf);
1729 if (shdr_info[cnt].newscn == NULL)
1732 error (EXIT_FAILURE, 0,
1733 gettext ("while create section header section: %s"),
1736 elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1738 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
1739 if (shdr_info[cnt].data == NULL)
1742 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
1746 char *debug_basename = basename (debug_fname_embed ?: debug_fname);
1747 off_t crc_offset = strlen (debug_basename) + 1;
1748 /* Align to 4 byte boundary */
1749 crc_offset = ((crc_offset - 1) & ~3) + 4;
1751 shdr_info[cnt].data->d_align = 4;
1752 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
1754 debuglink_buf = xcalloc (1, shdr_info[cnt].data->d_size);
1755 shdr_info[cnt].data->d_buf = debuglink_buf;
1757 strcpy (shdr_info[cnt].data->d_buf, debug_basename);
1759 /* Cache this Elf_Data describing the CRC32 word in the section.
1760 We'll fill this in when we have written the debug file. */
1761 debuglink_crc_data = *shdr_info[cnt].data;
1762 debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
1764 debuglink_crc_data.d_size = 4;
1766 /* One more section done. */
1770 /* Index of the section header table in the shdr_info array. */
1773 /* Add the section header string table section name. */
1774 shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".shstrtab", 10);
1775 shdr_info[cnt].idx = idx;
1777 /* Create the section header. */
1778 shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
1779 shdr_info[cnt].shdr.sh_flags = 0;
1780 shdr_info[cnt].shdr.sh_addr = 0;
1781 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1782 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1783 shdr_info[cnt].shdr.sh_entsize = 0;
1784 /* We set the offset to zero here. Before we write the ELF file the
1785 field must have the correct value. This is done in the final
1786 loop over all section. Then we have all the information needed. */
1787 shdr_info[cnt].shdr.sh_offset = 0;
1788 shdr_info[cnt].shdr.sh_addralign = 1;
1790 /* Create the section. */
1791 shdr_info[cnt].newscn = elf_newscn (newelf);
1792 if (shdr_info[cnt].newscn == NULL)
1795 error (EXIT_FAILURE, 0,
1796 gettext ("while create section header section: %s"),
1799 elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1801 /* Finalize the string table and fill in the correct indices in the
1803 shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1804 if (shstrtab_data == NULL)
1807 error (EXIT_FAILURE, 0,
1808 gettext ("while create section header string table: %s"),
1811 if (dwelf_strtab_finalize (shst, shstrtab_data) == NULL)
1814 error (EXIT_FAILURE, 0,
1815 gettext ("no memory to create section header string table"));
1818 /* We have to set the section size. */
1819 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1821 /* Update the section information. */
1822 GElf_Off lastoffset = 0;
1823 for (cnt = 1; cnt <= shdridx; ++cnt)
1824 if (shdr_info[cnt].idx > 0)
1828 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1829 elf_assert (scn != NULL);
1831 /* Update the name. */
1832 shdr_info[cnt].shdr.sh_name = dwelf_strent_off (shdr_info[cnt].se);
1834 /* Update the section header from the input file. Some fields
1835 might be section indeces which now have to be adjusted. Keep
1836 the index to the "current" sh_link in case we need it to lookup
1837 symbol table names. */
1838 size_t sh_link = shdr_info[cnt].shdr.sh_link;
1839 if (shdr_info[cnt].shdr.sh_link != 0)
1840 shdr_info[cnt].shdr.sh_link =
1841 shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1843 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1845 elf_assert (shdr_info[cnt].data != NULL
1846 && shdr_info[cnt].data->d_buf != NULL);
1848 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1849 /* First word is the section group flag.
1850 Followed by section indexes, that need to be renumbered. */
1851 for (size_t inner = 1;
1852 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1854 if (grpref[inner] < shnum)
1855 grpref[inner] = shdr_info[grpref[inner]].idx;
1860 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */
1861 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1862 shdr_info[cnt].shdr.sh_info =
1863 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1865 /* Get the data from the old file if necessary. We already
1866 created the data for the section header string table. */
1869 if (shdr_info[cnt].data == NULL)
1871 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1872 if (shdr_info[cnt].data == NULL)
1873 INTERNAL_ERROR (fname);
1876 /* Set the data. This is done by copying from the old file. */
1877 newdata = elf_newdata (scn);
1878 if (newdata == NULL)
1879 INTERNAL_ERROR (fname);
1881 /* Copy the structure. */
1882 *newdata = *shdr_info[cnt].data;
1884 /* We know the size. */
1885 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1887 /* We have to adjust symbol tables. The st_shndx member might
1888 have to be updated. */
1889 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1890 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1892 Elf_Data *versiondata = NULL;
1893 Elf_Data *shndxdata = NULL;
1895 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
1897 if (shdr_info[cnt].symtab_idx != 0)
1899 elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1900 /* This section has extended section information.
1901 We have to modify that information, too. */
1902 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1905 elf_assert (shndxdata != NULL
1906 && shndxdata->d_buf != NULL
1907 && ((shndxdata->d_size / sizeof (Elf32_Word))
1908 >= shdr_info[cnt].data->d_size / elsize));
1911 if (shdr_info[cnt].version_idx != 0)
1913 elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1914 /* This section has associated version
1915 information. We have to modify that
1916 information, too. */
1917 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1920 elf_assert (versiondata != NULL
1921 && versiondata->d_buf != NULL
1922 && ((versiondata->d_size / sizeof (GElf_Versym))
1923 >= shdr_info[cnt].data->d_size / elsize));
1926 shdr_info[cnt].newsymidx
1927 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1928 / elsize, sizeof (Elf32_Word));
1930 bool last_was_local = true;
1933 for (destidx = inner = 1;
1934 inner < shdr_info[cnt].data->d_size / elsize;
1940 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1944 INTERNAL_ERROR (fname);
1946 if (sym->st_shndx == SHN_UNDEF
1947 || (sym->st_shndx >= SHN_LORESERVE
1948 && sym->st_shndx != SHN_XINDEX))
1950 /* This is no section index, leave it alone
1951 unless it is moved. */
1952 if (destidx != inner
1953 && gelf_update_symshndx (shdr_info[cnt].data,
1957 INTERNAL_ERROR (fname);
1959 shdr_info[cnt].newsymidx[inner] = destidx++;
1962 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1964 last_was_local = false;
1965 shdr_info[cnt].shdr.sh_info = destidx - 1;
1971 /* Get the full section index, if necessary from the
1973 if (sym->st_shndx == SHN_XINDEX)
1974 elf_assert (shndxdata != NULL
1975 && shndxdata->d_buf != NULL);
1976 size_t sidx = (sym->st_shndx != SHN_XINDEX
1977 ? sym->st_shndx : xshndx);
1978 elf_assert (sidx < shnum);
1979 sec = shdr_info[sidx].idx;
1983 GElf_Section nshndx;
1986 if (sec < SHN_LORESERVE)
1993 nshndx = SHN_XINDEX;
1997 elf_assert (sec < SHN_LORESERVE || shndxdata != NULL);
1999 if ((inner != destidx || nshndx != sym->st_shndx
2000 || (shndxdata != NULL && nxshndx != xshndx))
2001 && (sym->st_shndx = nshndx,
2002 gelf_update_symshndx (shdr_info[cnt].data,
2006 INTERNAL_ERROR (fname);
2008 shdr_info[cnt].newsymidx[inner] = destidx++;
2011 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
2013 last_was_local = false;
2014 shdr_info[cnt].shdr.sh_info = destidx - 1;
2017 else if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0
2018 && GELF_ST_TYPE (sym->st_info) != STT_SECTION
2019 && shdr_info[sidx].shdr.sh_type != SHT_GROUP)
2021 /* Removing a real symbol from an allocated
2022 symbol table is hard and probably a
2023 mistake. Really removing it means
2024 rewriting the dynamic segment and hash
2025 sections. Just warn and set the symbol
2026 section to UNDEF. */
2028 gettext ("Cannot remove symbol [%zd] from allocated symbol table [%zd]"), inner, cnt);
2029 sym->st_shndx = SHN_UNDEF;
2030 if (gelf_update_sym (shdr_info[cnt].data, destidx,
2032 INTERNAL_ERROR (fname);
2033 shdr_info[cnt].newsymidx[inner] = destidx++;
2035 else if (debug_fname != NULL
2036 && shdr_info[cnt].debug_data == NULL)
2037 /* The symbol points to a section that is discarded
2038 but isn't preserved in the debug file. Check that
2039 this is a section or group signature symbol
2040 for a section which has been removed. Or a special
2041 data marker symbol to a debug section. */
2043 elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
2044 || ((shdr_info[sidx].shdr.sh_type
2046 && (shdr_info[sidx].shdr.sh_info
2048 || ebl_data_marker_symbol (ebl, sym,
2049 elf_strptr (elf, sh_link,
2054 if (destidx != inner)
2056 /* The size of the symbol table changed. */
2057 shdr_info[cnt].shdr.sh_size = newdata->d_size
2059 any_symtab_changes = true;
2063 /* The symbol table didn't really change. */
2064 free (shdr_info[cnt].newsymidx);
2065 shdr_info[cnt].newsymidx = NULL;
2070 /* If we have to, compute the offset of the section.
2071 If allocate and unallocated sections are mixed, we only update
2072 the allocated ones now. The unallocated ones come second. */
2073 if (! mixed_allocated_unallocated
2074 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0)
2076 if (shdr_info[cnt].shdr.sh_offset == 0)
2077 shdr_info[cnt].shdr.sh_offset
2078 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
2079 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
2081 /* Set the section header in the new file. */
2082 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
2083 /* There cannot be any overflows. */
2084 INTERNAL_ERROR (fname);
2086 /* Remember the last section written so far. */
2087 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
2088 ? shdr_info[cnt].shdr.sh_size : 0);
2089 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
2090 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
2094 /* We might have to update the unallocated sections after we done the
2095 allocated ones. lastoffset is set to right after the last allocated
2097 if (mixed_allocated_unallocated)
2098 for (cnt = 1; cnt <= shdridx; ++cnt)
2099 if (shdr_info[cnt].idx > 0)
2101 scn = elf_getscn (newelf, shdr_info[cnt].idx);
2102 if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
2104 if (shdr_info[cnt].shdr.sh_offset == 0)
2105 shdr_info[cnt].shdr.sh_offset
2106 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
2107 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
2109 /* Set the section header in the new file. */
2110 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
2111 /* There cannot be any overflows. */
2112 INTERNAL_ERROR (fname);
2114 /* Remember the last section written so far. */
2115 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
2116 ? shdr_info[cnt].shdr.sh_size : 0);
2117 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
2118 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
2122 /* Adjust symbol references if symbol tables changed. */
2123 if (any_symtab_changes)
2124 /* Find all relocation sections which use this symbol table. */
2125 for (cnt = 1; cnt <= shdridx; ++cnt)
2127 /* Update section headers when the data size has changed.
2128 We also update the SHT_NOBITS section in the debug
2129 file so that the section headers match in sh_size. */
2130 inline void update_section_size (const Elf_Data *newdata)
2133 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2134 shdr->sh_size = newdata->d_size;
2135 (void) gelf_update_shdr (scn, shdr);
2136 if (debugelf != NULL)
2138 /* libelf will use d_size to set sh_size. */
2139 Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
2141 if (debugdata == NULL)
2142 INTERNAL_ERROR (fname);
2143 debugdata->d_size = newdata->d_size;
2147 if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
2148 /* Ignore sections which are discarded. When we are saving a
2149 relocation section in a separate debug file, we must fix up
2150 the symbol table references. */
2153 const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
2154 elf_assert (symtabidx < shnum + 2);
2155 const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
2156 switch (shdr_info[cnt].shdr.sh_type)
2158 inline bool no_symtab_updates (void)
2160 /* If the symbol table hasn't changed, do not do anything. */
2161 if (shdr_info[symtabidx].newsymidx == NULL)
2164 /* If the symbol table is not discarded, but additionally
2165 duplicated in the separate debug file and this section
2166 is discarded, don't adjust anything. */
2167 return (shdr_info[cnt].idx == 0
2168 && shdr_info[symtabidx].debug_data != NULL);
2173 if (no_symtab_updates ())
2176 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
2177 ? elf_getscn (debugelf, cnt)
2178 : elf_getscn (newelf,
2179 shdr_info[cnt].idx),
2181 elf_assert (d != NULL && d->d_buf != NULL
2182 && shdr_info[cnt].shdr.sh_entsize != 0);
2183 size_t nrels = (shdr_info[cnt].shdr.sh_size
2184 / shdr_info[cnt].shdr.sh_entsize);
2186 size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2187 const Elf32_Word symidxn = (shdr_info[symtabidx].data->d_size
2189 if (shdr_info[cnt].shdr.sh_type == SHT_REL)
2190 for (size_t relidx = 0; relidx < nrels; ++relidx)
2193 if (gelf_getrel (d, relidx, &rel_mem) == NULL)
2194 INTERNAL_ERROR (fname);
2196 size_t symidx = GELF_R_SYM (rel_mem.r_info);
2197 elf_assert (symidx < symidxn);
2198 if (newsymidx[symidx] != symidx)
2201 = GELF_R_INFO (newsymidx[symidx],
2202 GELF_R_TYPE (rel_mem.r_info));
2204 if (gelf_update_rel (d, relidx, &rel_mem) == 0)
2205 INTERNAL_ERROR (fname);
2209 for (size_t relidx = 0; relidx < nrels; ++relidx)
2212 if (gelf_getrela (d, relidx, &rel_mem) == NULL)
2213 INTERNAL_ERROR (fname);
2215 size_t symidx = GELF_R_SYM (rel_mem.r_info);
2216 elf_assert (symidx < symidxn);
2217 if (newsymidx[symidx] != symidx)
2220 = GELF_R_INFO (newsymidx[symidx],
2221 GELF_R_TYPE (rel_mem.r_info));
2223 if (gelf_update_rela (d, relidx, &rel_mem) == 0)
2224 INTERNAL_ERROR (fname);
2230 if (no_symtab_updates ())
2233 /* We have to recompute the hash table. */
2235 elf_assert (shdr_info[cnt].idx > 0);
2237 /* The hash section in the new file. */
2238 scn = elf_getscn (newelf, shdr_info[cnt].idx);
2240 /* The symbol table data. */
2241 Elf_Data *symd = elf_getdata (elf_getscn (newelf,
2242 shdr_info[symtabidx].idx),
2244 elf_assert (symd != NULL && symd->d_buf != NULL);
2246 /* The hash table data. */
2247 Elf_Data *hashd = elf_getdata (scn, NULL);
2248 elf_assert (hashd != NULL && hashd->d_buf != NULL);
2250 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
2252 /* Sane arches first. */
2253 elf_assert (hashd->d_size >= 2 * sizeof (Elf32_Word));
2254 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
2256 size_t strshndx = shdr_info[symtabidx].old_sh_link;
2257 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2259 Elf32_Word nchain = bucket[1];
2260 Elf32_Word nbucket = bucket[0];
2261 uint64_t used_buf = ((2ULL + nchain + nbucket)
2262 * sizeof (Elf32_Word));
2263 elf_assert (used_buf <= hashd->d_size);
2265 /* Adjust the nchain value. The symbol table size
2266 changed. We keep the same size for the bucket array. */
2267 bucket[1] = symd->d_size / elsize;
2269 Elf32_Word *chain = bucket + nbucket;
2271 /* New size of the section. */
2272 size_t n_size = ((2 + symd->d_size / elsize + nbucket)
2273 * sizeof (Elf32_Word));
2274 elf_assert (n_size <= hashd->d_size);
2275 hashd->d_size = n_size;
2276 update_section_size (hashd);
2278 /* Clear the arrays. */
2279 memset (bucket, '\0',
2280 (symd->d_size / elsize + nbucket)
2281 * sizeof (Elf32_Word));
2283 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
2284 inner < symd->d_size / elsize; ++inner)
2287 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
2288 elf_assert (sym != NULL);
2290 const char *name = elf_strptr (elf, strshndx,
2292 elf_assert (name != NULL && nbucket != 0);
2293 size_t hidx = elf_hash (name) % nbucket;
2295 if (bucket[hidx] == 0)
2296 bucket[hidx] = inner;
2299 hidx = bucket[hidx];
2301 while (chain[hidx] != 0 && chain[hidx] < nchain)
2304 chain[hidx] = inner;
2310 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
2311 elf_assert (shdr_info[cnt].shdr.sh_entsize
2312 == sizeof (Elf64_Xword));
2314 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
2316 size_t strshndx = shdr_info[symtabidx].old_sh_link;
2317 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2319 elf_assert (symd->d_size >= 2 * sizeof (Elf64_Xword));
2320 Elf64_Xword nbucket = bucket[0];
2321 Elf64_Xword nchain = bucket[1];
2322 uint64_t maxwords = hashd->d_size / sizeof (Elf64_Xword);
2323 elf_assert (maxwords >= 2
2324 && maxwords - 2 >= nbucket
2325 && maxwords - 2 - nbucket >= nchain);
2327 /* Adjust the nchain value. The symbol table size
2328 changed. We keep the same size for the bucket array. */
2329 bucket[1] = symd->d_size / elsize;
2331 Elf64_Xword *chain = bucket + nbucket;
2333 /* New size of the section. */
2334 size_t n_size = ((2 + symd->d_size / elsize + nbucket)
2335 * sizeof (Elf64_Xword));
2336 elf_assert (n_size <= hashd->d_size);
2337 hashd->d_size = n_size;
2338 update_section_size (hashd);
2340 /* Clear the arrays. */
2341 memset (bucket, '\0',
2342 (symd->d_size / elsize + nbucket)
2343 * sizeof (Elf64_Xword));
2345 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
2346 inner < symd->d_size / elsize; ++inner)
2349 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
2350 elf_assert (sym != NULL);
2352 const char *name = elf_strptr (elf, strshndx,
2354 elf_assert (name != NULL && nbucket != 0);
2355 size_t hidx = elf_hash (name) % nbucket;
2357 if (bucket[hidx] == 0)
2358 bucket[hidx] = inner;
2361 hidx = bucket[hidx];
2363 while (chain[hidx] != 0 && chain[hidx] < nchain)
2366 chain[hidx] = inner;
2372 case SHT_GNU_versym:
2373 /* If the symbol table changed we have to adjust the entries. */
2374 if (no_symtab_updates ())
2377 elf_assert (shdr_info[cnt].idx > 0);
2379 /* The symbol version section in the new file. */
2380 scn = elf_getscn (newelf, shdr_info[cnt].idx);
2382 /* The symbol table data. */
2383 symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
2385 elf_assert (symd != NULL && symd->d_buf != NULL);
2386 size_t symz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2387 const Elf32_Word syms = (shdr_info[symtabidx].data->d_size / symz);
2389 /* The version symbol data. */
2390 Elf_Data *verd = elf_getdata (scn, NULL);
2391 elf_assert (verd != NULL && verd->d_buf != NULL);
2393 /* The symbol version array. */
2394 GElf_Half *verstab = (GElf_Half *) verd->d_buf;
2396 /* Walk through the list and */
2397 size_t elsize = gelf_fsize (elf, verd->d_type, 1, EV_CURRENT);
2398 Elf32_Word vers = verd->d_size / elsize;
2399 for (size_t inner = 1; inner < vers && inner < syms; ++inner)
2400 if (newsymidx[inner] != 0 && newsymidx[inner] < vers)
2401 /* Overwriting the same array works since the
2402 reordering can only move entries to lower indices
2404 verstab[newsymidx[inner]] = verstab[inner];
2406 /* New size of the section. */
2407 verd->d_size = gelf_fsize (newelf, verd->d_type,
2409 / gelf_fsize (elf, symd->d_type, 1,
2412 update_section_size (verd);
2416 if (no_symtab_updates ())
2419 /* Yes, the symbol table changed.
2420 Update the section header of the section group. */
2421 scn = elf_getscn (newelf, shdr_info[cnt].idx);
2423 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2424 elf_assert (shdr != NULL);
2426 size_t symsz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2427 const Elf32_Word symn = (shdr_info[symtabidx].data->d_size
2429 elf_assert (shdr->sh_info < symn);
2430 shdr->sh_info = newsymidx[shdr->sh_info];
2432 (void) gelf_update_shdr (scn, shdr);
2437 /* Remove any relocations between debug sections in ET_REL
2438 for the debug file when requested. These relocations are always
2439 zero based between the unallocated sections. */
2440 if (debug_fname != NULL && removing_sections
2441 && reloc_debug && ehdr->e_type == ET_REL)
2442 remove_debug_relocations (ebl, debugelf, ehdr, fname, shstrndx);
2444 /* Now that we have done all adjustments to the data,
2445 we can actually write out the debug file. */
2446 if (debug_fname != NULL && removing_sections)
2448 /* Finally write the file. */
2449 if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
2451 error (0, 0, gettext ("while writing '%s': %s"),
2452 tmp_debug_fname, elf_errmsg (-1));
2457 /* Create the real output file. First rename, then change the
2459 if (rename (tmp_debug_fname, debug_fname) != 0
2460 || fchmod (debug_fd, mode) != 0)
2462 error (0, errno, gettext ("while creating '%s'"), debug_fname);
2467 /* The temporary file does not exist anymore. */
2468 free (tmp_debug_fname);
2469 tmp_debug_fname = NULL;
2474 Elf_Data debug_crc_data =
2476 .d_type = ELF_T_WORD,
2477 .d_buf = &debug_crc,
2478 .d_size = sizeof (debug_crc),
2479 .d_version = EV_CURRENT
2482 /* Compute the checksum which we will add to the executable. */
2483 if (crc32_file (debug_fd, &debug_crc) != 0)
2485 error (0, errno, gettext ("\
2486 while computing checksum for debug information"));
2487 unlink (debug_fname);
2492 /* Store it in the debuglink section data. */
2493 if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
2494 &debug_crc_data, ehdr->e_ident[EI_DATA])
2495 != &debuglink_crc_data))
2496 INTERNAL_ERROR (fname);
2500 lastsec_offset = shdr_info[shdridx].shdr.sh_offset;
2501 lastsec_size = shdr_info[shdridx].shdr.sh_size;
2504 /* Finally finish the ELF header. Fill in the fields not handled by
2505 libelf from the old file. */
2506 newehdr = gelf_getehdr (newelf, &newehdr_mem);
2507 if (newehdr == NULL)
2508 INTERNAL_ERROR (fname);
2510 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
2511 newehdr->e_type = ehdr->e_type;
2512 newehdr->e_machine = ehdr->e_machine;
2513 newehdr->e_version = ehdr->e_version;
2514 newehdr->e_entry = ehdr->e_entry;
2515 newehdr->e_flags = ehdr->e_flags;
2516 newehdr->e_phoff = ehdr->e_phoff;
2518 /* We need to position the section header table. */
2519 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
2520 newehdr->e_shoff = ((lastsec_offset + lastsec_size + offsize - 1)
2521 & ~((GElf_Off) (offsize - 1)));
2522 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
2524 if (gelf_update_ehdr (newelf, newehdr) == 0)
2526 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
2527 output_fname ?: fname, elf_errmsg (-1));
2532 /* The new section header string table index. */
2533 if (update_shdrstrndx (newelf, idx) != 0)
2535 error (0, 0, gettext ("%s: error updating shdrstrndx: %s"),
2536 output_fname ?: fname, elf_errmsg (-1));
2541 /* We have everything from the old file. */
2542 if (elf_cntl (elf, ELF_C_FDDONE) != 0)
2544 error (0, 0, gettext ("%s: error while reading the file: %s"),
2545 fname, elf_errmsg (-1));
2550 /* The ELF library better follows our layout when this is not a
2551 relocatable object file. */
2552 elf_flagelf (newelf, ELF_C_SET,
2553 (phnum > 0 ? ELF_F_LAYOUT : 0)
2554 | (permissive ? ELF_F_PERMISSIVE : 0));
2556 /* Finally write the file. */
2557 if (elf_update (newelf, ELF_C_WRITE) == -1)
2559 error (0, 0, gettext ("while writing '%s': %s"),
2560 output_fname ?: fname, elf_errmsg (-1));
2566 /* libelf can't cope without the section headers being properly intact.
2567 So we just let it write them normally, and then we nuke them later. */
2569 if (newehdr->e_ident[EI_CLASS] == ELFCLASS32)
2571 assert (offsetof (Elf32_Ehdr, e_shentsize) + sizeof (Elf32_Half)
2572 == offsetof (Elf32_Ehdr, e_shnum));
2573 assert (offsetof (Elf32_Ehdr, e_shnum) + sizeof (Elf32_Half)
2574 == offsetof (Elf32_Ehdr, e_shstrndx));
2575 const Elf32_Off zero_off = 0;
2576 const Elf32_Half zero[3] = { 0, 0, SHN_UNDEF };
2577 if (pwrite_retry (fd, &zero_off, sizeof zero_off,
2578 offsetof (Elf32_Ehdr, e_shoff)) != sizeof zero_off
2579 || (pwrite_retry (fd, zero, sizeof zero,
2580 offsetof (Elf32_Ehdr, e_shentsize))
2582 || ftruncate (fd, lastsec_offset) < 0)
2584 error (0, errno, gettext ("while writing '%s'"),
2585 output_fname ?: fname);
2591 assert (offsetof (Elf64_Ehdr, e_shentsize) + sizeof (Elf64_Half)
2592 == offsetof (Elf64_Ehdr, e_shnum));
2593 assert (offsetof (Elf64_Ehdr, e_shnum) + sizeof (Elf64_Half)
2594 == offsetof (Elf64_Ehdr, e_shstrndx));
2595 const Elf64_Off zero_off = 0;
2596 const Elf64_Half zero[3] = { 0, 0, SHN_UNDEF };
2597 if (pwrite_retry (fd, &zero_off, sizeof zero_off,
2598 offsetof (Elf64_Ehdr, e_shoff)) != sizeof zero_off
2599 || (pwrite_retry (fd, zero, sizeof zero,
2600 offsetof (Elf64_Ehdr, e_shentsize))
2602 || ftruncate (fd, lastsec_offset) < 0)
2604 error (0, errno, gettext ("while writing '%s'"),
2605 output_fname ?: fname);
2612 if (shdr_info != NULL)
2614 /* For some sections we might have created an table to map symbol
2615 table indices. Or we might kept (original) data around to put
2616 into the .debug file. */
2617 for (cnt = 1; cnt <= shdridx; ++cnt)
2619 free (shdr_info[cnt].newsymidx);
2620 if (shdr_info[cnt].debug_data != NULL)
2621 free (shdr_info[cnt].debug_data->d_buf);
2624 /* Free data we allocated for the .gnu_debuglink section. */
2625 free (debuglink_buf);
2627 /* Free the memory. */
2628 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
2632 /* Free other resources. */
2633 if (shstrtab_data != NULL)
2634 free (shstrtab_data->d_buf);
2636 dwelf_strtab_free (shst);
2638 /* That was it. Close the descriptors. */
2639 if (elf_end (newelf) != 0)
2641 error (0, 0, gettext ("error while finishing '%s': %s"),
2642 output_fname ?: fname, elf_errmsg (-1));
2646 if (debugelf != NULL && elf_end (debugelf) != 0)
2648 error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
2654 /* Close the EBL backend. */
2656 ebl_closebackend (ebl);
2660 /* If requested, preserve the timestamp. */
2663 if (futimens (fd, tvp) != 0)
2665 error (0, errno, gettext ("\
2666 cannot set access and modification date of '%s'"),
2667 output_fname ?: fname);
2672 /* Close the file descriptor if we created a new file. */
2673 if (output_fname != NULL)
2677 unlink (output_fname);
2684 cleanup_debug (void)
2688 if (tmp_debug_fname != NULL)
2690 unlink (tmp_debug_fname);
2691 free (tmp_debug_fname);
2692 tmp_debug_fname = NULL;
2700 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
2701 struct timespec tvp[2])
2703 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
2704 size_t fname_len = strlen (fname) + 1;
2705 char new_prefix[prefix_len + 1 + fname_len];
2706 char *cp = new_prefix;
2708 /* Create the full name of the file. */
2711 cp = mempcpy (cp, prefix, prefix_len);
2714 memcpy (cp, fname, fname_len);
2717 /* Process all the files contained in the archive. */
2719 Elf_Cmd cmd = ELF_C_RDWR;
2721 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
2723 /* The the header for this element. */
2724 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
2726 if (elf_kind (subelf) == ELF_K_ELF)
2727 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
2728 else if (elf_kind (subelf) == ELF_K_AR)
2729 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
2731 /* Get next archive element. */
2732 cmd = elf_next (subelf);
2733 if (unlikely (elf_end (subelf) != 0))
2734 INTERNAL_ERROR (fname);
2739 if (unlikely (futimens (fd, tvp) != 0))
2741 error (0, errno, gettext ("\
2742 cannot set access and modification date of '%s'"), fname);
2747 if (unlikely (close (fd) != 0))
2748 error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
2754 #include "debugpred.h"