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