Home | History | Annotate | Download | only in src
      1 /* Combine stripped files with separate symbols and debug information.
      2    Copyright (C) 2007-2012, 2014, 2015 Red Hat, Inc.
      3    This file is part of elfutils.
      4    Written by Roland McGrath <roland (at) redhat.com>, 2007.
      5 
      6    This file is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    elfutils is distributed in the hope that it will be useful, but
     12    WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18 
     19 /* TODO:
     20 
     21   * SHX_XINDEX
     22 
     23   * prelink vs .debug_* linked addresses
     24 
     25  */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 # include <config.h>
     29 #endif
     30 
     31 #include <argp.h>
     32 #include <assert.h>
     33 #include <errno.h>
     34 #include <error.h>
     35 #include <fcntl.h>
     36 #include <fnmatch.h>
     37 #include <libintl.h>
     38 #include <locale.h>
     39 #include <stdbool.h>
     40 #include <stdio.h>
     41 #include <stdio_ext.h>
     42 #include <inttypes.h>
     43 #include <stdlib.h>
     44 #include <string.h>
     45 #include <unistd.h>
     46 #include <sys/stat.h>
     47 
     48 #include <gelf.h>
     49 #include <libebl.h>
     50 #include <libdwfl.h>
     51 #include "system.h"
     52 
     53 #ifndef _
     54 # define _(str) gettext (str)
     55 #endif
     56 
     57 /* Name and version of program.  */
     58 static void print_version (FILE *stream, struct argp_state *state);
     59 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
     60 
     61 /* Bug report address.  */
     62 ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
     63 
     64 /* Definitions of arguments for argp functions.  */
     65 static const struct argp_option options[] =
     66 {
     67   /* Group 2 will follow group 1 from dwfl_standard_argp.  */
     68   { "match-file-names", 'f', NULL, 0,
     69     N_("Match MODULE against file names, not module names"), 2 },
     70   { "ignore-missing", 'i', NULL, 0, N_("Silently skip unfindable files"), 0 },
     71 
     72   { NULL, 0, NULL, 0, N_("Output options:"), 0 },
     73   { "output", 'o', "FILE", 0, N_("Place output into FILE"), 0 },
     74   { "output-directory", 'd', "DIRECTORY",
     75     0, N_("Create multiple output files under DIRECTORY"), 0 },
     76   { "module-names", 'm', NULL, 0, N_("Use module rather than file names"), 0 },
     77   { "all", 'a', NULL, 0,
     78     N_("Create output for modules that have no separate debug information"),
     79     0 },
     80   { "relocate", 'R', NULL, 0,
     81     N_("Apply relocations to section contents in ET_REL files"), 0 },
     82   { "list-only", 'n', NULL, 0,
     83     N_("Only list module and file names, build IDs"), 0 },
     84  { "force", 'F', NULL, 0,
     85     N_("Force combining files even if some ELF headers don't seem to match"),
     86    0 },
     87   { NULL, 0, NULL, 0, NULL, 0 }
     88 };
     89 
     90 struct arg_info
     91 {
     92   const char *output_file;
     93   const char *output_dir;
     94   Dwfl *dwfl;
     95   char **args;
     96   bool list;
     97   bool all;
     98   bool ignore;
     99   bool modnames;
    100   bool match_files;
    101   bool relocate;
    102   bool force;
    103 };
    104 
    105 /* Handle program arguments.  */
    106 static error_t
    107 parse_opt (int key, char *arg, struct argp_state *state)
    108 {
    109   struct arg_info *info = state->input;
    110 
    111   switch (key)
    112     {
    113     case ARGP_KEY_INIT:
    114       state->child_inputs[0] = &info->dwfl;
    115       break;
    116 
    117     case 'o':
    118       if (info->output_file != NULL)
    119 	{
    120 	  argp_error (state, _("-o option specified twice"));
    121 	  return EINVAL;
    122 	}
    123       info->output_file = arg;
    124       break;
    125 
    126     case 'd':
    127       if (info->output_dir != NULL)
    128 	{
    129 	  argp_error (state, _("-d option specified twice"));
    130 	  return EINVAL;
    131 	}
    132       info->output_dir = arg;
    133       break;
    134 
    135     case 'm':
    136       info->modnames = true;
    137       break;
    138     case 'f':
    139       info->match_files = true;
    140       break;
    141     case 'a':
    142       info->all = true;
    143       break;
    144     case 'i':
    145       info->ignore = true;
    146       break;
    147     case 'n':
    148       info->list = true;
    149       break;
    150     case 'R':
    151       info->relocate = true;
    152       break;
    153     case 'F':
    154       info->force = true;
    155       break;
    156 
    157     case ARGP_KEY_ARGS:
    158     case ARGP_KEY_NO_ARGS:
    159       /* We "consume" all the arguments here.  */
    160       info->args = &state->argv[state->next];
    161 
    162       if (info->output_file != NULL && info->output_dir != NULL)
    163 	{
    164 	  argp_error (state, _("only one of -o or -d allowed"));
    165 	  return EINVAL;
    166 	}
    167 
    168       if (info->list && (info->dwfl == NULL
    169 			 || info->output_dir != NULL
    170 			 || info->output_file != NULL))
    171 	{
    172 	  argp_error (state,
    173 		      _("-n cannot be used with explicit files or -o or -d"));
    174 	  return EINVAL;
    175 	}
    176 
    177       if (info->output_dir != NULL)
    178 	{
    179 	  struct stat st;
    180 	  error_t fail = 0;
    181 	  if (stat (info->output_dir, &st) < 0)
    182 	    fail = errno;
    183 	  else if (!S_ISDIR (st.st_mode))
    184 	    fail = ENOTDIR;
    185 	  if (fail)
    186 	    {
    187 	      argp_failure (state, EXIT_FAILURE, fail,
    188 			    _("output directory '%s'"), info->output_dir);
    189 	      return fail;
    190 	    }
    191 	}
    192 
    193       if (info->dwfl == NULL)
    194 	{
    195 	  if (state->next + 2 != state->argc)
    196 	    {
    197 	      argp_error (state, _("exactly two file arguments are required"));
    198 	      return EINVAL;
    199 	    }
    200 
    201 	  if (info->ignore || info->all || info->modnames || info->relocate)
    202 	    {
    203 	      argp_error (state, _("\
    204 -m, -a, -R, and -i options not allowed with explicit files"));
    205 	      return EINVAL;
    206 	    }
    207 
    208 	  /* Bail out immediately to prevent dwfl_standard_argp's parser
    209 	     from defaulting to "-e a.out".  */
    210 	  return ENOSYS;
    211 	}
    212       else if (info->output_file == NULL && info->output_dir == NULL
    213 	       && !info->list)
    214 	{
    215 	  argp_error (state,
    216 		      _("-o or -d is required when using implicit files"));
    217 	  return EINVAL;
    218 	}
    219       break;
    220 
    221     default:
    222       return ARGP_ERR_UNKNOWN;
    223     }
    224   return 0;
    225 }
    226 
    227 /* Print the version information.  */
    228 static void
    229 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
    230 {
    231   fprintf (stream, "unstrip (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
    232   fprintf (stream, _("\
    233 Copyright (C) %s Red Hat, Inc.\n\
    234 This is free software; see the source for copying conditions.  There is NO\n\
    235 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
    236 "), "2012");
    237   fprintf (stream, gettext ("Written by %s.\n"), "Roland McGrath");
    238 }
    239 
    240 #define ELF_CHECK(call, msg)						      \
    242   do									      \
    243     {									      \
    244       if (unlikely (!(call)))						      \
    245 	error (EXIT_FAILURE, 0, msg, elf_errmsg (-1));			      \
    246     } while (0)
    247 
    248 /* Copy INELF to newly-created OUTELF, exit via error for any problems.  */
    249 static void
    250 copy_elf (Elf *outelf, Elf *inelf)
    251 {
    252   ELF_CHECK (gelf_newehdr (outelf, gelf_getclass (inelf)),
    253 	     _("cannot create ELF header: %s"));
    254 
    255   GElf_Ehdr ehdr_mem;
    256   GElf_Ehdr *ehdr = gelf_getehdr (inelf, &ehdr_mem);
    257   ELF_CHECK (gelf_update_ehdr (outelf, ehdr),
    258 	     _("cannot copy ELF header: %s"));
    259 
    260   size_t phnum;
    261   ELF_CHECK (elf_getphdrnum (inelf, &phnum) == 0,
    262 	     _("cannot get number of program headers: %s"));
    263 
    264   if (phnum > 0)
    265     {
    266       ELF_CHECK (gelf_newphdr (outelf, phnum),
    267 		 _("cannot create program headers: %s"));
    268 
    269       GElf_Phdr phdr_mem;
    270       for (size_t i = 0; i < phnum; ++i)
    271 	ELF_CHECK (gelf_update_phdr (outelf, i,
    272 				     gelf_getphdr (inelf, i, &phdr_mem)),
    273 		   _("cannot copy program header: %s"));
    274     }
    275 
    276   Elf_Scn *scn = NULL;
    277   while ((scn = elf_nextscn (inelf, scn)) != NULL)
    278     {
    279       Elf_Scn *newscn = elf_newscn (outelf);
    280 
    281       GElf_Shdr shdr_mem;
    282       ELF_CHECK (gelf_update_shdr (newscn, gelf_getshdr (scn, &shdr_mem)),
    283 		 _("cannot copy section header: %s"));
    284 
    285       Elf_Data *data = elf_getdata (scn, NULL);
    286       ELF_CHECK (data != NULL, _("cannot get section data: %s"));
    287       Elf_Data *newdata = elf_newdata (newscn);
    288       ELF_CHECK (newdata != NULL, _("cannot copy section data: %s"));
    289       *newdata = *data;
    290       elf_flagdata (newdata, ELF_C_SET, ELF_F_DIRTY);
    291     }
    292 }
    293 
    294 /* Create directories containing PATH.  */
    295 static void
    296 make_directories (const char *path)
    297 {
    298   const char *lastslash = strrchr (path, '/');
    299   if (lastslash == NULL)
    300     return;
    301 
    302   while (lastslash > path && lastslash[-1] == '/')
    303     --lastslash;
    304   if (lastslash == path)
    305     return;
    306 
    307   char *dir = strndupa (path, lastslash - path);
    308   while (mkdir (dir, 0777) < 0 && errno != EEXIST)
    309     if (errno == ENOENT)
    310       make_directories (dir);
    311     else
    312       error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
    313 }
    314 
    315 /* Keep track of new section data we are creating, so we can free it
    316    when done.  */
    317 struct data_list
    318 {
    319   void *data;
    320   struct data_list *next;
    321 };
    322 
    323 struct data_list *new_data_list;
    324 
    325 static void
    326 record_new_data (void *data)
    327 {
    328   struct data_list *next = new_data_list;
    329   new_data_list = xmalloc (sizeof (struct data_list));
    330   new_data_list->data = data;
    331   new_data_list->next = next;
    332 }
    333 
    334 static void
    335 free_new_data (void)
    336 {
    337   struct data_list *list = new_data_list;
    338   while (list != NULL)
    339     {
    340       struct data_list *next = list->next;
    341       free (list->data);
    342       free (list);
    343       list = next;
    344     }
    345   new_data_list = NULL;
    346 }
    347 
    348 /* The binutils linker leaves gratuitous section symbols in .symtab
    349    that strip has to remove.  Older linkers likewise include a
    350    symbol for every section, even unallocated ones, in .dynsym.
    351    Because of this, the related sections can shrink in the stripped
    352    file from their original size.  Older versions of strip do not
    353    adjust the sh_size field in the debuginfo file's SHT_NOBITS
    354    version of the section header, so it can appear larger.  */
    355 static bool
    356 section_can_shrink (const GElf_Shdr *shdr)
    357 {
    358   switch (shdr->sh_type)
    359     {
    360     case SHT_SYMTAB:
    361     case SHT_DYNSYM:
    362     case SHT_HASH:
    363     case SHT_GNU_versym:
    364       return true;
    365     }
    366   return false;
    367 }
    368 
    369 /* See if this symbol table has a leading section symbol for every single
    370    section, in order.  The binutils linker produces this.  While we're here,
    371    update each section symbol's st_value.  */
    372 static size_t
    373 symtab_count_leading_section_symbols (Elf *elf, Elf_Scn *scn, size_t shnum,
    374 				      Elf_Data *newsymdata)
    375 {
    376   Elf_Data *data = elf_getdata (scn, NULL);
    377   Elf_Data *shndxdata = NULL;	/* XXX */
    378 
    379   for (size_t i = 1; i < shnum; ++i)
    380     {
    381       GElf_Sym sym_mem;
    382       GElf_Word shndx = SHN_UNDEF;
    383       GElf_Sym *sym = gelf_getsymshndx (data, shndxdata, i, &sym_mem, &shndx);
    384       ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
    385 
    386       GElf_Shdr shdr_mem;
    387       GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, i), &shdr_mem);
    388       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
    389 
    390       if (sym->st_shndx != SHN_XINDEX)
    391 	shndx = sym->st_shndx;
    392 
    393       if (shndx != i || GELF_ST_TYPE (sym->st_info) != STT_SECTION)
    394 	return i;
    395 
    396       sym->st_value = shdr->sh_addr;
    397       if (sym->st_shndx != SHN_XINDEX)
    398 	shndx = SHN_UNDEF;
    399       ELF_CHECK (gelf_update_symshndx (newsymdata, shndxdata, i, sym, shndx),
    400 		 _("cannot update symbol table: %s"));
    401     }
    402 
    403   return shnum;
    404 }
    405 
    406 static void
    407 update_shdr (Elf_Scn *outscn, GElf_Shdr *newshdr)
    408 {
    409   ELF_CHECK (gelf_update_shdr (outscn, newshdr),
    410 	     _("cannot update section header: %s"));
    411 }
    412 
    413 /* We expanded the output section, so update its header.  */
    414 static void
    415 update_sh_size (Elf_Scn *outscn, const Elf_Data *data)
    416 {
    417   GElf_Shdr shdr_mem;
    418   GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem);
    419   ELF_CHECK (newshdr != NULL, _("cannot get section header: %s"));
    420 
    421   newshdr->sh_size = data->d_size;
    422 
    423   update_shdr (outscn, newshdr);
    424 }
    425 
    426 /* Update relocation sections using the symbol table.  */
    427 static void
    428 adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
    429 	       size_t map[], const GElf_Shdr *symshdr)
    430 {
    431   Elf_Data *data = elf_getdata (outscn, NULL);
    432 
    433   inline void adjust_reloc (GElf_Xword *info)
    434     {
    435       size_t ndx = GELF_R_SYM (*info);
    436       if (ndx != STN_UNDEF)
    437 	*info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info));
    438     }
    439 
    440   switch (shdr->sh_type)
    441     {
    442     case SHT_REL:
    443       for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
    444 	{
    445 	  GElf_Rel rel_mem;
    446 	  GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
    447 	  adjust_reloc (&rel->r_info);
    448 	  ELF_CHECK (gelf_update_rel (data, i, rel),
    449 		     _("cannot update relocation: %s"));
    450 	}
    451       break;
    452 
    453     case SHT_RELA:
    454       for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
    455 	{
    456 	  GElf_Rela rela_mem;
    457 	  GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
    458 	  adjust_reloc (&rela->r_info);
    459 	  ELF_CHECK (gelf_update_rela (data, i, rela),
    460 		     _("cannot update relocation: %s"));
    461 	}
    462       break;
    463 
    464     case SHT_GROUP:
    465       {
    466 	GElf_Shdr shdr_mem;
    467 	GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem);
    468 	ELF_CHECK (newshdr != NULL, _("cannot get section header: %s"));
    469 	if (newshdr->sh_info != STN_UNDEF)
    470 	  {
    471 	    newshdr->sh_info = map[newshdr->sh_info - 1];
    472 	    update_shdr (outscn, newshdr);
    473 	  }
    474 	break;
    475       }
    476 
    477     case SHT_HASH:
    478       /* We must expand the table and rejigger its contents.  */
    479       {
    480 	const size_t nsym = symshdr->sh_size / symshdr->sh_entsize;
    481 	const size_t onent = shdr->sh_size / shdr->sh_entsize;
    482 	assert (data->d_size == shdr->sh_size);
    483 
    484 #define CONVERT_HASH(Hash_Word)						      \
    485 	{								      \
    486 	  const Hash_Word *const old_hash = data->d_buf;		      \
    487 	  const size_t nbucket = old_hash[0];				      \
    488 	  const size_t nchain = old_hash[1];				      \
    489 	  const Hash_Word *const old_bucket = &old_hash[2];		      \
    490 	  const Hash_Word *const old_chain = &old_bucket[nbucket];	      \
    491 	  assert (onent == 2 + nbucket + nchain);			      \
    492 									      \
    493 	  const size_t nent = 2 + nbucket + nsym;			      \
    494 	  Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]);     \
    495 	  Hash_Word *const new_bucket = &new_hash[2];			      \
    496 	  Hash_Word *const new_chain = &new_bucket[nbucket];		      \
    497 									      \
    498 	  new_hash[0] = nbucket;					      \
    499 	  new_hash[1] = nsym;						      \
    500 	  for (size_t i = 0; i < nbucket; ++i)				      \
    501 	    if (old_bucket[i] != STN_UNDEF)				      \
    502 	      new_bucket[i] = map[old_bucket[i] - 1];			      \
    503 									      \
    504 	  for (size_t i = 1; i < nchain; ++i)				      \
    505 	    if (old_chain[i] != STN_UNDEF)				      \
    506 	      new_chain[map[i - 1]] = map[old_chain[i] - 1];		      \
    507 									      \
    508 	  record_new_data (new_hash);					\
    509 	  data->d_buf = new_hash;					      \
    510 	  data->d_size = nent * sizeof new_hash[0];			      \
    511 	}
    512 
    513 	switch (shdr->sh_entsize)
    514 	  {
    515 	  case 4:
    516 	    CONVERT_HASH (Elf32_Word);
    517 	    break;
    518 	  case 8:
    519 	    CONVERT_HASH (Elf64_Xword);
    520 	    break;
    521 	  default:
    522 	    abort ();
    523 	  }
    524 
    525 	elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
    526 	update_sh_size (outscn, data);
    527 
    528 #undef	CONVERT_HASH
    529       }
    530       break;
    531 
    532     case SHT_GNU_versym:
    533       /* We must expand the table and move its elements around.  */
    534       {
    535 	const size_t nent = symshdr->sh_size / symshdr->sh_entsize;
    536 	const size_t onent = shdr->sh_size / shdr->sh_entsize;
    537 	assert (nent >= onent);
    538 
    539 	/* We don't bother using gelf_update_versym because there is
    540 	   really no conversion to be done.  */
    541 	assert (sizeof (Elf32_Versym) == sizeof (GElf_Versym));
    542 	assert (sizeof (Elf64_Versym) == sizeof (GElf_Versym));
    543 	GElf_Versym *versym = xcalloc (nent, sizeof versym[0]);
    544 
    545 	for (size_t i = 1; i < onent; ++i)
    546 	  {
    547 	    GElf_Versym *v = gelf_getversym (data, i, &versym[map[i - 1]]);
    548 	    ELF_CHECK (v != NULL, _("cannot get symbol version: %s"));
    549 	  }
    550 
    551 	record_new_data (versym);
    552 	data->d_buf = versym;
    553 	data->d_size = nent * shdr->sh_entsize;
    554 	elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
    555 	update_sh_size (outscn, data);
    556       }
    557       break;
    558 
    559     default:
    560       error (EXIT_FAILURE, 0,
    561 	     _("unexpected section type in [%zu] with sh_link to symtab"),
    562 	     elf_ndxscn (inscn));
    563     }
    564 }
    565 
    566 /* Adjust all the relocation sections in the file.  */
    567 static void
    568 adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr,
    569 		   size_t map[])
    570 {
    571   size_t new_sh_link = elf_ndxscn (symtab);
    572   Elf_Scn *scn = NULL;
    573   while ((scn = elf_nextscn (elf, scn)) != NULL)
    574     if (scn != symtab)
    575       {
    576 	GElf_Shdr shdr_mem;
    577 	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    578 	ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
    579 	if (shdr->sh_type != SHT_NOBITS && shdr->sh_link == new_sh_link)
    580 	  adjust_relocs (scn, scn, shdr, map, symshdr);
    581       }
    582 }
    583 
    584 /* The original file probably had section symbols for all of its
    585    sections, even the unallocated ones.  To match it as closely as
    586    possible, add in section symbols for the added sections.  */
    587 static Elf_Data *
    588 add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
    589 			 Elf *elf, bool rel, Elf_Scn *symscn, size_t shnum)
    590 {
    591   const size_t added = shnum - old_shnum;
    592 
    593   GElf_Shdr shdr_mem;
    594   GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
    595   ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
    596 
    597   const size_t nsym = shdr->sh_size / shdr->sh_entsize;
    598   size_t symndx_map[nsym - 1];
    599 
    600   shdr->sh_info += added;
    601   shdr->sh_size += added * shdr->sh_entsize;
    602   update_shdr (symscn, shdr);
    603 
    604   Elf_Data *symdata = elf_getdata (symscn, NULL);
    605   Elf_Data *shndxdata = NULL;	/* XXX */
    606 
    607   symdata->d_size = shdr->sh_size;
    608   symdata->d_buf = xmalloc (symdata->d_size);
    609   record_new_data (symdata->d_buf);
    610 
    611   /* Copy the existing section symbols.  */
    612   Elf_Data *old_symdata = elf_getdata (old_symscn, NULL);
    613   for (size_t i = 0; i < old_shnum; ++i)
    614     {
    615       GElf_Sym sym_mem;
    616       GElf_Word shndx = SHN_UNDEF;
    617       GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
    618 					i, &sym_mem, &shndx);
    619       ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
    620 				       sym, shndx),
    621 		 _("cannot update symbol table: %s"));
    622 
    623       if (i > 0)
    624 	symndx_map[i - 1] = i;
    625     }
    626 
    627   /* Add in the new section symbols.  */
    628   for (size_t i = old_shnum; i < shnum; ++i)
    629     {
    630       GElf_Shdr i_shdr_mem;
    631       GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem);
    632       ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s"));
    633       GElf_Sym sym =
    634 	{
    635 	  .st_value = rel ? 0 : i_shdr->sh_addr,
    636 	  .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION),
    637 	  .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX
    638 	};
    639       GElf_Word shndx = i < SHN_LORESERVE ? SHN_UNDEF : i;
    640       ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
    641 				       &sym, shndx),
    642 		 _("cannot update symbol table: %s"));
    643     }
    644 
    645   /* Now copy the rest of the existing symbols.  */
    646   for (size_t i = old_shnum; i < nsym; ++i)
    647     {
    648       GElf_Sym sym_mem;
    649       GElf_Word shndx = SHN_UNDEF;
    650       GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
    651 					i, &sym_mem, &shndx);
    652       ELF_CHECK (gelf_update_symshndx (symdata, shndxdata,
    653 				       i + added, sym, shndx),
    654 		 _("cannot update symbol table: %s"));
    655 
    656       symndx_map[i - 1] = i + added;
    657     }
    658 
    659   /* Adjust any relocations referring to the old symbol table.  */
    660   adjust_all_relocs (elf, symscn, shdr, symndx_map);
    661 
    662   return symdata;
    663 }
    664 
    665 /* This has the side effect of updating STT_SECTION symbols' values,
    666    in case of prelink adjustments.  */
    667 static Elf_Data *
    668 check_symtab_section_symbols (Elf *elf, bool rel, Elf_Scn *scn,
    669 			      size_t shnum, size_t shstrndx,
    670 			      Elf_Scn *oscn, size_t oshnum, size_t oshstrndx,
    671 			      size_t debuglink)
    672 {
    673   size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum,
    674 						   elf_getdata (scn, NULL));
    675 
    676   if (n == oshnum)
    677     return add_new_section_symbols (oscn, n, elf, rel, scn, shnum);
    678 
    679   if (n == oshstrndx || (n == debuglink && n == oshstrndx - 1))
    680     return add_new_section_symbols (oscn, n, elf, rel, scn, shstrndx);
    681 
    682   return NULL;
    683 }
    684 
    685 struct section
    687 {
    688   Elf_Scn *scn;
    689   const char *name;
    690   Elf_Scn *outscn;
    691   struct Ebl_Strent *strent;
    692   GElf_Shdr shdr;
    693 };
    694 
    695 static int
    696 compare_alloc_sections (const struct section *s1, const struct section *s2,
    697 			bool rel)
    698 {
    699   if (!rel)
    700     {
    701       /* Sort by address.  */
    702       if (s1->shdr.sh_addr < s2->shdr.sh_addr)
    703 	return -1;
    704       if (s1->shdr.sh_addr > s2->shdr.sh_addr)
    705 	return 1;
    706     }
    707 
    708   /* At the same address, preserve original section order.  */
    709   return (ssize_t) elf_ndxscn (s1->scn) - (ssize_t) elf_ndxscn (s2->scn);
    710 }
    711 
    712 static int
    713 compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
    714 			  const char *name1, const char *name2)
    715 {
    716   /* Sort by sh_flags as an arbitrary ordering.  */
    717   if (shdr1->sh_flags < shdr2->sh_flags)
    718     return -1;
    719   if (shdr1->sh_flags > shdr2->sh_flags)
    720     return 1;
    721 
    722   /* Sort by name as last resort.  */
    723   return strcmp (name1, name2);
    724 }
    725 
    726 static int
    727 compare_sections (const void *a, const void *b, bool rel)
    728 {
    729   const struct section *s1 = a;
    730   const struct section *s2 = b;
    731 
    732   /* Sort all non-allocated sections last.  */
    733   if ((s1->shdr.sh_flags ^ s2->shdr.sh_flags) & SHF_ALLOC)
    734     return (s1->shdr.sh_flags & SHF_ALLOC) ? -1 : 1;
    735 
    736   return ((s1->shdr.sh_flags & SHF_ALLOC)
    737 	  ? compare_alloc_sections (s1, s2, rel)
    738 	  : compare_unalloc_sections (&s1->shdr, &s2->shdr,
    739 				      s1->name, s2->name));
    740 }
    741 
    742 static int
    743 compare_sections_rel (const void *a, const void *b)
    744 {
    745   return compare_sections (a, b, true);
    746 }
    747 
    748 static int
    749 compare_sections_nonrel (const void *a, const void *b)
    750 {
    751   return compare_sections (a, b, false);
    752 }
    753 
    754 
    755 struct symbol
    756 {
    757   size_t *map;
    758 
    759   union
    760   {
    761     const char *name;
    762     struct Ebl_Strent *strent;
    763   };
    764   union
    765   {
    766     struct
    767     {
    768       GElf_Addr value;
    769       GElf_Xword size;
    770       GElf_Word shndx;
    771       union
    772       {
    773 	struct
    774 	{
    775 	  uint8_t info;
    776 	  uint8_t other;
    777 	} info;
    778 	int16_t compare;
    779       };
    780     };
    781 
    782     /* For a symbol discarded after first sort, this matches its better's
    783        map pointer.  */
    784     size_t *duplicate;
    785   };
    786 };
    787 
    788 /* Collect input symbols into our internal form.  */
    789 static void
    790 collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn,
    791 		 const size_t nent, const GElf_Addr bias,
    792 		 const size_t scnmap[], struct symbol *table, size_t *map,
    793 		 struct section *split_bss)
    794 {
    795   Elf_Data *symdata = elf_getdata (symscn, NULL);
    796   Elf_Data *strdata = elf_getdata (strscn, NULL);
    797   Elf_Data *shndxdata = NULL;	/* XXX */
    798 
    799   for (size_t i = 1; i < nent; ++i)
    800     {
    801       GElf_Sym sym_mem;
    802       GElf_Word shndx = SHN_UNDEF;
    803       GElf_Sym *sym = gelf_getsymshndx (symdata, shndxdata, i,
    804 					&sym_mem, &shndx);
    805       ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
    806       if (sym->st_shndx != SHN_XINDEX)
    807 	shndx = sym->st_shndx;
    808 
    809       if (sym->st_name >= strdata->d_size)
    810 	error (EXIT_FAILURE, 0,
    811 	       _("invalid string offset in symbol [%zu]"), i);
    812 
    813       struct symbol *s = &table[i - 1];
    814       s->map = &map[i - 1];
    815       s->name = strdata->d_buf + sym->st_name;
    816       s->value = sym->st_value + bias;
    817       s->size = sym->st_size;
    818       s->shndx = shndx;
    819       s->info.info = sym->st_info;
    820       s->info.other = sym->st_other;
    821 
    822       if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
    823 	s->shndx = scnmap[shndx - 1];
    824 
    825       if (GELF_ST_TYPE (s->info.info) == STT_SECTION && !rel)
    826 	{
    827 	  /* Update the value to match the output section.  */
    828 	  GElf_Shdr shdr_mem;
    829 	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, s->shndx),
    830 					  &shdr_mem);
    831 	  ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
    832 	  s->value = shdr->sh_addr;
    833 	}
    834       else if (split_bss != NULL
    835 	       && s->value < split_bss->shdr.sh_addr
    836 	       && s->value >= split_bss[-1].shdr.sh_addr
    837 	       && shndx == elf_ndxscn (split_bss->outscn))
    838 	/* This symbol was in .bss and was split into .dynbss.  */
    839 	s->shndx = elf_ndxscn (split_bss[-1].outscn);
    840     }
    841 }
    842 
    843 
    844 #define CMP(value)							      \
    845   if (s1->value < s2->value)						      \
    846     return -1;								      \
    847   if (s1->value > s2->value)						      \
    848     return 1
    849 
    850 /* Compare symbols with a consistent ordering,
    851    but one only meaningful for equality.  */
    852 static int
    853 compare_symbols (const void *a, const void *b)
    854 {
    855   const struct symbol *s1 = a;
    856   const struct symbol *s2 = b;
    857 
    858   CMP (value);
    859   CMP (size);
    860   CMP (shndx);
    861 
    862   return (s1->compare - s2->compare) ?: strcmp (s1->name, s2->name);
    863 }
    864 
    865 /* Compare symbols for output order after slots have been assigned.  */
    866 static int
    867 compare_symbols_output (const void *a, const void *b)
    868 {
    869   const struct symbol *s1 = a;
    870   const struct symbol *s2 = b;
    871   int cmp;
    872 
    873   /* Sort discarded symbols last.  */
    874   cmp = (s1->name == NULL) - (s2->name == NULL);
    875 
    876   if (cmp == 0)
    877     /* Local symbols must come first.  */
    878     cmp = ((GELF_ST_BIND (s2->info.info) == STB_LOCAL)
    879 	   - (GELF_ST_BIND (s1->info.info) == STB_LOCAL));
    880 
    881   if (cmp == 0)
    882     /* binutils always puts section symbols first.  */
    883     cmp = ((GELF_ST_TYPE (s2->info.info) == STT_SECTION)
    884 	   - (GELF_ST_TYPE (s1->info.info) == STT_SECTION));
    885 
    886   if (cmp == 0)
    887     {
    888       if (GELF_ST_TYPE (s1->info.info) == STT_SECTION)
    889 	{
    890 	  /* binutils always puts section symbols in section index order.  */
    891 	  CMP (shndx);
    892 	  else
    893 	    assert (s1 == s2);
    894 	}
    895 
    896       /* Nothing really matters, so preserve the original order.  */
    897       CMP (map);
    898       else
    899 	assert (s1 == s2);
    900     }
    901 
    902   return cmp;
    903 }
    904 
    905 #undef CMP
    906 
    907 /* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK
    908    flag if the section contains relocation information.  */
    909 static bool
    910 sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2,
    911 		      Elf64_Word sh_type)
    912 {
    913   if (sh_type == SHT_REL || sh_type == SHT_RELA)
    914     {
    915       sh_flags1 &= ~SHF_INFO_LINK;
    916       sh_flags2 &= ~SHF_INFO_LINK;
    917     }
    918 
    919   return sh_flags1 == sh_flags2;
    920 }
    921 
    922 /* Return true iff the flags, size, and name match.  */
    923 static bool
    924 sections_match (const struct section *sections, size_t i,
    925 		const GElf_Shdr *shdr, const char *name)
    926 {
    927   return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags,
    928 				sections[i].shdr.sh_type)
    929 	  && (sections[i].shdr.sh_size == shdr->sh_size
    930 	      || (sections[i].shdr.sh_size < shdr->sh_size
    931 		  && section_can_shrink (&sections[i].shdr)))
    932 	  && !strcmp (sections[i].name, name));
    933 }
    934 
    935 /* Locate a matching allocated section in SECTIONS.  */
    936 static struct section *
    937 find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name,
    938 		    struct section sections[], size_t nalloc)
    939 {
    940   const GElf_Addr addr = shdr->sh_addr + bias;
    941   size_t l = 0, u = nalloc;
    942   while (l < u)
    943     {
    944       size_t i = (l + u) / 2;
    945       if (addr < sections[i].shdr.sh_addr)
    946 	u = i;
    947       else if (addr > sections[i].shdr.sh_addr)
    948 	l = i + 1;
    949       else
    950 	{
    951 	  /* We've found allocated sections with this address.
    952 	     Find one with matching size, flags, and name.  */
    953 	  while (i > 0 && sections[i - 1].shdr.sh_addr == addr)
    954 	    --i;
    955 	  for (; i < nalloc && sections[i].shdr.sh_addr == addr;
    956 	       ++i)
    957 	    if (sections_match (sections, i, shdr, name))
    958 	      return &sections[i];
    959 	  break;
    960 	}
    961     }
    962   return NULL;
    963 }
    964 
    965 static inline const char *
    966 get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
    967 {
    968   if (shdr->sh_name >= shstrtab->d_size)
    969     error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
    970 	   ndx, elf_errmsg (-1));
    971   return shstrtab->d_buf + shdr->sh_name;
    972 }
    973 
    974 /* Fix things up when prelink has moved some allocated sections around
    975    and the debuginfo file's section headers no longer match up.
    976    This fills in SECTIONS[0..NALLOC-1].outscn or exits.
    977    If there was a .bss section that was split into two sections
    978    with the new one preceding it in sh_addr, we return that pointer.  */
    979 static struct section *
    980 find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
    981 			     Elf *main, const GElf_Ehdr *main_ehdr,
    982 			     Elf_Data *main_shstrtab, GElf_Addr bias,
    983 			     struct section *sections,
    984 			     size_t nalloc, size_t nsections)
    985 {
    986   Elf_Scn *undo = NULL;
    987   for (size_t i = nalloc; i < nsections; ++i)
    988     {
    989       const struct section *sec = &sections[i];
    990       if (sec->shdr.sh_type == SHT_PROGBITS
    991 	  && !(sec->shdr.sh_flags & SHF_ALLOC)
    992 	  && !strcmp (sec->name, ".gnu.prelink_undo"))
    993 	{
    994 	  undo = sec->scn;
    995 	  break;
    996 	}
    997     }
    998 
    999   /* Find the original allocated sections before prelinking.  */
   1000   struct section *undo_sections = NULL;
   1001   size_t undo_nalloc = 0;
   1002   if (undo != NULL)
   1003     {
   1004       /* Clear assignments that might have been bogus.  */
   1005       for (size_t i = 0; i < nalloc; ++i)
   1006 	sections[i].outscn = NULL;
   1007 
   1008       Elf_Data *undodata = elf_rawdata (undo, NULL);
   1009       ELF_CHECK (undodata != NULL,
   1010 		 _("cannot read '.gnu.prelink_undo' section: %s"));
   1011 
   1012       union
   1013       {
   1014 	Elf32_Ehdr e32;
   1015 	Elf64_Ehdr e64;
   1016       } ehdr;
   1017       Elf_Data dst =
   1018 	{
   1019 	  .d_buf = &ehdr,
   1020 	  .d_size = sizeof ehdr,
   1021 	  .d_type = ELF_T_EHDR,
   1022 	  .d_version = EV_CURRENT
   1023 	};
   1024       Elf_Data src = *undodata;
   1025       src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT);
   1026       src.d_type = ELF_T_EHDR;
   1027       ELF_CHECK (gelf_xlatetom (main, &dst, &src,
   1028 				main_ehdr->e_ident[EI_DATA]) != NULL,
   1029 		 _("cannot read '.gnu.prelink_undo' section: %s"));
   1030 
   1031       uint_fast16_t phnum;
   1032       uint_fast16_t shnum;
   1033       if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
   1034 	{
   1035 	  phnum = ehdr.e32.e_phnum;
   1036 	  shnum = ehdr.e32.e_shnum;
   1037 	}
   1038       else
   1039 	{
   1040 	  phnum = ehdr.e64.e_phnum;
   1041 	  shnum = ehdr.e64.e_shnum;
   1042 	}
   1043 
   1044       size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT);
   1045       src.d_buf += src.d_size + phsize;
   1046       src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum - 1, EV_CURRENT);
   1047       src.d_type = ELF_T_SHDR;
   1048       if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
   1049 	  || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
   1050 	error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
   1051 	       ".gnu.prelink_undo");
   1052 
   1053       bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
   1054       size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
   1055       if (unlikely ((shnum - 1) > SIZE_MAX / shsize))
   1056 	error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
   1057 	       (size_t) shnum, ".gnu.prelink_undo");
   1058       const size_t shdr_bytes = (shnum - 1) * shsize;
   1059       void *shdr = xmalloc (shdr_bytes);
   1060       dst.d_buf = shdr;
   1061       dst.d_size = shdr_bytes;
   1062       ELF_CHECK (gelf_xlatetom (main, &dst, &src,
   1063 				main_ehdr->e_ident[EI_DATA]) != NULL,
   1064 		 _("cannot read '.gnu.prelink_undo' section: %s"));
   1065 
   1066       undo_sections = xmalloc ((shnum - 1) * sizeof undo_sections[0]);
   1067       for (size_t i = 0; i < shnum - 1; ++i)
   1068 	{
   1069 	  struct section *sec = &undo_sections[undo_nalloc];
   1070 	  Elf32_Shdr (*s32)[shnum - 1] = shdr;
   1071 	  Elf64_Shdr (*s64)[shnum - 1] = shdr;
   1072 	  if (class32)
   1073 	    {
   1074 #define COPY(field) sec->shdr.field = (*s32)[i].field
   1075 	      COPY (sh_name);
   1076 	      COPY (sh_type);
   1077 	      COPY (sh_flags);
   1078 	      COPY (sh_addr);
   1079 	      COPY (sh_offset);
   1080 	      COPY (sh_size);
   1081 	      COPY (sh_link);
   1082 	      COPY (sh_info);
   1083 	      COPY (sh_addralign);
   1084 	      COPY (sh_entsize);
   1085 #undef	COPY
   1086 	    }
   1087 	  else
   1088 	    sec->shdr = (*s64)[i];
   1089 	  if (sec->shdr.sh_flags & SHF_ALLOC)
   1090 	    {
   1091 	      sec->shdr.sh_addr += bias;
   1092 	      sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab);
   1093 	      sec->scn = elf_getscn (main, i + 1); /* Really just for ndx.  */
   1094 	      sec->outscn = NULL;
   1095 	      sec->strent = NULL;
   1096 	      ++undo_nalloc;
   1097 	    }
   1098 	}
   1099       qsort (undo_sections, undo_nalloc,
   1100 	     sizeof undo_sections[0], compare_sections_nonrel);
   1101       free (shdr);
   1102     }
   1103 
   1104   bool fail = false;
   1105   inline void check_match (bool match, Elf_Scn *scn, const char *name)
   1106     {
   1107       if (!match)
   1108 	{
   1109 	  fail = true;
   1110 	  error (0, 0, _("cannot find matching section for [%zu] '%s'"),
   1111 		 elf_ndxscn (scn), name);
   1112 	}
   1113     }
   1114 
   1115   Elf_Scn *scn = NULL;
   1116   while ((scn = elf_nextscn (debug, scn)) != NULL)
   1117     {
   1118       GElf_Shdr shdr_mem;
   1119       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1120       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1121 
   1122       if (!(shdr->sh_flags & SHF_ALLOC))
   1123 	continue;
   1124 
   1125       const char *name = get_section_name (elf_ndxscn (scn), shdr,
   1126 					   debug_shstrtab);
   1127 
   1128       if (undo_sections != NULL)
   1129 	{
   1130 	  struct section *sec = find_alloc_section (shdr, 0, name,
   1131 						    undo_sections,
   1132 						    undo_nalloc);
   1133 	  if (sec != NULL)
   1134 	    {
   1135 	      sec->outscn = scn;
   1136 	      continue;
   1137 	    }
   1138 	}
   1139 
   1140       /* If there is no prelink info, we are just here to find
   1141 	 the sections to give error messages about.  */
   1142       for (size_t i = 0; shdr != NULL && i < nalloc; ++i)
   1143 	if (sections[i].outscn == scn)
   1144 	  shdr = NULL;
   1145       check_match (shdr == NULL, scn, name);
   1146     }
   1147 
   1148   if (fail)
   1149     exit (EXIT_FAILURE);
   1150 
   1151   /* Now we have lined up output sections for each of the original sections
   1152      before prelinking.  Translate those to the prelinked sections.
   1153      This matches what prelink's undo_sections does.  */
   1154   struct section *split_bss = NULL;
   1155   for (size_t i = 0; i < undo_nalloc; ++i)
   1156     {
   1157       const struct section *undo_sec = &undo_sections[i];
   1158 
   1159       const char *name = undo_sec->name;
   1160       scn = undo_sec->scn; /* This is just for elf_ndxscn.  */
   1161 
   1162       for (size_t j = 0; j < nalloc; ++j)
   1163 	{
   1164 	  struct section *sec = &sections[j];
   1165 #define RELA_SCALED(field) \
   1166 	  (2 * sec->shdr.field == 3 * undo_sec->shdr.field)
   1167 	  if (sec->outscn == NULL
   1168 	      && sec->shdr.sh_name == undo_sec->shdr.sh_name
   1169 	      && sec->shdr.sh_flags == undo_sec->shdr.sh_flags
   1170 	      && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign
   1171 	      && (((sec->shdr.sh_type == undo_sec->shdr.sh_type
   1172 		    && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
   1173 		    && (sec->shdr.sh_size == undo_sec->shdr.sh_size
   1174 			|| (sec->shdr.sh_size > undo_sec->shdr.sh_size
   1175 			    && main_ehdr->e_type == ET_EXEC
   1176 			    && !strcmp (sec->name, ".dynstr"))))
   1177 		   || (sec->shdr.sh_size == undo_sec->shdr.sh_size
   1178 		       && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
   1179 			    && undo_sec->shdr.sh_type == SHT_NOBITS)
   1180 			   || undo_sec->shdr.sh_type == SHT_PROGBITS)
   1181 		       && !strcmp (sec->name, ".plt")))
   1182 		  || (sec->shdr.sh_type == SHT_RELA
   1183 		      && undo_sec->shdr.sh_type == SHT_REL
   1184 		      && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size))
   1185 		  || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
   1186 		      && (sec->shdr.sh_type == undo_sec->shdr.sh_type
   1187 			  || (sec->shdr.sh_type == SHT_PROGBITS
   1188 			      && undo_sec->shdr.sh_type == SHT_NOBITS))
   1189 		      && sec->shdr.sh_size <= undo_sec->shdr.sh_size
   1190 		      && (!strcmp (sec->name, ".bss")
   1191 			  || !strcmp (sec->name, ".sbss"))
   1192 		      && (sec->shdr.sh_size == undo_sec->shdr.sh_size
   1193 			  || (split_bss = sec) > sections))))
   1194 	    {
   1195 	      sec->outscn = undo_sec->outscn;
   1196 	      undo_sec = NULL;
   1197 	      break;
   1198 	    }
   1199 	}
   1200 
   1201       check_match (undo_sec == NULL, scn, name);
   1202     }
   1203 
   1204   free (undo_sections);
   1205 
   1206   if (fail)
   1207     exit (EXIT_FAILURE);
   1208 
   1209   return split_bss;
   1210 }
   1211 
   1212 /* Create new .shstrtab contents, subroutine of copy_elided_sections.
   1213    This can't be open coded there and still use variable-length auto arrays,
   1214    since the end of our block would free other VLAs too.  */
   1215 static Elf_Data *
   1216 new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
   1217 	      Elf_Data *shstrtab, size_t unstripped_shstrndx,
   1218 	      struct section *sections, size_t stripped_shnum,
   1219 	      struct Ebl_Strtab *strtab)
   1220 {
   1221   if (strtab == NULL)
   1222     return NULL;
   1223 
   1224   struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1];
   1225   memset (unstripped_strent, 0, sizeof unstripped_strent);
   1226   for (struct section *sec = sections;
   1227        sec < &sections[stripped_shnum - 1];
   1228        ++sec)
   1229     if (sec->outscn != NULL)
   1230       {
   1231 	if (sec->strent == NULL)
   1232 	  {
   1233 	    sec->strent = ebl_strtabadd (strtab, sec->name, 0);
   1234 	    ELF_CHECK (sec->strent != NULL,
   1235 		       _("cannot add section name to string table: %s"));
   1236 	  }
   1237 	unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent;
   1238       }
   1239 
   1240   /* Add names of sections we aren't touching.  */
   1241   for (size_t i = 0; i < unstripped_shnum - 1; ++i)
   1242     if (unstripped_strent[i] == NULL)
   1243       {
   1244 	Elf_Scn *scn = elf_getscn (unstripped, i + 1);
   1245 	GElf_Shdr shdr_mem;
   1246 	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1247 	const char *name = get_section_name (i + 1, shdr, shstrtab);
   1248 	unstripped_strent[i] = ebl_strtabadd (strtab, name, 0);
   1249 	ELF_CHECK (unstripped_strent[i] != NULL,
   1250 		   _("cannot add section name to string table: %s"));
   1251       }
   1252     else
   1253       unstripped_strent[i] = NULL;
   1254 
   1255   /* Now finalize the string table so we can get offsets.  */
   1256   Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped,
   1257 						   unstripped_shstrndx), NULL);
   1258   ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
   1259 	     _("cannot update section header string table data: %s"));
   1260   ebl_strtabfinalize (strtab, strtab_data);
   1261 
   1262   /* Update the sh_name fields of sections we aren't modifying later.  */
   1263   for (size_t i = 0; i < unstripped_shnum - 1; ++i)
   1264     if (unstripped_strent[i] != NULL)
   1265       {
   1266 	Elf_Scn *scn = elf_getscn (unstripped, i + 1);
   1267 	GElf_Shdr shdr_mem;
   1268 	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1269 	shdr->sh_name = ebl_strtaboffset (unstripped_strent[i]);
   1270 	if (i + 1 == unstripped_shstrndx)
   1271 	  shdr->sh_size = strtab_data->d_size;
   1272 	update_shdr (scn, shdr);
   1273       }
   1274 
   1275   return strtab_data;
   1276 }
   1277 
   1278 /* Fill in any SHT_NOBITS sections in UNSTRIPPED by
   1279    copying their contents and sh_type from STRIPPED.  */
   1280 static void
   1281 copy_elided_sections (Elf *unstripped, Elf *stripped,
   1282 		      const GElf_Ehdr *stripped_ehdr, GElf_Addr bias)
   1283 {
   1284   size_t unstripped_shstrndx;
   1285   ELF_CHECK (elf_getshdrstrndx (unstripped, &unstripped_shstrndx) == 0,
   1286 	     _("cannot get section header string table section index: %s"));
   1287 
   1288   size_t stripped_shstrndx;
   1289   ELF_CHECK (elf_getshdrstrndx (stripped, &stripped_shstrndx) == 0,
   1290 	     _("cannot get section header string table section index: %s"));
   1291 
   1292   size_t unstripped_shnum;
   1293   ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
   1294 	     _("cannot get section count: %s"));
   1295 
   1296   size_t stripped_shnum;
   1297   ELF_CHECK (elf_getshdrnum (stripped, &stripped_shnum) == 0,
   1298 	     _("cannot get section count: %s"));
   1299 
   1300   if (unlikely (stripped_shnum > unstripped_shnum))
   1301     error (EXIT_FAILURE, 0, _("\
   1302 more sections in stripped file than debug file -- arguments reversed?"));
   1303 
   1304   /* Cache the stripped file's section details.  */
   1305   struct section sections[stripped_shnum - 1];
   1306   Elf_Scn *scn = NULL;
   1307   while ((scn = elf_nextscn (stripped, scn)) != NULL)
   1308     {
   1309       size_t i = elf_ndxscn (scn) - 1;
   1310       GElf_Shdr *shdr = gelf_getshdr (scn, &sections[i].shdr);
   1311       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1312       sections[i].name = elf_strptr (stripped, stripped_shstrndx,
   1313 				     shdr->sh_name);
   1314       if (sections[i].name == NULL)
   1315 	error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
   1316 	       elf_ndxscn (scn), elf_errmsg (-1));
   1317       sections[i].scn = scn;
   1318       sections[i].outscn = NULL;
   1319       sections[i].strent = NULL;
   1320     }
   1321 
   1322   const struct section *stripped_symtab = NULL;
   1323 
   1324   /* Sort the sections, allocated by address and others after.  */
   1325   qsort (sections, stripped_shnum - 1, sizeof sections[0],
   1326 	 stripped_ehdr->e_type == ET_REL
   1327 	 ? compare_sections_rel : compare_sections_nonrel);
   1328   size_t nalloc = stripped_shnum - 1;
   1329   while (nalloc > 0 && !(sections[nalloc - 1].shdr.sh_flags & SHF_ALLOC))
   1330     {
   1331       --nalloc;
   1332       if (sections[nalloc].shdr.sh_type == SHT_SYMTAB)
   1333 	stripped_symtab = &sections[nalloc];
   1334     }
   1335 
   1336   /* Locate a matching unallocated section in SECTIONS.  */
   1337   inline struct section *find_unalloc_section (const GElf_Shdr *shdr,
   1338 					       const char *name)
   1339     {
   1340       size_t l = nalloc, u = stripped_shnum - 1;
   1341       while (l < u)
   1342 	{
   1343 	  size_t i = (l + u) / 2;
   1344 	  struct section *sec = &sections[i];
   1345 	  int cmp = compare_unalloc_sections (shdr, &sec->shdr,
   1346 					      name, sec->name);
   1347 	  if (cmp < 0)
   1348 	    u = i;
   1349 	  else if (cmp > 0)
   1350 	    l = i + 1;
   1351 	  else
   1352 	    return sec;
   1353 	}
   1354       return NULL;
   1355     }
   1356 
   1357   Elf_Data *shstrtab = elf_getdata (elf_getscn (unstripped,
   1358 						unstripped_shstrndx), NULL);
   1359   ELF_CHECK (shstrtab != NULL,
   1360 	     _("cannot read section header string table: %s"));
   1361 
   1362   /* Match each debuginfo section with its corresponding stripped section.  */
   1363   bool check_prelink = false;
   1364   Elf_Scn *unstripped_symtab = NULL;
   1365   size_t alloc_avail = 0;
   1366   scn = NULL;
   1367   while ((scn = elf_nextscn (unstripped, scn)) != NULL)
   1368     {
   1369       GElf_Shdr shdr_mem;
   1370       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1371       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1372 
   1373       if (shdr->sh_type == SHT_SYMTAB)
   1374 	{
   1375 	  unstripped_symtab = scn;
   1376 	  continue;
   1377 	}
   1378 
   1379       const size_t ndx = elf_ndxscn (scn);
   1380       if (ndx == unstripped_shstrndx)
   1381 	continue;
   1382 
   1383       const char *name = get_section_name (ndx, shdr, shstrtab);
   1384 
   1385       struct section *sec = NULL;
   1386       if (shdr->sh_flags & SHF_ALLOC)
   1387 	{
   1388 	  if (stripped_ehdr->e_type != ET_REL)
   1389 	    {
   1390 	      /* Look for the section that matches.  */
   1391 	      sec = find_alloc_section (shdr, bias, name, sections, nalloc);
   1392 	      if (sec == NULL)
   1393 		{
   1394 		  /* We couldn't figure it out.  It may be a prelink issue.  */
   1395 		  check_prelink = true;
   1396 		  continue;
   1397 		}
   1398 	    }
   1399 	  else
   1400 	    {
   1401 	      /* The sh_addr of allocated sections does not help us,
   1402 		 but the order usually matches.  */
   1403 	      if (likely (sections_match (sections, alloc_avail, shdr, name)))
   1404 		sec = &sections[alloc_avail++];
   1405 	      else
   1406 		for (size_t i = alloc_avail + 1; i < nalloc; ++i)
   1407 		  if (sections_match (sections, i, shdr, name))
   1408 		    {
   1409 		      sec = &sections[i];
   1410 		      break;
   1411 		    }
   1412 	    }
   1413 	}
   1414       else
   1415 	{
   1416 	  /* Look for the section that matches.  */
   1417 	  sec = find_unalloc_section (shdr, name);
   1418 	  if (sec == NULL)
   1419 	    {
   1420 	      /* An additional unallocated section is fine if not SHT_NOBITS.
   1421 		 We looked it up anyway in case it's an unallocated section
   1422 		 copied in both files (e.g. SHT_NOTE), and don't keep both.  */
   1423 	      if (shdr->sh_type != SHT_NOBITS)
   1424 		continue;
   1425 
   1426 	      /* Somehow some old .debug files wound up with SHT_NOBITS
   1427 		 .comment sections, so let those pass.  */
   1428 	      if (!strcmp (name, ".comment"))
   1429 		continue;
   1430 	    }
   1431 	}
   1432 
   1433       if (sec == NULL)
   1434 	error (EXIT_FAILURE, 0,
   1435 	       _("cannot find matching section for [%zu] '%s'"),
   1436 	       elf_ndxscn (scn), name);
   1437 
   1438       sec->outscn = scn;
   1439     }
   1440 
   1441   /* If that failed due to changes made by prelink, we take another tack.
   1442      We keep track of a .bss section that was partly split into .dynbss
   1443      so that collect_symbols can update symbols' st_shndx fields.  */
   1444   struct section *split_bss = NULL;
   1445   if (check_prelink)
   1446     {
   1447       Elf_Data *data = elf_getdata (elf_getscn (stripped, stripped_shstrndx),
   1448 				    NULL);
   1449       ELF_CHECK (data != NULL,
   1450 		 _("cannot read section header string table: %s"));
   1451       split_bss = find_alloc_sections_prelink (unstripped, shstrtab,
   1452 					       stripped, stripped_ehdr,
   1453 					       data, bias, sections,
   1454 					       nalloc, stripped_shnum - 1);
   1455     }
   1456 
   1457   /* Make sure each main file section has a place to go.  */
   1458   const struct section *stripped_dynsym = NULL;
   1459   size_t debuglink = SHN_UNDEF;
   1460   size_t ndx_section[stripped_shnum - 1];
   1461   struct Ebl_Strtab *strtab = NULL;
   1462   for (struct section *sec = sections;
   1463        sec < &sections[stripped_shnum - 1];
   1464        ++sec)
   1465     {
   1466       size_t secndx = elf_ndxscn (sec->scn);
   1467 
   1468       if (sec->outscn == NULL)
   1469 	{
   1470 	  /* We didn't find any corresponding section for this.  */
   1471 
   1472 	  if (secndx == stripped_shstrndx)
   1473 	    {
   1474 	      /* We only need one .shstrtab.  */
   1475 	      ndx_section[secndx - 1] = unstripped_shstrndx;
   1476 	      continue;
   1477 	    }
   1478 
   1479 	  if (unstripped_symtab != NULL && sec == stripped_symtab)
   1480 	    {
   1481 	      /* We don't need a second symbol table.  */
   1482 	      ndx_section[secndx - 1] = elf_ndxscn (unstripped_symtab);
   1483 	      continue;
   1484 	    }
   1485 
   1486 	  if (unstripped_symtab != NULL && stripped_symtab != NULL
   1487 	      && secndx == stripped_symtab->shdr.sh_link)
   1488 	    {
   1489 	      /* ... nor its string table.  */
   1490 	      GElf_Shdr shdr_mem;
   1491 	      GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
   1492 	      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1493 	      ndx_section[secndx - 1] = shdr->sh_link;
   1494 	      continue;
   1495 	    }
   1496 
   1497 	  if (!(sec->shdr.sh_flags & SHF_ALLOC)
   1498 	      && !strcmp (sec->name, ".gnu_debuglink"))
   1499 	    {
   1500 	      /* This was created by stripping.  We don't want it.  */
   1501 	      debuglink = secndx;
   1502 	      ndx_section[secndx - 1] = SHN_UNDEF;
   1503 	      continue;
   1504 	    }
   1505 
   1506 	  sec->outscn = elf_newscn (unstripped);
   1507 	  Elf_Data *newdata = elf_newdata (sec->outscn);
   1508 	  ELF_CHECK (newdata != NULL && gelf_update_shdr (sec->outscn,
   1509 							  &sec->shdr),
   1510 		     _("cannot add new section: %s"));
   1511 
   1512 	  if (strtab == NULL)
   1513 	    strtab = ebl_strtabinit (true);
   1514 	  sec->strent = ebl_strtabadd (strtab, sec->name, 0);
   1515 	  ELF_CHECK (sec->strent != NULL,
   1516 		     _("cannot add section name to string table: %s"));
   1517 	}
   1518 
   1519       /* Cache the mapping of original section indices to output sections.  */
   1520       ndx_section[secndx - 1] = elf_ndxscn (sec->outscn);
   1521     }
   1522 
   1523   /* We added some sections, so we need a new shstrtab.  */
   1524   Elf_Data *strtab_data = new_shstrtab (unstripped, unstripped_shnum,
   1525 					shstrtab, unstripped_shstrndx,
   1526 					sections, stripped_shnum,
   1527 					strtab);
   1528 
   1529   /* Get the updated section count.  */
   1530   ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
   1531 	     _("cannot get section count: %s"));
   1532 
   1533   bool placed[unstripped_shnum - 1];
   1534   memset (placed, 0, sizeof placed);
   1535 
   1536   /* Now update the output sections and copy in their data.  */
   1537   GElf_Off offset = 0;
   1538   for (const struct section *sec = sections;
   1539        sec < &sections[stripped_shnum - 1];
   1540        ++sec)
   1541     if (sec->outscn != NULL)
   1542       {
   1543 	GElf_Shdr shdr_mem;
   1544 	GElf_Shdr *shdr = gelf_getshdr (sec->outscn, &shdr_mem);
   1545 	ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1546 
   1547 	/* In an ET_REL file under --relocate, the sh_addr of SHF_ALLOC
   1548 	   sections will have been set nonzero by relocation.  This
   1549 	   touched the shdrs of whichever file had the symtab.  sh_addr
   1550 	   is still zero in the corresponding shdr.  The relocated
   1551 	   address is what we want to use.  */
   1552 	if (stripped_ehdr->e_type != ET_REL
   1553 	    || !(shdr_mem.sh_flags & SHF_ALLOC)
   1554 	    || shdr_mem.sh_addr == 0)
   1555 	  shdr_mem.sh_addr = sec->shdr.sh_addr;
   1556 
   1557 	shdr_mem.sh_type = sec->shdr.sh_type;
   1558 	shdr_mem.sh_size = sec->shdr.sh_size;
   1559 	shdr_mem.sh_info = sec->shdr.sh_info;
   1560 	shdr_mem.sh_link = sec->shdr.sh_link;
   1561 
   1562 	/* Buggy binutils objdump might have stripped the SHF_INFO_LINK
   1563 	   put it back if necessary.  */
   1564 	if ((sec->shdr.sh_type == SHT_REL || sec->shdr.sh_type == SHT_RELA)
   1565 	    && sec->shdr.sh_flags != shdr_mem.sh_flags
   1566 	    && (sec->shdr.sh_flags & SHF_INFO_LINK) != 0)
   1567 	  shdr_mem.sh_flags |= SHF_INFO_LINK;
   1568 
   1569 	if (sec->shdr.sh_link != SHN_UNDEF)
   1570 	  shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1];
   1571 	if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0)
   1572 	  shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1];
   1573 
   1574 	if (strtab != NULL)
   1575 	  shdr_mem.sh_name = ebl_strtaboffset (sec->strent);
   1576 
   1577 	Elf_Data *indata = elf_getdata (sec->scn, NULL);
   1578 	ELF_CHECK (indata != NULL, _("cannot get section data: %s"));
   1579 	Elf_Data *outdata = elf_getdata (sec->outscn, NULL);
   1580 	ELF_CHECK (outdata != NULL, _("cannot copy section data: %s"));
   1581 	*outdata = *indata;
   1582 	elf_flagdata (outdata, ELF_C_SET, ELF_F_DIRTY);
   1583 
   1584 	/* Preserve the file layout of the allocated sections.  */
   1585 	if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC))
   1586 	  {
   1587 	    shdr_mem.sh_offset = sec->shdr.sh_offset;
   1588 	    placed[elf_ndxscn (sec->outscn) - 1] = true;
   1589 
   1590 	    const GElf_Off end_offset = (shdr_mem.sh_offset
   1591 					 + (shdr_mem.sh_type == SHT_NOBITS
   1592 					    ? 0 : shdr_mem.sh_size));
   1593 	    if (end_offset > offset)
   1594 	      offset = end_offset;
   1595 	  }
   1596 
   1597 	update_shdr (sec->outscn, &shdr_mem);
   1598 
   1599 	if (shdr_mem.sh_type == SHT_SYMTAB || shdr_mem.sh_type == SHT_DYNSYM)
   1600 	  {
   1601 	    /* We must adjust all the section indices in the symbol table.  */
   1602 
   1603 	    Elf_Data *shndxdata = NULL;	/* XXX */
   1604 
   1605 	    for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i)
   1606 	      {
   1607 		GElf_Sym sym_mem;
   1608 		GElf_Word shndx = SHN_UNDEF;
   1609 		GElf_Sym *sym = gelf_getsymshndx (outdata, shndxdata,
   1610 						  i, &sym_mem, &shndx);
   1611 		ELF_CHECK (sym != NULL,
   1612 			   _("cannot get symbol table entry: %s"));
   1613 		if (sym->st_shndx != SHN_XINDEX)
   1614 		  shndx = sym->st_shndx;
   1615 
   1616 		if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
   1617 		  {
   1618 		    if (shndx >= stripped_shnum)
   1619 		      error (EXIT_FAILURE, 0,
   1620 			     _("symbol [%zu] has invalid section index"), i);
   1621 
   1622 		    shndx = ndx_section[shndx - 1];
   1623 		    if (shndx < SHN_LORESERVE)
   1624 		      {
   1625 			sym->st_shndx = shndx;
   1626 			shndx = SHN_UNDEF;
   1627 		      }
   1628 		    else
   1629 		      sym->st_shndx = SHN_XINDEX;
   1630 
   1631 		    ELF_CHECK (gelf_update_symshndx (outdata, shndxdata,
   1632 						     i, sym, shndx),
   1633 			       _("cannot update symbol table: %s"));
   1634 		  }
   1635 	      }
   1636 
   1637 	    if (shdr_mem.sh_type == SHT_SYMTAB)
   1638 	      stripped_symtab = sec;
   1639 	    if (shdr_mem.sh_type == SHT_DYNSYM)
   1640 	      stripped_dynsym = sec;
   1641 	  }
   1642       }
   1643 
   1644   /* We may need to update the symbol table.  */
   1645   Elf_Data *symdata = NULL;
   1646   struct Ebl_Strtab *symstrtab = NULL;
   1647   Elf_Data *symstrdata = NULL;
   1648   if (unstripped_symtab != NULL && (stripped_symtab != NULL
   1649 				    || check_prelink /* Section adjustments. */
   1650 				    || (stripped_ehdr->e_type != ET_REL
   1651 					&& bias != 0)))
   1652     {
   1653       /* Merge the stripped file's symbol table into the unstripped one.  */
   1654       const size_t stripped_nsym = (stripped_symtab == NULL ? 1
   1655 				    : (stripped_symtab->shdr.sh_size
   1656 				       / stripped_symtab->shdr.sh_entsize));
   1657 
   1658       GElf_Shdr shdr_mem;
   1659       GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
   1660       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1661       const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize;
   1662 
   1663       /* First collect all the symbols from both tables.  */
   1664 
   1665       const size_t total_syms = stripped_nsym - 1 + unstripped_nsym - 1;
   1666       struct symbol symbols[total_syms];
   1667       size_t symndx_map[total_syms];
   1668 
   1669       if (stripped_symtab != NULL)
   1670 	collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL,
   1671 			 stripped_symtab->scn,
   1672 			 elf_getscn (stripped, stripped_symtab->shdr.sh_link),
   1673 			 stripped_nsym, 0, ndx_section,
   1674 			 symbols, symndx_map, NULL);
   1675 
   1676       Elf_Scn *unstripped_strtab = elf_getscn (unstripped, shdr->sh_link);
   1677       collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL,
   1678 		       unstripped_symtab, unstripped_strtab, unstripped_nsym,
   1679 		       stripped_ehdr->e_type == ET_REL ? 0 : bias, NULL,
   1680 		       &symbols[stripped_nsym - 1],
   1681 		       &symndx_map[stripped_nsym - 1], split_bss);
   1682 
   1683       /* Next, sort our array of all symbols.  */
   1684       qsort (symbols, total_syms, sizeof symbols[0], compare_symbols);
   1685 
   1686       /* Now we can weed out the duplicates.  Assign remaining symbols
   1687 	 new slots, collecting a map from old indices to new.  */
   1688       size_t nsym = 0;
   1689       for (struct symbol *s = symbols; s < &symbols[total_syms]; ++s)
   1690 	{
   1691 	  /* Skip a section symbol for a removed section.  */
   1692 	  if (s->shndx == SHN_UNDEF
   1693 	      && GELF_ST_TYPE (s->info.info) == STT_SECTION)
   1694 	    {
   1695 	      s->name = NULL;	/* Mark as discarded. */
   1696 	      *s->map = STN_UNDEF;
   1697 	      s->duplicate = NULL;
   1698 	      continue;
   1699 	    }
   1700 
   1701 	  struct symbol *n = s;
   1702 	  while (n + 1 < &symbols[total_syms] && !compare_symbols (s, n + 1))
   1703 	    ++n;
   1704 
   1705 	  while (s < n)
   1706 	    {
   1707 	      /* This is a duplicate.  Its twin will get the next slot.  */
   1708 	      s->name = NULL;	/* Mark as discarded. */
   1709 	      s->duplicate = n->map;
   1710 	      ++s;
   1711 	    }
   1712 
   1713 	  /* Allocate the next slot.  */
   1714 	  *s->map = ++nsym;
   1715 	}
   1716 
   1717       /* Now we sort again, to determine the order in the output.  */
   1718       qsort (symbols, total_syms, sizeof symbols[0], compare_symbols_output);
   1719 
   1720       if (nsym < total_syms)
   1721 	/* The discarded symbols are now at the end of the table.  */
   1722 	assert (symbols[nsym].name == NULL);
   1723 
   1724       /* Now a final pass updates the map with the final order,
   1725 	 and builds up the new string table.  */
   1726       symstrtab = ebl_strtabinit (true);
   1727       for (size_t i = 0; i < nsym; ++i)
   1728 	{
   1729 	  assert (symbols[i].name != NULL);
   1730 	  assert (*symbols[i].map != 0);
   1731 	  *symbols[i].map = 1 + i;
   1732 	  symbols[i].strent = ebl_strtabadd (symstrtab, symbols[i].name, 0);
   1733 	}
   1734 
   1735       /* Scan the discarded symbols too, just to update their slots
   1736 	 in SYMNDX_MAP to refer to their live duplicates.  */
   1737       for (size_t i = nsym; i < total_syms; ++i)
   1738 	{
   1739 	  assert (symbols[i].name == NULL);
   1740 	  if (symbols[i].duplicate == NULL)
   1741 	    assert (*symbols[i].map == STN_UNDEF);
   1742 	  else
   1743 	    {
   1744 	      assert (*symbols[i].duplicate != STN_UNDEF);
   1745 	      *symbols[i].map = *symbols[i].duplicate;
   1746 	    }
   1747 	}
   1748 
   1749       /* Now we are ready to write the new symbol table.  */
   1750       symdata = elf_getdata (unstripped_symtab, NULL);
   1751       symstrdata = elf_getdata (unstripped_strtab, NULL);
   1752       Elf_Data *shndxdata = NULL;	/* XXX */
   1753 
   1754       /* If symtab and the section header table share the string table
   1755 	 add the section names to the strtab and then (after finalizing)
   1756 	 fixup the section header sh_names.  Also dispose of the old data.  */
   1757       struct Ebl_Strent *unstripped_strent[unstripped_shnum - 1];
   1758       if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
   1759 	{
   1760 	  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
   1761 	    {
   1762 	      Elf_Scn *sec = elf_getscn (unstripped, i + 1);
   1763 	      GElf_Shdr mem;
   1764 	      GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
   1765 	      const char *name = get_section_name (i + 1, hdr, shstrtab);
   1766 	      unstripped_strent[i + 1] = ebl_strtabadd (symstrtab, name, 0);
   1767 	      ELF_CHECK (unstripped_strent[i + 1] != NULL,
   1768 			 _("cannot add section name to string table: %s"));
   1769 	    }
   1770 
   1771 	  if (strtab != NULL)
   1772 	    {
   1773 	      ebl_strtabfree (strtab);
   1774 	      free (strtab_data->d_buf);
   1775 	      strtab = NULL;
   1776 	    }
   1777 	}
   1778 
   1779       ebl_strtabfinalize (symstrtab, symstrdata);
   1780       elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY);
   1781 
   1782       /* And update the section header names if necessary.  */
   1783       if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
   1784 	{
   1785 	  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
   1786 	    {
   1787 	      Elf_Scn *sec = elf_getscn (unstripped, i + 1);
   1788 	      GElf_Shdr mem;
   1789 	      GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
   1790 	      shdr->sh_name = ebl_strtaboffset (unstripped_strent[i + 1]);
   1791 	      update_shdr (sec, hdr);
   1792 	    }
   1793 	}
   1794 
   1795       /* Now update the symtab shdr.  Reload symtab shdr because sh_name
   1796 	 might have changed above. */
   1797       shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
   1798       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1799 
   1800       shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize;
   1801       symdata->d_buf = xmalloc (symdata->d_size);
   1802       record_new_data (symdata->d_buf);
   1803 
   1804       GElf_Sym sym;
   1805       memset (&sym, 0, sizeof sym);
   1806       ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 0, &sym, SHN_UNDEF),
   1807 		 _("cannot update symbol table: %s"));
   1808 
   1809       shdr->sh_info = 1;
   1810       for (size_t i = 0; i < nsym; ++i)
   1811 	{
   1812 	  struct symbol *s = &symbols[i];
   1813 
   1814 	  /* Fill in the symbol details.  */
   1815 	  sym.st_name = ebl_strtaboffset (s->strent);
   1816 	  sym.st_value = s->value; /* Already biased to output address.  */
   1817 	  sym.st_size = s->size;
   1818 	  sym.st_shndx = s->shndx; /* Already mapped to output index.  */
   1819 	  sym.st_info = s->info.info;
   1820 	  sym.st_other = s->info.other;
   1821 
   1822 	  /* Keep track of the number of leading local symbols.  */
   1823 	  if (GELF_ST_BIND (sym.st_info) == STB_LOCAL)
   1824 	    {
   1825 	      assert (shdr->sh_info == 1 + i);
   1826 	      shdr->sh_info = 1 + i + 1;
   1827 	    }
   1828 
   1829 	  ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 1 + i,
   1830 					   &sym, SHN_UNDEF),
   1831 		     _("cannot update symbol table: %s"));
   1832 
   1833 	}
   1834       elf_flagdata (symdata, ELF_C_SET, ELF_F_DIRTY);
   1835       update_shdr (unstripped_symtab, shdr);
   1836 
   1837       if (stripped_symtab != NULL)
   1838 	{
   1839 	  /* Adjust any relocations referring to the old symbol table.  */
   1840 	  const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn);
   1841 	  for (const struct section *sec = sections;
   1842 	       sec < &sections[stripped_shnum - 1];
   1843 	       ++sec)
   1844 	    if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link)
   1845 	      adjust_relocs (sec->outscn, sec->scn, &sec->shdr,
   1846 			     symndx_map, shdr);
   1847 	}
   1848 
   1849       /* Also adjust references to the other old symbol table.  */
   1850       adjust_all_relocs (unstripped, unstripped_symtab, shdr,
   1851 			 &symndx_map[stripped_nsym - 1]);
   1852     }
   1853   else if (stripped_symtab != NULL && stripped_shnum != unstripped_shnum)
   1854     check_symtab_section_symbols (unstripped,
   1855 				  stripped_ehdr->e_type == ET_REL,
   1856 				  stripped_symtab->scn,
   1857 				  unstripped_shnum, unstripped_shstrndx,
   1858 				  stripped_symtab->outscn,
   1859 				  stripped_shnum, stripped_shstrndx,
   1860 				  debuglink);
   1861 
   1862   if (stripped_dynsym != NULL)
   1863     (void) check_symtab_section_symbols (unstripped,
   1864 					 stripped_ehdr->e_type == ET_REL,
   1865 					 stripped_dynsym->outscn,
   1866 					 unstripped_shnum,
   1867 					 unstripped_shstrndx,
   1868 					 stripped_dynsym->scn, stripped_shnum,
   1869 					 stripped_shstrndx, debuglink);
   1870 
   1871   /* We need to preserve the layout of the stripped file so the
   1872      phdrs will match up.  This requires us to do our own layout of
   1873      the added sections.  We do manual layout even for ET_REL just
   1874      so we can try to match what the original probably had.  */
   1875 
   1876   elf_flagelf (unstripped, ELF_C_SET, ELF_F_LAYOUT);
   1877 
   1878   if (offset == 0)
   1879     /* For ET_REL we are starting the layout from scratch.  */
   1880     offset = gelf_fsize (unstripped, ELF_T_EHDR, 1, EV_CURRENT);
   1881 
   1882   bool skip_reloc = false;
   1883   do
   1884     {
   1885       skip_reloc = !skip_reloc;
   1886       for (size_t i = 0; i < unstripped_shnum - 1; ++i)
   1887 	if (!placed[i])
   1888 	  {
   1889 	    scn = elf_getscn (unstripped, 1 + i);
   1890 
   1891 	    GElf_Shdr shdr_mem;
   1892 	    GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
   1893 	    ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   1894 
   1895 	    /* We must make sure we have read in the data of all sections
   1896 	       beforehand and marked them to be written out.  When we're
   1897 	       modifying the existing file in place, we might overwrite
   1898 	       this part of the file before we get to handling the section.  */
   1899 
   1900 	    ELF_CHECK (elf_flagdata (elf_getdata (scn, NULL),
   1901 				     ELF_C_SET, ELF_F_DIRTY),
   1902 		       _("cannot read section data: %s"));
   1903 
   1904 	    if (skip_reloc
   1905 		&& (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA))
   1906 	      continue;
   1907 
   1908 	    GElf_Off align = shdr->sh_addralign ?: 1;
   1909 	    offset = (offset + align - 1) & -align;
   1910 	    shdr->sh_offset = offset;
   1911 	    if (shdr->sh_type != SHT_NOBITS)
   1912 	      offset += shdr->sh_size;
   1913 
   1914 	    update_shdr (scn, shdr);
   1915 
   1916 	    if (unstripped_shstrndx == 1 + i)
   1917 	      {
   1918 		/* Place the section headers immediately after
   1919 		   .shstrtab, and update the ELF header.  */
   1920 
   1921 		GElf_Ehdr ehdr_mem;
   1922 		GElf_Ehdr *ehdr = gelf_getehdr (unstripped, &ehdr_mem);
   1923 		ELF_CHECK (ehdr != NULL, _("cannot get ELF header: %s"));
   1924 
   1925 		GElf_Off sh_align = gelf_getclass (unstripped) * 4;
   1926 		offset = (offset + sh_align - 1) & -sh_align;
   1927 		ehdr->e_shnum = unstripped_shnum;
   1928 		ehdr->e_shoff = offset;
   1929 		offset += unstripped_shnum * ehdr->e_shentsize;
   1930 		ELF_CHECK (gelf_update_ehdr (unstripped, ehdr),
   1931 			   _("cannot update ELF header: %s"));
   1932 	      }
   1933 
   1934 	    placed[i] = true;
   1935 	  }
   1936     }
   1937   while (skip_reloc);
   1938 
   1939   size_t phnum;
   1940   ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
   1941 	     _("cannot get number of program headers: %s"));
   1942 
   1943   if (phnum > 0)
   1944     ELF_CHECK (gelf_newphdr (unstripped, phnum),
   1945 	       _("cannot create program headers: %s"));
   1946 
   1947   /* Copy each program header from the stripped file.  */
   1948   for (size_t i = 0; i < phnum; ++i)
   1949     {
   1950       GElf_Phdr phdr_mem;
   1951       GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
   1952       ELF_CHECK (phdr != NULL, _("cannot get program header: %s"));
   1953 
   1954       ELF_CHECK (gelf_update_phdr (unstripped, i, phdr),
   1955 		 _("cannot update program header: %s"));
   1956     }
   1957 
   1958   /* Finally, write out the file.  */
   1959   ELF_CHECK (elf_update (unstripped, ELF_C_WRITE) > 0,
   1960 	     _("cannot write output file: %s"));
   1961 
   1962   if (strtab != NULL)
   1963     {
   1964       ebl_strtabfree (strtab);
   1965       free (strtab_data->d_buf);
   1966     }
   1967 
   1968   if (symstrtab != NULL)
   1969     {
   1970       ebl_strtabfree (symstrtab);
   1971       free (symstrdata->d_buf);
   1972     }
   1973   free_new_data ();
   1974 }
   1975 
   1976 /* Process one pair of files, already opened.  */
   1977 static void
   1978 handle_file (const char *output_file, bool create_dirs,
   1979 	     Elf *stripped, const GElf_Ehdr *stripped_ehdr,
   1980 	     Elf *unstripped)
   1981 {
   1982   size_t phnum;
   1983   ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
   1984 	     _("cannot get number of program headers: %s"));
   1985 
   1986   /* Determine the address bias between the debuginfo file and the main
   1987      file, which may have been modified by prelinking.  */
   1988   GElf_Addr bias = 0;
   1989   if (unstripped != NULL)
   1990     for (size_t i = 0; i < phnum; ++i)
   1991       {
   1992 	GElf_Phdr phdr_mem;
   1993 	GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
   1994 	ELF_CHECK (phdr != NULL, _("cannot get program header: %s"));
   1995 	if (phdr->p_type == PT_LOAD)
   1996 	  {
   1997 	    GElf_Phdr unstripped_phdr_mem;
   1998 	    GElf_Phdr *unstripped_phdr = gelf_getphdr (unstripped, i,
   1999 						       &unstripped_phdr_mem);
   2000 	    ELF_CHECK (unstripped_phdr != NULL,
   2001 		       _("cannot get program header: %s"));
   2002 	    bias = phdr->p_vaddr - unstripped_phdr->p_vaddr;
   2003 	    break;
   2004 	  }
   2005       }
   2006 
   2007   /* One day we could adjust all the DWARF data (like prelink itself does).  */
   2008   if (bias != 0)
   2009     {
   2010       if (output_file == NULL)
   2011 	error (0, 0, _("\
   2012 DWARF data not adjusted for prelinking bias; consider prelink -u"));
   2013       else
   2014 	error (0, 0, _("\
   2015 DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"),
   2016 	       output_file);
   2017     }
   2018 
   2019   if (output_file == NULL)
   2020     /* Modify the unstripped file in place.  */
   2021     copy_elided_sections (unstripped, stripped, stripped_ehdr, bias);
   2022   else
   2023     {
   2024       if (create_dirs)
   2025 	make_directories (output_file);
   2026 
   2027       /* Copy the unstripped file and then modify it.  */
   2028       int outfd = open (output_file, O_RDWR | O_CREAT,
   2029 			  stripped_ehdr->e_type == ET_REL ? 0666 : 0777);
   2030       if (outfd < 0)
   2031 	error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file);
   2032       Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL);
   2033       ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s"));
   2034 
   2035       if (unstripped == NULL)
   2036 	{
   2037 	  /* Actually, we are just copying out the main file as it is.  */
   2038 	  copy_elf (outelf, stripped);
   2039 	  if (stripped_ehdr->e_type != ET_REL)
   2040 	    elf_flagelf (outelf, ELF_C_SET, ELF_F_LAYOUT);
   2041 	  ELF_CHECK (elf_update (outelf, ELF_C_WRITE) > 0,
   2042 		     _("cannot write output file: %s"));
   2043 	}
   2044       else
   2045 	{
   2046 	  copy_elf (outelf, unstripped);
   2047 	  copy_elided_sections (outelf, stripped, stripped_ehdr, bias);
   2048 	}
   2049 
   2050       elf_end (outelf);
   2051       close (outfd);
   2052     }
   2053 }
   2054 
   2055 static int
   2056 open_file (const char *file, bool writable)
   2057 {
   2058   int fd = open (file, writable ? O_RDWR : O_RDONLY);
   2059   if (fd < 0)
   2060     error (EXIT_FAILURE, errno, _("cannot open '%s'"), file);
   2061   return fd;
   2062 }
   2063 
   2064 /* Handle a pair of files we need to open by name.  */
   2065 static void
   2066 handle_explicit_files (const char *output_file, bool create_dirs, bool force,
   2067 		       const char *stripped_file, const char *unstripped_file)
   2068 {
   2069 
   2070   /* Warn, and exit if not forced to continue, if some ELF header
   2071      sanity check for the stripped and unstripped files failed.  */
   2072   void warn (const char *msg)
   2073   {
   2074     error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.",
   2075 	   force ? _("WARNING: ") : "",
   2076 	   stripped_file, unstripped_file, msg,
   2077 	   force ? "" : _(", use --force"));
   2078   }
   2079 
   2080   int stripped_fd = open_file (stripped_file, false);
   2081   Elf *stripped = elf_begin (stripped_fd, ELF_C_READ, NULL);
   2082   GElf_Ehdr stripped_ehdr;
   2083   ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
   2084 	     _("cannot create ELF descriptor: %s"));
   2085 
   2086   int unstripped_fd = -1;
   2087   Elf *unstripped = NULL;
   2088   if (unstripped_file != NULL)
   2089     {
   2090       unstripped_fd = open_file (unstripped_file, output_file == NULL);
   2091       unstripped = elf_begin (unstripped_fd,
   2092 			      (output_file == NULL ? ELF_C_RDWR : ELF_C_READ),
   2093 			      NULL);
   2094       GElf_Ehdr unstripped_ehdr;
   2095       ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr),
   2096 		 _("cannot create ELF descriptor: %s"));
   2097 
   2098       if (memcmp (stripped_ehdr.e_ident,
   2099 		  unstripped_ehdr.e_ident, EI_NIDENT) != 0)
   2100 	warn (_("ELF header identification (e_ident) different"));
   2101 
   2102       if (stripped_ehdr.e_type != unstripped_ehdr.e_type)
   2103 	warn (_("ELF header type (e_type) different"));
   2104 
   2105       if (stripped_ehdr.e_machine != unstripped_ehdr.e_machine)
   2106 	warn (_("ELF header machine type (e_machine) different"));
   2107 
   2108       if (stripped_ehdr.e_phnum < unstripped_ehdr.e_phnum)
   2109 	warn (_("stripped program header (e_phnum) smaller than unstripped"));
   2110     }
   2111 
   2112   handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped);
   2113 
   2114   elf_end (stripped);
   2115   close (stripped_fd);
   2116 
   2117   elf_end (unstripped);
   2118   close (unstripped_fd);
   2119 }
   2120 
   2121 
   2122 /* Handle a pair of files opened implicitly by libdwfl for one module.  */
   2123 static void
   2124 handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
   2125 		    Dwfl_Module *mod, bool all, bool ignore, bool relocate)
   2126 {
   2127   GElf_Addr bias;
   2128   Elf *stripped = dwfl_module_getelf (mod, &bias);
   2129   if (stripped == NULL)
   2130     {
   2131       if (ignore)
   2132 	return;
   2133 
   2134       const char *file;
   2135       const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
   2136 					      NULL, NULL, &file, NULL);
   2137       if (file == NULL)
   2138 	error (EXIT_FAILURE, 0,
   2139 	       _("cannot find stripped file for module '%s': %s"),
   2140 	       modname, dwfl_errmsg (-1));
   2141       else
   2142 	error (EXIT_FAILURE, 0,
   2143 	       _("cannot open stripped file '%s' for module '%s': %s"),
   2144 	       modname, file, dwfl_errmsg (-1));
   2145     }
   2146 
   2147   Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias));
   2148   if (debug == NULL && !all)
   2149     {
   2150       if (ignore)
   2151 	return;
   2152 
   2153       const char *file;
   2154       const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
   2155 					      NULL, NULL, NULL, &file);
   2156       if (file == NULL)
   2157 	error (EXIT_FAILURE, 0,
   2158 	       _("cannot find debug file for module '%s': %s"),
   2159 	       modname, dwfl_errmsg (-1));
   2160       else
   2161 	error (EXIT_FAILURE, 0,
   2162 	       _("cannot open debug file '%s' for module '%s': %s"),
   2163 	       modname, file, dwfl_errmsg (-1));
   2164     }
   2165 
   2166   if (debug == stripped)
   2167     {
   2168       if (all)
   2169 	debug = NULL;
   2170       else
   2171 	{
   2172 	  const char *file;
   2173 	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
   2174 						  NULL, NULL, &file, NULL);
   2175 	  error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"),
   2176 		 modname, file);
   2177 	}
   2178     }
   2179 
   2180   GElf_Ehdr stripped_ehdr;
   2181   ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
   2182 	     _("cannot create ELF descriptor: %s"));
   2183 
   2184   if (stripped_ehdr.e_type == ET_REL)
   2185     {
   2186       if (!relocate)
   2187 	{
   2188 	  /* We can't use the Elf handles already open,
   2189 	     because the DWARF sections have been relocated.  */
   2190 
   2191 	  const char *stripped_file = NULL;
   2192 	  const char *unstripped_file = NULL;
   2193 	  (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL,
   2194 				   &stripped_file, &unstripped_file);
   2195 
   2196 	  handle_explicit_files (output_file, create_dirs, force,
   2197 				 stripped_file, unstripped_file);
   2198 	  return;
   2199 	}
   2200 
   2201       /* Relocation is what we want!  This ensures that all sections that can
   2202 	 get sh_addr values assigned have them, even ones not used in DWARF.
   2203 	 They might still be used in the symbol table.  */
   2204       if (dwfl_module_relocations (mod) < 0)
   2205 	error (EXIT_FAILURE, 0,
   2206 	       _("cannot cache section addresses for module '%s': %s"),
   2207 	       dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
   2208 	       dwfl_errmsg (-1));
   2209     }
   2210 
   2211   handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug);
   2212 }
   2213 
   2214 /* Handle one module being written to the output directory.  */
   2215 static void
   2216 handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool force,
   2217 			  bool all, bool ignore, bool modnames, bool relocate)
   2218 {
   2219   if (! modnames)
   2220     {
   2221       /* Make sure we've searched for the ELF file.  */
   2222       GElf_Addr bias;
   2223       (void) dwfl_module_getelf (mod, &bias);
   2224     }
   2225 
   2226   const char *file;
   2227   const char *name = dwfl_module_info (mod, NULL, NULL, NULL,
   2228 				       NULL, NULL, &file, NULL);
   2229 
   2230   if (file == NULL && ignore)
   2231     return;
   2232 
   2233   char *output_file;
   2234   if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file) < 0)
   2235     error (EXIT_FAILURE, 0, _("memory exhausted"));
   2236 
   2237   handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate);
   2238 }
   2239 
   2240 
   2241 static void
   2242 list_module (Dwfl_Module *mod)
   2243 {
   2244   /* Make sure we have searched for the files.  */
   2245   GElf_Addr bias;
   2246   bool have_elf = dwfl_module_getelf (mod, &bias) != NULL;
   2247   bool have_dwarf = dwfl_module_getdwarf (mod, &bias) != NULL;
   2248 
   2249   const char *file;
   2250   const char *debug;
   2251   Dwarf_Addr start;
   2252   Dwarf_Addr end;
   2253   const char *name = dwfl_module_info (mod, NULL, &start, &end,
   2254 				       NULL, NULL, &file, &debug);
   2255   if (file != NULL && debug != NULL && (debug == file || !strcmp (debug, file)))
   2256     debug = ".";
   2257 
   2258   const unsigned char *id;
   2259   GElf_Addr id_vaddr;
   2260   int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
   2261 
   2262   printf ("%#" PRIx64 "+%#" PRIx64 " ", start, end - start);
   2263 
   2264   if (id_len > 0)
   2265     {
   2266       do
   2267 	printf ("%02" PRIx8, *id++);
   2268       while (--id_len > 0);
   2269       if (id_vaddr != 0)
   2270 	printf ("@%#" PRIx64, id_vaddr);
   2271     }
   2272   else
   2273     putchar ('-');
   2274 
   2275   printf (" %s %s %s\n",
   2276 	  file ?: have_elf ? "." : "-",
   2277 	  debug ?: have_dwarf ? "." : "-",
   2278 	  name);
   2279 }
   2280 
   2281 
   2282 struct match_module_info
   2283 {
   2284   char **patterns;
   2285   Dwfl_Module *found;
   2286   bool match_files;
   2287 };
   2288 
   2289 static int
   2290 match_module (Dwfl_Module *mod,
   2291 	      void **userdata __attribute__ ((unused)),
   2292 	      const char *name,
   2293 	      Dwarf_Addr start __attribute__ ((unused)),
   2294 	      void *arg)
   2295 {
   2296   struct match_module_info *info = arg;
   2297 
   2298   if (info->patterns[0] == NULL) /* Match all.  */
   2299     {
   2300     match:
   2301       info->found = mod;
   2302       return DWARF_CB_ABORT;
   2303     }
   2304 
   2305   if (info->match_files)
   2306     {
   2307       /* Make sure we've searched for the ELF file.  */
   2308       GElf_Addr bias;
   2309       (void) dwfl_module_getelf (mod, &bias);
   2310 
   2311       const char *file;
   2312       const char *check = dwfl_module_info (mod, NULL, NULL, NULL,
   2313 					    NULL, NULL, &file, NULL);
   2314       assert (check == name);
   2315       if (file == NULL)
   2316 	return DWARF_CB_OK;
   2317 
   2318       name = file;
   2319     }
   2320 
   2321   for (char **p = info->patterns; *p != NULL; ++p)
   2322     if (fnmatch (*p, name, 0) == 0)
   2323       goto match;
   2324 
   2325   return DWARF_CB_OK;
   2326 }
   2327 
   2328 /* Handle files opened implicitly via libdwfl.  */
   2329 static void
   2330 handle_implicit_modules (const struct arg_info *info)
   2331 {
   2332   struct match_module_info mmi = { info->args, NULL, info->match_files };
   2333   inline ptrdiff_t next (ptrdiff_t offset)
   2334     {
   2335       return dwfl_getmodules (info->dwfl, &match_module, &mmi, offset);
   2336     }
   2337   ptrdiff_t offset = next (0);
   2338   if (offset == 0)
   2339     error (EXIT_FAILURE, 0, _("no matching modules found"));
   2340 
   2341   if (info->list)
   2342     do
   2343       list_module (mmi.found);
   2344     while ((offset = next (offset)) > 0);
   2345   else if (info->output_dir == NULL)
   2346     {
   2347       if (next (offset) != 0)
   2348 	error (EXIT_FAILURE, 0, _("matched more than one module"));
   2349       handle_dwfl_module (info->output_file, false, info->force, mmi.found,
   2350 			  info->all, info->ignore, info->relocate);
   2351     }
   2352   else
   2353     do
   2354       handle_output_dir_module (info->output_dir, mmi.found, info->force,
   2355 				info->all, info->ignore,
   2356 				info->modnames, info->relocate);
   2357     while ((offset = next (offset)) > 0);
   2358 }
   2359 
   2360 int
   2362 main (int argc, char **argv)
   2363 {
   2364   /* We use no threads here which can interfere with handling a stream.  */
   2365   __fsetlocking (stdin, FSETLOCKING_BYCALLER);
   2366   __fsetlocking (stdout, FSETLOCKING_BYCALLER);
   2367   __fsetlocking (stderr, FSETLOCKING_BYCALLER);
   2368 
   2369   /* Set locale.  */
   2370   setlocale (LC_ALL, "");
   2371 
   2372   /* Make sure the message catalog can be found.  */
   2373   bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
   2374 
   2375   /* Initialize the message catalog.  */
   2376   textdomain (PACKAGE_TARNAME);
   2377 
   2378   /* Parse and process arguments.  */
   2379   const struct argp_child argp_children[] =
   2380     {
   2381       {
   2382 	.argp = dwfl_standard_argp (),
   2383 	.header = N_("Input selection options:"),
   2384 	.group = 1,
   2385       },
   2386       { .argp = NULL },
   2387     };
   2388   const struct argp argp =
   2389     {
   2390       .options = options,
   2391       .parser = parse_opt,
   2392       .children = argp_children,
   2393       .args_doc = N_("STRIPPED-FILE DEBUG-FILE\n[MODULE...]"),
   2394       .doc = N_("\
   2395 Combine stripped files with separate symbols and debug information.\v\
   2396 The first form puts the result in DEBUG-FILE if -o was not given.\n\
   2397 \n\
   2398 MODULE arguments give file name patterns matching modules to process.\n\
   2399 With -f these match the file name of the main (stripped) file \
   2400 (slashes are never special), otherwise they match the simple module names.  \
   2401 With no arguments, process all modules found.\n\
   2402 \n\
   2403 Multiple modules are written to files under OUTPUT-DIRECTORY, \
   2404 creating subdirectories as needed.  \
   2405 With -m these files have simple module names, otherwise they have the \
   2406 name of the main file complete with directory underneath OUTPUT-DIRECTORY.\n\
   2407 \n\
   2408 With -n no files are written, but one line to standard output for each module:\
   2409 \n\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n\
   2410 START and SIZE are hexadecimal giving the address bounds of the module.  \
   2411 BUILDID is hexadecimal for the build ID bits, or - if no ID is known; \
   2412 the hexadecimal may be followed by @0xADDR giving the address where the \
   2413 ID resides if that is known.  \
   2414 FILE is the file name found for the module, or - if none was found, \
   2415 or . if an ELF image is available but not from any named file.  \
   2416 DEBUGFILE is the separate debuginfo file name, \
   2417 or - if no debuginfo was found, or . if FILE contains the debug information.\
   2418 ")
   2419     };
   2420 
   2421   int remaining;
   2422   struct arg_info info = { .args = NULL };
   2423   error_t result = argp_parse (&argp, argc, argv, 0, &remaining, &info);
   2424   if (result == ENOSYS)
   2425     assert (info.dwfl == NULL);
   2426   else if (result)
   2427     return EXIT_FAILURE;
   2428   assert (info.args != NULL);
   2429 
   2430   /* Tell the library which version we are expecting.  */
   2431   elf_version (EV_CURRENT);
   2432 
   2433   if (info.dwfl == NULL)
   2434     {
   2435       assert (result == ENOSYS);
   2436 
   2437       if (info.output_dir != NULL)
   2438 	{
   2439 	  char *file;
   2440 	  if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0)
   2441 	    error (EXIT_FAILURE, 0, _("memory exhausted"));
   2442 	  handle_explicit_files (file, true, info.force,
   2443 				 info.args[0], info.args[1]);
   2444 	  free (file);
   2445 	}
   2446       else
   2447 	handle_explicit_files (info.output_file, false, info.force,
   2448 			       info.args[0], info.args[1]);
   2449     }
   2450   else
   2451     {
   2452       /* parse_opt checked this.  */
   2453       assert (info.output_file != NULL || info.output_dir != NULL || info.list);
   2454 
   2455       handle_implicit_modules (&info);
   2456 
   2457       dwfl_end (info.dwfl);
   2458     }
   2459 
   2460   return 0;
   2461 }
   2462 
   2463 
   2464 #include "debugpred.h"
   2465