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