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