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