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