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