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