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