1 /* Discard section not used at runtime from object files.
2 Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5
6 Red Hat elfutils is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 2 of the License.
9
10 Red Hat elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with Red Hat elfutils; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18
19 Red Hat elfutils is an included package of the Open Invention Network.
20 An included package of the Open Invention Network is a package for which
21 Open Invention Network licensees cross-license their patents. No patent
22 license is granted, either expressly or impliedly, by designation as an
23 included package. Should you wish to participate in the Open Invention
24 Network licensing program, please visit www.openinventionnetwork.com
25 <http://www.openinventionnetwork.com>. */
26
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30
31 #include <argp.h>
32 #include <assert.h>
33 #include <byteswap.h>
34 #include <endian.h>
35 #include <error.h>
36 #include <fcntl.h>
37 #include <gelf.h>
38 #include <libelf.h>
39 #include <libintl.h>
40 #include <locale.h>
41 #include <mcheck.h>
42 #include <stdbool.h>
43 #include <stdio.h>
44 #include <stdio_ext.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <sys/param.h>
49 #include <sys/time.h>
50
51 #include <elf-knowledge.h>
52 #include <libebl.h>
53 #include <system.h>
54
55
56 /* Name and version of program. */
57 static void print_version (FILE *stream, struct argp_state *state);
58 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
59
60 /* Bug report address. */
61 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
62
63
64 /* Values for the parameters which have no short form. */
65 #define OPT_REMOVE_COMMENT 0x100
66 #define OPT_PERMISSIVE 0x101
67
68
69 /* Definitions of arguments for argp functions. */
70 static const struct argp_option options[] =
71 {
72 { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
73 { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 },
74 { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 },
75 { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
76
77 { NULL, 0, NULL, 0, N_("Output options:"), 0 },
78 { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 },
79 { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
80 { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 },
81 { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 },
82 { "preserve-dates", 'p', NULL, 0,
83 N_("Copy modified/access timestamps to the output"), 0 },
84 { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
85 N_("Remove .comment section"), 0 },
86 { "remove-section", 'R', "SECTION", OPTION_HIDDEN, NULL, 0 },
87 { "permissive", OPT_PERMISSIVE, NULL, 0,
88 N_("Relax a few rules to handle slightly broken ELF files"), 0 },
89 { NULL, 0, NULL, 0, NULL, 0 }
90 };
91
92 /* Short description of program. */
93 static const char doc[] = N_("Discard symbols from object files.");
94
95 /* Strings for arguments in help texts. */
96 static const char args_doc[] = N_("[FILE...]");
97
98 /* Prototype for option handler. */
99 static error_t parse_opt (int key, char *arg, struct argp_state *state);
100
101 /* Data structure to communicate with argp functions. */
102 static struct argp argp =
103 {
104 options, parse_opt, args_doc, doc, NULL, NULL, NULL
105 };
106
107
108 /* Print symbols in file named FNAME. */
109 static int process_file (const char *fname);
110
111 /* Handle one ELF file. */
112 static int handle_elf (int fd, Elf *elf, const char *prefix,
113 const char *fname, mode_t mode, struct timeval tvp[2]);
114
115 /* Handle all files contained in the archive. */
116 static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
117 struct timeval tvp[2]);
118
119 #define INTERNAL_ERROR(fname) \
120 error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"), \
121 fname, __LINE__, PACKAGE_VERSION, __DATE__, elf_errmsg (-1))
122
123
124 /* Name of the output file. */
125 static const char *output_fname;
126
127 /* Name of the debug output file. */
128 static const char *debug_fname;
129
130 /* Name to pretend the debug output file has. */
131 static const char *debug_fname_embed;
132
133 /* If true output files shall have same date as the input file. */
134 static bool preserve_dates;
135
136 /* If true .comment sections will be removed. */
137 static bool remove_comment;
138
139 /* If true remove all debug sections. */
140 static bool remove_debug;
141
142 /* If true relax some ELF rules for input files. */
143 static bool permissive;
144
145
146 int
main(int argc,char * argv[])147 main (int argc, char *argv[])
148 {
149 int remaining;
150 int result = 0;
151
152 /* Make memory leak detection possible. */
153 mtrace ();
154
155 /* We use no threads here which can interfere with handling a stream. */
156 __fsetlocking (stdin, FSETLOCKING_BYCALLER);
157 __fsetlocking (stdout, FSETLOCKING_BYCALLER);
158 __fsetlocking (stderr, FSETLOCKING_BYCALLER);
159
160 /* Set locale. */
161 setlocale (LC_ALL, "");
162
163 /* Make sure the message catalog can be found. */
164 bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
165
166 /* Initialize the message catalog. */
167 textdomain (PACKAGE_TARNAME);
168
169 /* Parse and process arguments. */
170 if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
171 return EXIT_FAILURE;
172
173 /* Tell the library which version we are expecting. */
174 elf_version (EV_CURRENT);
175
176 if (remaining == argc)
177 /* The user didn't specify a name so we use a.out. */
178 result = process_file ("a.out");
179 else
180 {
181 /* If we have seen the '-o' or '-f' option there must be exactly one
182 input file. */
183 if ((output_fname != NULL || debug_fname != NULL)
184 && remaining + 1 < argc)
185 error (EXIT_FAILURE, 0, gettext ("\
186 Only one input file allowed together with '-o' and '-f'"));
187
188 /* Process all the remaining files. */
189 do
190 result |= process_file (argv[remaining]);
191 while (++remaining < argc);
192 }
193
194 return result;
195 }
196
197
198 /* Print the version information. */
199 static void
print_version(FILE * stream,struct argp_state * state)200 print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
201 {
202 fprintf (stream, "strip (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
203 fprintf (stream, gettext ("\
204 Copyright (C) %s Red Hat, Inc.\n\
205 This is free software; see the source for copying conditions. There is NO\n\
206 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
207 "), "2008");
208 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
209 }
210
211
212 /* Handle program arguments. */
213 static error_t
parse_opt(int key,char * arg,struct argp_state * state)214 parse_opt (int key, char *arg, struct argp_state *state)
215 {
216 switch (key)
217 {
218 case 'f':
219 if (debug_fname != NULL)
220 {
221 error (0, 0, gettext ("-f option specified twice"));
222 return EINVAL;
223 }
224 debug_fname = arg;
225 break;
226
227 case 'F':
228 if (debug_fname_embed != NULL)
229 {
230 error (0, 0, gettext ("-F option specified twice"));
231 return EINVAL;
232 }
233 debug_fname_embed = arg;
234 break;
235
236 case 'o':
237 if (output_fname != NULL)
238 {
239 error (0, 0, gettext ("-o option specified twice"));
240 return EINVAL;
241 }
242 output_fname = arg;
243 break;
244
245 case 'p':
246 preserve_dates = true;
247 break;
248
249 case OPT_REMOVE_COMMENT:
250 remove_comment = true;
251 break;
252
253 case 'R':
254 if (!strcmp (arg, ".comment"))
255 remove_comment = true;
256 else
257 {
258 argp_error (state,
259 gettext ("-R option supports only .comment section"));
260 return EINVAL;
261 }
262 break;
263
264 case 'g':
265 case 'd':
266 case 'S':
267 remove_debug = true;
268 break;
269
270 case OPT_PERMISSIVE:
271 permissive = true;
272 break;
273
274 case 's': /* Ignored for compatibility. */
275 break;
276
277 default:
278 return ARGP_ERR_UNKNOWN;
279 }
280 return 0;
281 }
282
283
284 static int
process_file(const char * fname)285 process_file (const char *fname)
286 {
287 /* If we have to preserve the modify and access timestamps get them
288 now. We cannot use fstat() after opening the file since the open
289 would change the access time. */
290 struct stat64 pre_st;
291 struct timeval tv[2];
292 again:
293 if (preserve_dates)
294 {
295 if (stat64 (fname, &pre_st) != 0)
296 {
297 error (0, errno, gettext ("cannot stat input file '%s'"), fname);
298 return 1;
299 }
300
301 /* If we have to preserve the timestamp, we need it in the
302 format utimes() understands. */
303 TIMESPEC_TO_TIMEVAL (&tv[0], &pre_st.st_atim);
304 TIMESPEC_TO_TIMEVAL (&tv[1], &pre_st.st_mtim);
305 }
306
307 /* Open the file. */
308 int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
309 if (fd == -1)
310 {
311 error (0, errno, gettext ("while opening '%s'"), fname);
312 return 1;
313 }
314
315 /* We always use fstat() even if we called stat() before. This is
316 done to make sure the information returned by stat() is for the
317 same file. */
318 struct stat64 st;
319 if (fstat64 (fd, &st) != 0)
320 {
321 error (0, errno, gettext ("cannot stat input file '%s'"), fname);
322 return 1;
323 }
324 /* Paranoid mode on. */
325 if (preserve_dates
326 && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
327 {
328 /* We detected a race. Try again. */
329 close (fd);
330 goto again;
331 }
332
333 /* Now get the ELF descriptor. */
334 Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
335 NULL);
336 int result;
337 switch (elf_kind (elf))
338 {
339 case ELF_K_ELF:
340 result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
341 preserve_dates ? tv : NULL);
342 break;
343
344 case ELF_K_AR:
345 /* It is not possible to strip the content of an archive direct
346 the output to a specific file. */
347 if (unlikely (output_fname != NULL || debug_fname != NULL))
348 {
349 error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"),
350 fname);
351 result = 1;
352 }
353 else
354 result = handle_ar (fd, elf, NULL, fname, preserve_dates ? tv : NULL);
355 break;
356
357 default:
358 error (0, 0, gettext ("%s: File format not recognized"), fname);
359 result = 1;
360 break;
361 }
362
363 if (unlikely (elf_end (elf) != 0))
364 INTERNAL_ERROR (fname);
365
366 close (fd);
367
368 return result;
369 }
370
371
372 /* Maximum size of array allocated on stack. */
373 #define MAX_STACK_ALLOC (400 * 1024)
374
375 static int
handle_elf(int fd,Elf * elf,const char * prefix,const char * fname,mode_t mode,struct timeval tvp[2])376 handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
377 mode_t mode, struct timeval tvp[2])
378 {
379 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
380 size_t fname_len = strlen (fname) + 1;
381 char *fullname = alloca (prefix_len + 1 + fname_len);
382 char *cp = fullname;
383 Elf *debugelf = NULL;
384 char *tmp_debug_fname = NULL;
385 int result = 0;
386 size_t shdridx = 0;
387 size_t shstrndx;
388 struct shdr_info
389 {
390 Elf_Scn *scn;
391 GElf_Shdr shdr;
392 Elf_Data *data;
393 Elf_Data *debug_data;
394 const char *name;
395 Elf32_Word idx; /* Index in new file. */
396 Elf32_Word old_sh_link; /* Original value of shdr.sh_link. */
397 Elf32_Word symtab_idx;
398 Elf32_Word version_idx;
399 Elf32_Word group_idx;
400 Elf32_Word group_cnt;
401 Elf_Scn *newscn;
402 struct Ebl_Strent *se;
403 Elf32_Word *newsymidx;
404 } *shdr_info = NULL;
405 Elf_Scn *scn;
406 size_t cnt;
407 size_t idx;
408 bool changes;
409 GElf_Ehdr newehdr_mem;
410 GElf_Ehdr *newehdr;
411 GElf_Ehdr debugehdr_mem;
412 GElf_Ehdr *debugehdr;
413 struct Ebl_Strtab *shst = NULL;
414 Elf_Data debuglink_crc_data;
415 bool any_symtab_changes = false;
416 Elf_Data *shstrtab_data = NULL;
417
418 /* Create the full name of the file. */
419 if (prefix != NULL)
420 {
421 cp = mempcpy (cp, prefix, prefix_len);
422 *cp++ = ':';
423 }
424 memcpy (cp, fname, fname_len);
425
426 /* If we are not replacing the input file open a new file here. */
427 if (output_fname != NULL)
428 {
429 fd = open (output_fname, O_RDWR | O_CREAT, mode);
430 if (unlikely (fd == -1))
431 {
432 error (0, errno, gettext ("cannot open '%s'"), output_fname);
433 return 1;
434 }
435 }
436
437 int debug_fd = -1;
438
439 /* Get the EBL handling. The -g option is currently the only reason
440 we need EBL so dont open the backend unless necessary. */
441 Ebl *ebl = NULL;
442 if (remove_debug)
443 {
444 ebl = ebl_openbackend (elf);
445 if (ebl == NULL)
446 {
447 error (0, errno, gettext ("cannot open EBL backend"));
448 result = 1;
449 goto fail;
450 }
451 }
452
453 /* Open the additional file the debug information will be stored in. */
454 if (debug_fname != NULL)
455 {
456 /* Create a temporary file name. We do not want to overwrite
457 the debug file if the file would not contain any
458 information. */
459 size_t debug_fname_len = strlen (debug_fname);
460 tmp_debug_fname = (char *) alloca (debug_fname_len + sizeof (".XXXXXX"));
461 strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
462 ".XXXXXX");
463
464 debug_fd = mkstemp (tmp_debug_fname);
465 if (unlikely (debug_fd == -1))
466 {
467 error (0, errno, gettext ("cannot open '%s'"), debug_fname);
468 result = 1;
469 goto fail;
470 }
471 }
472
473 /* Get the information from the old file. */
474 GElf_Ehdr ehdr_mem;
475 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
476 if (ehdr == NULL)
477 INTERNAL_ERROR (fname);
478
479 /* Get the section header string table index. */
480 if (unlikely (elf_getshstrndx (elf, &shstrndx) < 0))
481 error (EXIT_FAILURE, 0,
482 gettext ("cannot get section header string table index"));
483
484 /* We now create a new ELF descriptor for the same file. We
485 construct it almost exactly in the same way with some information
486 dropped. */
487 Elf *newelf;
488 if (output_fname != NULL)
489 newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
490 else
491 newelf = elf_clone (elf, ELF_C_EMPTY);
492
493 if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
494 || (ehdr->e_type != ET_REL
495 && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0)))
496 {
497 error (0, 0, gettext ("cannot create new file '%s': %s"),
498 output_fname, elf_errmsg (-1));
499 goto fail;
500 }
501
502 /* Copy over the old program header if needed. */
503 if (ehdr->e_type != ET_REL)
504 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
505 {
506 GElf_Phdr phdr_mem;
507 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
508 if (phdr == NULL
509 || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
510 INTERNAL_ERROR (fname);
511 }
512
513 if (debug_fname != NULL)
514 {
515 /* Also create an ELF descriptor for the debug file */
516 debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
517 if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
518 || (ehdr->e_type != ET_REL
519 && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0)))
520 {
521 error (0, 0, gettext ("cannot create new file '%s': %s"),
522 debug_fname, elf_errmsg (-1));
523 goto fail_close;
524 }
525
526 /* Copy over the old program header if needed. */
527 if (ehdr->e_type != ET_REL)
528 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
529 {
530 GElf_Phdr phdr_mem;
531 GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
532 if (phdr == NULL
533 || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
534 INTERNAL_ERROR (fname);
535 }
536 }
537
538 /* Number of sections. */
539 size_t shnum;
540 if (unlikely (elf_getshnum (elf, &shnum) < 0))
541 {
542 error (0, 0, gettext ("cannot determine number of sections: %s"),
543 elf_errmsg (-1));
544 goto fail_close;
545 }
546
547 /* Storage for section information. We leave room for two more
548 entries since we unconditionally create a section header string
549 table. Maybe some weird tool created an ELF file without one.
550 The other one is used for the debug link section. */
551 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
552 shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
553 sizeof (struct shdr_info));
554 else
555 {
556 shdr_info = (struct shdr_info *) alloca ((shnum + 2)
557 * sizeof (struct shdr_info));
558 memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
559 }
560
561 /* Prepare section information data structure. */
562 scn = NULL;
563 cnt = 1;
564 while ((scn = elf_nextscn (elf, scn)) != NULL)
565 {
566 /* This should always be true (i.e., there should not be any
567 holes in the numbering). */
568 assert (elf_ndxscn (scn) == cnt);
569
570 shdr_info[cnt].scn = scn;
571
572 /* Get the header. */
573 if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
574 INTERNAL_ERROR (fname);
575
576 /* Get the name of the section. */
577 shdr_info[cnt].name = elf_strptr (elf, shstrndx,
578 shdr_info[cnt].shdr.sh_name);
579 if (shdr_info[cnt].name == NULL)
580 {
581 error (0, 0, gettext ("illformed file '%s'"), fname);
582 goto fail_close;
583 }
584
585 /* Mark them as present but not yet investigated. */
586 shdr_info[cnt].idx = 1;
587
588 /* Remember the shdr.sh_link value. */
589 shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
590
591 /* Sections in files other than relocatable object files which
592 are not loaded can be freely moved by us. In relocatable
593 object files everything can be moved. */
594 if (ehdr->e_type == ET_REL
595 || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
596 shdr_info[cnt].shdr.sh_offset = 0;
597
598 /* If this is an extended section index table store an
599 appropriate reference. */
600 if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
601 {
602 assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
603 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
604 }
605 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
606 {
607 /* Cross-reference the sections contained in the section
608 group. */
609 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
610 if (shdr_info[cnt].data == NULL)
611 INTERNAL_ERROR (fname);
612
613 /* XXX Fix for unaligned access. */
614 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
615 size_t inner;
616 for (inner = 1;
617 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
618 ++inner)
619 shdr_info[grpref[inner]].group_idx = cnt;
620
621 if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
622 /* If the section group contains only one element and this
623 is n COMDAT section we can drop it right away. */
624 shdr_info[cnt].idx = 0;
625 else
626 shdr_info[cnt].group_cnt = inner - 1;
627 }
628 else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
629 {
630 assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
631 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
632 }
633
634 /* If this section is part of a group make sure it is not
635 discarded right away. */
636 if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
637 {
638 assert (shdr_info[cnt].group_idx != 0);
639
640 if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
641 {
642 /* The section group section will be removed. */
643 shdr_info[cnt].group_idx = 0;
644 shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP;
645 }
646 }
647
648 /* Increment the counter. */
649 ++cnt;
650 }
651
652 /* Now determine which sections can go away. The general rule is that
653 all sections which are not used at runtime are stripped out. But
654 there are a few exceptions:
655
656 - special sections named ".comment" and ".note" are kept
657 - OS or architecture specific sections are kept since we might not
658 know how to handle them
659 - if a section is referred to from a section which is not removed
660 in the sh_link or sh_info element it cannot be removed either
661 */
662 for (cnt = 1; cnt < shnum; ++cnt)
663 /* Check whether the section can be removed. */
664 if (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr,
665 shdr_info[cnt].name, remove_comment,
666 remove_debug))
667 {
668 /* For now assume this section will be removed. */
669 shdr_info[cnt].idx = 0;
670
671 idx = shdr_info[cnt].group_idx;
672 while (idx != 0)
673 {
674 /* The section group data is already loaded. */
675 assert (shdr_info[idx].data != NULL);
676
677 /* If the references section group is a normal section
678 group and has one element remaining, or if it is an
679 empty COMDAT section group it is removed. */
680 bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
681 & GRP_COMDAT) != 0;
682
683 --shdr_info[idx].group_cnt;
684 if ((!is_comdat && shdr_info[idx].group_cnt == 1)
685 || (is_comdat && shdr_info[idx].group_cnt == 0))
686 {
687 shdr_info[idx].idx = 0;
688 /* Continue recursively. */
689 idx = shdr_info[idx].group_idx;
690 }
691 else
692 break;
693 }
694 }
695
696 /* Mark the SHT_NULL section as handled. */
697 shdr_info[0].idx = 2;
698
699
700 /* Handle exceptions: section groups and cross-references. We might
701 have to repeat this a few times since the resetting of the flag
702 might propagate. */
703 do
704 {
705 changes = false;
706
707 for (cnt = 1; cnt < shnum; ++cnt)
708 {
709 if (shdr_info[cnt].idx == 0)
710 {
711 /* If a relocation section is marked as being removed make
712 sure the section it is relocating is removed, too. */
713 if ((shdr_info[cnt].shdr.sh_type == SHT_REL
714 || shdr_info[cnt].shdr.sh_type == SHT_RELA)
715 && shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
716 shdr_info[cnt].idx = 1;
717 }
718
719 if (shdr_info[cnt].idx == 1)
720 {
721 /* The content of symbol tables we don't remove must not
722 reference any section which we do remove. Otherwise
723 we cannot remove the section. */
724 if (debug_fname != NULL
725 && shdr_info[cnt].debug_data == NULL
726 && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
727 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB))
728 {
729 /* Make sure the data is loaded. */
730 if (shdr_info[cnt].data == NULL)
731 {
732 shdr_info[cnt].data
733 = elf_getdata (shdr_info[cnt].scn, NULL);
734 if (shdr_info[cnt].data == NULL)
735 INTERNAL_ERROR (fname);
736 }
737 Elf_Data *symdata = shdr_info[cnt].data;
738
739 /* If there is an extended section index table load it
740 as well. */
741 if (shdr_info[cnt].symtab_idx != 0
742 && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
743 {
744 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
745
746 shdr_info[shdr_info[cnt].symtab_idx].data
747 = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
748 NULL);
749 if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
750 INTERNAL_ERROR (fname);
751 }
752 Elf_Data *xndxdata
753 = shdr_info[shdr_info[cnt].symtab_idx].data;
754
755 /* Go through all symbols and make sure the section they
756 reference is not removed. */
757 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
758 ehdr->e_version);
759
760 for (size_t inner = 0;
761 inner < shdr_info[cnt].data->d_size / elsize;
762 ++inner)
763 {
764 GElf_Sym sym_mem;
765 Elf32_Word xndx;
766 GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
767 inner, &sym_mem,
768 &xndx);
769 if (sym == NULL)
770 INTERNAL_ERROR (fname);
771
772 size_t scnidx = sym->st_shndx;
773 if (scnidx == SHN_UNDEF || scnidx >= shnum
774 || (scnidx >= SHN_LORESERVE
775 && scnidx <= SHN_HIRESERVE
776 && scnidx != SHN_XINDEX)
777 /* Don't count in the section symbols. */
778 || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
779 /* This is no section index, leave it alone. */
780 continue;
781 else if (scnidx == SHN_XINDEX)
782 scnidx = xndx;
783
784 if (shdr_info[scnidx].idx == 0)
785 /* This symbol table has a real symbol in
786 a discarded section. So preserve the
787 original table in the debug file. */
788 shdr_info[cnt].debug_data = symdata;
789 }
790 }
791
792 /* Cross referencing happens:
793 - for the cases the ELF specification says. That are
794 + SHT_DYNAMIC in sh_link to string table
795 + SHT_HASH in sh_link to symbol table
796 + SHT_REL and SHT_RELA in sh_link to symbol table
797 + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
798 + SHT_GROUP in sh_link to symbol table
799 + SHT_SYMTAB_SHNDX in sh_link to symbol table
800 Other (OS or architecture-specific) sections might as
801 well use this field so we process it unconditionally.
802 - references inside section groups
803 - specially marked references in sh_info if the SHF_INFO_LINK
804 flag is set
805 */
806
807 if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
808 {
809 shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
810 changes |= shdr_info[cnt].shdr.sh_link < cnt;
811 }
812
813 /* Handle references through sh_info. */
814 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr)
815 && shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
816 {
817 shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
818 changes |= shdr_info[cnt].shdr.sh_info < cnt;
819 }
820
821 /* Mark the section as investigated. */
822 shdr_info[cnt].idx = 2;
823 }
824
825 if (debug_fname != NULL
826 && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL))
827 {
828 /* This section is being preserved in the debug file.
829 Sections it refers to must be preserved there too.
830
831 In this pass we mark sections to be preserved in both
832 files by setting the .debug_data pointer to the original
833 file's .data pointer. Below, we'll copy the section
834 contents. */
835
836 inline void check_preserved (size_t i)
837 {
838 if (i != 0 && shdr_info[i].idx != 0)
839 {
840 if (shdr_info[i].data == NULL)
841 shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL);
842 if (shdr_info[i].data == NULL)
843 INTERNAL_ERROR (fname);
844
845 shdr_info[i].debug_data = shdr_info[i].data;
846 changes |= i < cnt;
847 }
848 }
849
850 check_preserved (shdr_info[cnt].shdr.sh_link);
851 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
852 check_preserved (shdr_info[cnt].shdr.sh_info);
853 }
854 }
855 }
856 while (changes);
857
858 /* Copy the removed sections to the debug output file.
859 The ones that are not removed in the stripped file are SHT_NOBITS. */
860 if (debug_fname != NULL)
861 {
862 for (cnt = 1; cnt < shnum; ++cnt)
863 {
864 scn = elf_newscn (debugelf);
865 if (scn == NULL)
866 error (EXIT_FAILURE, 0,
867 gettext ("while generating output file: %s"),
868 elf_errmsg (-1));
869
870 bool discard_section = (shdr_info[cnt].idx > 0
871 && shdr_info[cnt].debug_data == NULL
872 && shdr_info[cnt].shdr.sh_type != SHT_NOTE
873 && cnt != ehdr->e_shstrndx);
874
875 /* Set the section header in the new file. */
876 GElf_Shdr debugshdr = shdr_info[cnt].shdr;
877 if (discard_section)
878 debugshdr.sh_type = SHT_NOBITS;
879
880 if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
881 /* There cannot be any overflows. */
882 INTERNAL_ERROR (fname);
883
884 /* Get the data from the old file if necessary. */
885 if (shdr_info[cnt].data == NULL)
886 {
887 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
888 if (shdr_info[cnt].data == NULL)
889 INTERNAL_ERROR (fname);
890 }
891
892 /* Set the data. This is done by copying from the old file. */
893 Elf_Data *debugdata = elf_newdata (scn);
894 if (debugdata == NULL)
895 INTERNAL_ERROR (fname);
896
897 /* Copy the structure. This data may be modified in place
898 before we write out the file. */
899 *debugdata = *shdr_info[cnt].data;
900 if (discard_section)
901 debugdata->d_buf = NULL;
902 else if (shdr_info[cnt].debug_data != NULL)
903 {
904 /* Copy the original data before it gets modified. */
905 shdr_info[cnt].debug_data = debugdata;
906 debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
907 debugdata->d_buf, debugdata->d_size);
908 }
909 }
910
911 /* Finish the ELF header. Fill in the fields not handled by
912 libelf from the old file. */
913 debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
914 if (debugehdr == NULL)
915 INTERNAL_ERROR (fname);
916
917 memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
918 debugehdr->e_type = ehdr->e_type;
919 debugehdr->e_machine = ehdr->e_machine;
920 debugehdr->e_version = ehdr->e_version;
921 debugehdr->e_entry = ehdr->e_entry;
922 debugehdr->e_flags = ehdr->e_flags;
923 debugehdr->e_shstrndx = ehdr->e_shstrndx;
924
925 if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
926 {
927 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
928 debug_fname, elf_errmsg (-1));
929 result = 1;
930 goto fail_close;
931 }
932 }
933
934 /* Mark the section header string table as unused, we will create
935 a new one. */
936 shdr_info[shstrndx].idx = 0;
937
938 /* We need a string table for the section headers. */
939 shst = ebl_strtabinit (true);
940 if (shst == NULL)
941 error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
942 output_fname ?: fname);
943
944 /* Assign new section numbers. */
945 shdr_info[0].idx = 0;
946 for (cnt = idx = 1; cnt < shnum; ++cnt)
947 if (shdr_info[cnt].idx > 0)
948 {
949 shdr_info[cnt].idx = idx++;
950
951 /* Create a new section. */
952 shdr_info[cnt].newscn = elf_newscn (newelf);
953 if (shdr_info[cnt].newscn == NULL)
954 error (EXIT_FAILURE, 0, gettext ("while generating output file: %s"),
955 elf_errmsg (-1));
956
957 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
958
959 /* Add this name to the section header string table. */
960 shdr_info[cnt].se = ebl_strtabadd (shst, shdr_info[cnt].name, 0);
961 }
962
963 /* Test whether we are doing anything at all. */
964 if (cnt == idx)
965 /* Nope, all removable sections are already gone. */
966 goto fail_close;
967
968 /* Create the reference to the file with the debug info. */
969 if (debug_fname != NULL)
970 {
971 /* Add the section header string table section name. */
972 shdr_info[cnt].se = ebl_strtabadd (shst, ".gnu_debuglink", 15);
973 shdr_info[cnt].idx = idx++;
974
975 /* Create the section header. */
976 shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
977 shdr_info[cnt].shdr.sh_flags = 0;
978 shdr_info[cnt].shdr.sh_addr = 0;
979 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
980 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
981 shdr_info[cnt].shdr.sh_entsize = 0;
982 shdr_info[cnt].shdr.sh_addralign = 4;
983 /* We set the offset to zero here. Before we write the ELF file the
984 field must have the correct value. This is done in the final
985 loop over all section. Then we have all the information needed. */
986 shdr_info[cnt].shdr.sh_offset = 0;
987
988 /* Create the section. */
989 shdr_info[cnt].newscn = elf_newscn (newelf);
990 if (shdr_info[cnt].newscn == NULL)
991 error (EXIT_FAILURE, 0,
992 gettext ("while create section header section: %s"),
993 elf_errmsg (-1));
994 assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
995
996 shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
997 if (shdr_info[cnt].data == NULL)
998 error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
999 elf_errmsg (-1));
1000
1001 char *debug_basename = basename (debug_fname_embed ?: debug_fname);
1002 off_t crc_offset = strlen (debug_basename) + 1;
1003 /* Align to 4 byte boundary */
1004 crc_offset = ((crc_offset - 1) & ~3) + 4;
1005
1006 shdr_info[cnt].data->d_align = 4;
1007 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
1008 = crc_offset + 4;
1009 shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size);
1010
1011 strcpy (shdr_info[cnt].data->d_buf, debug_basename);
1012
1013 /* Cache this Elf_Data describing the CRC32 word in the section.
1014 We'll fill this in when we have written the debug file. */
1015 debuglink_crc_data = *shdr_info[cnt].data;
1016 debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
1017 + crc_offset);
1018 debuglink_crc_data.d_size = 4;
1019
1020 /* One more section done. */
1021 ++cnt;
1022 }
1023
1024 /* Index of the section header table in the shdr_info array. */
1025 shdridx = cnt;
1026
1027 /* Add the section header string table section name. */
1028 shdr_info[cnt].se = ebl_strtabadd (shst, ".shstrtab", 10);
1029 shdr_info[cnt].idx = idx;
1030
1031 /* Create the section header. */
1032 shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
1033 shdr_info[cnt].shdr.sh_flags = 0;
1034 shdr_info[cnt].shdr.sh_addr = 0;
1035 shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
1036 shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
1037 shdr_info[cnt].shdr.sh_entsize = 0;
1038 /* We set the offset to zero here. Before we write the ELF file the
1039 field must have the correct value. This is done in the final
1040 loop over all section. Then we have all the information needed. */
1041 shdr_info[cnt].shdr.sh_offset = 0;
1042 shdr_info[cnt].shdr.sh_addralign = 1;
1043
1044 /* Create the section. */
1045 shdr_info[cnt].newscn = elf_newscn (newelf);
1046 if (shdr_info[cnt].newscn == NULL)
1047 error (EXIT_FAILURE, 0,
1048 gettext ("while create section header section: %s"),
1049 elf_errmsg (-1));
1050 assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
1051
1052 /* Finalize the string table and fill in the correct indices in the
1053 section headers. */
1054 shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
1055 if (shstrtab_data == NULL)
1056 error (EXIT_FAILURE, 0,
1057 gettext ("while create section header string table: %s"),
1058 elf_errmsg (-1));
1059 ebl_strtabfinalize (shst, shstrtab_data);
1060
1061 /* We have to set the section size. */
1062 shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
1063
1064 /* Update the section information. */
1065 GElf_Off lastoffset = 0;
1066 for (cnt = 1; cnt <= shdridx; ++cnt)
1067 if (shdr_info[cnt].idx > 0)
1068 {
1069 Elf_Data *newdata;
1070
1071 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1072 assert (scn != NULL);
1073
1074 /* Update the name. */
1075 shdr_info[cnt].shdr.sh_name = ebl_strtaboffset (shdr_info[cnt].se);
1076
1077 /* Update the section header from the input file. Some fields
1078 might be section indeces which now have to be adjusted. */
1079 if (shdr_info[cnt].shdr.sh_link != 0)
1080 shdr_info[cnt].shdr.sh_link =
1081 shdr_info[shdr_info[cnt].shdr.sh_link].idx;
1082
1083 if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
1084 {
1085 assert (shdr_info[cnt].data != NULL);
1086
1087 Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
1088 for (size_t inner = 0;
1089 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
1090 ++inner)
1091 grpref[inner] = shdr_info[grpref[inner]].idx;
1092 }
1093
1094 /* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag. */
1095 if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
1096 shdr_info[cnt].shdr.sh_info =
1097 shdr_info[shdr_info[cnt].shdr.sh_info].idx;
1098
1099 /* Get the data from the old file if necessary. We already
1100 created the data for the section header string table. */
1101 if (cnt < shnum)
1102 {
1103 if (shdr_info[cnt].data == NULL)
1104 {
1105 shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
1106 if (shdr_info[cnt].data == NULL)
1107 INTERNAL_ERROR (fname);
1108 }
1109
1110 /* Set the data. This is done by copying from the old file. */
1111 newdata = elf_newdata (scn);
1112 if (newdata == NULL)
1113 INTERNAL_ERROR (fname);
1114
1115 /* Copy the structure. */
1116 *newdata = *shdr_info[cnt].data;
1117
1118 /* We know the size. */
1119 shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
1120
1121 /* We have to adjust symbol tables. The st_shndx member might
1122 have to be updated. */
1123 if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
1124 || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
1125 {
1126 Elf_Data *versiondata = NULL;
1127 Elf_Data *shndxdata = NULL;
1128
1129 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1130 ehdr->e_version);
1131
1132 if (shdr_info[cnt].symtab_idx != 0)
1133 {
1134 assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
1135 /* This section has extended section information.
1136 We have to modify that information, too. */
1137 shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
1138 NULL);
1139
1140 assert ((versiondata->d_size / sizeof (Elf32_Word))
1141 >= shdr_info[cnt].data->d_size / elsize);
1142 }
1143
1144 if (shdr_info[cnt].version_idx != 0)
1145 {
1146 assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
1147 /* This section has associated version
1148 information. We have to modify that
1149 information, too. */
1150 versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
1151 NULL);
1152
1153 assert ((versiondata->d_size / sizeof (GElf_Versym))
1154 >= shdr_info[cnt].data->d_size / elsize);
1155 }
1156
1157 shdr_info[cnt].newsymidx
1158 = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
1159 / elsize, sizeof (Elf32_Word));
1160
1161 bool last_was_local = true;
1162 size_t destidx;
1163 size_t inner;
1164 for (destidx = inner = 1;
1165 inner < shdr_info[cnt].data->d_size / elsize;
1166 ++inner)
1167 {
1168 Elf32_Word sec;
1169 GElf_Sym sym_mem;
1170 Elf32_Word xshndx;
1171 GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
1172 shndxdata, inner,
1173 &sym_mem, &xshndx);
1174 if (sym == NULL)
1175 INTERNAL_ERROR (fname);
1176
1177 if (sym->st_shndx == SHN_UNDEF
1178 || (sym->st_shndx >= shnum
1179 && sym->st_shndx != SHN_XINDEX))
1180 {
1181 /* This is no section index, leave it alone
1182 unless it is moved. */
1183 if (destidx != inner
1184 && gelf_update_symshndx (shdr_info[cnt].data,
1185 shndxdata,
1186 destidx, sym,
1187 xshndx) == 0)
1188 INTERNAL_ERROR (fname);
1189
1190 shdr_info[cnt].newsymidx[inner] = destidx++;
1191
1192 if (last_was_local
1193 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1194 {
1195 last_was_local = false;
1196 shdr_info[cnt].shdr.sh_info = destidx - 1;
1197 }
1198
1199 continue;
1200 }
1201
1202 /* Get the full section index, if necessary from the
1203 XINDEX table. */
1204 if (sym->st_shndx != SHN_XINDEX)
1205 sec = shdr_info[sym->st_shndx].idx;
1206 else
1207 {
1208 assert (shndxdata != NULL);
1209
1210 sec = shdr_info[xshndx].idx;
1211 }
1212
1213 if (sec != 0)
1214 {
1215 GElf_Section nshndx;
1216 Elf32_Word nxshndx;
1217
1218 if (sec < SHN_LORESERVE)
1219 {
1220 nshndx = sec;
1221 nxshndx = 0;
1222 }
1223 else
1224 {
1225 nshndx = SHN_XINDEX;
1226 nxshndx = sec;
1227 }
1228
1229 assert (sec < SHN_LORESERVE || shndxdata != NULL);
1230
1231 if ((inner != destidx || nshndx != sym->st_shndx
1232 || (shndxdata != NULL && nxshndx != xshndx))
1233 && (sym->st_shndx = nshndx,
1234 gelf_update_symshndx (shdr_info[cnt].data,
1235 shndxdata,
1236 destidx, sym,
1237 nxshndx) == 0))
1238 INTERNAL_ERROR (fname);
1239
1240 shdr_info[cnt].newsymidx[inner] = destidx++;
1241
1242 if (last_was_local
1243 && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
1244 {
1245 last_was_local = false;
1246 shdr_info[cnt].shdr.sh_info = destidx - 1;
1247 }
1248 }
1249 else if (debug_fname == NULL
1250 || shdr_info[cnt].debug_data == NULL)
1251 /* This is a section symbol for a section which has
1252 been removed. */
1253 assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION);
1254 }
1255
1256 if (destidx != inner)
1257 {
1258 /* The size of the symbol table changed. */
1259 shdr_info[cnt].shdr.sh_size = newdata->d_size
1260 = destidx * elsize;
1261 any_symtab_changes = true;
1262 }
1263 else
1264 {
1265 /* The symbol table didn't really change. */
1266 free (shdr_info[cnt].newsymidx);
1267 shdr_info[cnt].newsymidx = NULL;
1268 }
1269 }
1270 }
1271
1272 /* If we have to, compute the offset of the section. */
1273 if (shdr_info[cnt].shdr.sh_offset == 0)
1274 shdr_info[cnt].shdr.sh_offset
1275 = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
1276 & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
1277
1278 /* Set the section header in the new file. */
1279 if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
1280 /* There cannot be any overflows. */
1281 INTERNAL_ERROR (fname);
1282
1283 /* Remember the last section written so far. */
1284 GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
1285 ? shdr_info[cnt].shdr.sh_size : 0);
1286 if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
1287 lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
1288 }
1289
1290 /* Adjust symbol references if symbol tables changed. */
1291 if (any_symtab_changes)
1292 /* Find all relocation sections which use this symbol table. */
1293 for (cnt = 1; cnt <= shdridx; ++cnt)
1294 {
1295 /* Update section headers when the data size has changed.
1296 We also update the SHT_NOBITS section in the debug
1297 file so that the section headers match in sh_size. */
1298 inline void update_section_size (const Elf_Data *newdata)
1299 {
1300 GElf_Shdr shdr_mem;
1301 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1302 shdr->sh_size = newdata->d_size;
1303 (void) gelf_update_shdr (scn, shdr);
1304 if (debugelf != NULL)
1305 {
1306 /* libelf will use d_size to set sh_size. */
1307 Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
1308 cnt), NULL);
1309 debugdata->d_size = newdata->d_size;
1310 }
1311 }
1312
1313 if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
1314 /* Ignore sections which are discarded. When we are saving a
1315 relocation section in a separate debug file, we must fix up
1316 the symbol table references. */
1317 continue;
1318
1319 const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
1320 const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
1321 switch (shdr_info[cnt].shdr.sh_type)
1322 {
1323 inline bool no_symtab_updates (void)
1324 {
1325 /* If the symbol table hasn't changed, do not do anything. */
1326 if (shdr_info[symtabidx].newsymidx == NULL)
1327 return true;
1328
1329 /* If the symbol table is not discarded, but additionally
1330 duplicated in the separate debug file and this section
1331 is discarded, don't adjust anything. */
1332 return (shdr_info[cnt].idx == 0
1333 && shdr_info[symtabidx].debug_data != NULL);
1334 }
1335
1336 case SHT_REL:
1337 case SHT_RELA:
1338 if (no_symtab_updates ())
1339 break;
1340
1341 Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
1342 ? elf_getscn (debugelf, cnt)
1343 : elf_getscn (newelf,
1344 shdr_info[cnt].idx),
1345 NULL);
1346 assert (d != NULL);
1347 size_t nrels = (shdr_info[cnt].shdr.sh_size
1348 / shdr_info[cnt].shdr.sh_entsize);
1349
1350 if (shdr_info[cnt].shdr.sh_type == SHT_REL)
1351 for (size_t relidx = 0; relidx < nrels; ++relidx)
1352 {
1353 GElf_Rel rel_mem;
1354 if (gelf_getrel (d, relidx, &rel_mem) == NULL)
1355 INTERNAL_ERROR (fname);
1356
1357 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1358 if (newsymidx[symidx] != symidx)
1359 {
1360 rel_mem.r_info
1361 = GELF_R_INFO (newsymidx[symidx],
1362 GELF_R_TYPE (rel_mem.r_info));
1363
1364 if (gelf_update_rel (d, relidx, &rel_mem) == 0)
1365 INTERNAL_ERROR (fname);
1366 }
1367 }
1368 else
1369 for (size_t relidx = 0; relidx < nrels; ++relidx)
1370 {
1371 GElf_Rela rel_mem;
1372 if (gelf_getrela (d, relidx, &rel_mem) == NULL)
1373 INTERNAL_ERROR (fname);
1374
1375 size_t symidx = GELF_R_SYM (rel_mem.r_info);
1376 if (newsymidx[symidx] != symidx)
1377 {
1378 rel_mem.r_info
1379 = GELF_R_INFO (newsymidx[symidx],
1380 GELF_R_TYPE (rel_mem.r_info));
1381
1382 if (gelf_update_rela (d, relidx, &rel_mem) == 0)
1383 INTERNAL_ERROR (fname);
1384 }
1385 }
1386 break;
1387
1388 case SHT_HASH:
1389 if (no_symtab_updates ())
1390 break;
1391
1392 /* We have to recompute the hash table. */
1393
1394 assert (shdr_info[cnt].idx > 0);
1395
1396 /* The hash section in the new file. */
1397 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1398
1399 /* The symbol table data. */
1400 Elf_Data *symd = elf_getdata (elf_getscn (newelf,
1401 shdr_info[symtabidx].idx),
1402 NULL);
1403 assert (symd != NULL);
1404
1405 /* The hash table data. */
1406 Elf_Data *hashd = elf_getdata (scn, NULL);
1407 assert (hashd != NULL);
1408
1409 if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
1410 {
1411 /* Sane arches first. */
1412 Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
1413
1414 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1415 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1416 ehdr->e_version);
1417
1418 /* Adjust the nchain value. The symbol table size
1419 changed. We keep the same size for the bucket array. */
1420 bucket[1] = symd->d_size / elsize;
1421 Elf32_Word nbucket = bucket[0];
1422 bucket += 2;
1423 Elf32_Word *chain = bucket + nbucket;
1424
1425 /* New size of the section. */
1426 hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
1427 * sizeof (Elf32_Word));
1428 update_section_size (hashd);
1429
1430 /* Clear the arrays. */
1431 memset (bucket, '\0',
1432 (symd->d_size / elsize + nbucket)
1433 * sizeof (Elf32_Word));
1434
1435 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1436 inner < symd->d_size / elsize; ++inner)
1437 {
1438 GElf_Sym sym_mem;
1439 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1440 assert (sym != NULL);
1441
1442 const char *name = elf_strptr (elf, strshndx,
1443 sym->st_name);
1444 assert (name != NULL);
1445 size_t hidx = elf_hash (name) % nbucket;
1446
1447 if (bucket[hidx] == 0)
1448 bucket[hidx] = inner;
1449 else
1450 {
1451 hidx = bucket[hidx];
1452
1453 while (chain[hidx] != 0)
1454 hidx = chain[hidx];
1455
1456 chain[hidx] = inner;
1457 }
1458 }
1459 }
1460 else
1461 {
1462 /* Alpha and S390 64-bit use 64-bit SHT_HASH entries. */
1463 assert (shdr_info[cnt].shdr.sh_entsize
1464 == sizeof (Elf64_Xword));
1465
1466 Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
1467
1468 size_t strshndx = shdr_info[symtabidx].old_sh_link;
1469 size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1,
1470 ehdr->e_version);
1471
1472 /* Adjust the nchain value. The symbol table size
1473 changed. We keep the same size for the bucket array. */
1474 bucket[1] = symd->d_size / elsize;
1475 Elf64_Xword nbucket = bucket[0];
1476 bucket += 2;
1477 Elf64_Xword *chain = bucket + nbucket;
1478
1479 /* New size of the section. */
1480 hashd->d_size = ((2 + symd->d_size / elsize + nbucket)
1481 * sizeof (Elf64_Xword));
1482 update_section_size (hashd);
1483
1484 /* Clear the arrays. */
1485 memset (bucket, '\0',
1486 (symd->d_size / elsize + nbucket)
1487 * sizeof (Elf64_Xword));
1488
1489 for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
1490 inner < symd->d_size / elsize; ++inner)
1491 {
1492 GElf_Sym sym_mem;
1493 GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
1494 assert (sym != NULL);
1495
1496 const char *name = elf_strptr (elf, strshndx,
1497 sym->st_name);
1498 assert (name != NULL);
1499 size_t hidx = elf_hash (name) % nbucket;
1500
1501 if (bucket[hidx] == 0)
1502 bucket[hidx] = inner;
1503 else
1504 {
1505 hidx = bucket[hidx];
1506
1507 while (chain[hidx] != 0)
1508 hidx = chain[hidx];
1509
1510 chain[hidx] = inner;
1511 }
1512 }
1513 }
1514 break;
1515
1516 case SHT_GNU_versym:
1517 /* If the symbol table changed we have to adjust the entries. */
1518 if (no_symtab_updates ())
1519 break;
1520
1521 assert (shdr_info[cnt].idx > 0);
1522
1523 /* The symbol version section in the new file. */
1524 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1525
1526 /* The symbol table data. */
1527 symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
1528 NULL);
1529 assert (symd != NULL);
1530
1531 /* The version symbol data. */
1532 Elf_Data *verd = elf_getdata (scn, NULL);
1533 assert (verd != NULL);
1534
1535 /* The symbol version array. */
1536 GElf_Half *verstab = (GElf_Half *) verd->d_buf;
1537
1538 /* Walk through the list and */
1539 size_t elsize = gelf_fsize (elf, verd->d_type, 1,
1540 ehdr->e_version);
1541 for (size_t inner = 1; inner < verd->d_size / elsize; ++inner)
1542 if (newsymidx[inner] != 0)
1543 /* Overwriting the same array works since the
1544 reordering can only move entries to lower indices
1545 in the array. */
1546 verstab[newsymidx[inner]] = verstab[inner];
1547
1548 /* New size of the section. */
1549 verd->d_size = gelf_fsize (newelf, verd->d_type,
1550 symd->d_size
1551 / gelf_fsize (elf, symd->d_type, 1,
1552 ehdr->e_version),
1553 ehdr->e_version);
1554 update_section_size (verd);
1555 break;
1556
1557 case SHT_GROUP:
1558 if (no_symtab_updates ())
1559 break;
1560
1561 /* Yes, the symbol table changed.
1562 Update the section header of the section group. */
1563 scn = elf_getscn (newelf, shdr_info[cnt].idx);
1564 GElf_Shdr shdr_mem;
1565 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
1566 assert (shdr != NULL);
1567
1568 shdr->sh_info = newsymidx[shdr->sh_info];
1569
1570 (void) gelf_update_shdr (scn, shdr);
1571 break;
1572 }
1573 }
1574
1575 /* Now that we have done all adjustments to the data,
1576 we can actually write out the debug file. */
1577 if (debug_fname != NULL)
1578 {
1579 uint32_t debug_crc;
1580 Elf_Data debug_crc_data =
1581 {
1582 .d_type = ELF_T_WORD,
1583 .d_buf = &debug_crc,
1584 .d_size = sizeof (debug_crc),
1585 .d_version = EV_CURRENT
1586 };
1587
1588 /* Finally write the file. */
1589 if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
1590 {
1591 error (0, 0, gettext ("while writing '%s': %s"),
1592 debug_fname, elf_errmsg (-1));
1593 result = 1;
1594 goto fail_close;
1595 }
1596
1597 /* Create the real output file. First rename, then change the
1598 mode. */
1599 if (rename (tmp_debug_fname, debug_fname) != 0
1600 || fchmod (debug_fd, mode) != 0)
1601 {
1602 error (0, errno, gettext ("while creating '%s'"), debug_fname);
1603 result = 1;
1604 goto fail_close;
1605 }
1606
1607 /* The temporary file does not exist anymore. */
1608 tmp_debug_fname = NULL;
1609
1610 /* Compute the checksum which we will add to the executable. */
1611 if (crc32_file (debug_fd, &debug_crc) != 0)
1612 {
1613 error (0, errno,
1614 gettext ("while computing checksum for debug information"));
1615 unlink (debug_fname);
1616 result = 1;
1617 goto fail_close;
1618 }
1619
1620 /* Store it in the debuglink section data. */
1621 if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
1622 &debug_crc_data, ehdr->e_ident[EI_DATA])
1623 != &debuglink_crc_data))
1624 INTERNAL_ERROR (fname);
1625 }
1626
1627 /* Finally finish the ELF header. Fill in the fields not handled by
1628 libelf from the old file. */
1629 newehdr = gelf_getehdr (newelf, &newehdr_mem);
1630 if (newehdr == NULL)
1631 INTERNAL_ERROR (fname);
1632
1633 memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
1634 newehdr->e_type = ehdr->e_type;
1635 newehdr->e_machine = ehdr->e_machine;
1636 newehdr->e_version = ehdr->e_version;
1637 newehdr->e_entry = ehdr->e_entry;
1638 newehdr->e_flags = ehdr->e_flags;
1639 newehdr->e_phoff = ehdr->e_phoff;
1640 /* We need to position the section header table. */
1641 const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
1642 newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
1643 + shdr_info[shdridx].shdr.sh_size + offsize - 1)
1644 & ~((GElf_Off) (offsize - 1)));
1645 newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
1646
1647 /* The new section header string table index. */
1648 if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
1649 newehdr->e_shstrndx = idx;
1650 else
1651 {
1652 /* The index does not fit in the ELF header field. */
1653 shdr_info[0].scn = elf_getscn (elf, 0);
1654
1655 if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
1656 INTERNAL_ERROR (fname);
1657
1658 shdr_info[0].shdr.sh_link = idx;
1659 (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
1660
1661 newehdr->e_shstrndx = SHN_XINDEX;
1662 }
1663
1664 if (gelf_update_ehdr (newelf, newehdr) == 0)
1665 {
1666 error (0, 0, gettext ("%s: error while creating ELF header: %s"),
1667 fname, elf_errmsg (-1));
1668 return 1;
1669 }
1670
1671 /* We have everything from the old file. */
1672 if (elf_cntl (elf, ELF_C_FDDONE) != 0)
1673 {
1674 error (0, 0, gettext ("%s: error while reading the file: %s"),
1675 fname, elf_errmsg (-1));
1676 return 1;
1677 }
1678
1679 /* The ELF library better follows our layout when this is not a
1680 relocatable object file. */
1681 elf_flagelf (newelf, ELF_C_SET,
1682 (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
1683 | (permissive ? ELF_F_PERMISSIVE : 0));
1684
1685 /* Finally write the file. */
1686 if (elf_update (newelf, ELF_C_WRITE) == -1)
1687 {
1688 error (0, 0, gettext ("while writing '%s': %s"),
1689 fname, elf_errmsg (-1));
1690 result = 1;
1691 }
1692
1693 fail_close:
1694 if (shdr_info != NULL)
1695 {
1696 /* For some sections we might have created an table to map symbol
1697 table indices. */
1698 if (any_symtab_changes)
1699 for (cnt = 1; cnt <= shdridx; ++cnt)
1700 {
1701 free (shdr_info[cnt].newsymidx);
1702 if (shdr_info[cnt].debug_data != NULL)
1703 free (shdr_info[cnt].debug_data->d_buf);
1704 }
1705
1706 /* Free the memory. */
1707 if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
1708 free (shdr_info);
1709 }
1710
1711 /* Free other resources. */
1712 if (shstrtab_data != NULL)
1713 free (shstrtab_data->d_buf);
1714 if (shst != NULL)
1715 ebl_strtabfree (shst);
1716
1717 /* That was it. Close the descriptors. */
1718 if (elf_end (newelf) != 0)
1719 {
1720 error (0, 0, gettext ("error while finishing '%s': %s"), fname,
1721 elf_errmsg (-1));
1722 result = 1;
1723 }
1724
1725 if (debugelf != NULL && elf_end (debugelf) != 0)
1726 {
1727 error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
1728 elf_errmsg (-1));
1729 result = 1;
1730 }
1731
1732 fail:
1733 /* Close the EBL backend. */
1734 if (ebl != NULL)
1735 ebl_closebackend (ebl);
1736
1737 /* Close debug file descriptor, if opened */
1738 if (debug_fd >= 0)
1739 {
1740 if (tmp_debug_fname != NULL)
1741 unlink (tmp_debug_fname);
1742 close (debug_fd);
1743 }
1744
1745 /* If requested, preserve the timestamp. */
1746 if (tvp != NULL)
1747 {
1748 if (futimes (fd, tvp) != 0)
1749 {
1750 error (0, errno, gettext ("\
1751 cannot set access and modification date of '%s'"),
1752 output_fname ?: fname);
1753 result = 1;
1754 }
1755 }
1756
1757 /* Close the file descriptor if we created a new file. */
1758 if (output_fname != NULL)
1759 close (fd);
1760
1761 return result;
1762 }
1763
1764
1765 static int
handle_ar(int fd,Elf * elf,const char * prefix,const char * fname,struct timeval tvp[2])1766 handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
1767 struct timeval tvp[2])
1768 {
1769 size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
1770 size_t fname_len = strlen (fname) + 1;
1771 char new_prefix[prefix_len + 1 + fname_len];
1772 char *cp = new_prefix;
1773
1774 /* Create the full name of the file. */
1775 if (prefix != NULL)
1776 {
1777 cp = mempcpy (cp, prefix, prefix_len);
1778 *cp++ = ':';
1779 }
1780 memcpy (cp, fname, fname_len);
1781
1782
1783 /* Process all the files contained in the archive. */
1784 Elf *subelf;
1785 Elf_Cmd cmd = ELF_C_RDWR;
1786 int result = 0;
1787 while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
1788 {
1789 /* The the header for this element. */
1790 Elf_Arhdr *arhdr = elf_getarhdr (subelf);
1791
1792 if (elf_kind (subelf) == ELF_K_ELF)
1793 result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
1794 else if (elf_kind (subelf) == ELF_K_AR)
1795 result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
1796
1797 /* Get next archive element. */
1798 cmd = elf_next (subelf);
1799 if (unlikely (elf_end (subelf) != 0))
1800 INTERNAL_ERROR (fname);
1801 }
1802
1803 if (tvp != NULL)
1804 {
1805 if (unlikely (futimes (fd, tvp) != 0))
1806 {
1807 error (0, errno, gettext ("\
1808 cannot set access and modification date of '%s'"), fname);
1809 result = 1;
1810 }
1811 }
1812
1813 if (unlikely (close (fd) != 0))
1814 error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
1815
1816 return result;
1817 }
1818
1819
1820 #include "debugpred.h"
1821