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