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 <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)600 adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr,
601 size_t map[], size_t map_size)
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 GElf_Shdr shdr_mem;
609 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
610 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
611 /* Don't redo SHT_GROUP, groups are in both the stripped and debug,
612 it will already have been done by adjust_relocs for the
613 stripped_symtab. */
614 if (shdr->sh_type != SHT_NOBITS && shdr->sh_type != SHT_GROUP
615 && shdr->sh_link == new_sh_link)
616 adjust_relocs (scn, scn, shdr, map, map_size, symshdr);
617 }
618 }
619
620 /* The original file probably had section symbols for all of its
621 sections, even the unallocated ones. To match it as closely as
622 possible, add in section symbols for the added sections. */
623 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)624 add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
625 Elf *elf, bool rel, Elf_Scn *symscn, size_t shnum)
626 {
627 const size_t added = shnum - old_shnum;
628
629 GElf_Shdr shdr_mem;
630 GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
631 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
632 if (shdr->sh_entsize == 0)
633 error_exit (0, "Symbol table section cannot have zero sh_entsize");
634
635 const size_t nsym = shdr->sh_size / shdr->sh_entsize;
636 size_t symndx_map[nsym - 1];
637
638 shdr->sh_info += added;
639 shdr->sh_size += added * shdr->sh_entsize;
640 update_shdr (symscn, shdr);
641
642 Elf_Data *symdata = elf_getdata (symscn, NULL);
643 Elf_Data *shndxdata = NULL; /* XXX */
644
645 symdata->d_size = shdr->sh_size;
646 symdata->d_buf = xmalloc (symdata->d_size);
647 record_new_data (symdata->d_buf);
648
649 /* Copy the existing section symbols. */
650 Elf_Data *old_symdata = elf_getdata (old_symscn, NULL);
651 for (size_t i = 0; i < old_shnum; ++i)
652 {
653 GElf_Sym sym_mem;
654 GElf_Word shndx = SHN_UNDEF;
655 GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
656 i, &sym_mem, &shndx);
657 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
658 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
659 sym, shndx),
660 _("cannot update symbol table: %s"));
661
662 if (i > 0)
663 symndx_map[i - 1] = i;
664 }
665
666 /* Add in the new section symbols. */
667 for (size_t i = old_shnum; i < shnum; ++i)
668 {
669 GElf_Shdr i_shdr_mem;
670 GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem);
671 ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s"));
672 GElf_Sym sym =
673 {
674 .st_value = rel ? 0 : i_shdr->sh_addr,
675 .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION),
676 .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX
677 };
678 GElf_Word shndx = i < SHN_LORESERVE ? SHN_UNDEF : i;
679 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
680 &sym, shndx),
681 _("cannot update symbol table: %s"));
682 }
683
684 /* Now copy the rest of the existing symbols. */
685 for (size_t i = old_shnum; i < nsym; ++i)
686 {
687 GElf_Sym sym_mem;
688 GElf_Word shndx = SHN_UNDEF;
689 GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
690 i, &sym_mem, &shndx);
691 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
692 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata,
693 i + added, sym, shndx),
694 _("cannot update symbol table: %s"));
695
696 symndx_map[i - 1] = i + added;
697 }
698
699 /* Adjust any relocations referring to the old symbol table. */
700 adjust_all_relocs (elf, symscn, shdr, symndx_map, nsym - 1);
701
702 return symdata;
703 }
704
705 /* This has the side effect of updating STT_SECTION symbols' values,
706 in case of prelink adjustments. */
707 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)708 check_symtab_section_symbols (Elf *elf, bool rel, Elf_Scn *scn,
709 size_t shnum, size_t shstrndx,
710 Elf_Scn *oscn, size_t oshnum, size_t oshstrndx,
711 size_t debuglink)
712 {
713 size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum,
714 elf_getdata (scn, NULL));
715
716 if (n == oshnum)
717 return add_new_section_symbols (oscn, n, elf, rel, scn, shnum);
718
719 if (n == oshstrndx || (n == debuglink && n == oshstrndx - 1))
720 return add_new_section_symbols (oscn, n, elf, rel, scn, shstrndx);
721
722 return NULL;
723 }
724
725 struct section
726 {
727 Elf_Scn *scn;
728 const char *name;
729 const char *sig;
730 Elf_Scn *outscn;
731 Dwelf_Strent *strent;
732 GElf_Shdr shdr;
733 };
734
735 static int
compare_alloc_sections(const struct section * s1,const struct section * s2,bool rel)736 compare_alloc_sections (const struct section *s1, const struct section *s2,
737 bool rel)
738 {
739 if (!rel)
740 {
741 /* Sort by address. */
742 if (s1->shdr.sh_addr < s2->shdr.sh_addr)
743 return -1;
744 if (s1->shdr.sh_addr > s2->shdr.sh_addr)
745 return 1;
746 }
747
748 /* At the same address, preserve original section order. */
749 return (ssize_t) elf_ndxscn (s1->scn) - (ssize_t) elf_ndxscn (s2->scn);
750 }
751
752 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)753 compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
754 const char *name1, const char *name2,
755 const char *sig1, const char *sig2)
756 {
757 /* Sort by sh_flags as an arbitrary ordering. */
758 if (shdr1->sh_flags < shdr2->sh_flags)
759 return -1;
760 if (shdr1->sh_flags > shdr2->sh_flags)
761 return 1;
762
763 /* Sizes should be the same. */
764 if (shdr1->sh_size < shdr2->sh_size)
765 return -1;
766 if (shdr1->sh_size > shdr2->sh_size)
767 return 1;
768
769 /* Are they both SHT_GROUP sections? Then compare signatures. */
770 if (sig1 != NULL && sig2 != NULL)
771 return strcmp (sig1, sig2);
772
773 /* Sort by name as last resort. */
774 return strcmp (name1, name2);
775 }
776
777 static int
compare_sections(const void * a,const void * b,bool rel)778 compare_sections (const void *a, const void *b, bool rel)
779 {
780 const struct section *s1 = a;
781 const struct section *s2 = b;
782
783 /* Sort all non-allocated sections last. */
784 if ((s1->shdr.sh_flags ^ s2->shdr.sh_flags) & SHF_ALLOC)
785 return (s1->shdr.sh_flags & SHF_ALLOC) ? -1 : 1;
786
787 return ((s1->shdr.sh_flags & SHF_ALLOC)
788 ? compare_alloc_sections (s1, s2, rel)
789 : compare_unalloc_sections (&s1->shdr, &s2->shdr,
790 s1->name, s2->name,
791 s1->sig, s2->sig));
792 }
793
794 static int
compare_sections_rel(const void * a,const void * b)795 compare_sections_rel (const void *a, const void *b)
796 {
797 return compare_sections (a, b, true);
798 }
799
800 static int
compare_sections_nonrel(const void * a,const void * b)801 compare_sections_nonrel (const void *a, const void *b)
802 {
803 return compare_sections (a, b, false);
804 }
805
806
807 struct symbol
808 {
809 size_t *map;
810
811 union
812 {
813 const char *name;
814 Dwelf_Strent *strent;
815 };
816 union
817 {
818 struct
819 {
820 GElf_Addr value;
821 GElf_Xword size;
822 GElf_Word shndx;
823 union
824 {
825 struct
826 {
827 uint8_t info;
828 uint8_t other;
829 } info;
830 int16_t compare;
831 };
832 };
833
834 /* For a symbol discarded after first sort, this matches its better's
835 map pointer. */
836 size_t *duplicate;
837 };
838 };
839
840 /* Collect input symbols into our internal form. */
841 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)842 collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn,
843 const size_t nent, const GElf_Addr bias,
844 const size_t scnmap[], struct symbol *table, size_t *map,
845 struct section *split_bss)
846 {
847 Elf_Data *symdata = elf_getdata (symscn, NULL);
848 ELF_CHECK (symdata != NULL, _("cannot get symbol section data: %s"));
849 Elf_Data *strdata = elf_getdata (strscn, NULL);
850 ELF_CHECK (strdata != NULL, _("cannot get string section data: %s"));
851 Elf_Data *shndxdata = NULL; /* XXX */
852
853 for (size_t i = 1; i < nent; ++i)
854 {
855 GElf_Sym sym_mem;
856 GElf_Word shndx = SHN_UNDEF;
857 GElf_Sym *sym = gelf_getsymshndx (symdata, shndxdata, i,
858 &sym_mem, &shndx);
859 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
860 if (sym->st_shndx != SHN_XINDEX)
861 shndx = sym->st_shndx;
862
863 if (sym->st_name >= strdata->d_size
864 || memrchr (strdata->d_buf + sym->st_name, '\0',
865 strdata->d_size - sym->st_name) == NULL)
866 error_exit (0,
867 _("invalid string offset in symbol [%zu]"), i);
868
869 struct symbol *s = &table[i - 1];
870 s->map = &map[i - 1];
871 s->name = strdata->d_buf + sym->st_name;
872 s->value = sym->st_value + bias;
873 s->size = sym->st_size;
874 s->shndx = shndx;
875 s->info.info = sym->st_info;
876 s->info.other = sym->st_other;
877
878 if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
879 s->shndx = scnmap[shndx - 1];
880
881 if (GELF_ST_TYPE (s->info.info) == STT_SECTION && !rel)
882 {
883 /* Update the value to match the output section. */
884 GElf_Shdr shdr_mem;
885 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, s->shndx),
886 &shdr_mem);
887 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
888 s->value = shdr->sh_addr;
889 }
890 else if (split_bss != NULL
891 && s->value < split_bss->shdr.sh_addr
892 && s->value >= split_bss[-1].shdr.sh_addr
893 && shndx == elf_ndxscn (split_bss->outscn))
894 /* This symbol was in .bss and was split into .dynbss. */
895 s->shndx = elf_ndxscn (split_bss[-1].outscn);
896 }
897 }
898
899
900 #define CMP(value) \
901 if (s1->value < s2->value) \
902 return -1; \
903 if (s1->value > s2->value) \
904 return 1
905
906 /* Compare symbols with a consistent ordering,
907 but one only meaningful for equality. */
908 static int
compare_symbols(const void * a,const void * b)909 compare_symbols (const void *a, const void *b)
910 {
911 const struct symbol *s1 = a;
912 const struct symbol *s2 = b;
913
914 CMP (value);
915 CMP (size);
916 CMP (shndx);
917
918 return (s1->compare - s2->compare) ?: strcmp (s1->name, s2->name);
919 }
920
921 /* Compare symbols for output order after slots have been assigned. */
922 static int
compare_symbols_output(const void * a,const void * b)923 compare_symbols_output (const void *a, const void *b)
924 {
925 const struct symbol *s1 = a;
926 const struct symbol *s2 = b;
927 int cmp;
928
929 /* Sort discarded symbols last. */
930 cmp = (s1->name == NULL) - (s2->name == NULL);
931
932 if (cmp == 0)
933 /* Local symbols must come first. */
934 cmp = ((GELF_ST_BIND (s2->info.info) == STB_LOCAL)
935 - (GELF_ST_BIND (s1->info.info) == STB_LOCAL));
936
937 if (cmp == 0)
938 /* binutils always puts section symbols first. */
939 cmp = ((GELF_ST_TYPE (s2->info.info) == STT_SECTION)
940 - (GELF_ST_TYPE (s1->info.info) == STT_SECTION));
941
942 if (cmp == 0)
943 {
944 if (GELF_ST_TYPE (s1->info.info) == STT_SECTION)
945 {
946 /* binutils always puts section symbols in section index order. */
947 CMP (shndx);
948 else if (s1 != s2)
949 error_exit (0, "section symbols in unexpected order");
950 }
951
952 /* Nothing really matters, so preserve the original order. */
953 CMP (map);
954 else if (s1 != s2)
955 error_exit (0, "found two identical symbols");
956 }
957
958 return cmp;
959 }
960
961 #undef CMP
962
963 /* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK
964 flag if the section contains relocation information. */
965 static bool
sections_flags_match(Elf64_Xword sh_flags1,Elf64_Xword sh_flags2,Elf64_Word sh_type)966 sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2,
967 Elf64_Word sh_type)
968 {
969 if (sh_type == SHT_REL || sh_type == SHT_RELA)
970 {
971 sh_flags1 &= ~SHF_INFO_LINK;
972 sh_flags2 &= ~SHF_INFO_LINK;
973 }
974
975 return sh_flags1 == sh_flags2;
976 }
977
978 /* Return true iff the flags, size, and name match. */
979 static bool
sections_match(const struct section * sections,size_t i,const GElf_Shdr * shdr,const char * name)980 sections_match (const struct section *sections, size_t i,
981 const GElf_Shdr *shdr, const char *name)
982 {
983 return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags,
984 sections[i].shdr.sh_type)
985 && (sections[i].shdr.sh_size == shdr->sh_size
986 || (sections[i].shdr.sh_size < shdr->sh_size
987 && section_can_shrink (§ions[i].shdr)))
988 && !strcmp (sections[i].name, name));
989 }
990
991 /* Locate a matching allocated section in SECTIONS. */
992 static struct section *
find_alloc_section(const GElf_Shdr * shdr,GElf_Addr bias,const char * name,struct section sections[],size_t nalloc)993 find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name,
994 struct section sections[], size_t nalloc)
995 {
996 const GElf_Addr addr = shdr->sh_addr + bias;
997 size_t l = 0, u = nalloc;
998 while (l < u)
999 {
1000 size_t i = (l + u) / 2;
1001 if (addr < sections[i].shdr.sh_addr)
1002 u = i;
1003 else if (addr > sections[i].shdr.sh_addr)
1004 l = i + 1;
1005 else
1006 {
1007 /* We've found allocated sections with this address.
1008 Find one with matching size, flags, and name. */
1009 while (i > 0 && sections[i - 1].shdr.sh_addr == addr)
1010 --i;
1011 for (; i < nalloc && sections[i].shdr.sh_addr == addr;
1012 ++i)
1013 if (sections_match (sections, i, shdr, name))
1014 return §ions[i];
1015 break;
1016 }
1017 }
1018 return NULL;
1019 }
1020
1021 static inline const char *
get_section_name(size_t ndx,const GElf_Shdr * shdr,const Elf_Data * shstrtab)1022 get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
1023 {
1024 if (shdr->sh_name >= shstrtab->d_size)
1025 error_exit (0, _("cannot read section [%zu] name: %s"),
1026 ndx, elf_errmsg (-1));
1027 return shstrtab->d_buf + shdr->sh_name;
1028 }
1029
1030 /* Returns the signature of a group section, or NULL if the given
1031 section isn't a group. */
1032 static const char *
get_group_sig(Elf * elf,GElf_Shdr * shdr)1033 get_group_sig (Elf *elf, GElf_Shdr *shdr)
1034 {
1035 if (shdr->sh_type != SHT_GROUP)
1036 return NULL;
1037
1038 Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
1039 if (symscn == NULL)
1040 error_exit (0, _("bad sh_link for group section: %s"),
1041 elf_errmsg (-1));
1042
1043 GElf_Shdr symshdr_mem;
1044 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1045 if (symshdr == NULL)
1046 error_exit (0, _("couldn't get shdr for group section: %s"),
1047 elf_errmsg (-1));
1048
1049 Elf_Data *symdata = elf_getdata (symscn, NULL);
1050 if (symdata == NULL)
1051 error_exit (0, _("bad data for group symbol section: %s"),
1052 elf_errmsg (-1));
1053
1054 GElf_Sym sym_mem;
1055 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1056 if (sym == NULL)
1057 error_exit (0, _("couldn't get symbol for group section: %s"),
1058 elf_errmsg (-1));
1059
1060 const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name);
1061 if (sig == NULL)
1062 error_exit (0, _("bad symbol name for group section: %s"),
1063 elf_errmsg (-1));
1064
1065 return sig;
1066 }
1067
1068 static inline bool
check_match(bool match,Elf_Scn * scn,const char * name)1069 check_match (bool match, Elf_Scn *scn, const char *name)
1070 {
1071 if (!match)
1072 {
1073 error (0, 0, _("cannot find matching section for [%zu] '%s'"),
1074 elf_ndxscn (scn), name);
1075 return true;
1076 }
1077
1078 return false;
1079 }
1080
1081
1082 /* Fix things up when prelink has moved some allocated sections around
1083 and the debuginfo file's section headers no longer match up.
1084 This fills in SECTIONS[0..NALLOC-1].outscn or exits.
1085 If there was a .bss section that was split into two sections
1086 with the new one preceding it in sh_addr, we return that pointer. */
1087 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)1088 find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
1089 Elf *main, const GElf_Ehdr *main_ehdr,
1090 Elf_Data *main_shstrtab, GElf_Addr bias,
1091 struct section *sections,
1092 size_t nalloc, size_t nsections)
1093 {
1094 Elf_Scn *undo = NULL;
1095 for (size_t i = nalloc; i < nsections; ++i)
1096 {
1097 const struct section *sec = §ions[i];
1098 if (sec->shdr.sh_type == SHT_PROGBITS
1099 && !(sec->shdr.sh_flags & SHF_ALLOC)
1100 && !strcmp (sec->name, ".gnu.prelink_undo"))
1101 {
1102 undo = sec->scn;
1103 break;
1104 }
1105 }
1106
1107 /* Find the original allocated sections before prelinking. */
1108 struct section *undo_sections = NULL;
1109 size_t undo_nalloc = 0;
1110 if (undo != NULL)
1111 {
1112 /* Clear assignments that might have been bogus. */
1113 for (size_t i = 0; i < nalloc; ++i)
1114 sections[i].outscn = NULL;
1115
1116 Elf_Data *undodata = elf_rawdata (undo, NULL);
1117 ELF_CHECK (undodata != NULL,
1118 _("cannot read '.gnu.prelink_undo' section: %s"));
1119
1120 union
1121 {
1122 Elf32_Ehdr e32;
1123 Elf64_Ehdr e64;
1124 } ehdr;
1125 Elf_Data dst =
1126 {
1127 .d_buf = &ehdr,
1128 .d_size = sizeof ehdr,
1129 .d_type = ELF_T_EHDR,
1130 .d_version = EV_CURRENT
1131 };
1132 Elf_Data src = *undodata;
1133 src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT);
1134 src.d_type = ELF_T_EHDR;
1135 ELF_CHECK (gelf_xlatetom (main, &dst, &src,
1136 main_ehdr->e_ident[EI_DATA]) != NULL,
1137 _("cannot read '.gnu.prelink_undo' section: %s"));
1138
1139 uint_fast16_t phnum;
1140 uint_fast16_t shnum; /* prelink doesn't handle > SHN_LORESERVE. */
1141 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
1142 {
1143 phnum = ehdr.e32.e_phnum;
1144 shnum = ehdr.e32.e_shnum;
1145 }
1146 else
1147 {
1148 phnum = ehdr.e64.e_phnum;
1149 shnum = ehdr.e64.e_shnum;
1150 }
1151
1152 bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
1153 size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
1154 if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1))
1155 error_exit (0, _("overflow with shnum = %zu in '%s' section"),
1156 (size_t) shnum, ".gnu.prelink_undo");
1157
1158 --shnum;
1159
1160 size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT);
1161 src.d_buf += src.d_size + phsize;
1162 src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum, EV_CURRENT);
1163 src.d_type = ELF_T_SHDR;
1164 if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
1165 || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
1166 error_exit (0, _("invalid contents in '%s' section"),
1167 ".gnu.prelink_undo");
1168
1169 const size_t shdr_bytes = shnum * shsize;
1170 void *shdr = xmalloc (shdr_bytes);
1171 dst.d_buf = shdr;
1172 dst.d_size = shdr_bytes;
1173 ELF_CHECK (gelf_xlatetom (main, &dst, &src,
1174 main_ehdr->e_ident[EI_DATA]) != NULL,
1175 _("cannot read '.gnu.prelink_undo' section: %s"));
1176
1177 undo_sections = xmalloc (shnum * sizeof undo_sections[0]);
1178 for (size_t i = 0; i < shnum; ++i)
1179 {
1180 struct section *sec = &undo_sections[undo_nalloc];
1181 Elf32_Shdr (*s32)[shnum] = shdr;
1182 Elf64_Shdr (*s64)[shnum] = shdr;
1183 if (class32)
1184 {
1185 #define COPY(field) sec->shdr.field = (*s32)[i].field
1186 COPY (sh_name);
1187 COPY (sh_type);
1188 COPY (sh_flags);
1189 COPY (sh_addr);
1190 COPY (sh_offset);
1191 COPY (sh_size);
1192 COPY (sh_link);
1193 COPY (sh_info);
1194 COPY (sh_addralign);
1195 COPY (sh_entsize);
1196 #undef COPY
1197 }
1198 else
1199 sec->shdr = (*s64)[i];
1200 if (sec->shdr.sh_flags & SHF_ALLOC)
1201 {
1202 sec->shdr.sh_addr += bias;
1203 sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab);
1204 sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */
1205 sec->outscn = NULL;
1206 sec->strent = NULL;
1207 sec->sig = get_group_sig (main, &sec->shdr);
1208 ++undo_nalloc;
1209 }
1210 }
1211 qsort (undo_sections, undo_nalloc,
1212 sizeof undo_sections[0], compare_sections_nonrel);
1213 free (shdr);
1214 }
1215
1216 bool fail = false;
1217 Elf_Scn *scn = NULL;
1218 while ((scn = elf_nextscn (debug, scn)) != NULL)
1219 {
1220 GElf_Shdr shdr_mem;
1221 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1222 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1223
1224 if (!(shdr->sh_flags & SHF_ALLOC))
1225 continue;
1226
1227 const char *name = get_section_name (elf_ndxscn (scn), shdr,
1228 debug_shstrtab);
1229
1230 if (undo_sections != NULL)
1231 {
1232 struct section *sec = find_alloc_section (shdr, 0, name,
1233 undo_sections,
1234 undo_nalloc);
1235 if (sec != NULL)
1236 {
1237 sec->outscn = scn;
1238 continue;
1239 }
1240 }
1241
1242 /* If there is no prelink info, we are just here to find
1243 the sections to give error messages about. */
1244 for (size_t i = 0; shdr != NULL && i < nalloc; ++i)
1245 if (sections[i].outscn == scn)
1246 shdr = NULL;
1247 fail |= check_match (shdr == NULL, scn, name);
1248 }
1249
1250 if (fail)
1251 exit (EXIT_FAILURE);
1252
1253 /* Now we have lined up output sections for each of the original sections
1254 before prelinking. Translate those to the prelinked sections.
1255 This matches what prelink's undo_sections does. */
1256 struct section *split_bss = NULL;
1257 for (size_t i = 0; i < undo_nalloc; ++i)
1258 {
1259 const struct section *undo_sec = &undo_sections[i];
1260
1261 const char *name = undo_sec->name;
1262 scn = undo_sec->scn; /* This is just for elf_ndxscn. */
1263
1264 for (size_t j = 0; j < nalloc; ++j)
1265 {
1266 struct section *sec = §ions[j];
1267 #define RELA_SCALED(field) \
1268 (2 * sec->shdr.field == 3 * undo_sec->shdr.field)
1269 if (sec->outscn == NULL
1270 && sec->shdr.sh_name == undo_sec->shdr.sh_name
1271 && sec->shdr.sh_flags == undo_sec->shdr.sh_flags
1272 && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign
1273 && (((sec->shdr.sh_type == undo_sec->shdr.sh_type
1274 && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
1275 && (sec->shdr.sh_size == undo_sec->shdr.sh_size
1276 || (sec->shdr.sh_size > undo_sec->shdr.sh_size
1277 && main_ehdr->e_type == ET_EXEC
1278 && !strcmp (sec->name, ".dynstr"))))
1279 || (sec->shdr.sh_size == undo_sec->shdr.sh_size
1280 && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
1281 && undo_sec->shdr.sh_type == SHT_NOBITS)
1282 || undo_sec->shdr.sh_type == SHT_PROGBITS)
1283 && !strcmp (sec->name, ".plt")))
1284 || (sec->shdr.sh_type == SHT_RELA
1285 && undo_sec->shdr.sh_type == SHT_REL
1286 && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size))
1287 || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
1288 && (sec->shdr.sh_type == undo_sec->shdr.sh_type
1289 || (sec->shdr.sh_type == SHT_PROGBITS
1290 && undo_sec->shdr.sh_type == SHT_NOBITS))
1291 && sec->shdr.sh_size <= undo_sec->shdr.sh_size
1292 && (!strcmp (sec->name, ".bss")
1293 || !strcmp (sec->name, ".sbss"))
1294 && (sec->shdr.sh_size == undo_sec->shdr.sh_size
1295 || (split_bss = sec) > sections))))
1296 {
1297 sec->outscn = undo_sec->outscn;
1298 undo_sec = NULL;
1299 break;
1300 }
1301 }
1302
1303 fail |= check_match (undo_sec == NULL, scn, name);
1304 }
1305
1306 free (undo_sections);
1307
1308 if (fail)
1309 exit (EXIT_FAILURE);
1310
1311 return split_bss;
1312 }
1313
1314 /* Create new .shstrtab contents, subroutine of copy_elided_sections.
1315 This can't be open coded there and still use variable-length auto arrays,
1316 since the end of our block would free other VLAs too. */
1317 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)1318 new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
1319 Elf_Data *shstrtab, size_t unstripped_shstrndx,
1320 struct section *sections, size_t stripped_shnum,
1321 Dwelf_Strtab *strtab)
1322 {
1323 if (strtab == NULL)
1324 return NULL;
1325
1326 Dwelf_Strent *unstripped_strent[unstripped_shnum];
1327 memset (unstripped_strent, 0, sizeof unstripped_strent);
1328 for (struct section *sec = sections;
1329 sec < §ions[stripped_shnum - 1];
1330 ++sec)
1331 if (sec->outscn != NULL)
1332 {
1333 if (sec->strent == NULL)
1334 {
1335 sec->strent = dwelf_strtab_add (strtab, sec->name);
1336 ELF_CHECK (sec->strent != NULL,
1337 _("cannot add section name to string table: %s"));
1338 }
1339 unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent;
1340 }
1341
1342 /* Add names of sections we aren't touching. */
1343 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
1344 if (unstripped_strent[i] == NULL)
1345 {
1346 Elf_Scn *scn = elf_getscn (unstripped, i + 1);
1347 GElf_Shdr shdr_mem;
1348 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1349 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1350 const char *name = get_section_name (i + 1, shdr, shstrtab);
1351 unstripped_strent[i] = dwelf_strtab_add (strtab, name);
1352 ELF_CHECK (unstripped_strent[i] != NULL,
1353 _("cannot add section name to string table: %s"));
1354 }
1355 else
1356 unstripped_strent[i] = NULL;
1357
1358 /* Now finalize the string table so we can get offsets. */
1359 Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped,
1360 unstripped_shstrndx), NULL);
1361 ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
1362 _("cannot update section header string table data: %s"));
1363 if (dwelf_strtab_finalize (strtab, strtab_data) == NULL)
1364 error_exit (0, "Not enough memory to create string table");
1365
1366 /* Update the sh_name fields of sections we aren't modifying later. */
1367 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
1368 if (unstripped_strent[i] != NULL)
1369 {
1370 Elf_Scn *scn = elf_getscn (unstripped, i + 1);
1371 GElf_Shdr shdr_mem;
1372 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1373 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1374 shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
1375 if (i + 1 == unstripped_shstrndx)
1376 shdr->sh_size = strtab_data->d_size;
1377 update_shdr (scn, shdr);
1378 }
1379
1380 return strtab_data;
1381 }
1382
1383 /* Fill in any SHT_NOBITS sections in UNSTRIPPED by
1384 copying their contents and sh_type from STRIPPED. */
1385 static void
copy_elided_sections(Elf * unstripped,Elf * stripped,const GElf_Ehdr * stripped_ehdr,GElf_Addr bias)1386 copy_elided_sections (Elf *unstripped, Elf *stripped,
1387 const GElf_Ehdr *stripped_ehdr, GElf_Addr bias)
1388 {
1389 size_t unstripped_shstrndx;
1390 ELF_CHECK (elf_getshdrstrndx (unstripped, &unstripped_shstrndx) == 0,
1391 _("cannot get section header string table section index: %s"));
1392
1393 size_t stripped_shstrndx;
1394 ELF_CHECK (elf_getshdrstrndx (stripped, &stripped_shstrndx) == 0,
1395 _("cannot get section header string table section index: %s"));
1396
1397 size_t unstripped_shnum;
1398 ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
1399 _("cannot get section count: %s"));
1400
1401 size_t stripped_shnum;
1402 ELF_CHECK (elf_getshdrnum (stripped, &stripped_shnum) == 0,
1403 _("cannot get section count: %s"));
1404
1405 if (unlikely (stripped_shnum > unstripped_shnum))
1406 error_exit (0, _("\
1407 more sections in stripped file than debug file -- arguments reversed?"));
1408
1409 if (unlikely (stripped_shnum == 0))
1410 error_exit (0, _("no sections in stripped file"));
1411
1412 /* Used as sanity check for allocated section offset, if the section
1413 offset needs to be preserved. We want to know the max size of the
1414 ELF file, to check if any existing section offsets are OK. */
1415 int64_t max_off = -1;
1416 if (stripped_ehdr->e_type != ET_REL)
1417 {
1418 elf_flagelf (stripped, ELF_C_SET, ELF_F_LAYOUT);
1419 max_off = elf_update (stripped, ELF_C_NULL);
1420 }
1421
1422 /* Cache the stripped file's section details. */
1423 struct section sections[stripped_shnum - 1];
1424 Elf_Scn *scn = NULL;
1425 while ((scn = elf_nextscn (stripped, scn)) != NULL)
1426 {
1427 size_t i = elf_ndxscn (scn) - 1;
1428 GElf_Shdr *shdr = gelf_getshdr (scn, §ions[i].shdr);
1429 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1430 sections[i].name = elf_strptr (stripped, stripped_shstrndx,
1431 shdr->sh_name);
1432 if (sections[i].name == NULL)
1433 error_exit (0, _("cannot read section [%zu] name: %s"),
1434 elf_ndxscn (scn), elf_errmsg (-1));
1435 sections[i].scn = scn;
1436 sections[i].outscn = NULL;
1437 sections[i].strent = NULL;
1438 sections[i].sig = get_group_sig (stripped, shdr);
1439 }
1440
1441 const struct section *stripped_symtab = NULL;
1442
1443 /* Sort the sections, allocated by address and others after. */
1444 qsort (sections, stripped_shnum - 1, sizeof sections[0],
1445 stripped_ehdr->e_type == ET_REL
1446 ? compare_sections_rel : compare_sections_nonrel);
1447 size_t nalloc = stripped_shnum - 1;
1448 while (nalloc > 0 && !(sections[nalloc - 1].shdr.sh_flags & SHF_ALLOC))
1449 {
1450 --nalloc;
1451 if (sections[nalloc].shdr.sh_type == SHT_SYMTAB)
1452 stripped_symtab = §ions[nalloc];
1453 }
1454
1455 Elf_Data *shstrtab = elf_getdata (elf_getscn (unstripped,
1456 unstripped_shstrndx), NULL);
1457 ELF_CHECK (shstrtab != NULL,
1458 _("cannot read section header string table: %s"));
1459
1460 /* Match each debuginfo section with its corresponding stripped section. */
1461 bool check_prelink = false;
1462 Elf_Scn *unstripped_symtab = NULL;
1463 size_t unstripped_strndx = 0;
1464 size_t alloc_avail = 0;
1465 scn = NULL;
1466 while ((scn = elf_nextscn (unstripped, scn)) != NULL)
1467 {
1468 GElf_Shdr shdr_mem;
1469 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1470 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1471
1472 if (shdr->sh_type == SHT_SYMTAB)
1473 {
1474 unstripped_symtab = scn;
1475 unstripped_strndx = shdr->sh_link;
1476 continue;
1477 }
1478
1479 const size_t ndx = elf_ndxscn (scn);
1480 if (ndx == unstripped_shstrndx || ndx == unstripped_strndx)
1481 continue;
1482
1483 const char *name = get_section_name (ndx, shdr, shstrtab);
1484
1485 struct section *sec = NULL;
1486 if (shdr->sh_flags & SHF_ALLOC)
1487 {
1488 if (stripped_ehdr->e_type != ET_REL)
1489 {
1490 /* Look for the section that matches. */
1491 sec = find_alloc_section (shdr, bias, name, sections, nalloc);
1492 if (sec == NULL)
1493 {
1494 /* We couldn't figure it out. It may be a prelink issue. */
1495 check_prelink = true;
1496 continue;
1497 }
1498 }
1499 else
1500 {
1501 /* The sh_addr of allocated sections does not help us,
1502 but the order usually matches. */
1503 if (likely (sections_match (sections, alloc_avail, shdr, name)))
1504 sec = §ions[alloc_avail++];
1505 else
1506 for (size_t i = alloc_avail + 1; i < nalloc; ++i)
1507 if (sections_match (sections, i, shdr, name))
1508 {
1509 sec = §ions[i];
1510 break;
1511 }
1512 }
1513 }
1514 else
1515 {
1516 /* Locate a matching unallocated section in SECTIONS. */
1517 const char *sig = get_group_sig (unstripped, shdr);
1518 size_t l = nalloc, u = stripped_shnum - 1;
1519 while (l < u)
1520 {
1521 size_t i = (l + u) / 2;
1522 struct section *section = §ions[i];
1523 int cmp = compare_unalloc_sections (shdr, §ion->shdr,
1524 name, section->name,
1525 sig, section->sig);
1526 if (cmp < 0)
1527 u = i;
1528 else if (cmp > 0)
1529 l = i + 1;
1530 else
1531 {
1532 sec = section;
1533 break;
1534 }
1535 }
1536
1537 if (sec == NULL)
1538 {
1539 /* An additional unallocated section is fine if not SHT_NOBITS.
1540 We looked it up anyway in case it's an unallocated section
1541 copied in both files (e.g. SHT_NOTE), and don't keep both. */
1542 if (shdr->sh_type != SHT_NOBITS)
1543 continue;
1544
1545 /* Somehow some old .debug files wound up with SHT_NOBITS
1546 .comment sections, so let those pass. */
1547 if (!strcmp (name, ".comment"))
1548 continue;
1549 }
1550 }
1551
1552 if (sec == NULL)
1553 error_exit (0, _("cannot find matching section for [%zu] '%s'"),
1554 elf_ndxscn (scn), name);
1555
1556 sec->outscn = scn;
1557 }
1558
1559 /* If that failed due to changes made by prelink, we take another tack.
1560 We keep track of a .bss section that was partly split into .dynbss
1561 so that collect_symbols can update symbols' st_shndx fields. */
1562 struct section *split_bss = NULL;
1563 if (check_prelink)
1564 {
1565 Elf_Data *data = elf_getdata (elf_getscn (stripped, stripped_shstrndx),
1566 NULL);
1567 ELF_CHECK (data != NULL,
1568 _("cannot read section header string table: %s"));
1569 split_bss = find_alloc_sections_prelink (unstripped, shstrtab,
1570 stripped, stripped_ehdr,
1571 data, bias, sections,
1572 nalloc, stripped_shnum - 1);
1573 }
1574
1575 /* Make sure each main file section has a place to go. */
1576 const struct section *stripped_dynsym = NULL;
1577 size_t debuglink = SHN_UNDEF;
1578 size_t ndx_sec_num = stripped_shnum - 1;
1579 size_t ndx_section[ndx_sec_num];
1580 Dwelf_Strtab *strtab = NULL;
1581 for (struct section *sec = sections;
1582 sec < §ions[ndx_sec_num];
1583 ++sec)
1584 {
1585 size_t secndx = elf_ndxscn (sec->scn);
1586
1587 if (sec->outscn == NULL)
1588 {
1589 /* We didn't find any corresponding section for this. */
1590
1591 if (secndx == stripped_shstrndx)
1592 {
1593 /* We only need one .shstrtab. */
1594 ndx_section[secndx - 1] = unstripped_shstrndx;
1595 continue;
1596 }
1597
1598 if (unstripped_symtab != NULL && sec == stripped_symtab)
1599 {
1600 /* We don't need a second symbol table. */
1601 ndx_section[secndx - 1] = elf_ndxscn (unstripped_symtab);
1602 continue;
1603 }
1604
1605 if (unstripped_symtab != NULL && stripped_symtab != NULL
1606 && secndx == stripped_symtab->shdr.sh_link
1607 && unstripped_strndx != 0)
1608 {
1609 /* ... nor its string table. */
1610 ndx_section[secndx - 1] = unstripped_strndx;
1611 continue;
1612 }
1613
1614 if (!(sec->shdr.sh_flags & SHF_ALLOC)
1615 && !strcmp (sec->name, ".gnu_debuglink"))
1616 {
1617 /* This was created by stripping. We don't want it. */
1618 debuglink = secndx;
1619 ndx_section[secndx - 1] = SHN_UNDEF;
1620 continue;
1621 }
1622
1623 sec->outscn = elf_newscn (unstripped);
1624 Elf_Data *newdata = elf_newdata (sec->outscn);
1625 ELF_CHECK (newdata != NULL && gelf_update_shdr (sec->outscn,
1626 &sec->shdr),
1627 _("cannot add new section: %s"));
1628
1629 if (strtab == NULL)
1630 strtab = dwelf_strtab_init (true);
1631 sec->strent = dwelf_strtab_add (strtab, sec->name);
1632 ELF_CHECK (sec->strent != NULL,
1633 _("cannot add section name to string table: %s"));
1634 }
1635
1636 /* Cache the mapping of original section indices to output sections. */
1637 ndx_section[secndx - 1] = elf_ndxscn (sec->outscn);
1638 }
1639
1640 /* We added some sections, so we need a new shstrtab. */
1641 Elf_Data *strtab_data = new_shstrtab (unstripped, unstripped_shnum,
1642 shstrtab, unstripped_shstrndx,
1643 sections, stripped_shnum,
1644 strtab);
1645
1646 /* Get the updated section count. */
1647 ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
1648 _("cannot get section count: %s"));
1649
1650 bool placed[unstripped_shnum - 1];
1651 memset (placed, 0, sizeof placed);
1652
1653 /* Now update the output sections and copy in their data. */
1654 GElf_Off offset = 0;
1655 for (const struct section *sec = sections;
1656 sec < §ions[stripped_shnum - 1];
1657 ++sec)
1658 if (sec->outscn != NULL)
1659 {
1660 GElf_Shdr shdr_mem;
1661 GElf_Shdr *shdr = gelf_getshdr (sec->outscn, &shdr_mem);
1662 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1663
1664 /* In an ET_REL file under --relocate, the sh_addr of SHF_ALLOC
1665 sections will have been set nonzero by relocation. This
1666 touched the shdrs of whichever file had the symtab. sh_addr
1667 is still zero in the corresponding shdr. The relocated
1668 address is what we want to use. */
1669 if (stripped_ehdr->e_type != ET_REL
1670 || !(shdr_mem.sh_flags & SHF_ALLOC)
1671 || shdr_mem.sh_addr == 0)
1672 shdr_mem.sh_addr = sec->shdr.sh_addr;
1673
1674 shdr_mem.sh_type = sec->shdr.sh_type;
1675 shdr_mem.sh_size = sec->shdr.sh_size;
1676 shdr_mem.sh_info = sec->shdr.sh_info;
1677 shdr_mem.sh_link = sec->shdr.sh_link;
1678
1679 /* Buggy binutils objdump might have stripped the SHF_INFO_LINK
1680 put it back if necessary. */
1681 if ((sec->shdr.sh_type == SHT_REL || sec->shdr.sh_type == SHT_RELA)
1682 && sec->shdr.sh_flags != shdr_mem.sh_flags
1683 && (sec->shdr.sh_flags & SHF_INFO_LINK) != 0)
1684 shdr_mem.sh_flags |= SHF_INFO_LINK;
1685
1686 if (sec->shdr.sh_link != SHN_UNDEF)
1687 {
1688 if (sec->shdr.sh_link > ndx_sec_num)
1689 error_exit (0,
1690 "section [%zd] has invalid sh_link %" PRId32,
1691 elf_ndxscn (sec->scn), sec->shdr.sh_link);
1692 shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1];
1693 }
1694 if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0)
1695 {
1696 if (sec->shdr.sh_info > ndx_sec_num)
1697 error_exit (0,
1698 "section [%zd] has invalid sh_info %" PRId32,
1699 elf_ndxscn (sec->scn), sec->shdr.sh_info);
1700 shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1];
1701 }
1702
1703 if (strtab != NULL)
1704 shdr_mem.sh_name = dwelf_strent_off (sec->strent);
1705
1706 Elf_Data *indata = elf_getdata (sec->scn, NULL);
1707 ELF_CHECK (indata != NULL, _("cannot get section data: %s"));
1708 Elf_Data *outdata = elf_getdata (sec->outscn, NULL);
1709 ELF_CHECK (outdata != NULL, _("cannot copy section data: %s"));
1710 *outdata = *indata;
1711 elf_flagdata (outdata, ELF_C_SET, ELF_F_DIRTY);
1712
1713 /* Preserve the file layout of the allocated sections. */
1714 if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC))
1715 {
1716 if (max_off > 0 && sec->shdr.sh_offset > (Elf64_Off) max_off)
1717 error_exit (0,
1718 "allocated section offset too large [%zd] %" PRIx64,
1719 elf_ndxscn (sec->scn), sec->shdr.sh_offset);
1720
1721 shdr_mem.sh_offset = sec->shdr.sh_offset;
1722 placed[elf_ndxscn (sec->outscn) - 1] = true;
1723
1724 const GElf_Off end_offset = (shdr_mem.sh_offset
1725 + (shdr_mem.sh_type == SHT_NOBITS
1726 ? 0 : shdr_mem.sh_size));
1727 if (end_offset > offset)
1728 offset = end_offset;
1729 }
1730
1731 update_shdr (sec->outscn, &shdr_mem);
1732
1733 if (shdr_mem.sh_type == SHT_SYMTAB || shdr_mem.sh_type == SHT_DYNSYM)
1734 {
1735 /* We must adjust all the section indices in the symbol table. */
1736
1737 Elf_Data *shndxdata = NULL; /* XXX */
1738
1739 if (shdr_mem.sh_entsize == 0)
1740 error_exit (0,
1741 "SYMTAB section cannot have zero sh_entsize");
1742 for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i)
1743 {
1744 GElf_Sym sym_mem;
1745 GElf_Word shndx = SHN_UNDEF;
1746 GElf_Sym *sym = gelf_getsymshndx (outdata, shndxdata,
1747 i, &sym_mem, &shndx);
1748 ELF_CHECK (sym != NULL,
1749 _("cannot get symbol table entry: %s"));
1750 if (sym->st_shndx != SHN_XINDEX)
1751 shndx = sym->st_shndx;
1752
1753 if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
1754 {
1755 if (shndx >= stripped_shnum)
1756 error_exit (0,
1757 _("symbol [%zu] has invalid section index"), i);
1758
1759 shndx = ndx_section[shndx - 1];
1760 if (shndx < SHN_LORESERVE)
1761 {
1762 sym->st_shndx = shndx;
1763 shndx = SHN_UNDEF;
1764 }
1765 else
1766 sym->st_shndx = SHN_XINDEX;
1767
1768 ELF_CHECK (gelf_update_symshndx (outdata, shndxdata,
1769 i, sym, shndx),
1770 _("cannot update symbol table: %s"));
1771 }
1772 }
1773
1774 if (shdr_mem.sh_type == SHT_SYMTAB)
1775 stripped_symtab = sec;
1776 if (shdr_mem.sh_type == SHT_DYNSYM)
1777 stripped_dynsym = sec;
1778 }
1779
1780 if (shdr_mem.sh_type == SHT_GROUP)
1781 {
1782 /* We must adjust all the section indices in the group.
1783 Skip the first word, which is the section group flag.
1784 Everything else is a section index. */
1785 Elf32_Word *shndx = (Elf32_Word *) outdata->d_buf;
1786 for (size_t i = 1; i < shdr_mem.sh_size / sizeof (Elf32_Word); ++i)
1787 if (shndx[i] == SHN_UNDEF || shndx[i] >= stripped_shnum)
1788 error_exit (0,
1789 _("group has invalid section index [%zd]"), i);
1790 else
1791 shndx[i] = ndx_section[shndx[i] - 1];
1792 }
1793 }
1794
1795 /* We may need to update the symbol table. */
1796 Elf_Data *symdata = NULL;
1797 Dwelf_Strtab *symstrtab = NULL;
1798 Elf_Data *symstrdata = NULL;
1799 if (unstripped_symtab != NULL && (stripped_symtab != NULL
1800 || check_prelink /* Section adjustments. */
1801 || (stripped_ehdr->e_type != ET_REL
1802 && bias != 0)))
1803 {
1804 /* Merge the stripped file's symbol table into the unstripped one. */
1805 const size_t stripped_nsym = (stripped_symtab == NULL ? 1
1806 : (stripped_symtab->shdr.sh_size
1807 / (stripped_symtab->shdr.sh_entsize == 0
1808 ? 1
1809 : stripped_symtab->shdr.sh_entsize)));
1810
1811 GElf_Shdr shdr_mem;
1812 GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
1813 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1814 if (shdr->sh_entsize == 0)
1815 error_exit (0,
1816 "unstripped SYMTAB section cannot have zero sh_entsize");
1817 const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize;
1818
1819 /* First collect all the symbols from both tables. */
1820
1821 const size_t total_syms = stripped_nsym - 1 + unstripped_nsym - 1;
1822 struct symbol *symbols = xmalloc (total_syms * sizeof (struct symbol));
1823 size_t *symndx_map = xmalloc (total_syms * sizeof (size_t));
1824
1825 if (stripped_symtab != NULL)
1826 collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL,
1827 stripped_symtab->scn,
1828 elf_getscn (stripped, stripped_symtab->shdr.sh_link),
1829 stripped_nsym, 0, ndx_section,
1830 symbols, symndx_map, NULL);
1831
1832 Elf_Scn *unstripped_strtab = elf_getscn (unstripped, shdr->sh_link);
1833 collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL,
1834 unstripped_symtab, unstripped_strtab, unstripped_nsym,
1835 stripped_ehdr->e_type == ET_REL ? 0 : bias, NULL,
1836 &symbols[stripped_nsym - 1],
1837 &symndx_map[stripped_nsym - 1], split_bss);
1838
1839 /* Next, sort our array of all symbols. */
1840 qsort (symbols, total_syms, sizeof symbols[0], compare_symbols);
1841
1842 /* Now we can weed out the duplicates. Assign remaining symbols
1843 new slots, collecting a map from old indices to new. */
1844 size_t nsym = 0;
1845 for (struct symbol *s = symbols; s < &symbols[total_syms]; ++s)
1846 {
1847 /* Skip a section symbol for a removed section. */
1848 if (s->shndx == SHN_UNDEF
1849 && GELF_ST_TYPE (s->info.info) == STT_SECTION)
1850 {
1851 s->name = NULL; /* Mark as discarded. */
1852 *s->map = STN_UNDEF;
1853 s->duplicate = NULL;
1854 continue;
1855 }
1856
1857 struct symbol *n = s;
1858 while (n + 1 < &symbols[total_syms] && !compare_symbols (s, n + 1))
1859 ++n;
1860
1861 while (s < n)
1862 {
1863 /* This is a duplicate. Its twin will get the next slot. */
1864 s->name = NULL; /* Mark as discarded. */
1865 s->duplicate = n->map;
1866 ++s;
1867 }
1868
1869 /* Allocate the next slot. */
1870 *s->map = ++nsym;
1871 }
1872
1873 /* Now we sort again, to determine the order in the output. */
1874 qsort (symbols, total_syms, sizeof symbols[0], compare_symbols_output);
1875
1876 if (nsym < total_syms)
1877 /* The discarded symbols are now at the end of the table. */
1878 assert (symbols[nsym].name == NULL);
1879
1880 /* Now a final pass updates the map with the final order,
1881 and builds up the new string table. */
1882 symstrtab = dwelf_strtab_init (true);
1883 for (size_t i = 0; i < nsym; ++i)
1884 {
1885 assert (symbols[i].name != NULL);
1886 assert (*symbols[i].map != 0);
1887 *symbols[i].map = 1 + i;
1888 symbols[i].strent = dwelf_strtab_add (symstrtab, symbols[i].name);
1889 }
1890
1891 /* Scan the discarded symbols too, just to update their slots
1892 in SYMNDX_MAP to refer to their live duplicates. */
1893 for (size_t i = nsym; i < total_syms; ++i)
1894 {
1895 assert (symbols[i].name == NULL);
1896 if (symbols[i].duplicate == NULL)
1897 assert (*symbols[i].map == STN_UNDEF);
1898 else
1899 {
1900 assert (*symbols[i].duplicate != STN_UNDEF);
1901 *symbols[i].map = *symbols[i].duplicate;
1902 }
1903 }
1904
1905 /* Now we are ready to write the new symbol table. */
1906 symdata = elf_getdata (unstripped_symtab, NULL);
1907 symstrdata = elf_getdata (unstripped_strtab, NULL);
1908 Elf_Data *shndxdata = NULL; /* XXX */
1909
1910 /* If symtab and the section header table share the string table
1911 add the section names to the strtab and then (after finalizing)
1912 fixup the section header sh_names. Also dispose of the old data. */
1913 Dwelf_Strent *unstripped_strent[unstripped_shnum - 1];
1914 if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
1915 {
1916 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
1917 {
1918 Elf_Scn *sec = elf_getscn (unstripped, i + 1);
1919 GElf_Shdr mem;
1920 GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
1921 const char *name = get_section_name (i + 1, hdr, shstrtab);
1922 unstripped_strent[i] = dwelf_strtab_add (symstrtab, name);
1923 ELF_CHECK (unstripped_strent[i] != NULL,
1924 _("cannot add section name to string table: %s"));
1925 }
1926
1927 if (strtab != NULL)
1928 {
1929 dwelf_strtab_free (strtab);
1930 free (strtab_data->d_buf);
1931 strtab = NULL;
1932 }
1933 }
1934
1935 if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL)
1936 error_exit (0, "Not enough memory to create symbol table");
1937
1938 elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY);
1939
1940 /* And update the section header names if necessary. */
1941 if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
1942 {
1943 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
1944 {
1945 Elf_Scn *sec = elf_getscn (unstripped, i + 1);
1946 GElf_Shdr mem;
1947 GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
1948 shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
1949 update_shdr (sec, hdr);
1950 }
1951 }
1952
1953 /* Now update the symtab shdr. Reload symtab shdr because sh_name
1954 might have changed above. */
1955 shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
1956 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1957
1958 shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize;
1959 symdata->d_buf = xmalloc (symdata->d_size);
1960 record_new_data (symdata->d_buf);
1961
1962 GElf_Sym sym;
1963 memset (&sym, 0, sizeof sym);
1964 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 0, &sym, SHN_UNDEF),
1965 _("cannot update symbol table: %s"));
1966
1967 shdr->sh_info = 1;
1968 for (size_t i = 0; i < nsym; ++i)
1969 {
1970 struct symbol *s = &symbols[i];
1971
1972 /* Fill in the symbol details. */
1973 sym.st_name = dwelf_strent_off (s->strent);
1974 sym.st_value = s->value; /* Already biased to output address. */
1975 sym.st_size = s->size;
1976 sym.st_shndx = s->shndx; /* Already mapped to output index. */
1977 sym.st_info = s->info.info;
1978 sym.st_other = s->info.other;
1979
1980 /* Keep track of the number of leading local symbols. */
1981 if (GELF_ST_BIND (sym.st_info) == STB_LOCAL)
1982 {
1983 assert (shdr->sh_info == 1 + i);
1984 shdr->sh_info = 1 + i + 1;
1985 }
1986
1987 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 1 + i,
1988 &sym, SHN_UNDEF),
1989 _("cannot update symbol table: %s"));
1990
1991 }
1992 elf_flagdata (symdata, ELF_C_SET, ELF_F_DIRTY);
1993 update_shdr (unstripped_symtab, shdr);
1994
1995 if (stripped_symtab != NULL)
1996 {
1997 /* Adjust any relocations referring to the old symbol table. */
1998 const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn);
1999 for (const struct section *sec = sections;
2000 sec < §ions[stripped_shnum - 1];
2001 ++sec)
2002 if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link)
2003 adjust_relocs (sec->outscn, sec->scn, &sec->shdr,
2004 symndx_map, total_syms, shdr);
2005 }
2006
2007 /* Also adjust references to the other old symbol table. */
2008 adjust_all_relocs (unstripped, unstripped_symtab, shdr,
2009 &symndx_map[stripped_nsym - 1],
2010 total_syms - (stripped_nsym - 1));
2011
2012 free (symbols);
2013 free (symndx_map);
2014 }
2015 else if (stripped_symtab != NULL && stripped_shnum != unstripped_shnum)
2016 check_symtab_section_symbols (unstripped,
2017 stripped_ehdr->e_type == ET_REL,
2018 stripped_symtab->scn,
2019 unstripped_shnum, unstripped_shstrndx,
2020 stripped_symtab->outscn,
2021 stripped_shnum, stripped_shstrndx,
2022 debuglink);
2023
2024 if (stripped_dynsym != NULL)
2025 (void) check_symtab_section_symbols (unstripped,
2026 stripped_ehdr->e_type == ET_REL,
2027 stripped_dynsym->outscn,
2028 unstripped_shnum,
2029 unstripped_shstrndx,
2030 stripped_dynsym->scn, stripped_shnum,
2031 stripped_shstrndx, debuglink);
2032
2033 /* We need to preserve the layout of the stripped file so the
2034 phdrs will match up. This requires us to do our own layout of
2035 the added sections. We do manual layout even for ET_REL just
2036 so we can try to match what the original probably had. */
2037
2038 elf_flagelf (unstripped, ELF_C_SET, ELF_F_LAYOUT);
2039
2040 if (offset == 0)
2041 /* For ET_REL we are starting the layout from scratch. */
2042 offset = gelf_fsize (unstripped, ELF_T_EHDR, 1, EV_CURRENT);
2043
2044 bool skip_reloc = false;
2045 do
2046 {
2047 skip_reloc = !skip_reloc;
2048 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
2049 if (!placed[i])
2050 {
2051 scn = elf_getscn (unstripped, 1 + i);
2052
2053 GElf_Shdr shdr_mem;
2054 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2055 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
2056
2057 /* We must make sure we have read in the data of all sections
2058 beforehand and marked them to be written out. When we're
2059 modifying the existing file in place, we might overwrite
2060 this part of the file before we get to handling the section. */
2061
2062 ELF_CHECK (elf_flagdata (elf_getdata (scn, NULL),
2063 ELF_C_SET, ELF_F_DIRTY),
2064 _("cannot read section data: %s"));
2065
2066 if (skip_reloc
2067 && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA))
2068 continue;
2069
2070 GElf_Off align = shdr->sh_addralign ?: 1;
2071 offset = (offset + align - 1) & -align;
2072 shdr->sh_offset = offset;
2073 if (shdr->sh_type != SHT_NOBITS)
2074 offset += shdr->sh_size;
2075
2076 update_shdr (scn, shdr);
2077
2078 if (unstripped_shstrndx == 1 + i)
2079 {
2080 /* Place the section headers immediately after
2081 .shstrtab, and update the ELF header. */
2082
2083 GElf_Ehdr ehdr_mem;
2084 GElf_Ehdr *ehdr = gelf_getehdr (unstripped, &ehdr_mem);
2085 ELF_CHECK (ehdr != NULL, _("cannot get ELF header: %s"));
2086
2087 GElf_Off sh_align = gelf_getclass (unstripped) * 4;
2088 offset = (offset + sh_align - 1) & -sh_align;
2089 ehdr->e_shnum = unstripped_shnum;
2090 ehdr->e_shoff = offset;
2091 offset += unstripped_shnum * ehdr->e_shentsize;
2092 ELF_CHECK (gelf_update_ehdr (unstripped, ehdr),
2093 _("cannot update ELF header: %s"));
2094 }
2095
2096 placed[i] = true;
2097 }
2098 }
2099 while (skip_reloc);
2100
2101 size_t phnum;
2102 ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
2103 _("cannot get number of program headers: %s"));
2104
2105 if (phnum > 0)
2106 ELF_CHECK (gelf_newphdr (unstripped, phnum),
2107 _("cannot create program headers: %s"));
2108
2109 /* Copy each program header from the stripped file. */
2110 for (size_t i = 0; i < phnum; ++i)
2111 {
2112 GElf_Phdr phdr_mem;
2113 GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
2114 ELF_CHECK (phdr != NULL, _("cannot get program header: %s"));
2115
2116 ELF_CHECK (gelf_update_phdr (unstripped, i, phdr),
2117 _("cannot update program header: %s"));
2118 }
2119
2120 /* Finally, write out the file. */
2121 ELF_CHECK (elf_update (unstripped, ELF_C_WRITE) > 0,
2122 _("cannot write output file: %s"));
2123
2124 if (strtab != NULL)
2125 {
2126 dwelf_strtab_free (strtab);
2127 free (strtab_data->d_buf);
2128 }
2129
2130 if (symstrtab != NULL)
2131 {
2132 dwelf_strtab_free (symstrtab);
2133 free (symstrdata->d_buf);
2134 }
2135 free_new_data ();
2136 }
2137
2138 /* Process one pair of files, already opened. */
2139 static void
handle_file(const char * output_file,bool create_dirs,Elf * stripped,const GElf_Ehdr * stripped_ehdr,Elf * unstripped)2140 handle_file (const char *output_file, bool create_dirs,
2141 Elf *stripped, const GElf_Ehdr *stripped_ehdr,
2142 Elf *unstripped)
2143 {
2144 size_t phnum;
2145 ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
2146 _("cannot get number of program headers: %s"));
2147
2148 /* Determine the address bias between the debuginfo file and the main
2149 file, which may have been modified by prelinking. */
2150 GElf_Addr bias = 0;
2151 if (unstripped != NULL)
2152 for (size_t i = 0; i < phnum; ++i)
2153 {
2154 GElf_Phdr phdr_mem;
2155 GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
2156 ELF_CHECK (phdr != NULL, _("cannot get program header: %s"));
2157 if (phdr->p_type == PT_LOAD)
2158 {
2159 GElf_Phdr unstripped_phdr_mem;
2160 GElf_Phdr *unstripped_phdr = gelf_getphdr (unstripped, i,
2161 &unstripped_phdr_mem);
2162 ELF_CHECK (unstripped_phdr != NULL,
2163 _("cannot get program header: %s"));
2164 bias = phdr->p_vaddr - unstripped_phdr->p_vaddr;
2165 break;
2166 }
2167 }
2168
2169 /* One day we could adjust all the DWARF data (like prelink itself does). */
2170 if (bias != 0)
2171 {
2172 if (output_file == NULL)
2173 error (0, 0, _("\
2174 DWARF data not adjusted for prelinking bias; consider prelink -u"));
2175 else
2176 error (0, 0, _("\
2177 DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"),
2178 output_file);
2179 }
2180
2181 if (output_file == NULL)
2182 /* Modify the unstripped file in place. */
2183 copy_elided_sections (unstripped, stripped, stripped_ehdr, bias);
2184 else
2185 {
2186 if (create_dirs)
2187 make_directories (output_file);
2188
2189 /* Copy the unstripped file and then modify it. */
2190 int outfd = open (output_file, O_RDWR | O_CREAT,
2191 (stripped_ehdr->e_type == ET_REL
2192 ? DEFFILEMODE : ACCESSPERMS));
2193 if (outfd < 0)
2194 error_exit (errno, _("cannot open '%s'"), output_file);
2195 Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL);
2196 ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s"));
2197
2198 if (unstripped == NULL)
2199 {
2200 /* Actually, we are just copying out the main file as it is. */
2201 copy_elf (outelf, stripped);
2202 if (stripped_ehdr->e_type != ET_REL)
2203 elf_flagelf (outelf, ELF_C_SET, ELF_F_LAYOUT);
2204 ELF_CHECK (elf_update (outelf, ELF_C_WRITE) > 0,
2205 _("cannot write output file: %s"));
2206 }
2207 else
2208 {
2209 copy_elf (outelf, unstripped);
2210 copy_elided_sections (outelf, stripped, stripped_ehdr, bias);
2211 }
2212
2213 elf_end (outelf);
2214 close (outfd);
2215 }
2216 }
2217
2218 static int
open_file(const char * file,bool writable)2219 open_file (const char *file, bool writable)
2220 {
2221 int fd = open (file, writable ? O_RDWR : O_RDONLY);
2222 if (fd < 0)
2223 error_exit (errno, _("cannot open '%s'"), file);
2224 return fd;
2225 }
2226
2227 /* Warn, and exit if not forced to continue, if some ELF header
2228 sanity check for the stripped and unstripped files failed. */
2229 static void
warn(const char * msg,bool force,const char * stripped_file,const char * unstripped_file)2230 warn (const char *msg, bool force,
2231 const char *stripped_file, const char *unstripped_file)
2232 {
2233 error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.",
2234 force ? _("WARNING: ") : "",
2235 stripped_file, unstripped_file, msg,
2236 force ? "" : _(", use --force"));
2237 }
2238
2239 /* Handle a pair of files we need to open by name. */
2240 static void
handle_explicit_files(const char * output_file,bool create_dirs,bool force,const char * stripped_file,const char * unstripped_file)2241 handle_explicit_files (const char *output_file, bool create_dirs, bool force,
2242 const char *stripped_file, const char *unstripped_file)
2243 {
2244 int stripped_fd = open_file (stripped_file, false);
2245 Elf *stripped = elf_begin (stripped_fd, ELF_C_READ, NULL);
2246 GElf_Ehdr stripped_ehdr;
2247 ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
2248 _("cannot create ELF descriptor: %s"));
2249
2250 int unstripped_fd = -1;
2251 Elf *unstripped = NULL;
2252 if (unstripped_file != NULL)
2253 {
2254 unstripped_fd = open_file (unstripped_file, output_file == NULL);
2255 unstripped = elf_begin (unstripped_fd,
2256 (output_file == NULL ? ELF_C_RDWR : ELF_C_READ),
2257 NULL);
2258 GElf_Ehdr unstripped_ehdr;
2259 ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr),
2260 _("cannot create ELF descriptor: %s"));
2261
2262 if (memcmp (stripped_ehdr.e_ident,
2263 unstripped_ehdr.e_ident, EI_NIDENT) != 0)
2264 warn (_("ELF header identification (e_ident) different"), force,
2265 stripped_file, unstripped_file);
2266
2267 if (stripped_ehdr.e_type != unstripped_ehdr.e_type)
2268 warn (_("ELF header type (e_type) different"), force,
2269 stripped_file, unstripped_file);
2270
2271 if (stripped_ehdr.e_machine != unstripped_ehdr.e_machine)
2272 warn (_("ELF header machine type (e_machine) different"), force,
2273 stripped_file, unstripped_file);
2274
2275 if (stripped_ehdr.e_phnum < unstripped_ehdr.e_phnum)
2276 warn (_("stripped program header (e_phnum) smaller than unstripped"),
2277 force, stripped_file, unstripped_file);
2278 }
2279
2280 handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped);
2281
2282 elf_end (stripped);
2283 close (stripped_fd);
2284
2285 elf_end (unstripped);
2286 close (unstripped_fd);
2287 }
2288
2289
2290 /* Handle a pair of files opened implicitly by libdwfl for one module. */
2291 static void
handle_dwfl_module(const char * output_file,bool create_dirs,bool force,Dwfl_Module * mod,bool all,bool ignore,bool relocate)2292 handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
2293 Dwfl_Module *mod, bool all, bool ignore, bool relocate)
2294 {
2295 GElf_Addr bias;
2296 Elf *stripped = dwfl_module_getelf (mod, &bias);
2297 if (stripped == NULL)
2298 {
2299 if (ignore)
2300 return;
2301
2302 const char *file;
2303 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
2304 NULL, NULL, &file, NULL);
2305 if (file == NULL)
2306 error_exit (0,
2307 _("cannot find stripped file for module '%s': %s"),
2308 modname, dwfl_errmsg (-1));
2309 else
2310 error_exit (0,
2311 _("cannot open stripped file '%s' for module '%s': %s"),
2312 modname, file, dwfl_errmsg (-1));
2313 }
2314
2315 Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias));
2316 if (debug == NULL && !all)
2317 {
2318 if (ignore)
2319 return;
2320
2321 const char *file;
2322 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
2323 NULL, NULL, NULL, &file);
2324 if (file == NULL)
2325 error_exit (0,
2326 _("cannot find debug file for module '%s': %s"),
2327 modname, dwfl_errmsg (-1));
2328 else
2329 error_exit (0,
2330 _("cannot open debug file '%s' for module '%s': %s"),
2331 modname, file, dwfl_errmsg (-1));
2332 }
2333
2334 if (debug == stripped)
2335 {
2336 if (all)
2337 debug = NULL;
2338 else
2339 {
2340 const char *file;
2341 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
2342 NULL, NULL, &file, NULL);
2343 error_exit (0, _("module '%s' file '%s' is not stripped"),
2344 modname, file);
2345 }
2346 }
2347
2348 GElf_Ehdr stripped_ehdr;
2349 ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
2350 _("cannot create ELF descriptor: %s"));
2351
2352 if (stripped_ehdr.e_type == ET_REL)
2353 {
2354 if (!relocate)
2355 {
2356 /* We can't use the Elf handles already open,
2357 because the DWARF sections have been relocated. */
2358
2359 const char *stripped_file = NULL;
2360 const char *unstripped_file = NULL;
2361 (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL,
2362 &stripped_file, &unstripped_file);
2363
2364 handle_explicit_files (output_file, create_dirs, force,
2365 stripped_file, unstripped_file);
2366 return;
2367 }
2368
2369 /* Relocation is what we want! This ensures that all sections that can
2370 get sh_addr values assigned have them, even ones not used in DWARF.
2371 They might still be used in the symbol table. */
2372 if (dwfl_module_relocations (mod) < 0)
2373 error_exit (0,
2374 _("cannot cache section addresses for module '%s': %s"),
2375 dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
2376 dwfl_errmsg (-1));
2377 }
2378
2379 handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug);
2380 }
2381
2382 /* Handle one module being written to the output directory. */
2383 static void
handle_output_dir_module(const char * output_dir,Dwfl_Module * mod,bool force,bool all,bool ignore,bool modnames,bool relocate)2384 handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool force,
2385 bool all, bool ignore, bool modnames, bool relocate)
2386 {
2387 if (! modnames)
2388 {
2389 /* Make sure we've searched for the ELF file. */
2390 GElf_Addr bias;
2391 (void) dwfl_module_getelf (mod, &bias);
2392 }
2393
2394 const char *file;
2395 const char *name = dwfl_module_info (mod, NULL, NULL, NULL,
2396 NULL, NULL, &file, NULL);
2397
2398 if (file == NULL && ignore)
2399 return;
2400
2401 char *output_file = xasprintf ("%s/%s", output_dir, modnames ? name : file);
2402
2403 handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate);
2404
2405 free (output_file);
2406 }
2407
2408
2409 static void
list_module(Dwfl_Module * mod)2410 list_module (Dwfl_Module *mod)
2411 {
2412 /* Make sure we have searched for the files. */
2413 GElf_Addr bias;
2414 bool have_elf = dwfl_module_getelf (mod, &bias) != NULL;
2415 bool have_dwarf = dwfl_module_getdwarf (mod, &bias) != NULL;
2416
2417 const char *file;
2418 const char *debug;
2419 Dwarf_Addr start;
2420 Dwarf_Addr end;
2421 const char *name = dwfl_module_info (mod, NULL, &start, &end,
2422 NULL, NULL, &file, &debug);
2423 if (file != NULL && debug != NULL && (debug == file || !strcmp (debug, file)))
2424 debug = ".";
2425
2426 const unsigned char *id;
2427 GElf_Addr id_vaddr;
2428 int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
2429
2430 printf ("%#" PRIx64 "+%#" PRIx64 " ", start, end - start);
2431
2432 if (id_len > 0)
2433 {
2434 do
2435 printf ("%02" PRIx8, *id++);
2436 while (--id_len > 0);
2437 if (id_vaddr != 0)
2438 printf ("@%#" PRIx64, id_vaddr);
2439 }
2440 else
2441 putchar ('-');
2442
2443 printf (" %s %s %s\n",
2444 file ?: have_elf ? "." : "-",
2445 debug ?: have_dwarf ? "." : "-",
2446 name);
2447 }
2448
2449
2450 struct match_module_info
2451 {
2452 char **patterns;
2453 Dwfl_Module *found;
2454 bool match_files;
2455 };
2456
2457 static int
match_module(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)2458 match_module (Dwfl_Module *mod,
2459 void **userdata __attribute__ ((unused)),
2460 const char *name,
2461 Dwarf_Addr start __attribute__ ((unused)),
2462 void *arg)
2463 {
2464 struct match_module_info *info = arg;
2465
2466 if (info->patterns[0] == NULL) /* Match all. */
2467 {
2468 match:
2469 info->found = mod;
2470 return DWARF_CB_ABORT;
2471 }
2472
2473 if (info->match_files)
2474 {
2475 /* Make sure we've searched for the ELF file. */
2476 GElf_Addr bias;
2477 (void) dwfl_module_getelf (mod, &bias);
2478
2479 const char *file;
2480 const char *check = dwfl_module_info (mod, NULL, NULL, NULL,
2481 NULL, NULL, &file, NULL);
2482 if (check == NULL || strcmp (check, name) != 0 || file == NULL)
2483 return DWARF_CB_OK;
2484
2485 name = file;
2486 }
2487
2488 for (char **p = info->patterns; *p != NULL; ++p)
2489 if (fnmatch (*p, name, 0) == 0)
2490 goto match;
2491
2492 return DWARF_CB_OK;
2493 }
2494
2495 /* Handle files opened implicitly via libdwfl. */
2496 static void
handle_implicit_modules(const struct arg_info * info)2497 handle_implicit_modules (const struct arg_info *info)
2498 {
2499 struct match_module_info mmi = { info->args, NULL, info->match_files };
2500 ptrdiff_t offset = dwfl_getmodules (info->dwfl, &match_module, &mmi, 0);
2501 if (offset == 0)
2502 error_exit (0, _("no matching modules found"));
2503
2504 if (info->list)
2505 do
2506 list_module (mmi.found);
2507 while ((offset = dwfl_getmodules (info->dwfl, &match_module, &mmi,
2508 offset)) > 0);
2509 else if (info->output_dir == NULL)
2510 {
2511 if (dwfl_getmodules (info->dwfl, &match_module, &mmi, offset) != 0)
2512 error_exit (0, _("matched more than one module"));
2513 handle_dwfl_module (info->output_file, false, info->force, mmi.found,
2514 info->all, info->ignore, info->relocate);
2515 }
2516 else
2517 do
2518 handle_output_dir_module (info->output_dir, mmi.found, info->force,
2519 info->all, info->ignore,
2520 info->modnames, info->relocate);
2521 while ((offset = dwfl_getmodules (info->dwfl, &match_module, &mmi,
2522 offset)) > 0);
2523 }
2524
2525 int
main(int argc,char ** argv)2526 main (int argc, char **argv)
2527 {
2528 /* We use no threads here which can interfere with handling a stream. */
2529 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
2530 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
2531 __fsetlocking (stderr, FSETLOCKING_BYCALLER);
2532
2533 /* Set locale. */
2534 setlocale (LC_ALL, "");
2535
2536 /* Make sure the message catalog can be found. */
2537 bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
2538
2539 /* Initialize the message catalog. */
2540 textdomain (PACKAGE_TARNAME);
2541
2542 /* Parse and process arguments. */
2543 const struct argp_child argp_children[] =
2544 {
2545 {
2546 .argp = dwfl_standard_argp (),
2547 .header = N_("Input selection options:"),
2548 .group = 1,
2549 },
2550 { .argp = NULL },
2551 };
2552 const struct argp argp =
2553 {
2554 .options = options,
2555 .parser = parse_opt,
2556 .children = argp_children,
2557 .args_doc = N_("STRIPPED-FILE DEBUG-FILE\n[MODULE...]"),
2558 .doc = N_("\
2559 Combine stripped files with separate symbols and debug information.\n\
2560 \n\
2561 The first form puts the result in DEBUG-FILE if -o was not given.\n\
2562 \n\
2563 MODULE arguments give file name patterns matching modules to process.\n\
2564 With -f these match the file name of the main (stripped) file \
2565 (slashes are never special), otherwise they match the simple module names. \
2566 With no arguments, process all modules found.\n\
2567 \n\
2568 Multiple modules are written to files under OUTPUT-DIRECTORY, \
2569 creating subdirectories as needed. \
2570 With -m these files have simple module names, otherwise they have the \
2571 name of the main file complete with directory underneath OUTPUT-DIRECTORY.\n\
2572 \n\
2573 With -n no files are written, but one line to standard output for each module:\
2574 \n\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n\
2575 START and SIZE are hexadecimal giving the address bounds of the module. \
2576 BUILDID is hexadecimal for the build ID bits, or - if no ID is known; \
2577 the hexadecimal may be followed by @0xADDR giving the address where the \
2578 ID resides if that is known. \
2579 FILE is the file name found for the module, or - if none was found, \
2580 or . if an ELF image is available but not from any named file. \
2581 DEBUGFILE is the separate debuginfo file name, \
2582 or - if no debuginfo was found, or . if FILE contains the debug information.\
2583 ")
2584 };
2585
2586 int remaining;
2587 struct arg_info info = { .args = NULL };
2588 error_t result = argp_parse (&argp, argc, argv, 0, &remaining, &info);
2589 if (result == ENOSYS)
2590 assert (info.dwfl == NULL);
2591 else if (result)
2592 return EXIT_FAILURE;
2593 assert (info.args != NULL);
2594
2595 /* Tell the library which version we are expecting. */
2596 elf_version (EV_CURRENT);
2597
2598 if (info.dwfl == NULL)
2599 {
2600 assert (result == ENOSYS);
2601
2602 if (info.output_dir != NULL)
2603 {
2604 char *file = xasprintf ("%s/%s", info.output_dir, info.args[0]);
2605 handle_explicit_files (file, true, info.force,
2606 info.args[0], info.args[1]);
2607 free (file);
2608 }
2609 else
2610 handle_explicit_files (info.output_file, false, info.force,
2611 info.args[0], info.args[1]);
2612 }
2613 else
2614 {
2615 /* parse_opt checked this. */
2616 assert (info.output_file != NULL || info.output_dir != NULL || info.list);
2617
2618 handle_implicit_modules (&info);
2619
2620 dwfl_end (info.dwfl);
2621 }
2622
2623 return 0;
2624 }
2625
2626
2627 #include "debugpred.h"
2628