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