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