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