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