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