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 /* Update relocation sections using the symbol table. */
436 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)437 adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
438 size_t map[], size_t map_size, const GElf_Shdr *symshdr)
439 {
440 Elf_Data *data = elf_getdata (outscn, NULL);
441
442 inline void adjust_reloc (GElf_Xword *info)
443 {
444 size_t ndx = GELF_R_SYM (*info);
445 if (ndx != STN_UNDEF)
446 {
447 if (ndx > map_size)
448 error (EXIT_FAILURE, 0, "bad symbol ndx section");
449 *info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info));
450 }
451 }
452
453 switch (shdr->sh_type)
454 {
455 case SHT_REL:
456 if (shdr->sh_entsize == 0)
457 error (EXIT_FAILURE, 0, "REL section cannot have zero sh_entsize");
458
459 for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
460 {
461 GElf_Rel rel_mem;
462 GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
463 adjust_reloc (&rel->r_info);
464 ELF_CHECK (gelf_update_rel (data, i, rel),
465 _("cannot update relocation: %s"));
466 }
467 break;
468
469 case SHT_RELA:
470 if (shdr->sh_entsize == 0)
471 error (EXIT_FAILURE, 0, "RELA section cannot have zero sh_entsize");
472
473 for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
474 {
475 GElf_Rela rela_mem;
476 GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
477 adjust_reloc (&rela->r_info);
478 ELF_CHECK (gelf_update_rela (data, i, rela),
479 _("cannot update relocation: %s"));
480 }
481 break;
482
483 case SHT_GROUP:
484 {
485 GElf_Shdr shdr_mem;
486 GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem);
487 ELF_CHECK (newshdr != NULL, _("cannot get section header: %s"));
488 if (newshdr->sh_info != STN_UNDEF)
489 {
490 newshdr->sh_info = map[newshdr->sh_info - 1];
491 update_shdr (outscn, newshdr);
492 }
493 break;
494 }
495
496 case SHT_HASH:
497 /* We must expand the table and rejigger its contents. */
498 {
499 if (shdr->sh_entsize == 0)
500 error (EXIT_FAILURE, 0, "HASH section cannot have zero sh_entsize");
501 if (symshdr->sh_entsize == 0)
502 error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
503 const size_t nsym = symshdr->sh_size / symshdr->sh_entsize;
504 const size_t onent = shdr->sh_size / shdr->sh_entsize;
505 if (data->d_size != shdr->sh_size)
506 error (EXIT_FAILURE, 0, "HASH section has inconsistent size");
507
508 #define CONVERT_HASH(Hash_Word) \
509 { \
510 const Hash_Word *const old_hash = data->d_buf; \
511 const size_t nbucket = old_hash[0]; \
512 const size_t nchain = old_hash[1]; \
513 const Hash_Word *const old_bucket = &old_hash[2]; \
514 const Hash_Word *const old_chain = &old_bucket[nbucket]; \
515 if (onent != 2 + nbucket + nchain) \
516 error (EXIT_FAILURE, 0, "HASH section has inconsistent entsize"); \
517 \
518 const size_t nent = 2 + nbucket + nsym; \
519 Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]); \
520 Hash_Word *const new_bucket = &new_hash[2]; \
521 Hash_Word *const new_chain = &new_bucket[nbucket]; \
522 \
523 new_hash[0] = nbucket; \
524 new_hash[1] = nsym; \
525 for (size_t i = 0; i < nbucket; ++i) \
526 if (old_bucket[i] != STN_UNDEF) \
527 new_bucket[i] = map[old_bucket[i] - 1]; \
528 \
529 for (size_t i = 1; i < nchain; ++i) \
530 if (old_chain[i] != STN_UNDEF) \
531 new_chain[map[i - 1]] = map[old_chain[i] - 1]; \
532 \
533 record_new_data (new_hash); \
534 data->d_buf = new_hash; \
535 data->d_size = nent * sizeof new_hash[0]; \
536 }
537
538 switch (shdr->sh_entsize)
539 {
540 case 4:
541 CONVERT_HASH (Elf32_Word);
542 break;
543 case 8:
544 CONVERT_HASH (Elf64_Xword);
545 break;
546 default:
547 abort ();
548 }
549
550 elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
551 update_sh_size (outscn, data);
552
553 #undef CONVERT_HASH
554 }
555 break;
556
557 case SHT_GNU_versym:
558 /* We must expand the table and move its elements around. */
559 {
560 if (shdr->sh_entsize == 0)
561 error (EXIT_FAILURE, 0,
562 "GNU_versym section cannot have zero sh_entsize");
563 if (symshdr->sh_entsize == 0)
564 error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
565 const size_t nent = symshdr->sh_size / symshdr->sh_entsize;
566 const size_t onent = shdr->sh_size / shdr->sh_entsize;
567 assert (nent >= onent);
568
569 /* We don't bother using gelf_update_versym because there is
570 really no conversion to be done. */
571 assert (sizeof (Elf32_Versym) == sizeof (GElf_Versym));
572 assert (sizeof (Elf64_Versym) == sizeof (GElf_Versym));
573 GElf_Versym *versym = xcalloc (nent, sizeof versym[0]);
574
575 for (size_t i = 1; i < onent; ++i)
576 {
577 GElf_Versym *v = gelf_getversym (data, i, &versym[map[i - 1]]);
578 ELF_CHECK (v != NULL, _("cannot get symbol version: %s"));
579 }
580
581 record_new_data (versym);
582 data->d_buf = versym;
583 data->d_size = nent * sizeof versym[0];
584 elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
585 update_sh_size (outscn, data);
586 }
587 break;
588
589 default:
590 error (EXIT_FAILURE, 0,
591 _("unexpected section type in [%zu] with sh_link to symtab"),
592 elf_ndxscn (inscn));
593 }
594 }
595
596 /* Adjust all the relocation sections in the file. */
597 static void
adjust_all_relocs(Elf * elf,Elf_Scn * symtab,const GElf_Shdr * symshdr,size_t map[],size_t map_size)598 adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr,
599 size_t map[], size_t map_size)
600 {
601 size_t new_sh_link = elf_ndxscn (symtab);
602 Elf_Scn *scn = NULL;
603 while ((scn = elf_nextscn (elf, scn)) != NULL)
604 if (scn != symtab)
605 {
606 GElf_Shdr shdr_mem;
607 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
608 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
609 /* Don't redo SHT_GROUP, groups are in both the stripped and debug,
610 it will already have been done by adjust_relocs for the
611 stripped_symtab. */
612 if (shdr->sh_type != SHT_NOBITS && shdr->sh_type != SHT_GROUP
613 && shdr->sh_link == new_sh_link)
614 adjust_relocs (scn, scn, shdr, map, map_size, symshdr);
615 }
616 }
617
618 /* The original file probably had section symbols for all of its
619 sections, even the unallocated ones. To match it as closely as
620 possible, add in section symbols for the added sections. */
621 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)622 add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
623 Elf *elf, bool rel, Elf_Scn *symscn, size_t shnum)
624 {
625 const size_t added = shnum - old_shnum;
626
627 GElf_Shdr shdr_mem;
628 GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
629 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
630 if (shdr->sh_entsize == 0)
631 error (EXIT_FAILURE, 0, "Symbol table section cannot have zero sh_entsize");
632
633 const size_t nsym = shdr->sh_size / shdr->sh_entsize;
634 size_t symndx_map[nsym - 1];
635
636 shdr->sh_info += added;
637 shdr->sh_size += added * shdr->sh_entsize;
638 update_shdr (symscn, shdr);
639
640 Elf_Data *symdata = elf_getdata (symscn, NULL);
641 Elf_Data *shndxdata = NULL; /* XXX */
642
643 symdata->d_size = shdr->sh_size;
644 symdata->d_buf = xmalloc (symdata->d_size);
645 record_new_data (symdata->d_buf);
646
647 /* Copy the existing section symbols. */
648 Elf_Data *old_symdata = elf_getdata (old_symscn, NULL);
649 for (size_t i = 0; i < old_shnum; ++i)
650 {
651 GElf_Sym sym_mem;
652 GElf_Word shndx = SHN_UNDEF;
653 GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
654 i, &sym_mem, &shndx);
655 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
656 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
657 sym, shndx),
658 _("cannot update symbol table: %s"));
659
660 if (i > 0)
661 symndx_map[i - 1] = i;
662 }
663
664 /* Add in the new section symbols. */
665 for (size_t i = old_shnum; i < shnum; ++i)
666 {
667 GElf_Shdr i_shdr_mem;
668 GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem);
669 ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s"));
670 GElf_Sym sym =
671 {
672 .st_value = rel ? 0 : i_shdr->sh_addr,
673 .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION),
674 .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX
675 };
676 GElf_Word shndx = i < SHN_LORESERVE ? SHN_UNDEF : i;
677 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
678 &sym, shndx),
679 _("cannot update symbol table: %s"));
680 }
681
682 /* Now copy the rest of the existing symbols. */
683 for (size_t i = old_shnum; i < nsym; ++i)
684 {
685 GElf_Sym sym_mem;
686 GElf_Word shndx = SHN_UNDEF;
687 GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
688 i, &sym_mem, &shndx);
689 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
690 ELF_CHECK (gelf_update_symshndx (symdata, shndxdata,
691 i + added, sym, shndx),
692 _("cannot update symbol table: %s"));
693
694 symndx_map[i - 1] = i + added;
695 }
696
697 /* Adjust any relocations referring to the old symbol table. */
698 adjust_all_relocs (elf, symscn, shdr, symndx_map, nsym - 1);
699
700 return symdata;
701 }
702
703 /* This has the side effect of updating STT_SECTION symbols' values,
704 in case of prelink adjustments. */
705 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)706 check_symtab_section_symbols (Elf *elf, bool rel, Elf_Scn *scn,
707 size_t shnum, size_t shstrndx,
708 Elf_Scn *oscn, size_t oshnum, size_t oshstrndx,
709 size_t debuglink)
710 {
711 size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum,
712 elf_getdata (scn, NULL));
713
714 if (n == oshnum)
715 return add_new_section_symbols (oscn, n, elf, rel, scn, shnum);
716
717 if (n == oshstrndx || (n == debuglink && n == oshstrndx - 1))
718 return add_new_section_symbols (oscn, n, elf, rel, scn, shstrndx);
719
720 return NULL;
721 }
722
723 struct section
724 {
725 Elf_Scn *scn;
726 const char *name;
727 const char *sig;
728 Elf_Scn *outscn;
729 Dwelf_Strent *strent;
730 GElf_Shdr shdr;
731 };
732
733 static int
compare_alloc_sections(const struct section * s1,const struct section * s2,bool rel)734 compare_alloc_sections (const struct section *s1, const struct section *s2,
735 bool rel)
736 {
737 if (!rel)
738 {
739 /* Sort by address. */
740 if (s1->shdr.sh_addr < s2->shdr.sh_addr)
741 return -1;
742 if (s1->shdr.sh_addr > s2->shdr.sh_addr)
743 return 1;
744 }
745
746 /* At the same address, preserve original section order. */
747 return (ssize_t) elf_ndxscn (s1->scn) - (ssize_t) elf_ndxscn (s2->scn);
748 }
749
750 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)751 compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
752 const char *name1, const char *name2,
753 const char *sig1, const char *sig2)
754 {
755 /* Sort by sh_flags as an arbitrary ordering. */
756 if (shdr1->sh_flags < shdr2->sh_flags)
757 return -1;
758 if (shdr1->sh_flags > shdr2->sh_flags)
759 return 1;
760
761 /* Sizes should be the same. */
762 if (shdr1->sh_size < shdr2->sh_size)
763 return -1;
764 if (shdr1->sh_size > shdr2->sh_size)
765 return 1;
766
767 /* Are they both SHT_GROUP sections? Then compare signatures. */
768 if (sig1 != NULL && sig2 != NULL)
769 return strcmp (sig1, sig2);
770
771 /* Sort by name as last resort. */
772 return strcmp (name1, name2);
773 }
774
775 static int
compare_sections(const void * a,const void * b,bool rel)776 compare_sections (const void *a, const void *b, bool rel)
777 {
778 const struct section *s1 = a;
779 const struct section *s2 = b;
780
781 /* Sort all non-allocated sections last. */
782 if ((s1->shdr.sh_flags ^ s2->shdr.sh_flags) & SHF_ALLOC)
783 return (s1->shdr.sh_flags & SHF_ALLOC) ? -1 : 1;
784
785 return ((s1->shdr.sh_flags & SHF_ALLOC)
786 ? compare_alloc_sections (s1, s2, rel)
787 : compare_unalloc_sections (&s1->shdr, &s2->shdr,
788 s1->name, s2->name,
789 s1->sig, s2->sig));
790 }
791
792 static int
compare_sections_rel(const void * a,const void * b)793 compare_sections_rel (const void *a, const void *b)
794 {
795 return compare_sections (a, b, true);
796 }
797
798 static int
compare_sections_nonrel(const void * a,const void * b)799 compare_sections_nonrel (const void *a, const void *b)
800 {
801 return compare_sections (a, b, false);
802 }
803
804
805 struct symbol
806 {
807 size_t *map;
808
809 union
810 {
811 const char *name;
812 Dwelf_Strent *strent;
813 };
814 union
815 {
816 struct
817 {
818 GElf_Addr value;
819 GElf_Xword size;
820 GElf_Word shndx;
821 union
822 {
823 struct
824 {
825 uint8_t info;
826 uint8_t other;
827 } info;
828 int16_t compare;
829 };
830 };
831
832 /* For a symbol discarded after first sort, this matches its better's
833 map pointer. */
834 size_t *duplicate;
835 };
836 };
837
838 /* Collect input symbols into our internal form. */
839 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)840 collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn,
841 const size_t nent, const GElf_Addr bias,
842 const size_t scnmap[], struct symbol *table, size_t *map,
843 struct section *split_bss)
844 {
845 Elf_Data *symdata = elf_getdata (symscn, NULL);
846 ELF_CHECK (symdata != NULL, _("cannot get symbol section data: %s"));
847 Elf_Data *strdata = elf_getdata (strscn, NULL);
848 ELF_CHECK (strdata != NULL, _("cannot get string section data: %s"));
849 Elf_Data *shndxdata = NULL; /* XXX */
850
851 for (size_t i = 1; i < nent; ++i)
852 {
853 GElf_Sym sym_mem;
854 GElf_Word shndx = SHN_UNDEF;
855 GElf_Sym *sym = gelf_getsymshndx (symdata, shndxdata, i,
856 &sym_mem, &shndx);
857 ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
858 if (sym->st_shndx != SHN_XINDEX)
859 shndx = sym->st_shndx;
860
861 if (sym->st_name >= strdata->d_size
862 || memrchr (strdata->d_buf + sym->st_name, '\0',
863 strdata->d_size - sym->st_name) == NULL)
864 error (EXIT_FAILURE, 0,
865 _("invalid string offset in symbol [%zu]"), i);
866
867 struct symbol *s = &table[i - 1];
868 s->map = &map[i - 1];
869 s->name = strdata->d_buf + sym->st_name;
870 s->value = sym->st_value + bias;
871 s->size = sym->st_size;
872 s->shndx = shndx;
873 s->info.info = sym->st_info;
874 s->info.other = sym->st_other;
875
876 if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
877 s->shndx = scnmap[shndx - 1];
878
879 if (GELF_ST_TYPE (s->info.info) == STT_SECTION && !rel)
880 {
881 /* Update the value to match the output section. */
882 GElf_Shdr shdr_mem;
883 GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, s->shndx),
884 &shdr_mem);
885 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
886 s->value = shdr->sh_addr;
887 }
888 else if (split_bss != NULL
889 && s->value < split_bss->shdr.sh_addr
890 && s->value >= split_bss[-1].shdr.sh_addr
891 && shndx == elf_ndxscn (split_bss->outscn))
892 /* This symbol was in .bss and was split into .dynbss. */
893 s->shndx = elf_ndxscn (split_bss[-1].outscn);
894 }
895 }
896
897
898 #define CMP(value) \
899 if (s1->value < s2->value) \
900 return -1; \
901 if (s1->value > s2->value) \
902 return 1
903
904 /* Compare symbols with a consistent ordering,
905 but one only meaningful for equality. */
906 static int
compare_symbols(const void * a,const void * b)907 compare_symbols (const void *a, const void *b)
908 {
909 const struct symbol *s1 = a;
910 const struct symbol *s2 = b;
911
912 CMP (value);
913 CMP (size);
914 CMP (shndx);
915
916 return (s1->compare - s2->compare) ?: strcmp (s1->name, s2->name);
917 }
918
919 /* Compare symbols for output order after slots have been assigned. */
920 static int
compare_symbols_output(const void * a,const void * b)921 compare_symbols_output (const void *a, const void *b)
922 {
923 const struct symbol *s1 = a;
924 const struct symbol *s2 = b;
925 int cmp;
926
927 /* Sort discarded symbols last. */
928 cmp = (s1->name == NULL) - (s2->name == NULL);
929
930 if (cmp == 0)
931 /* Local symbols must come first. */
932 cmp = ((GELF_ST_BIND (s2->info.info) == STB_LOCAL)
933 - (GELF_ST_BIND (s1->info.info) == STB_LOCAL));
934
935 if (cmp == 0)
936 /* binutils always puts section symbols first. */
937 cmp = ((GELF_ST_TYPE (s2->info.info) == STT_SECTION)
938 - (GELF_ST_TYPE (s1->info.info) == STT_SECTION));
939
940 if (cmp == 0)
941 {
942 if (GELF_ST_TYPE (s1->info.info) == STT_SECTION)
943 {
944 /* binutils always puts section symbols in section index order. */
945 CMP (shndx);
946 else if (s1 != s2)
947 error (EXIT_FAILURE, 0, "section symbols in unexpected order");
948 }
949
950 /* Nothing really matters, so preserve the original order. */
951 CMP (map);
952 else if (s1 != s2)
953 error (EXIT_FAILURE, 0, "found two identical symbols");
954 }
955
956 return cmp;
957 }
958
959 #undef CMP
960
961 /* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK
962 flag if the section contains relocation information. */
963 static bool
sections_flags_match(Elf64_Xword sh_flags1,Elf64_Xword sh_flags2,Elf64_Word sh_type)964 sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2,
965 Elf64_Word sh_type)
966 {
967 if (sh_type == SHT_REL || sh_type == SHT_RELA)
968 {
969 sh_flags1 &= ~SHF_INFO_LINK;
970 sh_flags2 &= ~SHF_INFO_LINK;
971 }
972
973 return sh_flags1 == sh_flags2;
974 }
975
976 /* Return true iff the flags, size, and name match. */
977 static bool
sections_match(const struct section * sections,size_t i,const GElf_Shdr * shdr,const char * name)978 sections_match (const struct section *sections, size_t i,
979 const GElf_Shdr *shdr, const char *name)
980 {
981 return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags,
982 sections[i].shdr.sh_type)
983 && (sections[i].shdr.sh_size == shdr->sh_size
984 || (sections[i].shdr.sh_size < shdr->sh_size
985 && section_can_shrink (§ions[i].shdr)))
986 && !strcmp (sections[i].name, name));
987 }
988
989 /* Locate a matching allocated section in SECTIONS. */
990 static struct section *
find_alloc_section(const GElf_Shdr * shdr,GElf_Addr bias,const char * name,struct section sections[],size_t nalloc)991 find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name,
992 struct section sections[], size_t nalloc)
993 {
994 const GElf_Addr addr = shdr->sh_addr + bias;
995 size_t l = 0, u = nalloc;
996 while (l < u)
997 {
998 size_t i = (l + u) / 2;
999 if (addr < sections[i].shdr.sh_addr)
1000 u = i;
1001 else if (addr > sections[i].shdr.sh_addr)
1002 l = i + 1;
1003 else
1004 {
1005 /* We've found allocated sections with this address.
1006 Find one with matching size, flags, and name. */
1007 while (i > 0 && sections[i - 1].shdr.sh_addr == addr)
1008 --i;
1009 for (; i < nalloc && sections[i].shdr.sh_addr == addr;
1010 ++i)
1011 if (sections_match (sections, i, shdr, name))
1012 return §ions[i];
1013 break;
1014 }
1015 }
1016 return NULL;
1017 }
1018
1019 static inline const char *
get_section_name(size_t ndx,const GElf_Shdr * shdr,const Elf_Data * shstrtab)1020 get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
1021 {
1022 if (shdr->sh_name >= shstrtab->d_size)
1023 error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
1024 ndx, elf_errmsg (-1));
1025 return shstrtab->d_buf + shdr->sh_name;
1026 }
1027
1028 /* Returns the signature of a group section, or NULL if the given
1029 section isn't a group. */
1030 static const char *
get_group_sig(Elf * elf,GElf_Shdr * shdr)1031 get_group_sig (Elf *elf, GElf_Shdr *shdr)
1032 {
1033 if (shdr->sh_type != SHT_GROUP)
1034 return NULL;
1035
1036 Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
1037 if (symscn == NULL)
1038 error (EXIT_FAILURE, 0, _("bad sh_link for group section: %s"),
1039 elf_errmsg (-1));
1040
1041 GElf_Shdr symshdr_mem;
1042 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1043 if (symshdr == NULL)
1044 error (EXIT_FAILURE, 0, _("couldn't get shdr for group section: %s"),
1045 elf_errmsg (-1));
1046
1047 Elf_Data *symdata = elf_getdata (symscn, NULL);
1048 if (symdata == NULL)
1049 error (EXIT_FAILURE, 0, _("bad data for group symbol section: %s"),
1050 elf_errmsg (-1));
1051
1052 GElf_Sym sym_mem;
1053 GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
1054 if (sym == NULL)
1055 error (EXIT_FAILURE, 0, _("couldn't get symbol for group section: %s"),
1056 elf_errmsg (-1));
1057
1058 const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name);
1059 if (sig == NULL)
1060 error (EXIT_FAILURE, 0, _("bad symbol name for group section: %s"),
1061 elf_errmsg (-1));
1062
1063 return sig;
1064 }
1065
1066 /* Fix things up when prelink has moved some allocated sections around
1067 and the debuginfo file's section headers no longer match up.
1068 This fills in SECTIONS[0..NALLOC-1].outscn or exits.
1069 If there was a .bss section that was split into two sections
1070 with the new one preceding it in sh_addr, we return that pointer. */
1071 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)1072 find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
1073 Elf *main, const GElf_Ehdr *main_ehdr,
1074 Elf_Data *main_shstrtab, GElf_Addr bias,
1075 struct section *sections,
1076 size_t nalloc, size_t nsections)
1077 {
1078 Elf_Scn *undo = NULL;
1079 for (size_t i = nalloc; i < nsections; ++i)
1080 {
1081 const struct section *sec = §ions[i];
1082 if (sec->shdr.sh_type == SHT_PROGBITS
1083 && !(sec->shdr.sh_flags & SHF_ALLOC)
1084 && !strcmp (sec->name, ".gnu.prelink_undo"))
1085 {
1086 undo = sec->scn;
1087 break;
1088 }
1089 }
1090
1091 /* Find the original allocated sections before prelinking. */
1092 struct section *undo_sections = NULL;
1093 size_t undo_nalloc = 0;
1094 if (undo != NULL)
1095 {
1096 /* Clear assignments that might have been bogus. */
1097 for (size_t i = 0; i < nalloc; ++i)
1098 sections[i].outscn = NULL;
1099
1100 Elf_Data *undodata = elf_rawdata (undo, NULL);
1101 ELF_CHECK (undodata != NULL,
1102 _("cannot read '.gnu.prelink_undo' section: %s"));
1103
1104 union
1105 {
1106 Elf32_Ehdr e32;
1107 Elf64_Ehdr e64;
1108 } ehdr;
1109 Elf_Data dst =
1110 {
1111 .d_buf = &ehdr,
1112 .d_size = sizeof ehdr,
1113 .d_type = ELF_T_EHDR,
1114 .d_version = EV_CURRENT
1115 };
1116 Elf_Data src = *undodata;
1117 src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT);
1118 src.d_type = ELF_T_EHDR;
1119 ELF_CHECK (gelf_xlatetom (main, &dst, &src,
1120 main_ehdr->e_ident[EI_DATA]) != NULL,
1121 _("cannot read '.gnu.prelink_undo' section: %s"));
1122
1123 uint_fast16_t phnum;
1124 uint_fast16_t shnum; /* prelink doesn't handle > SHN_LORESERVE. */
1125 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
1126 {
1127 phnum = ehdr.e32.e_phnum;
1128 shnum = ehdr.e32.e_shnum;
1129 }
1130 else
1131 {
1132 phnum = ehdr.e64.e_phnum;
1133 shnum = ehdr.e64.e_shnum;
1134 }
1135
1136 bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
1137 size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
1138 if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1))
1139 error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
1140 (size_t) shnum, ".gnu.prelink_undo");
1141
1142 --shnum;
1143
1144 size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT);
1145 src.d_buf += src.d_size + phsize;
1146 src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum, EV_CURRENT);
1147 src.d_type = ELF_T_SHDR;
1148 if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
1149 || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
1150 error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
1151 ".gnu.prelink_undo");
1152
1153 const size_t shdr_bytes = shnum * shsize;
1154 void *shdr = xmalloc (shdr_bytes);
1155 dst.d_buf = shdr;
1156 dst.d_size = shdr_bytes;
1157 ELF_CHECK (gelf_xlatetom (main, &dst, &src,
1158 main_ehdr->e_ident[EI_DATA]) != NULL,
1159 _("cannot read '.gnu.prelink_undo' section: %s"));
1160
1161 undo_sections = xmalloc (shnum * sizeof undo_sections[0]);
1162 for (size_t i = 0; i < shnum; ++i)
1163 {
1164 struct section *sec = &undo_sections[undo_nalloc];
1165 Elf32_Shdr (*s32)[shnum] = shdr;
1166 Elf64_Shdr (*s64)[shnum] = shdr;
1167 if (class32)
1168 {
1169 #define COPY(field) sec->shdr.field = (*s32)[i].field
1170 COPY (sh_name);
1171 COPY (sh_type);
1172 COPY (sh_flags);
1173 COPY (sh_addr);
1174 COPY (sh_offset);
1175 COPY (sh_size);
1176 COPY (sh_link);
1177 COPY (sh_info);
1178 COPY (sh_addralign);
1179 COPY (sh_entsize);
1180 #undef COPY
1181 }
1182 else
1183 sec->shdr = (*s64)[i];
1184 if (sec->shdr.sh_flags & SHF_ALLOC)
1185 {
1186 sec->shdr.sh_addr += bias;
1187 sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab);
1188 sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */
1189 sec->outscn = NULL;
1190 sec->strent = NULL;
1191 sec->sig = get_group_sig (main, &sec->shdr);
1192 ++undo_nalloc;
1193 }
1194 }
1195 qsort (undo_sections, undo_nalloc,
1196 sizeof undo_sections[0], compare_sections_nonrel);
1197 free (shdr);
1198 }
1199
1200 bool fail = false;
1201 inline void check_match (bool match, Elf_Scn *scn, const char *name)
1202 {
1203 if (!match)
1204 {
1205 fail = true;
1206 error (0, 0, _("cannot find matching section for [%zu] '%s'"),
1207 elf_ndxscn (scn), name);
1208 }
1209 }
1210
1211 Elf_Scn *scn = NULL;
1212 while ((scn = elf_nextscn (debug, scn)) != NULL)
1213 {
1214 GElf_Shdr shdr_mem;
1215 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1216 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1217
1218 if (!(shdr->sh_flags & SHF_ALLOC))
1219 continue;
1220
1221 const char *name = get_section_name (elf_ndxscn (scn), shdr,
1222 debug_shstrtab);
1223
1224 if (undo_sections != NULL)
1225 {
1226 struct section *sec = find_alloc_section (shdr, 0, name,
1227 undo_sections,
1228 undo_nalloc);
1229 if (sec != NULL)
1230 {
1231 sec->outscn = scn;
1232 continue;
1233 }
1234 }
1235
1236 /* If there is no prelink info, we are just here to find
1237 the sections to give error messages about. */
1238 for (size_t i = 0; shdr != NULL && i < nalloc; ++i)
1239 if (sections[i].outscn == scn)
1240 shdr = NULL;
1241 check_match (shdr == NULL, scn, name);
1242 }
1243
1244 if (fail)
1245 exit (EXIT_FAILURE);
1246
1247 /* Now we have lined up output sections for each of the original sections
1248 before prelinking. Translate those to the prelinked sections.
1249 This matches what prelink's undo_sections does. */
1250 struct section *split_bss = NULL;
1251 for (size_t i = 0; i < undo_nalloc; ++i)
1252 {
1253 const struct section *undo_sec = &undo_sections[i];
1254
1255 const char *name = undo_sec->name;
1256 scn = undo_sec->scn; /* This is just for elf_ndxscn. */
1257
1258 for (size_t j = 0; j < nalloc; ++j)
1259 {
1260 struct section *sec = §ions[j];
1261 #define RELA_SCALED(field) \
1262 (2 * sec->shdr.field == 3 * undo_sec->shdr.field)
1263 if (sec->outscn == NULL
1264 && sec->shdr.sh_name == undo_sec->shdr.sh_name
1265 && sec->shdr.sh_flags == undo_sec->shdr.sh_flags
1266 && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign
1267 && (((sec->shdr.sh_type == undo_sec->shdr.sh_type
1268 && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
1269 && (sec->shdr.sh_size == undo_sec->shdr.sh_size
1270 || (sec->shdr.sh_size > undo_sec->shdr.sh_size
1271 && main_ehdr->e_type == ET_EXEC
1272 && !strcmp (sec->name, ".dynstr"))))
1273 || (sec->shdr.sh_size == undo_sec->shdr.sh_size
1274 && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
1275 && undo_sec->shdr.sh_type == SHT_NOBITS)
1276 || undo_sec->shdr.sh_type == SHT_PROGBITS)
1277 && !strcmp (sec->name, ".plt")))
1278 || (sec->shdr.sh_type == SHT_RELA
1279 && undo_sec->shdr.sh_type == SHT_REL
1280 && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size))
1281 || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
1282 && (sec->shdr.sh_type == undo_sec->shdr.sh_type
1283 || (sec->shdr.sh_type == SHT_PROGBITS
1284 && undo_sec->shdr.sh_type == SHT_NOBITS))
1285 && sec->shdr.sh_size <= undo_sec->shdr.sh_size
1286 && (!strcmp (sec->name, ".bss")
1287 || !strcmp (sec->name, ".sbss"))
1288 && (sec->shdr.sh_size == undo_sec->shdr.sh_size
1289 || (split_bss = sec) > sections))))
1290 {
1291 sec->outscn = undo_sec->outscn;
1292 undo_sec = NULL;
1293 break;
1294 }
1295 }
1296
1297 check_match (undo_sec == NULL, scn, name);
1298 }
1299
1300 free (undo_sections);
1301
1302 if (fail)
1303 exit (EXIT_FAILURE);
1304
1305 return split_bss;
1306 }
1307
1308 /* Create new .shstrtab contents, subroutine of copy_elided_sections.
1309 This can't be open coded there and still use variable-length auto arrays,
1310 since the end of our block would free other VLAs too. */
1311 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)1312 new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
1313 Elf_Data *shstrtab, size_t unstripped_shstrndx,
1314 struct section *sections, size_t stripped_shnum,
1315 Dwelf_Strtab *strtab)
1316 {
1317 if (strtab == NULL)
1318 return NULL;
1319
1320 Dwelf_Strent *unstripped_strent[unstripped_shnum];
1321 memset (unstripped_strent, 0, sizeof unstripped_strent);
1322 for (struct section *sec = sections;
1323 sec < §ions[stripped_shnum - 1];
1324 ++sec)
1325 if (sec->outscn != NULL)
1326 {
1327 if (sec->strent == NULL)
1328 {
1329 sec->strent = dwelf_strtab_add (strtab, sec->name);
1330 ELF_CHECK (sec->strent != NULL,
1331 _("cannot add section name to string table: %s"));
1332 }
1333 unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent;
1334 }
1335
1336 /* Add names of sections we aren't touching. */
1337 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
1338 if (unstripped_strent[i] == NULL)
1339 {
1340 Elf_Scn *scn = elf_getscn (unstripped, i + 1);
1341 GElf_Shdr shdr_mem;
1342 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1343 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1344 const char *name = get_section_name (i + 1, shdr, shstrtab);
1345 unstripped_strent[i] = dwelf_strtab_add (strtab, name);
1346 ELF_CHECK (unstripped_strent[i] != NULL,
1347 _("cannot add section name to string table: %s"));
1348 }
1349 else
1350 unstripped_strent[i] = NULL;
1351
1352 /* Now finalize the string table so we can get offsets. */
1353 Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped,
1354 unstripped_shstrndx), NULL);
1355 ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
1356 _("cannot update section header string table data: %s"));
1357 if (dwelf_strtab_finalize (strtab, strtab_data) == NULL)
1358 error (EXIT_FAILURE, 0, "Not enough memory to create string table");
1359
1360 /* Update the sh_name fields of sections we aren't modifying later. */
1361 for (size_t i = 0; i < unstripped_shnum - 1; ++i)
1362 if (unstripped_strent[i] != NULL)
1363 {
1364 Elf_Scn *scn = elf_getscn (unstripped, i + 1);
1365 GElf_Shdr shdr_mem;
1366 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1367 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1368 shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
1369 if (i + 1 == unstripped_shstrndx)
1370 shdr->sh_size = strtab_data->d_size;
1371 update_shdr (scn, shdr);
1372 }
1373
1374 return strtab_data;
1375 }
1376
1377 /* Fill in any SHT_NOBITS sections in UNSTRIPPED by
1378 copying their contents and sh_type from STRIPPED. */
1379 static void
copy_elided_sections(Elf * unstripped,Elf * stripped,const GElf_Ehdr * stripped_ehdr,GElf_Addr bias)1380 copy_elided_sections (Elf *unstripped, Elf *stripped,
1381 const GElf_Ehdr *stripped_ehdr, GElf_Addr bias)
1382 {
1383 size_t unstripped_shstrndx;
1384 ELF_CHECK (elf_getshdrstrndx (unstripped, &unstripped_shstrndx) == 0,
1385 _("cannot get section header string table section index: %s"));
1386
1387 size_t stripped_shstrndx;
1388 ELF_CHECK (elf_getshdrstrndx (stripped, &stripped_shstrndx) == 0,
1389 _("cannot get section header string table section index: %s"));
1390
1391 size_t unstripped_shnum;
1392 ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
1393 _("cannot get section count: %s"));
1394
1395 size_t stripped_shnum;
1396 ELF_CHECK (elf_getshdrnum (stripped, &stripped_shnum) == 0,
1397 _("cannot get section count: %s"));
1398
1399 if (unlikely (stripped_shnum > unstripped_shnum))
1400 error (EXIT_FAILURE, 0, _("\
1401 more sections in stripped file than debug file -- arguments reversed?"));
1402
1403 if (unlikely (stripped_shnum == 0))
1404 error (EXIT_FAILURE, 0, _("no sections in stripped file"));
1405
1406 /* Used as sanity check for allocated section offset, if the section
1407 offset needs to be preserved. We want to know the max size of the
1408 ELF file, to check if any existing section offsets are OK. */
1409 int64_t max_off = -1;
1410 if (stripped_ehdr->e_type != ET_REL)
1411 {
1412 elf_flagelf (stripped, ELF_C_SET, ELF_F_LAYOUT);
1413 max_off = elf_update (stripped, ELF_C_NULL);
1414 }
1415
1416 /* Cache the stripped file's section details. */
1417 struct section sections[stripped_shnum - 1];
1418 Elf_Scn *scn = NULL;
1419 while ((scn = elf_nextscn (stripped, scn)) != NULL)
1420 {
1421 size_t i = elf_ndxscn (scn) - 1;
1422 GElf_Shdr *shdr = gelf_getshdr (scn, §ions[i].shdr);
1423 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1424 sections[i].name = elf_strptr (stripped, stripped_shstrndx,
1425 shdr->sh_name);
1426 if (sections[i].name == NULL)
1427 error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
1428 elf_ndxscn (scn), elf_errmsg (-1));
1429 sections[i].scn = scn;
1430 sections[i].outscn = NULL;
1431 sections[i].strent = NULL;
1432 sections[i].sig = get_group_sig (stripped, shdr);
1433 }
1434
1435 const struct section *stripped_symtab = NULL;
1436
1437 /* Sort the sections, allocated by address and others after. */
1438 qsort (sections, stripped_shnum - 1, sizeof sections[0],
1439 stripped_ehdr->e_type == ET_REL
1440 ? compare_sections_rel : compare_sections_nonrel);
1441 size_t nalloc = stripped_shnum - 1;
1442 while (nalloc > 0 && !(sections[nalloc - 1].shdr.sh_flags & SHF_ALLOC))
1443 {
1444 --nalloc;
1445 if (sections[nalloc].shdr.sh_type == SHT_SYMTAB)
1446 stripped_symtab = §ions[nalloc];
1447 }
1448
1449 /* Locate a matching unallocated section in SECTIONS. */
1450 inline struct section *find_unalloc_section (const GElf_Shdr *shdr,
1451 const char *name,
1452 const char *sig)
1453 {
1454 size_t l = nalloc, u = stripped_shnum - 1;
1455 while (l < u)
1456 {
1457 size_t i = (l + u) / 2;
1458 struct section *sec = §ions[i];
1459 int cmp = compare_unalloc_sections (shdr, &sec->shdr,
1460 name, sec->name,
1461 sig, sec->sig);
1462 if (cmp < 0)
1463 u = i;
1464 else if (cmp > 0)
1465 l = i + 1;
1466 else
1467 return sec;
1468 }
1469 return NULL;
1470 }
1471
1472 Elf_Data *shstrtab = elf_getdata (elf_getscn (unstripped,
1473 unstripped_shstrndx), NULL);
1474 ELF_CHECK (shstrtab != NULL,
1475 _("cannot read section header string table: %s"));
1476
1477 /* Match each debuginfo section with its corresponding stripped section. */
1478 bool check_prelink = false;
1479 Elf_Scn *unstripped_symtab = NULL;
1480 size_t unstripped_strndx = 0;
1481 size_t alloc_avail = 0;
1482 scn = NULL;
1483 while ((scn = elf_nextscn (unstripped, scn)) != NULL)
1484 {
1485 GElf_Shdr shdr_mem;
1486 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1487 ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
1488
1489 if (shdr->sh_type == SHT_SYMTAB)
1490 {
1491 unstripped_symtab = scn;
1492 unstripped_strndx = shdr->sh_link;
1493 continue;
1494 }
1495
1496 const size_t ndx = elf_ndxscn (scn);
1497 if (ndx == unstripped_shstrndx || ndx == unstripped_strndx)
1498 continue;
1499
1500 const char *name = get_section_name (ndx, shdr, shstrtab);
1501
1502 struct section *sec = NULL;
1503 if (shdr->sh_flags & SHF_ALLOC)
1504 {
1505 if (stripped_ehdr->e_type != ET_REL)
1506 {
1507 /* Look for the section that matches. */
1508 sec = find_alloc_section (shdr, bias, name, sections, nalloc);
1509 if (sec == NULL)
1510 {
1511 /* We couldn't figure it out. It may be a prelink issue. */
1512 check_prelink = true;
1513 continue;
1514 }
1515 }
1516 else
1517 {
1518 /* The sh_addr of allocated sections does not help us,
1519 but the order usually matches. */
1520 if (likely (sections_match (sections, alloc_avail, shdr, name)))
1521 sec = §ions[alloc_avail++];
1522 else
1523 for (size_t i = alloc_avail + 1; i < nalloc; ++i)
1524 if (sections_match (sections, i, shdr, name))
1525 {
1526 sec = §ions[i];
1527 break;
1528 }
1529 }
1530 }
1531 else
1532 {
1533 /* Look for the section that matches. */
1534 sec = find_unalloc_section (shdr, name,
1535 get_group_sig (unstripped, shdr));
1536 if (sec == NULL)
1537 {
1538 /* An additional unallocated section is fine if not SHT_NOBITS.
1539 We looked it up anyway in case it's an unallocated section
1540 copied in both files (e.g. SHT_NOTE), and don't keep both. */
1541 if (shdr->sh_type != SHT_NOBITS)
1542 continue;
1543
1544 /* Somehow some old .debug files wound up with SHT_NOBITS
1545 .comment sections, so let those pass. */
1546 if (!strcmp (name, ".comment"))
1547 continue;
1548 }
1549 }
1550
1551 if (sec == NULL)
1552 error (EXIT_FAILURE, 0,
1553 _("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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, 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_FAILURE, errno, _("cannot open '%s'"), file);
2224 return fd;
2225 }
2226
2227 /* Handle a pair of files we need to open by name. */
2228 static void
handle_explicit_files(const char * output_file,bool create_dirs,bool force,const char * stripped_file,const char * unstripped_file)2229 handle_explicit_files (const char *output_file, bool create_dirs, bool force,
2230 const char *stripped_file, const char *unstripped_file)
2231 {
2232
2233 /* Warn, and exit if not forced to continue, if some ELF header
2234 sanity check for the stripped and unstripped files failed. */
2235 void warn (const char *msg)
2236 {
2237 error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.",
2238 force ? _("WARNING: ") : "",
2239 stripped_file, unstripped_file, msg,
2240 force ? "" : _(", use --force"));
2241 }
2242
2243 int stripped_fd = open_file (stripped_file, false);
2244 Elf *stripped = elf_begin (stripped_fd, ELF_C_READ, NULL);
2245 GElf_Ehdr stripped_ehdr;
2246 ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
2247 _("cannot create ELF descriptor: %s"));
2248
2249 int unstripped_fd = -1;
2250 Elf *unstripped = NULL;
2251 if (unstripped_file != NULL)
2252 {
2253 unstripped_fd = open_file (unstripped_file, output_file == NULL);
2254 unstripped = elf_begin (unstripped_fd,
2255 (output_file == NULL ? ELF_C_RDWR : ELF_C_READ),
2256 NULL);
2257 GElf_Ehdr unstripped_ehdr;
2258 ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr),
2259 _("cannot create ELF descriptor: %s"));
2260
2261 if (memcmp (stripped_ehdr.e_ident,
2262 unstripped_ehdr.e_ident, EI_NIDENT) != 0)
2263 warn (_("ELF header identification (e_ident) different"));
2264
2265 if (stripped_ehdr.e_type != unstripped_ehdr.e_type)
2266 warn (_("ELF header type (e_type) different"));
2267
2268 if (stripped_ehdr.e_machine != unstripped_ehdr.e_machine)
2269 warn (_("ELF header machine type (e_machine) different"));
2270
2271 if (stripped_ehdr.e_phnum < unstripped_ehdr.e_phnum)
2272 warn (_("stripped program header (e_phnum) smaller than unstripped"));
2273 }
2274
2275 handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped);
2276
2277 elf_end (stripped);
2278 close (stripped_fd);
2279
2280 elf_end (unstripped);
2281 close (unstripped_fd);
2282 }
2283
2284
2285 /* Handle a pair of files opened implicitly by libdwfl for one module. */
2286 static void
handle_dwfl_module(const char * output_file,bool create_dirs,bool force,Dwfl_Module * mod,bool all,bool ignore,bool relocate)2287 handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
2288 Dwfl_Module *mod, bool all, bool ignore, bool relocate)
2289 {
2290 GElf_Addr bias;
2291 Elf *stripped = dwfl_module_getelf (mod, &bias);
2292 if (stripped == NULL)
2293 {
2294 if (ignore)
2295 return;
2296
2297 const char *file;
2298 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
2299 NULL, NULL, &file, NULL);
2300 if (file == NULL)
2301 error (EXIT_FAILURE, 0,
2302 _("cannot find stripped file for module '%s': %s"),
2303 modname, dwfl_errmsg (-1));
2304 else
2305 error (EXIT_FAILURE, 0,
2306 _("cannot open stripped file '%s' for module '%s': %s"),
2307 modname, file, dwfl_errmsg (-1));
2308 }
2309
2310 Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias));
2311 if (debug == NULL && !all)
2312 {
2313 if (ignore)
2314 return;
2315
2316 const char *file;
2317 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
2318 NULL, NULL, NULL, &file);
2319 if (file == NULL)
2320 error (EXIT_FAILURE, 0,
2321 _("cannot find debug file for module '%s': %s"),
2322 modname, dwfl_errmsg (-1));
2323 else
2324 error (EXIT_FAILURE, 0,
2325 _("cannot open debug file '%s' for module '%s': %s"),
2326 modname, file, dwfl_errmsg (-1));
2327 }
2328
2329 if (debug == stripped)
2330 {
2331 if (all)
2332 debug = NULL;
2333 else
2334 {
2335 const char *file;
2336 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
2337 NULL, NULL, &file, NULL);
2338 error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"),
2339 modname, file);
2340 }
2341 }
2342
2343 GElf_Ehdr stripped_ehdr;
2344 ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
2345 _("cannot create ELF descriptor: %s"));
2346
2347 if (stripped_ehdr.e_type == ET_REL)
2348 {
2349 if (!relocate)
2350 {
2351 /* We can't use the Elf handles already open,
2352 because the DWARF sections have been relocated. */
2353
2354 const char *stripped_file = NULL;
2355 const char *unstripped_file = NULL;
2356 (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL,
2357 &stripped_file, &unstripped_file);
2358
2359 handle_explicit_files (output_file, create_dirs, force,
2360 stripped_file, unstripped_file);
2361 return;
2362 }
2363
2364 /* Relocation is what we want! This ensures that all sections that can
2365 get sh_addr values assigned have them, even ones not used in DWARF.
2366 They might still be used in the symbol table. */
2367 if (dwfl_module_relocations (mod) < 0)
2368 error (EXIT_FAILURE, 0,
2369 _("cannot cache section addresses for module '%s': %s"),
2370 dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
2371 dwfl_errmsg (-1));
2372 }
2373
2374 handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug);
2375 }
2376
2377 /* Handle one module being written to the output directory. */
2378 static void
handle_output_dir_module(const char * output_dir,Dwfl_Module * mod,bool force,bool all,bool ignore,bool modnames,bool relocate)2379 handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool force,
2380 bool all, bool ignore, bool modnames, bool relocate)
2381 {
2382 if (! modnames)
2383 {
2384 /* Make sure we've searched for the ELF file. */
2385 GElf_Addr bias;
2386 (void) dwfl_module_getelf (mod, &bias);
2387 }
2388
2389 const char *file;
2390 const char *name = dwfl_module_info (mod, NULL, NULL, NULL,
2391 NULL, NULL, &file, NULL);
2392
2393 if (file == NULL && ignore)
2394 return;
2395
2396 char *output_file;
2397 if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file) < 0)
2398 error (EXIT_FAILURE, 0, _("memory exhausted"));
2399
2400 handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate);
2401 }
2402
2403
2404 static void
list_module(Dwfl_Module * mod)2405 list_module (Dwfl_Module *mod)
2406 {
2407 /* Make sure we have searched for the files. */
2408 GElf_Addr bias;
2409 bool have_elf = dwfl_module_getelf (mod, &bias) != NULL;
2410 bool have_dwarf = dwfl_module_getdwarf (mod, &bias) != NULL;
2411
2412 const char *file;
2413 const char *debug;
2414 Dwarf_Addr start;
2415 Dwarf_Addr end;
2416 const char *name = dwfl_module_info (mod, NULL, &start, &end,
2417 NULL, NULL, &file, &debug);
2418 if (file != NULL && debug != NULL && (debug == file || !strcmp (debug, file)))
2419 debug = ".";
2420
2421 const unsigned char *id;
2422 GElf_Addr id_vaddr;
2423 int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
2424
2425 printf ("%#" PRIx64 "+%#" PRIx64 " ", start, end - start);
2426
2427 if (id_len > 0)
2428 {
2429 do
2430 printf ("%02" PRIx8, *id++);
2431 while (--id_len > 0);
2432 if (id_vaddr != 0)
2433 printf ("@%#" PRIx64, id_vaddr);
2434 }
2435 else
2436 putchar ('-');
2437
2438 printf (" %s %s %s\n",
2439 file ?: have_elf ? "." : "-",
2440 debug ?: have_dwarf ? "." : "-",
2441 name);
2442 }
2443
2444
2445 struct match_module_info
2446 {
2447 char **patterns;
2448 Dwfl_Module *found;
2449 bool match_files;
2450 };
2451
2452 static int
match_module(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)2453 match_module (Dwfl_Module *mod,
2454 void **userdata __attribute__ ((unused)),
2455 const char *name,
2456 Dwarf_Addr start __attribute__ ((unused)),
2457 void *arg)
2458 {
2459 struct match_module_info *info = arg;
2460
2461 if (info->patterns[0] == NULL) /* Match all. */
2462 {
2463 match:
2464 info->found = mod;
2465 return DWARF_CB_ABORT;
2466 }
2467
2468 if (info->match_files)
2469 {
2470 /* Make sure we've searched for the ELF file. */
2471 GElf_Addr bias;
2472 (void) dwfl_module_getelf (mod, &bias);
2473
2474 const char *file;
2475 const char *check = dwfl_module_info (mod, NULL, NULL, NULL,
2476 NULL, NULL, &file, NULL);
2477 if (check == NULL || strcmp (check, name) != 0 || file == NULL)
2478 return DWARF_CB_OK;
2479
2480 name = file;
2481 }
2482
2483 for (char **p = info->patterns; *p != NULL; ++p)
2484 if (fnmatch (*p, name, 0) == 0)
2485 goto match;
2486
2487 return DWARF_CB_OK;
2488 }
2489
2490 /* Handle files opened implicitly via libdwfl. */
2491 static void
handle_implicit_modules(const struct arg_info * info)2492 handle_implicit_modules (const struct arg_info *info)
2493 {
2494 struct match_module_info mmi = { info->args, NULL, info->match_files };
2495 inline ptrdiff_t next (ptrdiff_t offset)
2496 {
2497 return dwfl_getmodules (info->dwfl, &match_module, &mmi, offset);
2498 }
2499 ptrdiff_t offset = next (0);
2500 if (offset == 0)
2501 error (EXIT_FAILURE, 0, _("no matching modules found"));
2502
2503 if (info->list)
2504 do
2505 list_module (mmi.found);
2506 while ((offset = next (offset)) > 0);
2507 else if (info->output_dir == NULL)
2508 {
2509 if (next (offset) != 0)
2510 error (EXIT_FAILURE, 0, _("matched more than one module"));
2511 handle_dwfl_module (info->output_file, false, info->force, mmi.found,
2512 info->all, info->ignore, info->relocate);
2513 }
2514 else
2515 do
2516 handle_output_dir_module (info->output_dir, mmi.found, info->force,
2517 info->all, info->ignore,
2518 info->modnames, info->relocate);
2519 while ((offset = next (offset)) > 0);
2520 }
2521
2522 int
main(int argc,char ** argv)2523 main (int argc, char **argv)
2524 {
2525 /* We use no threads here which can interfere with handling a stream. */
2526 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
2527 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
2528 __fsetlocking (stderr, FSETLOCKING_BYCALLER);
2529
2530 /* Set locale. */
2531 setlocale (LC_ALL, "");
2532
2533 /* Make sure the message catalog can be found. */
2534 bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
2535
2536 /* Initialize the message catalog. */
2537 textdomain (PACKAGE_TARNAME);
2538
2539 /* Parse and process arguments. */
2540 const struct argp_child argp_children[] =
2541 {
2542 {
2543 .argp = dwfl_standard_argp (),
2544 .header = N_("Input selection options:"),
2545 .group = 1,
2546 },
2547 { .argp = NULL },
2548 };
2549 const struct argp argp =
2550 {
2551 .options = options,
2552 .parser = parse_opt,
2553 .children = argp_children,
2554 .args_doc = N_("STRIPPED-FILE DEBUG-FILE\n[MODULE...]"),
2555 .doc = N_("\
2556 Combine stripped files with separate symbols and debug information.\n\
2557 \n\
2558 The first form puts the result in DEBUG-FILE if -o was not given.\n\
2559 \n\
2560 MODULE arguments give file name patterns matching modules to process.\n\
2561 With -f these match the file name of the main (stripped) file \
2562 (slashes are never special), otherwise they match the simple module names. \
2563 With no arguments, process all modules found.\n\
2564 \n\
2565 Multiple modules are written to files under OUTPUT-DIRECTORY, \
2566 creating subdirectories as needed. \
2567 With -m these files have simple module names, otherwise they have the \
2568 name of the main file complete with directory underneath OUTPUT-DIRECTORY.\n\
2569 \n\
2570 With -n no files are written, but one line to standard output for each module:\
2571 \n\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n\
2572 START and SIZE are hexadecimal giving the address bounds of the module. \
2573 BUILDID is hexadecimal for the build ID bits, or - if no ID is known; \
2574 the hexadecimal may be followed by @0xADDR giving the address where the \
2575 ID resides if that is known. \
2576 FILE is the file name found for the module, or - if none was found, \
2577 or . if an ELF image is available but not from any named file. \
2578 DEBUGFILE is the separate debuginfo file name, \
2579 or - if no debuginfo was found, or . if FILE contains the debug information.\
2580 ")
2581 };
2582
2583 int remaining;
2584 struct arg_info info = { .args = NULL };
2585 error_t result = argp_parse (&argp, argc, argv, 0, &remaining, &info);
2586 if (result == ENOSYS)
2587 assert (info.dwfl == NULL);
2588 else if (result)
2589 return EXIT_FAILURE;
2590 assert (info.args != NULL);
2591
2592 /* Tell the library which version we are expecting. */
2593 elf_version (EV_CURRENT);
2594
2595 if (info.dwfl == NULL)
2596 {
2597 assert (result == ENOSYS);
2598
2599 if (info.output_dir != NULL)
2600 {
2601 char *file;
2602 if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0)
2603 error (EXIT_FAILURE, 0, _("memory exhausted"));
2604 handle_explicit_files (file, true, info.force,
2605 info.args[0], info.args[1]);
2606 free (file);
2607 }
2608 else
2609 handle_explicit_files (info.output_file, false, info.force,
2610 info.args[0], info.args[1]);
2611 }
2612 else
2613 {
2614 /* parse_opt checked this. */
2615 assert (info.output_file != NULL || info.output_dir != NULL || info.list);
2616
2617 handle_implicit_modules (&info);
2618
2619 dwfl_end (info.dwfl);
2620 }
2621
2622 return 0;
2623 }
2624
2625
2626 #include "debugpred.h"
2627