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