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