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