strip: Split out debug section relocation into separate helper functions.
[platform/upstream/elfutils.git] / src / strip.c
1 /* Discard section not used at runtime from object files.
2    Copyright (C) 2000-2012, 2014, 2015, 2016, 2017 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5
6    This file is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    elfutils is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <argp.h>
24 #include <assert.h>
25 #include <byteswap.h>
26 #include <endian.h>
27 #include <fcntl.h>
28 #include <fnmatch.h>
29 #include <gelf.h>
30 #include <libelf.h>
31 #include <libintl.h>
32 #include <locale.h>
33 #include <stdbool.h>
34 #include <stdio.h>
35 #include <stdio_ext.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include <sys/stat.h>
40 #include <sys/time.h>
41
42 #include <elf-knowledge.h>
43 #include <libebl.h>
44 #include "libdwelf.h"
45 #include <libeu.h>
46 #include <system.h>
47 #include <printversion.h>
48
49 typedef uint8_t GElf_Byte;
50
51 /* Name and version of program.  */
52 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
53
54 /* Bug report address.  */
55 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
56
57
58 /* Values for the parameters which have no short form.  */
59 #define OPT_REMOVE_COMMENT      0x100
60 #define OPT_PERMISSIVE          0x101
61 #define OPT_STRIP_SECTIONS      0x102
62 #define OPT_RELOC_DEBUG         0x103
63 #define OPT_KEEP_SECTION        0x104
64
65
66 /* Definitions of arguments for argp functions.  */
67 static const struct argp_option options[] =
68 {
69   { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
70   { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 },
71   { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 },
72   { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
73
74   { NULL, 0, NULL, 0, N_("Output options:"), 0 },
75   { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 },
76   { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
77   { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 },
78   { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 },
79   { "strip-sections", OPT_STRIP_SECTIONS, NULL, 0,
80     N_("Remove section headers (not recommended)"), 0 },
81   { "preserve-dates", 'p', NULL, 0,
82     N_("Copy modified/access timestamps to the output"), 0 },
83   { "reloc-debug-sections", OPT_RELOC_DEBUG, NULL, 0,
84     N_("Resolve all trivial relocations between debug sections if the removed sections are placed in a debug file (only relevant for ET_REL files, operation is not reversable, needs -f)"), 0 },
85   { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
86     N_("Remove .comment section"), 0 },
87   { "remove-section", 'R', "SECTION", 0, N_("Remove the named section.  SECTION is an extended wildcard pattern.  May be given more than once.  Only non-allocated sections can be removed."), 0 },
88   { "keep-section", OPT_KEEP_SECTION, "SECTION", 0, N_("Keep the named section.  SECTION is an extended wildcard pattern.  May be given more than once."), 0 },
89   { "permissive", OPT_PERMISSIVE, NULL, 0,
90     N_("Relax a few rules to handle slightly broken ELF files"), 0 },
91   { NULL, 0, NULL, 0, NULL, 0 }
92 };
93
94 /* Short description of program.  */
95 static const char doc[] = N_("Discard symbols from object files.");
96
97 /* Strings for arguments in help texts.  */
98 static const char args_doc[] = N_("[FILE...]");
99
100 /* Prototype for option handler.  */
101 static error_t parse_opt (int key, char *arg, struct argp_state *state);
102
103 /* Data structure to communicate with argp functions.  */
104 static struct argp argp =
105 {
106   options, parse_opt, args_doc, doc, NULL, NULL, NULL
107 };
108
109
110 /* Print symbols in file named FNAME.  */
111 static int process_file (const char *fname);
112
113 /* Handle one ELF file.  */
114 static int handle_elf (int fd, Elf *elf, const char *prefix,
115                        const char *fname, mode_t mode, struct timespec tvp[2]);
116
117 /* Handle all files contained in the archive.  */
118 static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
119                       struct timespec tvp[2]) __attribute__ ((unused));
120
121 static int debug_fd = -1;
122 static char *tmp_debug_fname = NULL;
123
124 /* Close debug file descriptor, if opened. And remove temporary debug file.  */
125 static void cleanup_debug (void);
126
127 #define INTERNAL_ERROR(fname) \
128   do { \
129     cleanup_debug (); \
130     error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"),      \
131            fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \
132   } while (0)
133
134
135 /* Name of the output file.  */
136 static const char *output_fname;
137
138 /* Name of the debug output file.  */
139 static const char *debug_fname;
140
141 /* Name to pretend the debug output file has.  */
142 static const char *debug_fname_embed;
143
144 /* If true output files shall have same date as the input file.  */
145 static bool preserve_dates;
146
147 /* If true .comment sections will be removed.  */
148 static bool remove_comment;
149
150 /* If true remove all debug sections.  */
151 static bool remove_debug;
152
153 /* If true remove all section headers.  */
154 static bool remove_shdrs;
155
156 /* If true relax some ELF rules for input files.  */
157 static bool permissive;
158
159 /* If true perform relocations between debug sections.  */
160 static bool reloc_debug;
161
162 /* Sections the user explicitly wants to keep or remove.  */
163 struct section_pattern
164 {
165   char *pattern;
166   struct section_pattern *next;
167 };
168
169 static struct section_pattern *keep_secs = NULL;
170 static struct section_pattern *remove_secs = NULL;
171
172 static void
173 add_pattern (struct section_pattern **patterns, const char *pattern)
174 {
175   struct section_pattern *p = xmalloc (sizeof *p);
176   p->pattern = xstrdup (pattern);
177   p->next = *patterns;
178   *patterns = p;
179 }
180
181 static void
182 free_sec_patterns (struct section_pattern *patterns)
183 {
184   struct section_pattern *pattern = patterns;
185   while (pattern != NULL)
186     {
187       struct section_pattern *p = pattern;
188       pattern = p->next;
189       free (p->pattern);
190       free (p);
191     }
192 }
193
194 static void
195 free_patterns (void)
196 {
197   free_sec_patterns (keep_secs);
198   free_sec_patterns (remove_secs);
199 }
200
201 static bool
202 section_name_matches (struct section_pattern *patterns, const char *name)
203 {
204   struct section_pattern *pattern = patterns;
205   while (pattern != NULL)
206     {
207       if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0)
208         return true;
209       pattern = pattern->next;
210     }
211   return false;
212 }
213
214
215 int
216 main (int argc, char *argv[])
217 {
218   int remaining;
219   int result = 0;
220
221   /* We use no threads here which can interfere with handling a stream.  */
222   __fsetlocking (stdin, FSETLOCKING_BYCALLER);
223   __fsetlocking (stdout, FSETLOCKING_BYCALLER);
224   __fsetlocking (stderr, FSETLOCKING_BYCALLER);
225
226   /* Set locale.  */
227   setlocale (LC_ALL, "");
228
229   /* Make sure the message catalog can be found.  */
230   bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
231
232   /* Initialize the message catalog.  */
233   textdomain (PACKAGE_TARNAME);
234
235   /* Parse and process arguments.  */
236   if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
237     return EXIT_FAILURE;
238
239   if (reloc_debug && debug_fname == NULL)
240     error (EXIT_FAILURE, 0,
241            gettext ("--reloc-debug-sections used without -f"));
242
243   /* Tell the library which version we are expecting.  */
244   elf_version (EV_CURRENT);
245
246   if (remaining == argc)
247     /* The user didn't specify a name so we use a.out.  */
248     result = process_file ("a.out");
249   else
250     {
251       /* If we have seen the '-o' or '-f' option there must be exactly one
252          input file.  */
253       if ((output_fname != NULL || debug_fname != NULL)
254           && remaining + 1 < argc)
255         error (EXIT_FAILURE, 0, gettext ("\
256 Only one input file allowed together with '-o' and '-f'"));
257
258       /* Process all the remaining files.  */
259       do
260         result |= process_file (argv[remaining]);
261       while (++remaining < argc);
262     }
263
264   free_patterns ();
265   return result;
266 }
267
268
269 /* Handle program arguments.  */
270 static error_t
271 parse_opt (int key, char *arg, struct argp_state *state)
272 {
273   switch (key)
274     {
275     case 'f':
276       if (debug_fname != NULL)
277         {
278           error (0, 0, gettext ("-f option specified twice"));
279           return EINVAL;
280         }
281       debug_fname = arg;
282       break;
283
284     case 'F':
285       if (debug_fname_embed != NULL)
286         {
287           error (0, 0, gettext ("-F option specified twice"));
288           return EINVAL;
289         }
290       debug_fname_embed = arg;
291       break;
292
293     case 'o':
294       if (output_fname != NULL)
295         {
296           error (0, 0, gettext ("-o option specified twice"));
297           return EINVAL;
298         }
299       output_fname = arg;
300       break;
301
302     case 'p':
303       preserve_dates = true;
304       break;
305
306     case OPT_RELOC_DEBUG:
307       reloc_debug = true;
308       break;
309
310     case OPT_REMOVE_COMMENT:
311       remove_comment = true;
312       break;
313
314     case 'R':
315       if (fnmatch (arg, ".comment", FNM_EXTMATCH) == 0)
316         remove_comment = true;
317       add_pattern (&remove_secs, arg);
318       break;
319
320     case OPT_KEEP_SECTION:
321       add_pattern (&keep_secs, arg);
322       break;
323
324     case 'g':
325     case 'd':
326     case 'S':
327       remove_debug = true;
328       break;
329
330     case OPT_STRIP_SECTIONS:
331       remove_shdrs = true;
332       break;
333
334     case OPT_PERMISSIVE:
335       permissive = true;
336       break;
337
338     case 's':                   /* Ignored for compatibility.  */
339       break;
340
341     case ARGP_KEY_SUCCESS:
342       if (remove_comment == true
343           && section_name_matches (keep_secs, ".comment"))
344         {
345           argp_error (state,
346                       gettext ("cannot both keep and remove .comment section"));
347           return EINVAL;
348         }
349       break;
350
351     default:
352       return ARGP_ERR_UNKNOWN;
353     }
354   return 0;
355 }
356
357 static const char *
358 secndx_name (Elf *elf, size_t ndx)
359 {
360   size_t shstrndx;
361   GElf_Shdr mem;
362   Elf_Scn *sec = elf_getscn (elf, ndx);
363   GElf_Shdr *shdr = gelf_getshdr (sec, &mem);
364   if (shdr == NULL || elf_getshdrstrndx (elf, &shstrndx) < 0)
365     return "???";
366   return elf_strptr (elf, shstrndx, shdr->sh_name) ?: "???";
367 }
368
369 /* Get the extended section index table data for a symbol table section.  */
370 static Elf_Data *
371 get_xndxdata (Elf *elf, Elf_Scn *symscn)
372 {
373   Elf_Data *xndxdata = NULL;
374   GElf_Shdr shdr_mem;
375   GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
376   if (shdr != NULL && shdr->sh_type == SHT_SYMTAB)
377     {
378       size_t scnndx = elf_ndxscn (symscn);
379       Elf_Scn *xndxscn = NULL;
380       while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL)
381         {
382           GElf_Shdr xndxshdr_mem;
383           GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
384
385           if (xndxshdr != NULL
386               && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
387               && xndxshdr->sh_link == scnndx)
388             {
389               xndxdata = elf_getdata (xndxscn, NULL);
390               break;
391             }
392         }
393     }
394
395   return xndxdata;
396 }
397
398 /* Remove any relocations between debug sections in ET_REL
399    for the debug file when requested.  These relocations are always
400    zero based between the unallocated sections.  */
401 static void
402 remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr,
403                           const char *fname, size_t shstrndx)
404 {
405   Elf_Scn *scn = NULL;
406   while ((scn = elf_nextscn (elf, scn)) != NULL)
407     {
408       /* We need the actual section and header from the elf
409          not just the cached original in shdr_info because we
410          might want to change the size.  */
411       GElf_Shdr shdr_mem;
412       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
413       if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
414         {
415           /* Make sure that this relocation section points to a
416              section to relocate with contents, that isn't
417              allocated and that is a debug section.  */
418           Elf_Scn *tscn = elf_getscn (elf, shdr->sh_info);
419           GElf_Shdr tshdr_mem;
420           GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
421           if (tshdr->sh_type == SHT_NOBITS
422               || tshdr->sh_size == 0
423               || (tshdr->sh_flags & SHF_ALLOC) != 0)
424             continue;
425
426           const char *tname =  elf_strptr (elf, shstrndx,
427                                            tshdr->sh_name);
428           if (! tname || ! ebl_debugscn_p (ebl, tname))
429             continue;
430
431           /* OK, lets relocate all trivial cross debug section
432              relocations. */
433           Elf_Data *reldata = elf_getdata (scn, NULL);
434           if (reldata == NULL || reldata->d_buf == NULL)
435             INTERNAL_ERROR (fname);
436
437           /* Make sure we adjust the uncompressed debug data
438              (and recompress if necessary at the end).  */
439           GElf_Chdr tchdr;
440           int tcompress_type = 0;
441           if (gelf_getchdr (tscn, &tchdr) != NULL)
442             {
443               tcompress_type = tchdr.ch_type;
444               if (elf_compress (tscn, 0, 0) != 1)
445                 INTERNAL_ERROR (fname);
446             }
447
448           Elf_Data *tdata = elf_getdata (tscn, NULL);
449           if (tdata == NULL || tdata->d_buf == NULL
450               || tdata->d_type != ELF_T_BYTE)
451             INTERNAL_ERROR (fname);
452
453           /* Pick up the symbol table and shndx table to
454              resolve relocation symbol indexes.  */
455           Elf64_Word symt = shdr->sh_link;
456           Elf_Data *symdata, *xndxdata;
457           Elf_Scn * symscn = elf_getscn (elf, symt);
458           symdata = elf_getdata (symscn, NULL);
459           xndxdata = get_xndxdata (elf, symscn);
460           if (symdata == NULL)
461             INTERNAL_ERROR (fname);
462
463           /* Apply one relocation.  Returns true when trivial
464              relocation actually done.  */
465           bool relocate (GElf_Addr offset, const GElf_Sxword addend,
466                          bool is_rela, int rtype, int symndx)
467           {
468             /* R_*_NONE relocs can always just be removed.  */
469             if (rtype == 0)
470               return true;
471
472             /* We only do simple absolute relocations.  */
473             int addsub = 0;
474             Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub);
475             if (type == ELF_T_NUM)
476               return false;
477
478             /* These are the types we can relocate.  */
479 #define TYPES   DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half);             \
480                 DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);           \
481                 DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
482
483             /* And only for relocations against other debug sections.  */
484             GElf_Sym sym_mem;
485             Elf32_Word xndx;
486             GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
487                                               symndx, &sym_mem,
488                                               &xndx);
489             Elf32_Word sec = (sym->st_shndx == SHN_XINDEX
490                               ? xndx : sym->st_shndx);
491
492             if (ebl_debugscn_p (ebl, secndx_name (elf, sec)))
493               {
494                 size_t size;
495
496 #define DO_TYPE(NAME, Name) GElf_##Name Name;
497                 union { TYPES; } tmpbuf;
498 #undef DO_TYPE
499
500                 switch (type)
501                   {
502 #define DO_TYPE(NAME, Name)                             \
503                     case ELF_T_##NAME:                  \
504                       size = sizeof (GElf_##Name);      \
505                       tmpbuf.Name = 0;                  \
506                       break;
507                     TYPES;
508 #undef DO_TYPE
509                   default:
510                     return false;
511                   }
512
513                 if (offset > tdata->d_size
514                     || tdata->d_size - offset < size)
515                   {
516                     cleanup_debug ();
517                     error (EXIT_FAILURE, 0, gettext ("bad relocation"));
518                   }
519
520                 /* When the symbol value is zero then for SHT_REL
521                    sections this is all that needs to be checked.
522                    The addend is contained in the original data at
523                    the offset already.  So if the (section) symbol
524                    address is zero and the given addend is zero
525                    just remove the relocation, it isn't needed
526                    anymore.  */
527                 if (addend == 0 && sym->st_value == 0)
528                   return true;
529
530                 Elf_Data tmpdata =
531                   {
532                     .d_type = type,
533                     .d_buf = &tmpbuf,
534                     .d_size = size,
535                     .d_version = EV_CURRENT,
536                   };
537                 Elf_Data rdata =
538                   {
539                     .d_type = type,
540                     .d_buf = tdata->d_buf + offset,
541                     .d_size = size,
542                     .d_version = EV_CURRENT,
543                   };
544
545                 GElf_Addr value = sym->st_value;
546                 if (is_rela)
547                   {
548                     /* For SHT_RELA sections we just take the
549                        given addend and add it to the value.  */
550                     value += addend;
551                     /* For ADD/SUB relocations we need to fetch the
552                        current section contents.  */
553                     if (addsub != 0)
554                       {
555                         Elf_Data *d = gelf_xlatetom (elf, &tmpdata,
556                                                      &rdata,
557                                                      ehdr->e_ident[EI_DATA]);
558                         if (d == NULL)
559                           INTERNAL_ERROR (fname);
560                         assert (d == &tmpdata);
561                       }
562                   }
563                 else
564                   {
565                     /* For SHT_REL sections we have to peek at
566                        what is already in the section at the given
567                        offset to get the addend.  */
568                     Elf_Data *d = gelf_xlatetom (elf, &tmpdata,
569                                                  &rdata,
570                                                  ehdr->e_ident[EI_DATA]);
571                     if (d == NULL)
572                       INTERNAL_ERROR (fname);
573                     assert (d == &tmpdata);
574                   }
575
576                 switch (type)
577                   {
578 #define DO_TYPE(NAME, Name)                                      \
579                     case ELF_T_##NAME:                           \
580                       if (addsub < 0)                            \
581                         tmpbuf.Name -= (GElf_##Name) value;      \
582                       else                                       \
583                         tmpbuf.Name += (GElf_##Name) value;      \
584                       break;
585                     TYPES;
586 #undef DO_TYPE
587                   default:
588                     abort ();
589                   }
590
591                 /* Now finally put in the new value.  */
592                 Elf_Data *s = gelf_xlatetof (elf, &rdata,
593                                              &tmpdata,
594                                              ehdr->e_ident[EI_DATA]);
595                 if (s == NULL)
596                   INTERNAL_ERROR (fname);
597                 assert (s == &rdata);
598
599                 return true;
600               }
601             return false;
602           }
603
604           if (shdr->sh_entsize == 0)
605             INTERNAL_ERROR (fname);
606
607           size_t nrels = shdr->sh_size / shdr->sh_entsize;
608           size_t next = 0;
609           if (shdr->sh_type == SHT_REL)
610             for (size_t relidx = 0; relidx < nrels; ++relidx)
611               {
612                 GElf_Rel rel_mem;
613                 GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
614                 if (! relocate (r->r_offset, 0, false,
615                                 GELF_R_TYPE (r->r_info),
616                                 GELF_R_SYM (r->r_info)))
617                   {
618                     if (relidx != next)
619                       gelf_update_rel (reldata, next, r);
620                     ++next;
621                   }
622               }
623           else
624             for (size_t relidx = 0; relidx < nrels; ++relidx)
625               {
626                 GElf_Rela rela_mem;
627                 GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
628                 if (! relocate (r->r_offset, r->r_addend, true,
629                                 GELF_R_TYPE (r->r_info),
630                                 GELF_R_SYM (r->r_info)))
631                   {
632                     if (relidx != next)
633                       gelf_update_rela (reldata, next, r);
634                     ++next;
635                   }
636               }
637
638           nrels = next;
639           shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
640           gelf_update_shdr (scn, shdr);
641
642           if (tcompress_type != 0)
643             if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1)
644               INTERNAL_ERROR (fname);
645         }
646     }
647 }
648
649 static int
650 process_file (const char *fname)
651 {
652   /* If we have to preserve the modify and access timestamps get them
653      now.  We cannot use fstat() after opening the file since the open
654      would change the access time.  */
655   struct stat pre_st;
656   struct timespec tv[2];
657  again:
658   if (preserve_dates)
659     {
660       if (stat (fname, &pre_st) != 0)
661         {
662           error (0, errno, gettext ("cannot stat input file '%s'"), fname);
663           return 1;
664         }
665
666       /* If we have to preserve the timestamp, we need it in the
667          format utimes() understands.  */
668       tv[0] = pre_st.st_atim;
669       tv[1] = pre_st.st_mtim;
670     }
671
672   /* Open the file.  */
673   int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
674   if (fd == -1)
675     {
676       error (0, errno, gettext ("while opening '%s'"), fname);
677       return 1;
678     }
679
680   /* We always use fstat() even if we called stat() before.  This is
681      done to make sure the information returned by stat() is for the
682      same file.  */
683   struct stat st;
684   if (fstat (fd, &st) != 0)
685     {
686       error (0, errno, gettext ("cannot stat input file '%s'"), fname);
687       return 1;
688     }
689   /* Paranoid mode on.  */
690   if (preserve_dates
691       && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
692     {
693       /* We detected a race.  Try again.  */
694       close (fd);
695       goto again;
696     }
697
698   /* Now get the ELF descriptor.  */
699   Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
700                         NULL);
701   int result;
702   switch (elf_kind (elf))
703     {
704     case ELF_K_ELF:
705       result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
706                            preserve_dates ? tv : NULL);
707       break;
708
709     case ELF_K_AR:
710       /* It is not possible to strip the content of an archive direct
711          the output to a specific file.  */
712       if (unlikely (output_fname != NULL || debug_fname != NULL))
713         {
714           error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"),
715                  fname);
716           result = 1;
717         }
718       else
719         {
720           /* We would like to support ar archives, but currently it just
721              doesn't work at all since we call elf_clone on the members
722              which doesn't really support ar members.
723              result = handle_ar (fd, elf, NULL, fname,
724                                  preserve_dates ? tv : NULL);
725            */
726           error (0, 0, gettext ("%s: no support for stripping archive"),
727                  fname);
728           result = 1;
729         }
730       break;
731
732     default:
733       error (0, 0, gettext ("%s: File format not recognized"), fname);
734       result = 1;
735       break;
736     }
737
738   if (unlikely (elf_end (elf) != 0))
739     INTERNAL_ERROR (fname);
740
741   close (fd);
742
743   return result;
744 }
745
746
747 /* Maximum size of array allocated on stack.  */
748 #define MAX_STACK_ALLOC (400 * 1024)
749
750 static int
751 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
752             mode_t mode, struct timespec tvp[2])
753 {
754   size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
755   size_t fname_len = strlen (fname) + 1;
756   char *fullname = alloca (prefix_len + 1 + fname_len);
757   char *cp = fullname;
758   Elf *debugelf = NULL;
759   tmp_debug_fname = NULL;
760   int result = 0;
761   size_t shdridx = 0;
762   size_t shstrndx;
763   struct shdr_info
764   {
765     Elf_Scn *scn;
766     GElf_Shdr shdr;
767     Elf_Data *data;
768     Elf_Data *debug_data;
769     const char *name;
770     Elf32_Word idx;             /* Index in new file.  */
771     Elf32_Word old_sh_link;     /* Original value of shdr.sh_link.  */
772     Elf32_Word symtab_idx;
773     Elf32_Word version_idx;
774     Elf32_Word group_idx;
775     Elf32_Word group_cnt;
776     Elf_Scn *newscn;
777     Dwelf_Strent *se;
778     Elf32_Word *newsymidx;
779   } *shdr_info = NULL;
780   Elf_Scn *scn;
781   size_t cnt;
782   size_t idx;
783   bool changes;
784   GElf_Ehdr newehdr_mem;
785   GElf_Ehdr *newehdr;
786   GElf_Ehdr debugehdr_mem;
787   GElf_Ehdr *debugehdr;
788   Dwelf_Strtab *shst = NULL;
789   Elf_Data debuglink_crc_data;
790   bool any_symtab_changes = false;
791   Elf_Data *shstrtab_data = NULL;
792   void *debuglink_buf = NULL;
793
794   /* Create the full name of the file.  */
795   if (prefix != NULL)
796     {
797       cp = mempcpy (cp, prefix, prefix_len);
798       *cp++ = ':';
799     }
800   memcpy (cp, fname, fname_len);
801
802   /* If we are not replacing the input file open a new file here.  */
803   if (output_fname != NULL)
804     {
805       fd = open (output_fname, O_RDWR | O_CREAT, mode);
806       if (unlikely (fd == -1))
807         {
808           error (0, errno, gettext ("cannot open '%s'"), output_fname);
809           return 1;
810         }
811     }
812
813   debug_fd = -1;
814
815   /* Get the EBL handling.  Removing all debugging symbols with the -g
816      option or resolving all relocations between debug sections with
817      the --reloc-debug-sections option are currently the only reasons
818      we need EBL so don't open the backend unless necessary.  */
819   Ebl *ebl = NULL;
820   if (remove_debug || reloc_debug)
821     {
822       ebl = ebl_openbackend (elf);
823       if (ebl == NULL)
824         {
825           error (0, errno, gettext ("cannot open EBL backend"));
826           result = 1;
827           goto fail;
828         }
829     }
830
831   /* Open the additional file the debug information will be stored in.  */
832   if (debug_fname != NULL)
833     {
834       /* Create a temporary file name.  We do not want to overwrite
835          the debug file if the file would not contain any
836          information.  */
837       size_t debug_fname_len = strlen (debug_fname);
838       tmp_debug_fname = (char *) xmalloc (debug_fname_len + sizeof (".XXXXXX"));
839       strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
840               ".XXXXXX");
841
842       debug_fd = mkstemp (tmp_debug_fname);
843       if (unlikely (debug_fd == -1))
844         {
845           error (0, errno, gettext ("cannot open '%s'"), debug_fname);
846           result = 1;
847           goto fail;
848         }
849     }
850
851   /* Get the information from the old file.  */
852   GElf_Ehdr ehdr_mem;
853   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
854   if (ehdr == NULL)
855     INTERNAL_ERROR (fname);
856
857   /* Get the section header string table index.  */
858   if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
859     {
860       cleanup_debug ();
861       error (EXIT_FAILURE, 0,
862              gettext ("cannot get section header string table index"));
863     }
864
865   /* Get the number of phdrs in the old file.  */
866   size_t phnum;
867   if (elf_getphdrnum (elf, &phnum) != 0)
868     {
869       cleanup_debug ();
870       error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs"));
871     }
872
873   /* We now create a new ELF descriptor for the same file.  We
874      construct it almost exactly in the same way with some information
875      dropped.  */
876   Elf *newelf;
877   if (output_fname != NULL)
878     newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
879   else
880     newelf = elf_clone (elf, ELF_C_EMPTY);
881
882   if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0))
883     {
884       error (0, 0, gettext ("cannot create new ehdr for file '%s': %s"),
885              output_fname ?: fname, elf_errmsg (-1));
886       goto fail;
887     }
888
889   /* Copy over the old program header if needed.  */
890   if (phnum > 0)
891     {
892       if (unlikely (gelf_newphdr (newelf, phnum) == 0))
893         {
894           error (0, 0, gettext ("cannot create new phdr for file '%s': %s"),
895                  output_fname ?: fname, elf_errmsg (-1));
896           goto fail;
897         }
898
899       for (cnt = 0; cnt < phnum; ++cnt)
900         {
901           GElf_Phdr phdr_mem;
902           GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
903           if (phdr == NULL
904               || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
905             INTERNAL_ERROR (fname);
906         }
907     }
908
909   if (debug_fname != NULL)
910     {
911       /* Also create an ELF descriptor for the debug file */
912       debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
913       if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0))
914         {
915           error (0, 0, gettext ("cannot create new ehdr for file '%s': %s"),
916                  debug_fname, elf_errmsg (-1));
917           goto fail_close;
918         }
919
920       /* Copy over the old program header if needed.  */
921       if (phnum > 0)
922         {
923           if (unlikely (gelf_newphdr (debugelf, phnum) == 0))
924             {
925               error (0, 0, gettext ("cannot create new phdr for file '%s': %s"),
926                      debug_fname, elf_errmsg (-1));
927               goto fail_close;
928             }
929
930           for (cnt = 0; cnt < phnum; ++cnt)
931             {
932               GElf_Phdr phdr_mem;
933               GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
934               if (phdr == NULL
935                   || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
936                 INTERNAL_ERROR (fname);
937             }
938         }
939     }
940
941   /* Number of sections.  */
942   size_t shnum;
943   if (unlikely (elf_getshdrnum (elf, &shnum) < 0))
944     {
945       error (0, 0, gettext ("cannot determine number of sections: %s"),
946              elf_errmsg (-1));
947       goto fail_close;
948     }
949
950   if (shstrndx >= shnum)
951     goto illformed;
952
953 #define elf_assert(test) do { if (!(test)) goto illformed; } while (0)
954
955   /* Storage for section information.  We leave room for two more
956      entries since we unconditionally create a section header string
957      table.  Maybe some weird tool created an ELF file without one.
958      The other one is used for the debug link section.  */
959   if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
960     shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
961                                               sizeof (struct shdr_info));
962   else
963     {
964       shdr_info = (struct shdr_info *) alloca ((shnum + 2)
965                                                * sizeof (struct shdr_info));
966       memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
967     }
968
969   /* Track whether allocated sections all come before non-allocated ones.  */
970   bool seen_allocated = false;
971   bool seen_unallocated = false;
972   bool mixed_allocated_unallocated = false;
973
974   /* Prepare section information data structure.  */
975   scn = NULL;
976   cnt = 1;
977   while ((scn = elf_nextscn (elf, scn)) != NULL)
978     {
979       /* This should always be true (i.e., there should not be any
980          holes in the numbering).  */
981       elf_assert (elf_ndxscn (scn) == cnt);
982
983       shdr_info[cnt].scn = scn;
984
985       /* Get the header.  */
986       if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
987         INTERNAL_ERROR (fname);
988
989       /* Normally (in non-ET_REL files) we see all allocated sections first,
990          then all non-allocated.  */
991       if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
992         seen_unallocated = true;
993       else
994         {
995           if (seen_unallocated && seen_allocated)
996             mixed_allocated_unallocated = true;
997           seen_allocated = true;
998         }
999
1000       /* Get the name of the section.  */
1001       shdr_info[cnt].name = elf_strptr (elf, shstrndx,
1002                                         shdr_info[cnt].shdr.sh_name);
1003       if (shdr_info[cnt].name == NULL)
1004         {
1005         illformed:
1006           error (0, 0, gettext ("illformed file '%s'"), fname);
1007           goto fail_close;
1008         }
1009
1010       /* Sanity check the user.  */
1011       if (section_name_matches (remove_secs, shdr_info[cnt].name))
1012         {
1013           if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0)
1014             {
1015               error (0, 0,
1016                      gettext ("Cannot remove allocated section '%s'"),
1017                      shdr_info[cnt].name);
1018               result = 1;
1019               goto fail_close;
1020             }
1021
1022           if (section_name_matches (keep_secs, shdr_info[cnt].name))
1023             {
1024               error (0, 0,
1025                      gettext ("Cannot both keep and remove section '%s'"),
1026                      shdr_info[cnt].name);
1027               result = 1;
1028               goto fail_close;
1029             }
1030         }
1031
1032       /* Mark them as present but not yet investigated.  */
1033       shdr_info[cnt].idx = 1;
1034
1035       /* Remember the shdr.sh_link value.  */
1036       shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
1037       if (shdr_info[cnt].old_sh_link >= shnum)
1038         goto illformed;
1039
1040       /* Sections in files other than relocatable object files which
1041          not loaded can be freely moved by us.  In theory we can also
1042          freely move around allocated nobits sections.  But we don't
1043          to keep the layout of all allocated sections as similar as
1044          possible to the original file.  In relocatable object files
1045          everything can be moved.  */
1046       if (phnum == 0
1047           || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
1048         shdr_info[cnt].shdr.sh_offset = 0;
1049
1050       /* If this is an extended section index table store an
1051          appropriate reference.  */
1052       if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
1053         {
1054           elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
1055           shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
1056         }
1057       else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
1058         {
1059           /* Cross-reference the sections contained in the section
1060              group.  */
1061           shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1062           if (shdr_info[cnt].data == NULL
1063               || shdr_info[cnt].data->d_size < sizeof (Elf32_Word))
1064             INTERNAL_ERROR (fname);
1065
1066           /* XXX Fix for unaligned access.  */
1067           Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1068           size_t inner;
1069           for (inner = 1;
1070                inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1071                ++inner)
1072             {
1073               if (grpref[inner] < shnum)
1074                 shdr_info[grpref[inner]].group_idx = cnt;
1075               else
1076                 goto illformed;
1077             }
1078
1079           if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
1080             /* If the section group contains only one element and this
1081                is n COMDAT section we can drop it right away.  */
1082             shdr_info[cnt].idx = 0;
1083           else
1084             shdr_info[cnt].group_cnt = inner - 1;
1085         }
1086       else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
1087         {
1088           elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
1089           shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
1090         }
1091
1092       /* If this section is part of a group make sure it is not
1093          discarded right away.  */
1094       if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
1095         {
1096           elf_assert (shdr_info[cnt].group_idx != 0);
1097
1098           if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
1099             {
1100               /* The section group section might be removed.
1101                  Don't remove the SHF_GROUP flag.  The section is
1102                  either also removed, in which case the flag doesn't matter.
1103                  Or it moves with the group into the debug file, then
1104                  it will be reconnected with the new group and should
1105                  still have the flag set.  */
1106               shdr_info[cnt].group_idx = 0;
1107             }
1108         }
1109
1110       /* Increment the counter.  */
1111       ++cnt;
1112     }
1113
1114   /* Now determine which sections can go away.  The general rule is that
1115      all sections which are not used at runtime are stripped out.  But
1116      there are a few exceptions:
1117
1118      - special sections named ".comment" and ".note" are kept
1119      - OS or architecture specific sections are kept since we might not
1120        know how to handle them
1121      - if a section is referred to from a section which is not removed
1122        in the sh_link or sh_info element it cannot be removed either
1123      - the user might have explicitly said to remove or keep a section
1124   */
1125   for (cnt = 1; cnt < shnum; ++cnt)
1126     /* Check whether the section can be removed.  Since we will create
1127        a new .shstrtab assume it will be removed too.  */
1128     if (remove_shdrs ? !(shdr_info[cnt].shdr.sh_flags & SHF_ALLOC)
1129         : (ebl_section_strip_p (ebl, &shdr_info[cnt].shdr,
1130                                 shdr_info[cnt].name, remove_comment,
1131                                 remove_debug)
1132            || cnt == shstrndx
1133            || section_name_matches (remove_secs, shdr_info[cnt].name)))
1134       {
1135         /* The user might want to explicitly keep this one.  */
1136         if (section_name_matches (keep_secs, shdr_info[cnt].name))
1137           continue;
1138
1139         /* For now assume this section will be removed.  */
1140         shdr_info[cnt].idx = 0;
1141
1142         idx = shdr_info[cnt].group_idx;
1143         while (idx != 0)
1144           {
1145             /* The section group data is already loaded.  */
1146             elf_assert (shdr_info[idx].data != NULL
1147                         && shdr_info[idx].data->d_buf != NULL
1148                         && shdr_info[idx].data->d_size >= sizeof (Elf32_Word));
1149
1150             /* If the references section group is a normal section
1151                group and has one element remaining, or if it is an
1152                empty COMDAT section group it is removed.  */
1153             bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
1154                               & GRP_COMDAT) != 0;
1155
1156             --shdr_info[idx].group_cnt;
1157             if ((!is_comdat && shdr_info[idx].group_cnt == 1)
1158                 || (is_comdat && shdr_info[idx].group_cnt == 0))
1159               {
1160                 shdr_info[idx].idx = 0;
1161                 /* Continue recursively.  */
1162                 idx = shdr_info[idx].group_idx;
1163               }
1164             else
1165               break;
1166           }
1167       }
1168
1169   /* Mark the SHT_NULL section as handled.  */
1170   shdr_info[0].idx = 2;
1171
1172
1173   /* Handle exceptions: section groups and cross-references.  We might
1174      have to repeat this a few times since the resetting of the flag
1175      might propagate.  */
1176   do
1177     {
1178       changes = false;
1179
1180       for (cnt = 1; cnt < shnum; ++cnt)
1181         {
1182           if (shdr_info[cnt].idx == 0)
1183             {
1184               /* If a relocation section is marked as being removed make
1185                  sure the section it is relocating is removed, too.  */
1186               if (shdr_info[cnt].shdr.sh_type == SHT_REL
1187                    || shdr_info[cnt].shdr.sh_type == SHT_RELA)
1188                 {
1189                   if (shdr_info[cnt].shdr.sh_info >= shnum)
1190                     goto illformed;
1191                   else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
1192                     shdr_info[cnt].idx = 1;
1193                 }
1194
1195               /* If a group section is marked as being removed make
1196                  sure all the sections it contains are being removed, too.  */
1197               if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1198                 {
1199                   Elf32_Word *grpref;
1200                   grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1201                   for (size_t in = 1;
1202                        in < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1203                        ++in)
1204                     if (grpref[in] < shnum)
1205                       {
1206                         if (shdr_info[grpref[in]].idx != 0)
1207                           {
1208                             shdr_info[cnt].idx = 1;
1209                             break;
1210                           }
1211                       }
1212                     else
1213                       goto illformed;
1214                 }
1215             }
1216
1217           if (shdr_info[cnt].idx == 1)
1218             {
1219               /* The content of symbol tables we don't remove must not
1220                  reference any section which we do remove.  Otherwise
1221                  we cannot remove the section.  */
1222               if (debug_fname != NULL
1223                   && shdr_info[cnt].debug_data == NULL
1224                   && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1225                       || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB))
1226                 {
1227                   /* Make sure the data is loaded.  */
1228                   if (shdr_info[cnt].data == NULL)
1229                     {
1230                       shdr_info[cnt].data
1231                         = elf_getdata (shdr_info[cnt].scn, NULL);
1232                       if (shdr_info[cnt].data == NULL)
1233                         INTERNAL_ERROR (fname);
1234                     }
1235                   Elf_Data *symdata = shdr_info[cnt].data;
1236
1237                   /* If there is an extended section index table load it
1238                      as well.  */
1239                   if (shdr_info[cnt].symtab_idx != 0
1240                       && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
1241                     {
1242                       elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
1243
1244                       shdr_info[shdr_info[cnt].symtab_idx].data
1245                         = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1246                                        NULL);
1247                       if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
1248                         INTERNAL_ERROR (fname);
1249                     }
1250                   Elf_Data *xndxdata
1251                     = shdr_info[shdr_info[cnt].symtab_idx].data;
1252
1253                   /* Go through all symbols and make sure the section they
1254                      reference is not removed.  */
1255                   size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
1256
1257                   for (size_t inner = 0;
1258                        inner < shdr_info[cnt].data->d_size / elsize;
1259                        ++inner)
1260                     {
1261                       GElf_Sym sym_mem;
1262                       Elf32_Word xndx;
1263                       GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
1264                                                         inner, &sym_mem,
1265                                                         &xndx);
1266                       if (sym == NULL)
1267                         INTERNAL_ERROR (fname);
1268
1269                       size_t scnidx = sym->st_shndx;
1270                       if (scnidx == SHN_UNDEF || scnidx >= shnum
1271                           || (scnidx >= SHN_LORESERVE
1272                               && scnidx <= SHN_HIRESERVE
1273                               && scnidx != SHN_XINDEX)
1274                           /* Don't count in the section symbols.  */
1275                           || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
1276                         /* This is no section index, leave it alone.  */
1277                         continue;
1278                       else if (scnidx == SHN_XINDEX)
1279                         scnidx = xndx;
1280
1281                       if (scnidx >= shnum)
1282                         goto illformed;
1283
1284                       if (shdr_info[scnidx].idx == 0)
1285                         /* This symbol table has a real symbol in
1286                            a discarded section.  So preserve the
1287                            original table in the debug file.  Unless
1288                            it is a redundant data marker to a debug
1289                            (data only) section.  */
1290                         if (! (ebl_section_strip_p (ebl,
1291                                                     &shdr_info[scnidx].shdr,
1292                                                     shdr_info[scnidx].name,
1293                                                     remove_comment,
1294                                                     remove_debug)
1295                                && ebl_data_marker_symbol (ebl, sym,
1296                                         elf_strptr (elf,
1297                                                     shdr_info[cnt].shdr.sh_link,
1298                                                     sym->st_name))))
1299                           shdr_info[cnt].debug_data = symdata;
1300                     }
1301                 }
1302
1303               /* Cross referencing happens:
1304                  - for the cases the ELF specification says.  That are
1305                    + SHT_DYNAMIC in sh_link to string table
1306                    + SHT_HASH in sh_link to symbol table
1307                    + SHT_REL and SHT_RELA in sh_link to symbol table
1308                    + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
1309                    + SHT_GROUP in sh_link to symbol table
1310                    + SHT_SYMTAB_SHNDX in sh_link to symbol table
1311                    Other (OS or architecture-specific) sections might as
1312                    well use this field so we process it unconditionally.
1313                  - references inside section groups
1314                  - specially marked references in sh_info if the SHF_INFO_LINK
1315                  flag is set
1316               */
1317
1318               if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
1319                 {
1320                   shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
1321                   changes |= shdr_info[cnt].shdr.sh_link < cnt;
1322                 }
1323
1324               /* Handle references through sh_info.  */
1325               if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1326                 {
1327                   if (shdr_info[cnt].shdr.sh_info >= shnum)
1328                     goto illformed;
1329                   else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
1330                     {
1331                       shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
1332                       changes |= shdr_info[cnt].shdr.sh_info < cnt;
1333                     }
1334                 }
1335
1336               /* Mark the section as investigated.  */
1337               shdr_info[cnt].idx = 2;
1338             }
1339
1340           if (debug_fname != NULL
1341               && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL))
1342             {
1343               /* This section is being preserved in the debug file.
1344                  Sections it refers to must be preserved there too.
1345
1346                  In this pass we mark sections to be preserved in both
1347                  files by setting the .debug_data pointer to the original
1348                  file's .data pointer.  Below, we'll copy the section
1349                  contents.  */
1350
1351               inline void check_preserved (size_t i)
1352               {
1353                 if (i != 0 && i < shnum + 2 && shdr_info[i].idx != 0
1354                     && shdr_info[i].debug_data == NULL)
1355                   {
1356                     if (shdr_info[i].data == NULL)
1357                       shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL);
1358                     if (shdr_info[i].data == NULL)
1359                       INTERNAL_ERROR (fname);
1360
1361                     shdr_info[i].debug_data = shdr_info[i].data;
1362                     changes |= i < cnt;
1363                   }
1364               }
1365
1366               check_preserved (shdr_info[cnt].shdr.sh_link);
1367               if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1368                 check_preserved (shdr_info[cnt].shdr.sh_info);
1369             }
1370         }
1371     }
1372   while (changes);
1373
1374   /* Copy the removed sections to the debug output file.
1375      The ones that are not removed in the stripped file are SHT_NOBITS.  */
1376   if (debug_fname != NULL)
1377     {
1378       for (cnt = 1; cnt < shnum; ++cnt)
1379         {
1380           scn = elf_newscn (debugelf);
1381           if (scn == NULL)
1382             {
1383               cleanup_debug ();
1384               error (EXIT_FAILURE, 0,
1385                      gettext ("while generating output file: %s"),
1386                      elf_errmsg (-1));
1387             }
1388
1389           bool discard_section = (shdr_info[cnt].idx > 0
1390                                   && shdr_info[cnt].debug_data == NULL
1391                                   && shdr_info[cnt].shdr.sh_type != SHT_NOTE
1392                                   && shdr_info[cnt].shdr.sh_type != SHT_GROUP
1393                                   && cnt != shstrndx);
1394
1395           /* Set the section header in the new file.  */
1396           GElf_Shdr debugshdr = shdr_info[cnt].shdr;
1397           if (discard_section)
1398             debugshdr.sh_type = SHT_NOBITS;
1399
1400           if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
1401             /* There cannot be any overflows.  */
1402             INTERNAL_ERROR (fname);
1403
1404           /* Get the data from the old file if necessary. */
1405           if (shdr_info[cnt].data == NULL)
1406             {
1407               shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1408               if (shdr_info[cnt].data == NULL)
1409                 INTERNAL_ERROR (fname);
1410             }
1411
1412           /* Set the data.  This is done by copying from the old file.  */
1413           Elf_Data *debugdata = elf_newdata (scn);
1414           if (debugdata == NULL)
1415             INTERNAL_ERROR (fname);
1416
1417           /* Copy the structure.  This data may be modified in place
1418              before we write out the file.  */
1419           *debugdata = *shdr_info[cnt].data;
1420           if (discard_section)
1421             debugdata->d_buf = NULL;
1422           else if (shdr_info[cnt].debug_data != NULL
1423                    || shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1424             {
1425               /* Copy the original data before it gets modified.  */
1426               shdr_info[cnt].debug_data = debugdata;
1427               if (debugdata->d_buf == NULL)
1428                 INTERNAL_ERROR (fname);
1429               debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
1430                                          debugdata->d_buf, debugdata->d_size);
1431             }
1432         }
1433
1434       /* Finish the ELF header.  Fill in the fields not handled by
1435          libelf from the old file.  */
1436       debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
1437       if (debugehdr == NULL)
1438         INTERNAL_ERROR (fname);
1439
1440       memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1441       debugehdr->e_type = ehdr->e_type;
1442       debugehdr->e_machine = ehdr->e_machine;
1443       debugehdr->e_version = ehdr->e_version;
1444       debugehdr->e_entry = ehdr->e_entry;
1445       debugehdr->e_flags = ehdr->e_flags;
1446
1447       size_t shdrstrndx;
1448       if (elf_getshdrstrndx (elf, &shdrstrndx) < 0)
1449         {
1450           error (0, 0, gettext ("%s: error while getting shdrstrndx: %s"),
1451                  fname, elf_errmsg (-1));
1452           result = 1;
1453           goto fail_close;
1454         }
1455
1456       if (shstrndx < SHN_LORESERVE)
1457         debugehdr->e_shstrndx = shdrstrndx;
1458       else
1459         {
1460           debugehdr->e_shstrndx = SHN_XINDEX;
1461           Elf_Scn *scn0 = elf_getscn (debugelf, 0);
1462           GElf_Shdr shdr0_mem;
1463           GElf_Shdr *shdr0 = gelf_getshdr (scn0, &shdr0_mem);
1464           if (shdr0 == NULL)
1465             {
1466               error (0, 0, gettext ("%s: error getting zero section: %s"),
1467                      debug_fname, elf_errmsg (-1));
1468               result = 1;
1469               goto fail_close;
1470             }
1471
1472           shdr0->sh_link = shdrstrndx;
1473           if (gelf_update_shdr (scn0, shdr0) == 0)
1474             {
1475               error (0, 0, gettext ("%s: error while updating zero section: %s"),
1476                      debug_fname, elf_errmsg (-1));
1477               result = 1;
1478               goto fail_close;
1479             }
1480
1481         }
1482
1483       if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
1484         {
1485           error (0, 0, gettext ("%s: error while creating ELF header: %s"),
1486                  debug_fname, elf_errmsg (-1));
1487           result = 1;
1488           goto fail_close;
1489         }
1490     }
1491
1492   /* Although we always create a new section header string table we
1493      don't explicitly mark the existing one as unused.  It can still
1494      be used through a symbol table section we are keeping.  If not it
1495      will already be marked as unused.  */
1496
1497   /* We need a string table for the section headers.  */
1498   shst = dwelf_strtab_init (true);
1499   if (shst == NULL)
1500     {
1501       cleanup_debug ();
1502       error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
1503              output_fname ?: fname);
1504     }
1505
1506   /* Assign new section numbers.  */
1507   shdr_info[0].idx = 0;
1508   for (cnt = idx = 1; cnt < shnum; ++cnt)
1509     if (shdr_info[cnt].idx > 0)
1510       {
1511         shdr_info[cnt].idx = idx++;
1512
1513         /* Create a new section.  */
1514         shdr_info[cnt].newscn = elf_newscn (newelf);
1515         if (shdr_info[cnt].newscn == NULL)
1516           {
1517             cleanup_debug ();
1518             error (EXIT_FAILURE, 0,
1519                    gettext ("while generating output file: %s"),
1520                    elf_errmsg (-1));
1521           }
1522
1523         elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1524
1525         /* Add this name to the section header string table.  */
1526         shdr_info[cnt].se = dwelf_strtab_add (shst, shdr_info[cnt].name);
1527       }
1528
1529   /* Test whether we are doing anything at all.  Either all removable
1530      sections are already gone.  Or the only section we would remove is
1531      the .shstrtab section which we would add again.  */
1532   bool removing_sections = !(cnt == idx
1533                              || (cnt == idx + 1
1534                                  && shdr_info[shstrndx].idx == 0));
1535   if (output_fname == NULL && !removing_sections)
1536       goto fail_close;
1537
1538   /* Create the reference to the file with the debug info (if any).  */
1539   if (debug_fname != NULL && !remove_shdrs && removing_sections)
1540     {
1541       /* Add the section header string table section name.  */
1542       shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".gnu_debuglink", 15);
1543       shdr_info[cnt].idx = idx++;
1544
1545       /* Create the section header.  */
1546       shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
1547       shdr_info[cnt].shdr.sh_flags = 0;
1548       shdr_info[cnt].shdr.sh_addr = 0;
1549       shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1550       shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1551       shdr_info[cnt].shdr.sh_entsize = 0;
1552       shdr_info[cnt].shdr.sh_addralign = 4;
1553       /* We set the offset to zero here.  Before we write the ELF file the
1554          field must have the correct value.  This is done in the final
1555          loop over all section.  Then we have all the information needed.  */
1556       shdr_info[cnt].shdr.sh_offset = 0;
1557
1558       /* Create the section.  */
1559       shdr_info[cnt].newscn = elf_newscn (newelf);
1560       if (shdr_info[cnt].newscn == NULL)
1561         {
1562           cleanup_debug ();
1563           error (EXIT_FAILURE, 0,
1564                  gettext ("while create section header section: %s"),
1565                  elf_errmsg (-1));
1566         }
1567       elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
1568
1569       shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
1570       if (shdr_info[cnt].data == NULL)
1571         {
1572           cleanup_debug ();
1573           error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
1574                  elf_errmsg (-1));
1575         }
1576
1577       char *debug_basename = basename (debug_fname_embed ?: debug_fname);
1578       off_t crc_offset = strlen (debug_basename) + 1;
1579       /* Align to 4 byte boundary */
1580       crc_offset = ((crc_offset - 1) & ~3) + 4;
1581
1582       shdr_info[cnt].data->d_align = 4;
1583       shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
1584         = crc_offset + 4;
1585       debuglink_buf = xcalloc (1, shdr_info[cnt].data->d_size);
1586       shdr_info[cnt].data->d_buf = debuglink_buf;
1587
1588       strcpy (shdr_info[cnt].data->d_buf, debug_basename);
1589
1590       /* Cache this Elf_Data describing the CRC32 word in the section.
1591          We'll fill this in when we have written the debug file.  */
1592       debuglink_crc_data = *shdr_info[cnt].data;
1593       debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
1594                                   + crc_offset);
1595       debuglink_crc_data.d_size = 4;
1596
1597       /* One more section done.  */
1598       ++cnt;
1599     }
1600
1601   /* Index of the section header table in the shdr_info array.  */
1602   shdridx = cnt;
1603
1604   /* Add the section header string table section name.  */
1605   shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".shstrtab", 10);
1606   shdr_info[cnt].idx = idx;
1607
1608   /* Create the section header.  */
1609   shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
1610   shdr_info[cnt].shdr.sh_flags = 0;
1611   shdr_info[cnt].shdr.sh_addr = 0;
1612   shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1613   shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1614   shdr_info[cnt].shdr.sh_entsize = 0;
1615   /* We set the offset to zero here.  Before we write the ELF file the
1616      field must have the correct value.  This is done in the final
1617      loop over all section.  Then we have all the information needed.  */
1618   shdr_info[cnt].shdr.sh_offset = 0;
1619   shdr_info[cnt].shdr.sh_addralign = 1;
1620
1621   /* Create the section.  */
1622   shdr_info[cnt].newscn = elf_newscn (newelf);
1623   if (shdr_info[cnt].newscn == NULL)
1624     {
1625       cleanup_debug ();
1626       error (EXIT_FAILURE, 0,
1627              gettext ("while create section header section: %s"),
1628              elf_errmsg (-1));
1629     }
1630   elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1631
1632   /* Finalize the string table and fill in the correct indices in the
1633      section headers.  */
1634   shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1635   if (shstrtab_data == NULL)
1636     {
1637       cleanup_debug ();
1638       error (EXIT_FAILURE, 0,
1639              gettext ("while create section header string table: %s"),
1640              elf_errmsg (-1));
1641     }
1642   if (dwelf_strtab_finalize (shst, shstrtab_data) == NULL)
1643     {
1644       cleanup_debug ();
1645       error (EXIT_FAILURE, 0,
1646              gettext ("no memory to create section header string table"));
1647     }
1648
1649   /* We have to set the section size.  */
1650   shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1651
1652   /* Update the section information.  */
1653   GElf_Off lastoffset = 0;
1654   for (cnt = 1; cnt <= shdridx; ++cnt)
1655     if (shdr_info[cnt].idx > 0)
1656       {
1657         Elf_Data *newdata;
1658
1659         scn = elf_getscn (newelf, shdr_info[cnt].idx);
1660         elf_assert (scn != NULL);
1661
1662         /* Update the name.  */
1663         shdr_info[cnt].shdr.sh_name = dwelf_strent_off (shdr_info[cnt].se);
1664
1665         /* Update the section header from the input file.  Some fields
1666            might be section indeces which now have to be adjusted.  Keep
1667            the index to the "current" sh_link in case we need it to lookup
1668            symbol table names.  */
1669         size_t sh_link = shdr_info[cnt].shdr.sh_link;
1670         if (shdr_info[cnt].shdr.sh_link != 0)
1671           shdr_info[cnt].shdr.sh_link =
1672             shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1673
1674         if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1675           {
1676             elf_assert (shdr_info[cnt].data != NULL
1677                         && shdr_info[cnt].data->d_buf != NULL);
1678
1679             Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1680             /* First word is the section group flag.
1681                Followed by section indexes, that need to be renumbered.  */
1682             for (size_t inner = 1;
1683                  inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1684                  ++inner)
1685               if (grpref[inner] < shnum)
1686                 grpref[inner] = shdr_info[grpref[inner]].idx;
1687               else
1688                 goto illformed;
1689           }
1690
1691         /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag.  */
1692         if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1693           shdr_info[cnt].shdr.sh_info =
1694             shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1695
1696         /* Get the data from the old file if necessary.  We already
1697            created the data for the section header string table.  */
1698         if (cnt < shnum)
1699           {
1700             if (shdr_info[cnt].data == NULL)
1701               {
1702                 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1703                 if (shdr_info[cnt].data == NULL)
1704                   INTERNAL_ERROR (fname);
1705               }
1706
1707             /* Set the data.  This is done by copying from the old file.  */
1708             newdata = elf_newdata (scn);
1709             if (newdata == NULL)
1710               INTERNAL_ERROR (fname);
1711
1712             /* Copy the structure.  */
1713             *newdata = *shdr_info[cnt].data;
1714
1715             /* We know the size.  */
1716             shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1717
1718             /* We have to adjust symbol tables.  The st_shndx member might
1719                have to be updated.  */
1720             if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1721                 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1722               {
1723                 Elf_Data *versiondata = NULL;
1724                 Elf_Data *shndxdata = NULL;
1725
1726                 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
1727
1728                 if (shdr_info[cnt].symtab_idx != 0)
1729                   {
1730                     elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1731                     /* This section has extended section information.
1732                        We have to modify that information, too.  */
1733                     shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1734                                              NULL);
1735
1736                     elf_assert (shndxdata != NULL
1737                                 && shndxdata->d_buf != NULL
1738                                 && ((shndxdata->d_size / sizeof (Elf32_Word))
1739                                     >= shdr_info[cnt].data->d_size / elsize));
1740                   }
1741
1742                 if (shdr_info[cnt].version_idx != 0)
1743                   {
1744                     elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1745                     /* This section has associated version
1746                        information.  We have to modify that
1747                        information, too.  */
1748                     versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1749                                                NULL);
1750
1751                     elf_assert (versiondata != NULL
1752                                 && versiondata->d_buf != NULL
1753                                 && ((versiondata->d_size / sizeof (GElf_Versym))
1754                                     >= shdr_info[cnt].data->d_size / elsize));
1755                   }
1756
1757                 shdr_info[cnt].newsymidx
1758                   = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1759                                             / elsize, sizeof (Elf32_Word));
1760
1761                 bool last_was_local = true;
1762                 size_t destidx;
1763                 size_t inner;
1764                 for (destidx = inner = 1;
1765                      inner < shdr_info[cnt].data->d_size / elsize;
1766                      ++inner)
1767                   {
1768                     Elf32_Word sec;
1769                     GElf_Sym sym_mem;
1770                     Elf32_Word xshndx;
1771                     GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1772                                                       shndxdata, inner,
1773                                                       &sym_mem, &xshndx);
1774                     if (sym == NULL)
1775                       INTERNAL_ERROR (fname);
1776
1777                     if (sym->st_shndx == SHN_UNDEF
1778                         || (sym->st_shndx >= shnum
1779                             && sym->st_shndx != SHN_XINDEX))
1780                       {
1781                         /* This is no section index, leave it alone
1782                            unless it is moved.  */
1783                         if (destidx != inner
1784                             && gelf_update_symshndx (shdr_info[cnt].data,
1785                                                      shndxdata,
1786                                                      destidx, sym,
1787                                                      xshndx) == 0)
1788                           INTERNAL_ERROR (fname);
1789
1790                         shdr_info[cnt].newsymidx[inner] = destidx++;
1791
1792                         if (last_was_local
1793                             && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1794                           {
1795                             last_was_local = false;
1796                             shdr_info[cnt].shdr.sh_info = destidx - 1;
1797                           }
1798
1799                         continue;
1800                       }
1801
1802                     /* Get the full section index, if necessary from the
1803                        XINDEX table.  */
1804                     if (sym->st_shndx == SHN_XINDEX)
1805                       elf_assert (shndxdata != NULL
1806                                   && shndxdata->d_buf != NULL);
1807                     size_t sidx = (sym->st_shndx != SHN_XINDEX
1808                                    ? sym->st_shndx : xshndx);
1809                     sec = shdr_info[sidx].idx;
1810
1811                     if (sec != 0)
1812                       {
1813                         GElf_Section nshndx;
1814                         Elf32_Word nxshndx;
1815
1816                         if (sec < SHN_LORESERVE)
1817                           {
1818                             nshndx = sec;
1819                             nxshndx = 0;
1820                           }
1821                         else
1822                           {
1823                             nshndx = SHN_XINDEX;
1824                             nxshndx = sec;
1825                           }
1826
1827                         elf_assert (sec < SHN_LORESERVE || shndxdata != NULL);
1828
1829                         if ((inner != destidx || nshndx != sym->st_shndx
1830                              || (shndxdata != NULL && nxshndx != xshndx))
1831                             && (sym->st_shndx = nshndx,
1832                                 gelf_update_symshndx (shdr_info[cnt].data,
1833                                                       shndxdata,
1834                                                       destidx, sym,
1835                                                       nxshndx) == 0))
1836                           INTERNAL_ERROR (fname);
1837
1838                         shdr_info[cnt].newsymidx[inner] = destidx++;
1839
1840                         if (last_was_local
1841                             && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1842                           {
1843                             last_was_local = false;
1844                             shdr_info[cnt].shdr.sh_info = destidx - 1;
1845                           }
1846                       }
1847                     else if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0
1848                              && GELF_ST_TYPE (sym->st_info) != STT_SECTION
1849                              && shdr_info[sidx].shdr.sh_type != SHT_GROUP)
1850                       {
1851                         /* Removing a real symbol from an allocated
1852                            symbol table is hard and probably a
1853                            mistake.  Really removing it means
1854                            rewriting the dynamic segment and hash
1855                            sections.  Just warn and set the symbol
1856                            section to UNDEF.  */
1857                         error (0, 0,
1858                                gettext ("Cannot remove symbol [%zd] from allocated symbol table [%zd]"), inner, cnt);
1859                         sym->st_shndx = SHN_UNDEF;
1860                         if (gelf_update_sym (shdr_info[cnt].data, destidx,
1861                                              sym) == 0)
1862                           INTERNAL_ERROR (fname);
1863                         shdr_info[cnt].newsymidx[inner] = destidx++;
1864                       }
1865                     else if (debug_fname != NULL
1866                              && shdr_info[cnt].debug_data == NULL)
1867                       /* The symbol points to a section that is discarded
1868                          but isn't preserved in the debug file. Check that
1869                          this is a section or group signature symbol
1870                          for a section which has been removed.  Or a special
1871                          data marker symbol to a debug section.  */
1872                       {
1873                         elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
1874                                     || ((shdr_info[sidx].shdr.sh_type
1875                                          == SHT_GROUP)
1876                                         && (shdr_info[sidx].shdr.sh_info
1877                                             == inner))
1878                                     || ebl_data_marker_symbol (ebl, sym,
1879                                                 elf_strptr (elf, sh_link,
1880                                                             sym->st_name)));
1881                       }
1882                   }
1883
1884                 if (destidx != inner)
1885                   {
1886                     /* The size of the symbol table changed.  */
1887                     shdr_info[cnt].shdr.sh_size = newdata->d_size
1888                       = destidx * elsize;
1889                     any_symtab_changes = true;
1890                   }
1891                 else
1892                   {
1893                     /* The symbol table didn't really change.  */
1894                     free (shdr_info[cnt].newsymidx);
1895                     shdr_info[cnt].newsymidx = NULL;
1896                   }
1897               }
1898           }
1899
1900         /* If we have to, compute the offset of the section.
1901            If allocate and unallocated sections are mixed, we only update
1902            the allocated ones now.  The unallocated ones come second.  */
1903         if (! mixed_allocated_unallocated
1904             || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0)
1905           {
1906             if (shdr_info[cnt].shdr.sh_offset == 0)
1907               shdr_info[cnt].shdr.sh_offset
1908                 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1909                    & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1910
1911             /* Set the section header in the new file.  */
1912             if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1913               /* There cannot be any overflows.  */
1914               INTERNAL_ERROR (fname);
1915
1916             /* Remember the last section written so far.  */
1917             GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1918                                ? shdr_info[cnt].shdr.sh_size : 0);
1919             if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1920               lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1921           }
1922       }
1923
1924   /* We might have to update the unallocated sections after we done the
1925      allocated ones.  lastoffset is set to right after the last allocated
1926      section.  */
1927   if (mixed_allocated_unallocated)
1928     for (cnt = 1; cnt <= shdridx; ++cnt)
1929       if (shdr_info[cnt].idx > 0)
1930         {
1931           scn = elf_getscn (newelf, shdr_info[cnt].idx);
1932           if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
1933             {
1934               if (shdr_info[cnt].shdr.sh_offset == 0)
1935                 shdr_info[cnt].shdr.sh_offset
1936                   = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1937                      & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1938
1939               /* Set the section header in the new file.  */
1940               if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1941                 /* There cannot be any overflows.  */
1942                 INTERNAL_ERROR (fname);
1943
1944               /* Remember the last section written so far.  */
1945               GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1946                                  ? shdr_info[cnt].shdr.sh_size : 0);
1947               if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1948                 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1949             }
1950         }
1951
1952   /* Adjust symbol references if symbol tables changed.  */
1953   if (any_symtab_changes)
1954     /* Find all relocation sections which use this symbol table.  */
1955     for (cnt = 1; cnt <= shdridx; ++cnt)
1956       {
1957         /* Update section headers when the data size has changed.
1958            We also update the SHT_NOBITS section in the debug
1959            file so that the section headers match in sh_size.  */
1960         inline void update_section_size (const Elf_Data *newdata)
1961         {
1962           GElf_Shdr shdr_mem;
1963           GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1964           shdr->sh_size = newdata->d_size;
1965           (void) gelf_update_shdr (scn, shdr);
1966           if (debugelf != NULL)
1967             {
1968               /* libelf will use d_size to set sh_size.  */
1969               Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
1970                                                              cnt), NULL);
1971               if (debugdata == NULL)
1972                 INTERNAL_ERROR (fname);
1973               debugdata->d_size = newdata->d_size;
1974             }
1975         }
1976
1977         if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
1978           /* Ignore sections which are discarded.  When we are saving a
1979              relocation section in a separate debug file, we must fix up
1980              the symbol table references.  */
1981           continue;
1982
1983         const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1984         elf_assert (symtabidx < shnum + 2);
1985         const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
1986         switch (shdr_info[cnt].shdr.sh_type)
1987           {
1988             inline bool no_symtab_updates (void)
1989             {
1990               /* If the symbol table hasn't changed, do not do anything.  */
1991               if (shdr_info[symtabidx].newsymidx == NULL)
1992                 return true;
1993
1994               /* If the symbol table is not discarded, but additionally
1995                  duplicated in the separate debug file and this section
1996                  is discarded, don't adjust anything.  */
1997               return (shdr_info[cnt].idx == 0
1998                       && shdr_info[symtabidx].debug_data != NULL);
1999             }
2000
2001           case SHT_REL:
2002           case SHT_RELA:
2003             if (no_symtab_updates ())
2004               break;
2005
2006             Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
2007                                        ? elf_getscn (debugelf, cnt)
2008                                        : elf_getscn (newelf,
2009                                                      shdr_info[cnt].idx),
2010                                        NULL);
2011             elf_assert (d != NULL && d->d_buf != NULL
2012                         && shdr_info[cnt].shdr.sh_entsize != 0);
2013             size_t nrels = (shdr_info[cnt].shdr.sh_size
2014                             / shdr_info[cnt].shdr.sh_entsize);
2015
2016             size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2017             const Elf32_Word symidxn = (shdr_info[symtabidx].data->d_size
2018                                         / symsize);
2019             if (shdr_info[cnt].shdr.sh_type == SHT_REL)
2020               for (size_t relidx = 0; relidx < nrels; ++relidx)
2021                 {
2022                   GElf_Rel rel_mem;
2023                   if (gelf_getrel (d, relidx, &rel_mem) == NULL)
2024                     INTERNAL_ERROR (fname);
2025
2026                   size_t symidx = GELF_R_SYM (rel_mem.r_info);
2027                   elf_assert (symidx < symidxn);
2028                   if (newsymidx[symidx] != symidx)
2029                     {
2030                       rel_mem.r_info
2031                         = GELF_R_INFO (newsymidx[symidx],
2032                                        GELF_R_TYPE (rel_mem.r_info));
2033
2034                       if (gelf_update_rel (d, relidx, &rel_mem) == 0)
2035                         INTERNAL_ERROR (fname);
2036                     }
2037                 }
2038             else
2039               for (size_t relidx = 0; relidx < nrels; ++relidx)
2040                 {
2041                   GElf_Rela rel_mem;
2042                   if (gelf_getrela (d, relidx, &rel_mem) == NULL)
2043                     INTERNAL_ERROR (fname);
2044
2045                   size_t symidx = GELF_R_SYM (rel_mem.r_info);
2046                   elf_assert (symidx < symidxn);
2047                   if (newsymidx[symidx] != symidx)
2048                     {
2049                       rel_mem.r_info
2050                         = GELF_R_INFO (newsymidx[symidx],
2051                                        GELF_R_TYPE (rel_mem.r_info));
2052
2053                       if (gelf_update_rela (d, relidx, &rel_mem) == 0)
2054                         INTERNAL_ERROR (fname);
2055                     }
2056                 }
2057             break;
2058
2059           case SHT_HASH:
2060             if (no_symtab_updates ())
2061               break;
2062
2063             /* We have to recompute the hash table.  */
2064
2065             elf_assert (shdr_info[cnt].idx > 0);
2066
2067             /* The hash section in the new file.  */
2068             scn = elf_getscn (newelf, shdr_info[cnt].idx);
2069
2070             /* The symbol table data.  */
2071             Elf_Data *symd = elf_getdata (elf_getscn (newelf,
2072                                                       shdr_info[symtabidx].idx),
2073                                           NULL);
2074             elf_assert (symd != NULL && symd->d_buf != NULL);
2075
2076             /* The hash table data.  */
2077             Elf_Data *hashd = elf_getdata (scn, NULL);
2078             elf_assert (hashd != NULL && hashd->d_buf != NULL);
2079
2080             if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
2081               {
2082                 /* Sane arches first.  */
2083                 elf_assert (hashd->d_size >= 2 * sizeof (Elf32_Word));
2084                 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
2085
2086                 size_t strshndx = shdr_info[symtabidx].old_sh_link;
2087                 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2088
2089                 Elf32_Word nchain = bucket[1];
2090                 Elf32_Word nbucket = bucket[0];
2091                 uint64_t used_buf = ((2ULL + nchain + nbucket)
2092                                      * sizeof (Elf32_Word));
2093                 elf_assert (used_buf <= hashd->d_size);
2094
2095                 /* Adjust the nchain value.  The symbol table size
2096                    changed.  We keep the same size for the bucket array.  */
2097                 bucket[1] = symd->d_size / elsize;
2098                 bucket += 2;
2099                 Elf32_Word *chain = bucket + nbucket;
2100
2101                 /* New size of the section.  */
2102                 size_t n_size = ((2 + symd->d_size / elsize + nbucket)
2103                                  * sizeof (Elf32_Word));
2104                 elf_assert (n_size <= hashd->d_size);
2105                 hashd->d_size = n_size;
2106                 update_section_size (hashd);
2107
2108                 /* Clear the arrays.  */
2109                 memset (bucket, '\0',
2110                         (symd->d_size / elsize + nbucket)
2111                         * sizeof (Elf32_Word));
2112
2113                 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
2114                      inner < symd->d_size / elsize; ++inner)
2115                   {
2116                     GElf_Sym sym_mem;
2117                     GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
2118                     elf_assert (sym != NULL);
2119
2120                     const char *name = elf_strptr (elf, strshndx,
2121                                                    sym->st_name);
2122                     elf_assert (name != NULL && nbucket != 0);
2123                     size_t hidx = elf_hash (name) % nbucket;
2124
2125                     if (bucket[hidx] == 0)
2126                       bucket[hidx] = inner;
2127                     else
2128                       {
2129                         hidx = bucket[hidx];
2130
2131                         while (chain[hidx] != 0 && chain[hidx] < nchain)
2132                           hidx = chain[hidx];
2133
2134                         chain[hidx] = inner;
2135                       }
2136                   }
2137               }
2138             else
2139               {
2140                 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries.  */
2141                 elf_assert (shdr_info[cnt].shdr.sh_entsize
2142                             == sizeof (Elf64_Xword));
2143
2144                 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
2145
2146                 size_t strshndx = shdr_info[symtabidx].old_sh_link;
2147                 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2148
2149                 elf_assert (symd->d_size >= 2 * sizeof (Elf64_Xword));
2150                 Elf64_Xword nbucket = bucket[0];
2151                 Elf64_Xword nchain = bucket[1];
2152                 uint64_t maxwords = hashd->d_size / sizeof (Elf64_Xword);
2153                 elf_assert (maxwords >= 2
2154                             && maxwords - 2 >= nbucket
2155                             && maxwords - 2 - nbucket >= nchain);
2156
2157                 /* Adjust the nchain value.  The symbol table size
2158                    changed.  We keep the same size for the bucket array.  */
2159                 bucket[1] = symd->d_size / elsize;
2160                 bucket += 2;
2161                 Elf64_Xword *chain = bucket + nbucket;
2162
2163                 /* New size of the section.  */
2164                 size_t n_size = ((2 + symd->d_size / elsize + nbucket)
2165                                  * sizeof (Elf64_Xword));
2166                 elf_assert (n_size <= hashd->d_size);
2167                 hashd->d_size = n_size;
2168                 update_section_size (hashd);
2169
2170                 /* Clear the arrays.  */
2171                 memset (bucket, '\0',
2172                         (symd->d_size / elsize + nbucket)
2173                         * sizeof (Elf64_Xword));
2174
2175                 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
2176                      inner < symd->d_size / elsize; ++inner)
2177                   {
2178                     GElf_Sym sym_mem;
2179                     GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
2180                     elf_assert (sym != NULL);
2181
2182                     const char *name = elf_strptr (elf, strshndx,
2183                                                    sym->st_name);
2184                     elf_assert (name != NULL && nbucket != 0);
2185                     size_t hidx = elf_hash (name) % nbucket;
2186
2187                     if (bucket[hidx] == 0)
2188                       bucket[hidx] = inner;
2189                     else
2190                       {
2191                         hidx = bucket[hidx];
2192
2193                         while (chain[hidx] != 0 && chain[hidx] < nchain)
2194                           hidx = chain[hidx];
2195
2196                         chain[hidx] = inner;
2197                       }
2198                   }
2199               }
2200             break;
2201
2202           case SHT_GNU_versym:
2203             /* If the symbol table changed we have to adjust the entries.  */
2204             if (no_symtab_updates ())
2205               break;
2206
2207             elf_assert (shdr_info[cnt].idx > 0);
2208
2209             /* The symbol version section in the new file.  */
2210             scn = elf_getscn (newelf, shdr_info[cnt].idx);
2211
2212             /* The symbol table data.  */
2213             symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
2214                                 NULL);
2215             elf_assert (symd != NULL && symd->d_buf != NULL);
2216             size_t symz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2217             const Elf32_Word syms = (shdr_info[symtabidx].data->d_size / symz);
2218
2219             /* The version symbol data.  */
2220             Elf_Data *verd = elf_getdata (scn, NULL);
2221             elf_assert (verd != NULL && verd->d_buf != NULL);
2222
2223             /* The symbol version array.  */
2224             GElf_Half *verstab = (GElf_Half *) verd->d_buf;
2225
2226             /* Walk through the list and */
2227             size_t elsize = gelf_fsize (elf, verd->d_type, 1, EV_CURRENT);
2228             Elf32_Word vers = verd->d_size / elsize;
2229             for (size_t inner = 1; inner < vers && inner < syms; ++inner)
2230               if (newsymidx[inner] != 0 && newsymidx[inner] < vers)
2231                 /* Overwriting the same array works since the
2232                    reordering can only move entries to lower indices
2233                    in the array.  */
2234                 verstab[newsymidx[inner]] = verstab[inner];
2235
2236             /* New size of the section.  */
2237             verd->d_size = gelf_fsize (newelf, verd->d_type,
2238                                        symd->d_size
2239                                        / gelf_fsize (elf, symd->d_type, 1,
2240                                                      EV_CURRENT),
2241                                        EV_CURRENT);
2242             update_section_size (verd);
2243             break;
2244
2245           case SHT_GROUP:
2246             if (no_symtab_updates ())
2247               break;
2248
2249             /* Yes, the symbol table changed.
2250                Update the section header of the section group.  */
2251             scn = elf_getscn (newelf, shdr_info[cnt].idx);
2252             GElf_Shdr shdr_mem;
2253             GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2254             elf_assert (shdr != NULL);
2255
2256             size_t symsz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
2257             const Elf32_Word symn = (shdr_info[symtabidx].data->d_size
2258                                      / symsz);
2259             elf_assert (shdr->sh_info < symn);
2260             shdr->sh_info = newsymidx[shdr->sh_info];
2261
2262             (void) gelf_update_shdr (scn, shdr);
2263             break;
2264           }
2265       }
2266
2267   /* Remove any relocations between debug sections in ET_REL
2268      for the debug file when requested.  These relocations are always
2269      zero based between the unallocated sections.  */
2270   if (debug_fname != NULL && removing_sections
2271       && reloc_debug && ehdr->e_type == ET_REL)
2272     remove_debug_relocations (ebl, debugelf, ehdr, fname, shstrndx);
2273
2274   /* Now that we have done all adjustments to the data,
2275      we can actually write out the debug file.  */
2276   if (debug_fname != NULL && removing_sections)
2277     {
2278       /* Finally write the file.  */
2279       if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
2280         {
2281           error (0, 0, gettext ("while writing '%s': %s"),
2282                  tmp_debug_fname, elf_errmsg (-1));
2283           result = 1;
2284           goto fail_close;
2285         }
2286
2287       /* Create the real output file.  First rename, then change the
2288          mode.  */
2289       if (rename (tmp_debug_fname, debug_fname) != 0
2290           || fchmod (debug_fd, mode) != 0)
2291         {
2292           error (0, errno, gettext ("while creating '%s'"), debug_fname);
2293           result = 1;
2294           goto fail_close;
2295         }
2296
2297       /* The temporary file does not exist anymore.  */
2298       free (tmp_debug_fname);
2299       tmp_debug_fname = NULL;
2300
2301       if (!remove_shdrs)
2302         {
2303           uint32_t debug_crc;
2304           Elf_Data debug_crc_data =
2305             {
2306               .d_type = ELF_T_WORD,
2307               .d_buf = &debug_crc,
2308               .d_size = sizeof (debug_crc),
2309               .d_version = EV_CURRENT
2310             };
2311
2312           /* Compute the checksum which we will add to the executable.  */
2313           if (crc32_file (debug_fd, &debug_crc) != 0)
2314             {
2315               error (0, errno, gettext ("\
2316 while computing checksum for debug information"));
2317               unlink (debug_fname);
2318               result = 1;
2319               goto fail_close;
2320             }
2321
2322           /* Store it in the debuglink section data.  */
2323           if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
2324                                        &debug_crc_data, ehdr->e_ident[EI_DATA])
2325                         != &debuglink_crc_data))
2326             INTERNAL_ERROR (fname);
2327         }
2328     }
2329
2330   /* Finally finish the ELF header.  Fill in the fields not handled by
2331      libelf from the old file.  */
2332   newehdr = gelf_getehdr (newelf, &newehdr_mem);
2333   if (newehdr == NULL)
2334     INTERNAL_ERROR (fname);
2335
2336   memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
2337   newehdr->e_type = ehdr->e_type;
2338   newehdr->e_machine = ehdr->e_machine;
2339   newehdr->e_version = ehdr->e_version;
2340   newehdr->e_entry = ehdr->e_entry;
2341   newehdr->e_flags = ehdr->e_flags;
2342   newehdr->e_phoff = ehdr->e_phoff;
2343
2344   /* We need to position the section header table.  */
2345   const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
2346   newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
2347                        + shdr_info[shdridx].shdr.sh_size + offsize - 1)
2348                       & ~((GElf_Off) (offsize - 1)));
2349   newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
2350
2351   /* The new section header string table index.  */
2352   if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
2353     newehdr->e_shstrndx = idx;
2354   else
2355     {
2356       /* The index does not fit in the ELF header field.  */
2357       shdr_info[0].scn = elf_getscn (elf, 0);
2358
2359       if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
2360         INTERNAL_ERROR (fname);
2361
2362       shdr_info[0].shdr.sh_link = idx;
2363       (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
2364
2365       newehdr->e_shstrndx = SHN_XINDEX;
2366     }
2367
2368   if (gelf_update_ehdr (newelf, newehdr) == 0)
2369     {
2370       error (0, 0, gettext ("%s: error while creating ELF header: %s"),
2371              output_fname ?: fname, elf_errmsg (-1));
2372       cleanup_debug ();
2373       return 1;
2374     }
2375
2376   /* We have everything from the old file.  */
2377   if (elf_cntl (elf, ELF_C_FDDONE) != 0)
2378     {
2379       error (0, 0, gettext ("%s: error while reading the file: %s"),
2380              fname, elf_errmsg (-1));
2381       cleanup_debug ();
2382       return 1;
2383     }
2384
2385   /* The ELF library better follows our layout when this is not a
2386      relocatable object file.  */
2387   elf_flagelf (newelf, ELF_C_SET,
2388                (phnum > 0 ? ELF_F_LAYOUT : 0)
2389                | (permissive ? ELF_F_PERMISSIVE : 0));
2390
2391   /* Finally write the file.  */
2392   if (elf_update (newelf, ELF_C_WRITE) == -1)
2393     {
2394       error (0, 0, gettext ("while writing '%s': %s"),
2395              output_fname ?: fname, elf_errmsg (-1));
2396       result = 1;
2397     }
2398
2399   if (remove_shdrs)
2400     {
2401       /* libelf can't cope without the section headers being properly intact.
2402          So we just let it write them normally, and then we nuke them later.  */
2403
2404       if (newehdr->e_ident[EI_CLASS] == ELFCLASS32)
2405         {
2406           assert (offsetof (Elf32_Ehdr, e_shentsize) + sizeof (Elf32_Half)
2407                   == offsetof (Elf32_Ehdr, e_shnum));
2408           assert (offsetof (Elf32_Ehdr, e_shnum) + sizeof (Elf32_Half)
2409                   == offsetof (Elf32_Ehdr, e_shstrndx));
2410           const Elf32_Off zero_off = 0;
2411           const Elf32_Half zero[3] = { 0, 0, SHN_UNDEF };
2412           if (pwrite_retry (fd, &zero_off, sizeof zero_off,
2413                             offsetof (Elf32_Ehdr, e_shoff)) != sizeof zero_off
2414               || (pwrite_retry (fd, zero, sizeof zero,
2415                                 offsetof (Elf32_Ehdr, e_shentsize))
2416                   != sizeof zero)
2417               || ftruncate (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
2418             {
2419               error (0, errno, gettext ("while writing '%s'"),
2420                      output_fname ?: fname);
2421               result = 1;
2422             }
2423         }
2424       else
2425         {
2426           assert (offsetof (Elf64_Ehdr, e_shentsize) + sizeof (Elf64_Half)
2427                   == offsetof (Elf64_Ehdr, e_shnum));
2428           assert (offsetof (Elf64_Ehdr, e_shnum) + sizeof (Elf64_Half)
2429                   == offsetof (Elf64_Ehdr, e_shstrndx));
2430           const Elf64_Off zero_off = 0;
2431           const Elf64_Half zero[3] = { 0, 0, SHN_UNDEF };
2432           if (pwrite_retry (fd, &zero_off, sizeof zero_off,
2433                             offsetof (Elf64_Ehdr, e_shoff)) != sizeof zero_off
2434               || (pwrite_retry (fd, zero, sizeof zero,
2435                                 offsetof (Elf64_Ehdr, e_shentsize))
2436                   != sizeof zero)
2437               || ftruncate (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
2438             {
2439               error (0, errno, gettext ("while writing '%s'"),
2440                      output_fname ?: fname);
2441               result = 1;
2442             }
2443         }
2444     }
2445
2446  fail_close:
2447   if (shdr_info != NULL)
2448     {
2449       /* For some sections we might have created an table to map symbol
2450          table indices.  Or we might kept (original) data around to put
2451          into the .debug file.  */
2452       for (cnt = 1; cnt <= shdridx; ++cnt)
2453         {
2454           free (shdr_info[cnt].newsymidx);
2455           if (shdr_info[cnt].debug_data != NULL)
2456             free (shdr_info[cnt].debug_data->d_buf);
2457         }
2458
2459       /* Free data we allocated for the .gnu_debuglink section. */
2460       free (debuglink_buf);
2461
2462       /* Free the memory.  */
2463       if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
2464         free (shdr_info);
2465     }
2466
2467   /* Free other resources.  */
2468   if (shstrtab_data != NULL)
2469     free (shstrtab_data->d_buf);
2470   if (shst != NULL)
2471     dwelf_strtab_free (shst);
2472
2473   /* That was it.  Close the descriptors.  */
2474   if (elf_end (newelf) != 0)
2475     {
2476       error (0, 0, gettext ("error while finishing '%s': %s"),
2477              output_fname ?: fname, elf_errmsg (-1));
2478       result = 1;
2479     }
2480
2481   if (debugelf != NULL && elf_end (debugelf) != 0)
2482     {
2483       error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
2484              elf_errmsg (-1));
2485       result = 1;
2486     }
2487
2488  fail:
2489   /* Close the EBL backend.  */
2490   if (ebl != NULL)
2491     ebl_closebackend (ebl);
2492
2493   cleanup_debug ();
2494
2495   /* If requested, preserve the timestamp.  */
2496   if (tvp != NULL)
2497     {
2498       if (futimens (fd, tvp) != 0)
2499         {
2500           error (0, errno, gettext ("\
2501 cannot set access and modification date of '%s'"),
2502                  output_fname ?: fname);
2503           result = 1;
2504         }
2505     }
2506
2507   /* Close the file descriptor if we created a new file.  */
2508   if (output_fname != NULL)
2509     {
2510       close (fd);
2511       if (result != 0)
2512        unlink (output_fname);
2513     }
2514
2515   return result;
2516 }
2517
2518 static void
2519 cleanup_debug (void)
2520 {
2521   if (debug_fd >= 0)
2522     {
2523       if (tmp_debug_fname != NULL)
2524         {
2525           unlink (tmp_debug_fname);
2526           free (tmp_debug_fname);
2527           tmp_debug_fname = NULL;
2528         }
2529       close (debug_fd);
2530       debug_fd = -1;
2531     }
2532 }
2533
2534 static int
2535 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
2536            struct timespec tvp[2])
2537 {
2538   size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
2539   size_t fname_len = strlen (fname) + 1;
2540   char new_prefix[prefix_len + 1 + fname_len];
2541   char *cp = new_prefix;
2542
2543   /* Create the full name of the file.  */
2544   if (prefix != NULL)
2545     {
2546       cp = mempcpy (cp, prefix, prefix_len);
2547       *cp++ = ':';
2548     }
2549   memcpy (cp, fname, fname_len);
2550
2551
2552   /* Process all the files contained in the archive.  */
2553   Elf *subelf;
2554   Elf_Cmd cmd = ELF_C_RDWR;
2555   int result = 0;
2556   while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
2557     {
2558       /* The the header for this element.  */
2559       Elf_Arhdr *arhdr = elf_getarhdr (subelf);
2560
2561       if (elf_kind (subelf) == ELF_K_ELF)
2562         result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
2563       else if (elf_kind (subelf) == ELF_K_AR)
2564         result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
2565
2566       /* Get next archive element.  */
2567       cmd = elf_next (subelf);
2568       if (unlikely (elf_end (subelf) != 0))
2569         INTERNAL_ERROR (fname);
2570     }
2571
2572   if (tvp != NULL)
2573     {
2574       if (unlikely (futimens (fd, tvp) != 0))
2575         {
2576           error (0, errno, gettext ("\
2577 cannot set access and modification date of '%s'"), fname);
2578           result = 1;
2579         }
2580     }
2581
2582   if (unlikely (close (fd) != 0))
2583     error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
2584
2585   return result;
2586 }
2587
2588
2589 #include "debugpred.h"