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