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