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