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