2007-04-24 Roland McGrath <roland@redhat.com>
[platform/upstream/elfutils.git] / src / strip.c
1 /* Discard section not used at runtime from object files.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
3    This file is part of Red Hat elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5
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.
9
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.
14
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.
18
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>.  */
26
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30
31 #include <argp.h>
32 #include <assert.h>
33 #include <byteswap.h>
34 #include <endian.h>
35 #include <error.h>
36 #include <fcntl.h>
37 #include <gelf.h>
38 #include <libelf.h>
39 #include <libintl.h>
40 #include <locale.h>
41 #include <mcheck.h>
42 #include <stdbool.h>
43 #include <stdio.h>
44 #include <stdio_ext.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <sys/param.h>
49 #include <sys/time.h>
50
51 #include <elf-knowledge.h>
52 #include <libebl.h>
53 #include <system.h>
54
55
56 /* Name and version of program.  */
57 static void print_version (FILE *stream, struct argp_state *state);
58 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
59
60 /* Bug report address.  */
61 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
62
63
64 /* Values for the parameters which have no short form.  */
65 #define OPT_REMOVE_COMMENT      0x100
66 #define OPT_PERMISSIVE          0x101
67
68
69 /* Definitions of arguments for argp functions.  */
70 static const struct argp_option options[] =
71 {
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 },
76
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 }
90 };
91
92 /* Short description of program.  */
93 static const char doc[] = N_("Discard symbols from object files.");
94
95 /* Strings for arguments in help texts.  */
96 static const char args_doc[] = N_("[FILE...]");
97
98 /* Prototype for option handler.  */
99 static error_t parse_opt (int key, char *arg, struct argp_state *state);
100
101 /* Data structure to communicate with argp functions.  */
102 static struct argp argp =
103 {
104   options, parse_opt, args_doc, doc, NULL, NULL, NULL
105 };
106
107
108 /* Print symbols in file named FNAME.  */
109 static int process_file (const char *fname);
110
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]);
114
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]);
118
119 #define INTERNAL_ERROR(fname) \
120   error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"),      \
121          fname, __LINE__, VERSION, __DATE__, elf_errmsg (-1))
122
123
124 /* Name of the output file.  */
125 static const char *output_fname;
126
127 /* Name of the debug output file.  */
128 static const char *debug_fname;
129
130 /* Name to pretend the debug output file has.  */
131 static const char *debug_fname_embed;
132
133 /* If true output files shall have same date as the input file.  */
134 static bool preserve_dates;
135
136 /* If true .comment sections will be removed.  */
137 static bool remove_comment;
138
139 /* If true remove all debug sections.  */
140 static bool remove_debug;
141
142 /* If true relax some ELF rules for input files.  */
143 static bool permissive;
144
145
146 int
147 main (int argc, char *argv[])
148 {
149   int remaining;
150   int result = 0;
151
152   /* Make memory leak detection possible.  */
153   mtrace ();
154
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);
159
160   /* Set locale.  */
161   setlocale (LC_ALL, "");
162
163   /* Make sure the message catalog can be found.  */
164   bindtextdomain (PACKAGE, LOCALEDIR);
165
166   /* Initialize the message catalog.  */
167   textdomain (PACKAGE);
168
169   /* Parse and process arguments.  */
170   if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
171     return EXIT_FAILURE;
172
173   /* Tell the library which version we are expecting.  */
174   elf_version (EV_CURRENT);
175
176   if (remaining == argc)
177     /* The user didn't specify a name so we use a.out.  */
178     result = process_file ("a.out");
179   else
180     {
181       /* If we have seen the '-o' or '-f' option there must be exactly one
182          input file.  */
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'"));
187
188       /* Process all the remaining files.  */
189       do
190         result |= process_file (argv[remaining]);
191       while (++remaining < argc);
192     }
193
194   return result;
195 }
196
197
198 /* Print the version information.  */
199 static void
200 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
201 {
202   fprintf (stream, "strip (%s) %s\n", PACKAGE_NAME, 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\
207 "), "2007");
208   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
209 }
210
211
212 /* Handle program arguments.  */
213 static error_t
214 parse_opt (int key, char *arg, struct argp_state *state)
215 {
216   switch (key)
217     {
218     case 'f':
219       if (debug_fname != NULL)
220         {
221           error (0, 0, gettext ("-f option specified twice"));
222           return EINVAL;
223         }
224       debug_fname = arg;
225       break;
226
227     case 'F':
228       if (debug_fname_embed != NULL)
229         {
230           error (0, 0, gettext ("-F option specified twice"));
231           return EINVAL;
232         }
233       debug_fname_embed = arg;
234       break;
235
236     case 'o':
237       if (output_fname != NULL)
238         {
239           error (0, 0, gettext ("-o option specified twice"));
240           return EINVAL;
241         }
242       output_fname = arg;
243       break;
244
245     case 'p':
246       preserve_dates = true;
247       break;
248
249     case OPT_REMOVE_COMMENT:
250       remove_comment = true;
251       break;
252
253     case 'R':
254       if (!strcmp (arg, ".comment"))
255         remove_comment = true;
256       else
257         {
258           argp_error (state,
259                       gettext ("-R option supports only .comment section"));
260           return EINVAL;
261         }
262       break;
263
264     case 'g':
265     case 'd':
266     case 'S':
267       remove_debug = true;
268       break;
269
270     case OPT_PERMISSIVE:
271       permissive = true;
272       break;
273
274     case 's':                   /* Ignored for compatibility.  */
275       break;
276
277     default:
278       return ARGP_ERR_UNKNOWN;
279     }
280   return 0;
281 }
282
283
284 static int
285 process_file (const char *fname)
286 {
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];
292  again:
293   if (preserve_dates)
294     {
295       if (stat64 (fname, &pre_st) != 0)
296         {
297           error (0, errno, gettext ("cannot stat input file '%s'"), fname);
298           return 1;
299         }
300
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);
305     }
306
307   /* Open the file.  */
308   int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
309   if (fd == -1)
310     {
311       error (0, errno, gettext ("while opening '%s'"), fname);
312       return 1;
313     }
314
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
317      same file.  */
318   struct stat64 st;
319   if (fstat64 (fd, &st) != 0)
320     {
321       error (0, errno, gettext ("cannot stat input file '%s'"), fname);
322       return 1;
323     }
324   /* Paranoid mode on.  */
325   if (preserve_dates
326       && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
327     {
328       /* We detected a race.  Try again.  */
329       close (fd);
330       goto again;
331     }
332
333   /* Now get the ELF descriptor.  */
334   Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
335                         NULL);
336   int result;
337   switch (elf_kind (elf))
338     {
339     case ELF_K_ELF:
340       result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
341                            preserve_dates ? tv : NULL);
342       break;
343
344     case ELF_K_AR:
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))
348         {
349           error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"),
350                  fname);
351           result = 1;
352         }
353       else
354         result = handle_ar (fd, elf, NULL, fname, preserve_dates ? tv : NULL);
355       break;
356
357     default:
358       error (0, 0, gettext ("%s: File format not recognized"), fname);
359       result = 1;
360       break;
361     }
362
363   if (unlikely (elf_end (elf) != 0))
364     INTERNAL_ERROR (fname);
365
366   close (fd);
367
368   return result;
369 }
370
371
372 /* Maximum size of array allocated on stack.  */
373 #define MAX_STACK_ALLOC (400 * 1024)
374
375 static int
376 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
377             mode_t mode, struct timeval tvp[2])
378 {
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);
382   char *cp = fullname;
383   Elf *debugelf = NULL;
384   char *tmp_debug_fname = NULL;
385   int result = 0;
386   size_t shstrndx;
387   struct shdr_info
388   {
389     Elf_Scn *scn;
390     GElf_Shdr shdr;
391     Elf_Data *data;
392     const char *name;
393     Elf32_Word idx;             /* Index in new file.  */
394     Elf32_Word old_sh_link;     /* Original value of shdr.sh_link.  */
395     Elf32_Word symtab_idx;
396     Elf32_Word version_idx;
397     Elf32_Word group_idx;
398     Elf32_Word group_cnt;
399     Elf_Scn *newscn;
400     struct Ebl_Strent *se;
401     Elf32_Word *newsymidx;
402   } *shdr_info = NULL;
403   Elf_Scn *scn;
404   size_t cnt;
405   size_t idx;
406   bool changes;
407   GElf_Ehdr newehdr_mem;
408   GElf_Ehdr *newehdr;
409   GElf_Ehdr debugehdr_mem;
410   GElf_Ehdr *debugehdr;
411   struct Ebl_Strtab *shst = NULL;
412   Elf_Data debuglink_crc_data;
413   bool any_symtab_changes = false;
414   Elf_Data *shstrtab_data = NULL;
415
416   /* Create the full name of the file.  */
417   if (prefix != NULL)
418     {
419       cp = mempcpy (cp, prefix, prefix_len);
420       *cp++ = ':';
421     }
422   memcpy (cp, fname, fname_len);
423
424   /* If we are not replacing the input file open a new file here.  */
425   if (output_fname != NULL)
426     {
427       fd = open (output_fname, O_RDWR | O_CREAT, mode);
428       if (unlikely (fd == -1))
429         {
430           error (0, errno, gettext ("cannot open '%s'"), output_fname);
431           return 1;
432         }
433     }
434
435   int debug_fd = -1;
436
437   /* Get the EBL handling.  The -g option is currently the only reason
438      we need EBL so dont open the backend unless necessary.  */
439   Ebl *ebl = NULL;
440   if (remove_debug)
441     {
442       ebl = ebl_openbackend (elf);
443       if (ebl == NULL)
444         {
445           error (0, errno, gettext ("cannot open EBL backend"));
446           result = 1;
447           goto fail;
448         }
449     }
450
451   /* Open the additional file the debug information will be stored in.  */
452   if (debug_fname != NULL)
453     {
454       /* Create a temporary file name.  We do not want to overwrite
455          the debug file if the file would not contain any
456          information.  */
457       size_t debug_fname_len = strlen (debug_fname);
458       tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX"));
459       strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
460               ".XXXXXX");
461
462       debug_fd = mkstemp (tmp_debug_fname);
463       if (unlikely (debug_fd == -1))
464         {
465           error (0, errno, gettext ("cannot open '%s'"), debug_fname);
466           result = 1;
467           goto fail;
468         }
469     }
470
471   /* Get the information from the old file.  */
472   GElf_Ehdr ehdr_mem;
473   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
474   if (ehdr == NULL)
475     INTERNAL_ERROR (fname);
476
477   /* Get the section header string table index.  */
478   if (unlikely (elf_getshstrndx (elf, &shstrndx) < 0))
479     error (EXIT_FAILURE, 0,
480            gettext ("cannot get section header string table index"));
481
482   /* We now create a new ELF descriptor for the same file.  We
483      construct it almost exactly in the same way with some information
484      dropped.  */
485   Elf *newelf;
486   if (output_fname != NULL)
487     newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
488   else
489     newelf = elf_clone (elf, ELF_C_EMPTY);
490
491   if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
492       || (ehdr->e_type != ET_REL
493           && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0)))
494     {
495       error (0, 0, gettext ("cannot create new file '%s': %s"),
496              output_fname, elf_errmsg (-1));
497       goto fail;
498     }
499
500   /* Copy over the old program header if needed.  */
501   if (ehdr->e_type != ET_REL)
502     for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
503       {
504         GElf_Phdr phdr_mem;
505         GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
506         if (phdr == NULL
507             || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
508           INTERNAL_ERROR (fname);
509       }
510
511   if (debug_fname != NULL)
512     {
513       /* Also create an ELF descriptor for the debug file */
514       debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
515       if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
516           || (ehdr->e_type != ET_REL
517               && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0)))
518         {
519           error (0, 0, gettext ("cannot create new file '%s': %s"),
520                  debug_fname, elf_errmsg (-1));
521           goto fail_close;
522         }
523
524       /* Copy over the old program header if needed.  */
525       if (ehdr->e_type != ET_REL)
526         for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
527           {
528             GElf_Phdr phdr_mem;
529             GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
530             if (phdr == NULL
531                 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
532               INTERNAL_ERROR (fname);
533           }
534     }
535
536   /* Number of sections.  */
537   size_t shnum;
538   if (unlikely (elf_getshnum (elf, &shnum) < 0))
539     {
540       error (0, 0, gettext ("cannot determine number of sections: %s"),
541              elf_errmsg (-1));
542       goto fail_close;
543     }
544
545   /* Storage for section information.  We leave room for two more
546      entries since we unconditionally create a section header string
547      table.  Maybe some weird tool created an ELF file without one.
548      The other one is used for the debug link section.  */
549   if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
550     shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
551                                               sizeof (struct shdr_info));
552   else
553     {
554       shdr_info = (struct shdr_info *) alloca ((shnum + 2)
555                                                * sizeof (struct shdr_info));
556       memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
557     }
558
559   /* Prepare section information data structure.  */
560   scn = NULL;
561   cnt = 1;
562   while ((scn = elf_nextscn (elf, scn)) != NULL)
563     {
564       /* This should always be true (i.e., there should not be any
565          holes in the numbering).  */
566       assert (elf_ndxscn (scn) == cnt);
567
568       shdr_info[cnt].scn = scn;
569
570       /* Get the header.  */
571       if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
572         INTERNAL_ERROR (fname);
573
574       /* Get the name of the section.  */
575       shdr_info[cnt].name = elf_strptr (elf, shstrndx,
576                                         shdr_info[cnt].shdr.sh_name);
577       if (shdr_info[cnt].name == NULL)
578         {
579           error (0, 0, gettext ("illformed file '%s'"), fname);
580           goto fail_close;
581         }
582
583       /* Mark them as present but not yet investigated.  */
584       shdr_info[cnt].idx = 1;
585
586       /* Remember the shdr.sh_link value.  */
587       shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
588
589       /* Sections in files other than relocatable object files which
590          are not loaded can be freely moved by us.  In relocatable
591          object files everything can be moved.  */
592       if (ehdr->e_type == ET_REL
593           || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
594         shdr_info[cnt].shdr.sh_offset = 0;
595
596       /* If this is an extended section index table store an
597          appropriate reference.  */
598       if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
599         {
600           assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
601           shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
602         }
603       else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
604         {
605           /* Cross-reference the sections contained in the section
606              group.  */
607           shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
608           if (shdr_info[cnt].data == NULL)
609             INTERNAL_ERROR (fname);
610
611           /* XXX Fix for unaligned access.  */
612           Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
613           size_t inner;
614           for (inner = 1;
615                inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
616                ++inner)
617             shdr_info[grpref[inner]].group_idx = cnt;
618
619           if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
620             /* If the section group contains only one element and this
621                is n COMDAT section we can drop it right away.  */
622             shdr_info[cnt].idx = 0;
623           else
624             shdr_info[cnt].group_cnt = inner - 1;
625         }
626       else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
627         {
628           assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
629           shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
630         }
631
632       /* If this section is part of a group make sure it is not
633          discarded right away.  */
634       if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
635         {
636           assert (shdr_info[cnt].group_idx != 0);
637
638           if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
639             {
640               /* The section group section will be removed.  */
641               shdr_info[cnt].group_idx = 0;
642               shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP;
643             }
644         }
645
646       /* Increment the counter.  */
647       ++cnt;
648     }
649
650   /* Now determine which sections can go away.  The general rule is that
651      all sections which are not used at runtime are stripped out.  But
652      there are a few exceptions:
653
654      - special sections named ".comment" and ".note" are kept
655      - OS or architecture specific sections are kept since we might not
656        know how to handle them
657      - if a section is referred to from a section which is not removed
658        in the sh_link or sh_info element it cannot be removed either
659   */
660   for (cnt = 1; cnt < shnum; ++cnt)
661     /* Check whether the section can be removed.  */
662     if (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr,
663                              shdr_info[cnt].name, remove_comment,
664                              remove_debug))
665       {
666         /* For now assume this section will be removed.  */
667         shdr_info[cnt].idx = 0;
668
669         idx = shdr_info[cnt].group_idx;
670         while (idx != 0)
671           {
672             /* The section group data is already loaded.  */
673             assert (shdr_info[idx].data != NULL);
674
675             /* If the references section group is a normal section
676                group and has one element remaining, or if it is an
677                empty COMDAT section group it is removed.  */
678             bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
679                               & GRP_COMDAT) != 0;
680
681             --shdr_info[idx].group_cnt;
682             if ((!is_comdat && shdr_info[idx].group_cnt == 1)
683                 || (is_comdat && shdr_info[idx].group_cnt == 0))
684               {
685                 shdr_info[idx].idx = 0;
686                 /* Continue recursively.  */
687                 idx = shdr_info[idx].group_idx;
688               }
689             else
690               break;
691           }
692       }
693
694   /* Mark the SHT_NULL section as handled.  */
695   shdr_info[0].idx = 2;
696
697
698   /* Handle exceptions: section groups and cross-references.  We might
699      have to repeat this a few times since the resetting of the flag
700      might propagate.  */
701   do
702     {
703       changes = false;
704
705       for (cnt = 1; cnt < shnum; ++cnt)
706         {
707           if (shdr_info[cnt].idx == 0)
708             {
709               /* If a relocation section is marked as being removed make
710                  sure the section it is relocating is removed, too.  */
711               if ((shdr_info[cnt].shdr.sh_type == SHT_REL
712                    || shdr_info[cnt].shdr.sh_type == SHT_RELA)
713                   && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
714                 shdr_info[cnt].idx = 1;
715             }
716
717           if (shdr_info[cnt].idx == 1)
718             {
719               /* The content of symbol tables we don't remove must not
720                  reference any section which we do remove.  Otherwise
721                  we cannot remove the section.  */
722               if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
723                   || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
724                 {
725                   /* Make sure the data is loaded.  */
726                   if (shdr_info[cnt].data == NULL)
727                     {
728                       shdr_info[cnt].data
729                         = elf_getdata (shdr_info[cnt].scn, NULL);
730                       if (shdr_info[cnt].data == NULL)
731                         INTERNAL_ERROR (fname);
732                     }
733                   Elf_Data *symdata = shdr_info[cnt].data;
734
735                   /* If there is an extended section index table load it
736                      as well.  */
737                   if (shdr_info[cnt].symtab_idx != 0
738                       && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
739                     {
740                       assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
741
742                       shdr_info[shdr_info[cnt].symtab_idx].data
743                         = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
744                                        NULL);
745                       if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
746                         INTERNAL_ERROR (fname);
747                     }
748                   Elf_Data *xndxdata
749                     = shdr_info[shdr_info[cnt].symtab_idx].data;
750
751                   /* Go through all symbols and make sure the section they
752                      reference is not removed.  */
753                   size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
754                                               ehdr->e_version);
755
756                   for (size_t inner = 0;
757                        inner < shdr_info[cnt].data->d_size / elsize;
758                        ++inner)
759                     {
760                       GElf_Sym sym_mem;
761                       Elf32_Word xndx;
762                       GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
763                                                         inner, &sym_mem,
764                                                         &xndx);
765                       if (sym == NULL)
766                         INTERNAL_ERROR (fname);
767
768                       size_t scnidx = sym->st_shndx;
769                       if (scnidx == SHN_UNDEF || scnidx >= shnum
770                           || (scnidx >= SHN_LORESERVE
771                               && scnidx <= SHN_HIRESERVE
772                               && scnidx != SHN_XINDEX)
773                           /* Don't count in the section symbols.  */
774                           || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
775                         /* This is no section index, leave it alone.  */
776                         continue;
777                       else if (scnidx == SHN_XINDEX)
778                         scnidx = xndx;
779
780                       if (shdr_info[scnidx].idx == 0)
781                         {
782                           /* Mark this section as used.  */
783                           shdr_info[scnidx].idx = 1;
784                           changes |= scnidx < cnt;
785                         }
786                     }
787                 }
788
789               /* Cross referencing happens:
790                  - for the cases the ELF specification says.  That are
791                    + SHT_DYNAMIC in sh_link to string table
792                    + SHT_HASH in sh_link to symbol table
793                    + SHT_REL and SHT_RELA in sh_link to symbol table
794                    + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
795                    + SHT_GROUP in sh_link to symbol table
796                    + SHT_SYMTAB_SHNDX in sh_link to symbol table
797                    Other (OS or architecture-specific) sections might as
798                    well use this field so we process it unconditionally.
799                  - references inside section groups
800                  - specially marked references in sh_info if the SHF_INFO_LINK
801                  flag is set
802               */
803
804               if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
805                 {
806                   shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
807                   changes |= shdr_info[cnt].shdr.sh_link < cnt;
808                 }
809
810               /* Handle references through sh_info.  */
811               if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)
812                   && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
813                 {
814                   shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
815                   changes |= shdr_info[cnt].shdr.sh_info < cnt;
816                 }
817
818               /* Mark the section as investigated.  */
819               shdr_info[cnt].idx = 2;
820             }
821         }
822     }
823   while (changes);
824
825   /* Copy the removed sections to the debug output file.
826      The ones that are not removed in the stripped file are SHT_NOBITS.  */
827   if (debug_fname != NULL)
828     {
829       for (cnt = 1; cnt < shnum; ++cnt)
830         {
831           scn = elf_newscn (debugelf);
832           if (scn == NULL)
833             error (EXIT_FAILURE, 0,
834                    gettext ("while generating output file: %s"),
835                    elf_errmsg (-1));
836
837           bool discard_section = (shdr_info[cnt].idx > 0
838                                   && cnt != ehdr->e_shstrndx);
839
840           /* Set the section header in the new file.  */
841           GElf_Shdr debugshdr = shdr_info[cnt].shdr;
842           if (discard_section)
843             debugshdr.sh_type = SHT_NOBITS;
844
845           if (unlikely (gelf_update_shdr (scn, &debugshdr)) == 0)
846             /* There cannot be any overflows.  */
847             INTERNAL_ERROR (fname);
848
849           /* Get the data from the old file if necessary. */
850           if (shdr_info[cnt].data == NULL)
851             {
852               shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
853               if (shdr_info[cnt].data == NULL)
854                 INTERNAL_ERROR (fname);
855             }
856
857           /* Set the data.  This is done by copying from the old file.  */
858           Elf_Data *debugdata = elf_newdata (scn);
859           if (debugdata == NULL)
860             INTERNAL_ERROR (fname);
861
862           /* Copy the structure.  This data may be modified in place
863              before we write out the file.  */
864           *debugdata = *shdr_info[cnt].data;
865           if (discard_section)
866             debugdata->d_buf = NULL;
867         }
868
869       /* Finish the ELF header.  Fill in the fields not handled by
870          libelf from the old file.  */
871       debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
872       if (debugehdr == NULL)
873         INTERNAL_ERROR (fname);
874
875       memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
876       debugehdr->e_type = ehdr->e_type;
877       debugehdr->e_machine = ehdr->e_machine;
878       debugehdr->e_version = ehdr->e_version;
879       debugehdr->e_entry = ehdr->e_entry;
880       debugehdr->e_flags = ehdr->e_flags;
881       debugehdr->e_shstrndx = ehdr->e_shstrndx;
882
883       if (unlikely (gelf_update_ehdr (debugelf, debugehdr)) == 0)
884         {
885           error (0, 0, gettext ("%s: error while creating ELF header: %s"),
886                  debug_fname, elf_errmsg (-1));
887           result = 1;
888           goto fail_close;
889         }
890     }
891
892   /* Mark the section header string table as unused, we will create
893      a new one.  */
894   shdr_info[shstrndx].idx = 0;
895
896   /* We need a string table for the section headers.  */
897   shst = ebl_strtabinit (true);
898   if (shst == NULL)
899     error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
900            output_fname ?: fname);
901
902   /* Assign new section numbers.  */
903   shdr_info[0].idx = 0;
904   for (cnt = idx = 1; cnt < shnum; ++cnt)
905     if (shdr_info[cnt].idx > 0)
906       {
907         shdr_info[cnt].idx = idx++;
908
909         /* Create a new section.  */
910         shdr_info[cnt].newscn = elf_newscn (newelf);
911         if (shdr_info[cnt].newscn == NULL)
912           error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
913                  elf_errmsg (-1));
914
915         assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
916
917         /* Add this name to the section header string table.  */
918         shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
919       }
920
921   /* Test whether we are doing anything at all.  */
922   if (cnt == idx)
923     /* Nope, all removable sections are already gone.  */
924     goto fail_close;
925
926   /* Create the reference to the file with the debug info.  */
927   if (debug_fname != NULL)
928     {
929       /* Add the section header string table section name.  */
930       shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
931       shdr_info[cnt].idx = idx++;
932
933       /* Create the section header.  */
934       shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
935       shdr_info[cnt].shdr.sh_flags = 0;
936       shdr_info[cnt].shdr.sh_addr = 0;
937       shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
938       shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
939       shdr_info[cnt].shdr.sh_entsize = 0;
940       shdr_info[cnt].shdr.sh_addralign = 4;
941       /* We set the offset to zero here.  Before we write the ELF file the
942          field must have the correct value.  This is done in the final
943          loop over all section.  Then we have all the information needed.  */
944       shdr_info[cnt].shdr.sh_offset = 0;
945
946       /* Create the section.  */
947       shdr_info[cnt].newscn = elf_newscn (newelf);
948       if (shdr_info[cnt].newscn == NULL)
949         error (EXIT_FAILURE, 0,
950                gettext ("while create section header section: %s"),
951                elf_errmsg (-1));
952       assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
953
954       shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
955       if (shdr_info[cnt].data == NULL)
956         error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
957                elf_errmsg (-1));
958
959       char *debug_basename = basename (debug_fname_embed ?: debug_fname);
960       off_t crc_offset = strlen (debug_basename) + 1;
961       /* Align to 4 byte boundary */
962       crc_offset = ((crc_offset - 1) & ~3) + 4;
963
964       shdr_info[cnt].data->d_align = 4;
965       shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
966         = crc_offset + 4;
967       shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size);
968
969       strcpy (shdr_info[cnt].data->d_buf, debug_basename);
970
971       /* Cache this Elf_Data describing the CRC32 word in the section.
972          We'll fill this in when we have written the debug file.  */
973       debuglink_crc_data = *shdr_info[cnt].data;
974       debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
975                                   + crc_offset);
976       debuglink_crc_data.d_size = 4;
977
978       /* One more section done.  */
979       ++cnt;
980     }
981
982   /* Index of the section header table in the shdr_info array.  */
983   size_t shdridx = cnt;
984
985   /* Add the section header string table section name.  */
986   shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
987   shdr_info[cnt].idx = idx;
988
989   /* Create the section header.  */
990   shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
991   shdr_info[cnt].shdr.sh_flags = 0;
992   shdr_info[cnt].shdr.sh_addr = 0;
993   shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
994   shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
995   shdr_info[cnt].shdr.sh_entsize = 0;
996   /* We set the offset to zero here.  Before we write the ELF file the
997      field must have the correct value.  This is done in the final
998      loop over all section.  Then we have all the information needed.  */
999   shdr_info[cnt].shdr.sh_offset = 0;
1000   shdr_info[cnt].shdr.sh_addralign = 1;
1001
1002   /* Create the section.  */
1003   shdr_info[cnt].newscn = elf_newscn (newelf);
1004   if (shdr_info[cnt].newscn == NULL)
1005     error (EXIT_FAILURE, 0,
1006            gettext ("while create section header section: %s"),
1007            elf_errmsg (-1));
1008   assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1009
1010   /* Finalize the string table and fill in the correct indices in the
1011      section headers.  */
1012   shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1013   if (shstrtab_data == NULL)
1014     error (EXIT_FAILURE, 0,
1015            gettext ("while create section header string table: %s"),
1016            elf_errmsg (-1));
1017   ebl_strtabfinalize (shst, shstrtab_data);
1018
1019   /* We have to set the section size.  */
1020   shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1021
1022   /* Update the section information.  */
1023   GElf_Off lastoffset = 0;
1024   for (cnt = 1; cnt <= shdridx; ++cnt)
1025     if (shdr_info[cnt].idx > 0)
1026       {
1027         Elf_Data *newdata;
1028
1029         scn = elf_getscn (newelf, shdr_info[cnt].idx);
1030         assert (scn != NULL);
1031
1032         /* Update the name.  */
1033         shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
1034
1035         /* Update the section header from the input file.  Some fields
1036            might be section indeces which now have to be adjusted.  */
1037         if (shdr_info[cnt].shdr.sh_link != 0)
1038           shdr_info[cnt].shdr.sh_link =
1039             shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1040
1041         if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1042           {
1043             assert (shdr_info[cnt].data != NULL);
1044
1045             Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1046             for (size_t inner = 0;
1047                  inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1048                  ++inner)
1049               grpref[inner] = shdr_info[grpref[inner]].idx;
1050           }
1051
1052         /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag.  */
1053         if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1054           shdr_info[cnt].shdr.sh_info =
1055             shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1056
1057         /* Get the data from the old file if necessary.  We already
1058            created the data for the section header string table.  */
1059         if (cnt < shnum)
1060           {
1061             if (shdr_info[cnt].data == NULL)
1062               {
1063                 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1064                 if (shdr_info[cnt].data == NULL)
1065                   INTERNAL_ERROR (fname);
1066               }
1067
1068             /* Set the data.  This is done by copying from the old file.  */
1069             newdata = elf_newdata (scn);
1070             if (newdata == NULL)
1071               INTERNAL_ERROR (fname);
1072
1073             /* Copy the structure.  */
1074             *newdata = *shdr_info[cnt].data;
1075
1076             /* We know the size.  */
1077             shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1078
1079             /* We have to adjust symtol tables.  The st_shndx member might
1080                have to be updated.  */
1081             if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1082                 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1083               {
1084                 Elf_Data *versiondata = NULL;
1085                 Elf_Data *shndxdata = NULL;
1086
1087                 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1088                                             ehdr->e_version);
1089
1090                 if (shdr_info[cnt].symtab_idx != 0)
1091                   {
1092                     assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1093                     /* This section has extended section information.
1094                        We have to modify that information, too.  */
1095                     shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1096                                              NULL);
1097
1098                     assert ((versiondata->d_size / sizeof (Elf32_Word))
1099                             >= shdr_info[cnt].data->d_size / elsize);
1100                   }
1101
1102                 if (shdr_info[cnt].version_idx != 0)
1103                   {
1104                     assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1105                     /* This section has associated version
1106                        information.  We have to modify that
1107                        information, too.  */
1108                     versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1109                                                NULL);
1110
1111                     assert ((versiondata->d_size / sizeof (GElf_Versym))
1112                             >= shdr_info[cnt].data->d_size / elsize);
1113                   }
1114
1115                 shdr_info[cnt].newsymidx
1116                   = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1117                                             / elsize, sizeof (Elf32_Word));
1118
1119                 bool last_was_local = true;
1120                 size_t destidx;
1121                 size_t inner;
1122                 for (destidx = inner = 1;
1123                      inner < shdr_info[cnt].data->d_size / elsize;
1124                      ++inner)
1125                   {
1126                     Elf32_Word sec;
1127                     GElf_Sym sym_mem;
1128                     Elf32_Word xshndx;
1129                     GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1130                                                       shndxdata, inner,
1131                                                       &sym_mem, &xshndx);
1132                     if (sym == NULL)
1133                       INTERNAL_ERROR (fname);
1134
1135                     if (sym->st_shndx == SHN_UNDEF
1136                         || (sym->st_shndx >= shnum
1137                             && sym->st_shndx != SHN_XINDEX))
1138                       {
1139                         /* This is no section index, leave it alone
1140                            unless it is moved.  */
1141                         if (destidx != inner
1142                             && gelf_update_symshndx (shdr_info[cnt].data,
1143                                                      shndxdata,
1144                                                      destidx, sym,
1145                                                      xshndx) == 0)
1146                           INTERNAL_ERROR (fname);
1147
1148                         shdr_info[cnt].newsymidx[inner] = destidx++;
1149
1150                         if (last_was_local
1151                             && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1152                           {
1153                             last_was_local = false;
1154                             shdr_info[cnt].shdr.sh_info = destidx - 1;
1155                           }
1156
1157                         continue;
1158                       }
1159
1160                     /* Get the full section index, if necessary from the
1161                        XINDEX table.  */
1162                     if (sym->st_shndx != SHN_XINDEX)
1163                       sec = shdr_info[sym->st_shndx].idx;
1164                     else
1165                       {
1166                         assert (shndxdata != NULL);
1167
1168                         sec = shdr_info[xshndx].idx;
1169                       }
1170
1171                     if (sec != 0)
1172                       {
1173                         GElf_Section nshndx;
1174                         Elf32_Word nxshndx;
1175
1176                         if (sec < SHN_LORESERVE)
1177                           {
1178                             nshndx = sec;
1179                             nxshndx = 0;
1180                           }
1181                         else
1182                           {
1183                             nshndx = SHN_XINDEX;
1184                             nxshndx = sec;
1185                           }
1186
1187                         assert (sec < SHN_LORESERVE || shndxdata != NULL);
1188
1189                         if ((inner != destidx || nshndx != sym->st_shndx
1190                              || (shndxdata != NULL && nxshndx != xshndx))
1191                             && (sym->st_shndx = nshndx,
1192                                 gelf_update_symshndx (shdr_info[cnt].data,
1193                                                       shndxdata,
1194                                                       destidx, sym,
1195                                                       nxshndx) == 0))
1196                           INTERNAL_ERROR (fname);
1197
1198                         shdr_info[cnt].newsymidx[inner] = destidx++;
1199
1200                         if (last_was_local
1201                             && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1202                           {
1203                             last_was_local = false;
1204                             shdr_info[cnt].shdr.sh_info = destidx - 1;
1205                           }
1206                       }
1207                     else
1208                       /* This is a section symbol for a section which has
1209                          been removed.  */
1210                       assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
1211                   }
1212
1213                 if (destidx != inner)
1214                   {
1215                     /* The size of the symbol table changed.  */
1216                     shdr_info[cnt].shdr.sh_size = newdata->d_size
1217                       = destidx * elsize;
1218                     any_symtab_changes = true;
1219                   }
1220                 else
1221                   {
1222                     /* The symbol table didn't really change.  */
1223                     free (shdr_info[cnt].newsymidx);
1224                     shdr_info[cnt].newsymidx = NULL;
1225                   }
1226               }
1227           }
1228
1229         /* If we have to, compute the offset of the section.  */
1230         if (shdr_info[cnt].shdr.sh_offset == 0)
1231           shdr_info[cnt].shdr.sh_offset
1232             = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1233                & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1234
1235         /* Set the section header in the new file.  */
1236         if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1237           /* There cannot be any overflows.  */
1238           INTERNAL_ERROR (fname);
1239
1240         /* Remember the last section written so far.  */
1241         GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1242                            ? shdr_info[cnt].shdr.sh_size : 0);
1243         if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1244           lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1245       }
1246
1247   /* Adjust symbol references if symbol tables changed.  */
1248   if (any_symtab_changes)
1249     {
1250       /* Find all relocation sections which use this
1251          symbol table.  */
1252       for (cnt = 1; cnt <= shdridx; ++cnt)
1253         {
1254           if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
1255             /* Ignore sections which are discarded.  When we are saving a
1256                relocation section in a separate debug file, we must fix up
1257                the symbol table references.  */
1258             continue;
1259
1260           if (shdr_info[cnt].shdr.sh_type == SHT_REL
1261               || shdr_info[cnt].shdr.sh_type == SHT_RELA)
1262             {
1263               /* If the symbol table hasn't changed, do not do anything.  */
1264               if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
1265                 continue;
1266
1267               Elf32_Word *newsymidx
1268                 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
1269               Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
1270                                          ? elf_getscn (debugelf, cnt)
1271                                          : elf_getscn (newelf,
1272                                                        shdr_info[cnt].idx),
1273                                          NULL);
1274               assert (d != NULL);
1275               size_t nrels = (shdr_info[cnt].shdr.sh_size
1276                               / shdr_info[cnt].shdr.sh_entsize);
1277
1278               if (shdr_info[cnt].shdr.sh_type == SHT_REL)
1279                 for (size_t relidx = 0; relidx < nrels; ++relidx)
1280                   {
1281                     GElf_Rel rel_mem;
1282                     if (gelf_getrel (d, relidx, &rel_mem) == NULL)
1283                       INTERNAL_ERROR (fname);
1284
1285                     size_t symidx = GELF_R_SYM (rel_mem.r_info);
1286                     if (newsymidx[symidx] != symidx)
1287                       {
1288                         rel_mem.r_info
1289                           = GELF_R_INFO (newsymidx[symidx],
1290                                          GELF_R_TYPE (rel_mem.r_info));
1291
1292                         if (gelf_update_rel (d, relidx, &rel_mem) == 0)
1293                           INTERNAL_ERROR (fname);
1294                       }
1295                   }
1296               else
1297                 for (size_t relidx = 0; relidx < nrels; ++relidx)
1298                   {
1299                     GElf_Rela rel_mem;
1300                     if (gelf_getrela (d, relidx, &rel_mem) == NULL)
1301                       INTERNAL_ERROR (fname);
1302
1303                     size_t symidx = GELF_R_SYM (rel_mem.r_info);
1304                     if (newsymidx[symidx] != symidx)
1305                       {
1306                         rel_mem.r_info
1307                           = GELF_R_INFO (newsymidx[symidx],
1308                                          GELF_R_TYPE (rel_mem.r_info));
1309
1310                         if (gelf_update_rela (d, relidx, &rel_mem) == 0)
1311                           INTERNAL_ERROR (fname);
1312                       }
1313                   }
1314             }
1315           else if (shdr_info[cnt].shdr.sh_type == SHT_HASH)
1316             {
1317               /* We have to recompute the hash table.  */
1318               Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1319
1320               /* We do not have to do anything if the symbol table was
1321                  not changed.  */
1322               if (shdr_info[symtabidx].newsymidx == NULL)
1323                 continue;
1324
1325               assert (shdr_info[cnt].idx > 0);
1326
1327               /* The hash section in the new file.  */
1328               scn = elf_getscn (newelf, shdr_info[cnt].idx);
1329
1330               /* The symbol table data.  */
1331               Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1332                                                         shdr_info[symtabidx].idx),
1333                                             NULL);
1334               assert (symd != NULL);
1335
1336               /* The hash table data.  */
1337               Elf_Data *hashd = elf_getdata (scn, NULL);
1338               assert (hashd != NULL);
1339
1340               if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
1341                 {
1342                   /* Sane arches first.  */
1343                   Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
1344
1345                   size_t strshndx = shdr_info[symtabidx].old_sh_link;
1346                   size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1347                                               ehdr->e_version);
1348
1349                   /* Adjust the nchain value.  The symbol table size
1350                      changed.  We keep the same size for the bucket array.  */
1351                   bucket[1] = symd->d_size / elsize;
1352                   Elf32_Word nbucket = bucket[0];
1353                   bucket += 2;
1354                   Elf32_Word *chain = bucket + nbucket;
1355
1356                   /* New size of the section.  */
1357                   GElf_Shdr shdr_mem;
1358                   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1359                   shdr->sh_size = hashd->d_size
1360                     = (2 + symd->d_size / elsize + nbucket)
1361                       * sizeof (Elf32_Word);
1362                   (void) gelf_update_shdr (scn, shdr);
1363
1364                   /* Clear the arrays.  */
1365                   memset (bucket, '\0',
1366                           (symd->d_size / elsize + nbucket)
1367                           * sizeof (Elf32_Word));
1368
1369                   for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1370                        inner < symd->d_size / elsize; ++inner)
1371                     {
1372                       GElf_Sym sym_mem;
1373                       GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1374                       assert (sym != NULL);
1375
1376                       const char *name = elf_strptr (elf, strshndx,
1377                                                      sym->st_name);
1378                       assert (name != NULL);
1379                       size_t hidx = elf_hash (name) % nbucket;
1380
1381                       if (bucket[hidx] == 0)
1382                         bucket[hidx] = inner;
1383                       else
1384                         {
1385                           hidx = bucket[hidx];
1386
1387                           while (chain[hidx] != 0)
1388                             hidx = chain[hidx];
1389
1390                           chain[hidx] = inner;
1391                         }
1392                     }
1393                 }
1394               else
1395                 {
1396                   /* Alpha and S390 64-bit use 64-bit SHT_HASH entries.  */
1397                   assert (shdr_info[cnt].shdr.sh_entsize
1398                           == sizeof (Elf64_Xword));
1399
1400                   Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
1401
1402                   size_t strshndx = shdr_info[symtabidx].old_sh_link;
1403                   size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1404                                               ehdr->e_version);
1405
1406                   /* Adjust the nchain value.  The symbol table size
1407                      changed.  We keep the same size for the bucket array.  */
1408                   bucket[1] = symd->d_size / elsize;
1409                   Elf64_Xword nbucket = bucket[0];
1410                   bucket += 2;
1411                   Elf64_Xword *chain = bucket + nbucket;
1412
1413                   /* New size of the section.  */
1414                   GElf_Shdr shdr_mem;
1415                   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1416                   shdr->sh_size = hashd->d_size
1417                     = (2 + symd->d_size / elsize + nbucket)
1418                       * sizeof (Elf64_Xword);
1419                   (void) gelf_update_shdr (scn, shdr);
1420
1421                   /* Clear the arrays.  */
1422                   memset (bucket, '\0',
1423                           (symd->d_size / elsize + nbucket)
1424                           * sizeof (Elf64_Xword));
1425
1426                   for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1427                        inner < symd->d_size / elsize; ++inner)
1428                     {
1429                       GElf_Sym sym_mem;
1430                       GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1431                       assert (sym != NULL);
1432
1433                       const char *name = elf_strptr (elf, strshndx,
1434                                                      sym->st_name);
1435                       assert (name != NULL);
1436                       size_t hidx = elf_hash (name) % nbucket;
1437
1438                       if (bucket[hidx] == 0)
1439                         bucket[hidx] = inner;
1440                       else
1441                         {
1442                           hidx = bucket[hidx];
1443
1444                           while (chain[hidx] != 0)
1445                             hidx = chain[hidx];
1446
1447                           chain[hidx] = inner;
1448                         }
1449                     }
1450                 }
1451             }
1452           else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
1453             {
1454               /* If the symbol table changed we have to adjust the
1455                  entries.  */
1456               Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1457
1458               /* We do not have to do anything if the symbol table was
1459                  not changed.  */
1460               if (shdr_info[symtabidx].newsymidx == NULL)
1461                 continue;
1462
1463               assert (shdr_info[cnt].idx > 0);
1464
1465               /* The symbol version section in the new file.  */
1466               scn = elf_getscn (newelf, shdr_info[cnt].idx);
1467
1468               /* The symbol table data.  */
1469               Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1470                                                         shdr_info[symtabidx].idx),
1471                                             NULL);
1472               assert (symd != NULL);
1473
1474               /* The version symbol data.  */
1475               Elf_Data *verd = elf_getdata (scn, NULL);
1476               assert (verd != NULL);
1477
1478               /* The symbol version array.  */
1479               GElf_Half *verstab = (GElf_Half *) verd->d_buf;
1480
1481               /* New indices of the symbols.  */
1482               Elf32_Word *newsymidx = shdr_info[symtabidx].newsymidx;
1483
1484               /* Walk through the list and */
1485               size_t elsize = gelf_fsize (elf, verd->d_type, 1,
1486                                           ehdr->e_version);
1487               for (size_t inner = 1; inner < verd->d_size / elsize; ++inner)
1488                 if (newsymidx[inner] != 0)
1489                   /* Overwriting the same array works since the
1490                      reordering can only move entries to lower indices
1491                      in the array.  */
1492                   verstab[newsymidx[inner]] = verstab[inner];
1493
1494               /* New size of the section.  */
1495               GElf_Shdr shdr_mem;
1496               GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1497               shdr->sh_size = verd->d_size
1498                 = gelf_fsize (newelf, verd->d_type,
1499                               symd->d_size / gelf_fsize (elf, symd->d_type, 1,
1500                                                          ehdr->e_version),
1501                               ehdr->e_version);
1502               (void) gelf_update_shdr (scn, shdr);
1503             }
1504           else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1505             {
1506               /* Check whether the associated symbol table changed.  */
1507               if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
1508                 {
1509                   /* Yes the symbol table changed.  Update the section
1510                      header of the section group.  */
1511                   scn = elf_getscn (newelf, shdr_info[cnt].idx);
1512                   GElf_Shdr shdr_mem;
1513                   GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1514                   assert (shdr != NULL);
1515
1516                   size_t stabidx = shdr_info[cnt].old_sh_link;
1517                   shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
1518
1519                   (void) gelf_update_shdr (scn, shdr);
1520                 }
1521             }
1522         }
1523     }
1524
1525   /* Now that we have done all adjustments to the data,
1526      we can actually write out the debug file.  */
1527   if (debug_fname != NULL)
1528     {
1529       uint32_t debug_crc;
1530       Elf_Data debug_crc_data =
1531         {
1532           .d_type = ELF_T_WORD,
1533           .d_buf = &debug_crc,
1534           .d_size = sizeof (debug_crc),
1535           .d_version = EV_CURRENT
1536         };
1537
1538       /* Finally write the file.  */
1539       if (unlikely (elf_update (debugelf, ELF_C_WRITE)) == -1)
1540         {
1541           error (0, 0, gettext ("while writing '%s': %s"),
1542                  debug_fname, elf_errmsg (-1));
1543           result = 1;
1544           goto fail_close;
1545         }
1546
1547       /* Create the real output file.  First rename, then change the
1548          mode.  */
1549       if (rename (tmp_debug_fname, debug_fname) != 0
1550           || fchmod (debug_fd, mode) != 0)
1551         {
1552           error (0, errno, gettext ("while creating '%s'"), debug_fname);
1553           result = 1;
1554           goto fail_close;
1555         }
1556
1557       /* The temporary file does not exist anymore.  */
1558       tmp_debug_fname = NULL;
1559
1560       /* Compute the checksum which we will add to the executable.  */
1561       if (crc32_file (debug_fd, &debug_crc) != 0)
1562         {
1563           error (0, errno,
1564                  gettext ("while computing checksum for debug information"));
1565           unlink (debug_fname);
1566           result = 1;
1567           goto fail_close;
1568         }
1569
1570       /* Store it in the debuglink section data.  */
1571       if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
1572                                    &debug_crc_data, ehdr->e_ident[EI_DATA])
1573                     != &debuglink_crc_data))
1574         INTERNAL_ERROR (fname);
1575     }
1576
1577   /* Finally finish the ELF header.  Fill in the fields not handled by
1578      libelf from the old file.  */
1579   newehdr = gelf_getehdr (newelf, &newehdr_mem);
1580   if (newehdr == NULL)
1581     INTERNAL_ERROR (fname);
1582
1583   memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1584   newehdr->e_type = ehdr->e_type;
1585   newehdr->e_machine = ehdr->e_machine;
1586   newehdr->e_version = ehdr->e_version;
1587   newehdr->e_entry = ehdr->e_entry;
1588   newehdr->e_flags = ehdr->e_flags;
1589   newehdr->e_phoff = ehdr->e_phoff;
1590   /* We need to position the section header table.  */
1591   const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
1592   newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
1593                        + shdr_info[shdridx].shdr.sh_size + offsize - 1)
1594                       & ~((GElf_Off) (offsize - 1)));
1595   newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
1596
1597   /* The new section header string table index.  */
1598   if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
1599     newehdr->e_shstrndx = idx;
1600   else
1601     {
1602       /* The index does not fit in the ELF header field.  */
1603       shdr_info[0].scn = elf_getscn (elf, 0);
1604
1605       if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
1606         INTERNAL_ERROR (fname);
1607
1608       shdr_info[0].shdr.sh_link = idx;
1609       (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
1610
1611       newehdr->e_shstrndx = SHN_XINDEX;
1612     }
1613
1614   if (gelf_update_ehdr (newelf, newehdr) == 0)
1615     {
1616       error (0, 0, gettext ("%s: error while creating ELF header: %s"),
1617              fname, elf_errmsg (-1));
1618       return 1;
1619     }
1620
1621   /* We have everything from the old file.  */
1622   if (elf_cntl (elf, ELF_C_FDDONE) != 0)
1623     {
1624       error (0, 0, gettext ("%s: error while reading the file: %s"),
1625              fname, elf_errmsg (-1));
1626       return 1;
1627     }
1628
1629   /* The ELF library better follows our layout when this is not a
1630      relocatable object file.  */
1631   elf_flagelf (newelf, ELF_C_SET,
1632                (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
1633                | (permissive ? ELF_F_PERMISSIVE : 0));
1634
1635   /* Finally write the file.  */
1636   if (elf_update (newelf, ELF_C_WRITE) == -1)
1637     {
1638       error (0, 0, gettext ("while writing '%s': %s"),
1639              fname, elf_errmsg (-1));
1640       result = 1;
1641     }
1642
1643  fail_close:
1644   if (shdr_info != NULL)
1645     {
1646       /* For some sections we might have created an table to map symbol
1647          table indices.  */
1648       if (any_symtab_changes)
1649         for (cnt = 1; cnt <= shdridx; ++cnt)
1650           free (shdr_info[cnt].newsymidx);
1651
1652       /* Free the memory.  */
1653       if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
1654         free (shdr_info);
1655     }
1656
1657   /* Free other resources.  */
1658   if (shstrtab_data != NULL)
1659     free (shstrtab_data->d_buf);
1660   if (shst != NULL)
1661     ebl_strtabfree (shst);
1662
1663   /* That was it.  Close the descriptors.  */
1664   if (elf_end (newelf) != 0)
1665     {
1666       error (0, 0, gettext ("error while finishing '%s': %s"), fname,
1667              elf_errmsg (-1));
1668       result = 1;
1669     }
1670
1671   if (debugelf != NULL && elf_end (debugelf) != 0)
1672     {
1673       error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
1674              elf_errmsg (-1));
1675       result = 1;
1676     }
1677
1678  fail:
1679   /* Close the EBL backend.  */
1680   if (ebl != NULL)
1681     ebl_closebackend (ebl);
1682
1683   /* Close debug file descriptor, if opened */
1684   if (debug_fd >= 0)
1685     {
1686       if (tmp_debug_fname != NULL)
1687         unlink (tmp_debug_fname);
1688       close (debug_fd);
1689     }
1690
1691   /* If requested, preserve the timestamp.  */
1692   if (tvp != NULL)
1693     {
1694       if (futimes (fd, tvp) != 0)
1695         {
1696           error (0, errno, gettext ("\
1697 cannot set access and modification date of '%s'"),
1698                  output_fname ?: fname);
1699           result = 1;
1700         }
1701     }
1702
1703   /* Close the file descriptor if we created a new file.  */
1704   if (output_fname != NULL)
1705     close (fd);
1706
1707   return result;
1708 }
1709
1710
1711 static int
1712 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
1713            struct timeval tvp[2])
1714 {
1715   size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
1716   size_t fname_len = strlen (fname) + 1;
1717   char new_prefix[prefix_len + 1 + fname_len];
1718   char *cp = new_prefix;
1719
1720   /* Create the full name of the file.  */
1721   if (prefix != NULL)
1722     {
1723       cp = mempcpy (cp, prefix, prefix_len);
1724       *cp++ = ':';
1725     }
1726   memcpy (cp, fname, fname_len);
1727
1728
1729   /* Process all the files contained in the archive.  */
1730   Elf *subelf;
1731   Elf_Cmd cmd = ELF_C_RDWR;
1732   int result = 0;
1733   while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
1734     {
1735       /* The the header for this element.  */
1736       Elf_Arhdr *arhdr = elf_getarhdr (subelf);
1737
1738       if (elf_kind (subelf) == ELF_K_ELF)
1739         result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
1740       else if (elf_kind (subelf) == ELF_K_AR)
1741         result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
1742
1743       /* Get next archive element.  */
1744       cmd = elf_next (subelf);
1745       if (unlikely (elf_end (subelf) != 0))
1746         INTERNAL_ERROR (fname);
1747     }
1748
1749   if (tvp != NULL)
1750     {
1751       if (unlikely (futimes (fd, tvp) != 0))
1752         {
1753           error (0, errno, gettext ("\
1754 cannot set access and modification date of '%s'"), fname);
1755           result = 1;
1756         }
1757     }
1758
1759   if (unlikely (close (fd) != 0))
1760     error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
1761
1762   return result;
1763 }