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