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