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