1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 static void setup_section ();
26 static void copy_section ();
27 static void mark_symbols_used_in_relocations ();
29 #define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
31 static asymbol **isympp = NULL; /* Input symbols */
32 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
34 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
35 static int copy_byte = -1;
36 static int interleave = 4;
38 static boolean verbose; /* Print file and target names. */
39 static int status = 0; /* Exit status. */
44 strip_none, /* don't strip */
45 strip_debug, /* strip all debugger symbols */
46 strip_all /* strip all symbols */
49 /* Which symbols to remove. */
50 static enum strip_action strip_symbols;
55 locals_start_L, /* discard locals starting with L */
56 locals_all /* discard all locals */
59 /* Which local symbols to remove. Overrides strip_all. */
60 static enum locals_action discard_locals;
62 /* Options to handle if running as "strip". */
64 static struct option strip_options[] =
66 {"discard-all", no_argument, 0, 'x'},
67 {"discard-locals", no_argument, 0, 'X'},
68 {"format", required_argument, 0, 'F'}, /* Obsolete */
69 {"help", no_argument, 0, 'h'},
70 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
71 {"input-target", required_argument, 0, 'I'},
72 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
73 {"output-target", required_argument, 0, 'O'},
74 {"strip-all", no_argument, 0, 's'},
75 {"strip-debug", no_argument, 0, 'S'},
76 {"target", required_argument, 0, 'F'},
77 {"verbose", no_argument, 0, 'v'},
78 {"version", no_argument, 0, 'V'},
79 {0, no_argument, 0, 0}
82 /* Options to handle if running as "objcopy". */
84 static struct option copy_options[] =
86 {"byte", required_argument, 0, 'b'},
87 {"discard-all", no_argument, 0, 'x'},
88 {"discard-locals", no_argument, 0, 'X'},
89 {"format", required_argument, 0, 'F'}, /* Obsolete */
90 {"help", no_argument, 0, 'h'},
91 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
92 {"input-target", required_argument, 0, 'I'},
93 {"interleave", required_argument, 0, 'i'},
94 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
95 {"output-target", required_argument, 0, 'O'},
96 {"strip-all", no_argument, 0, 'S'},
97 {"strip-debug", no_argument, 0, 'g'},
98 {"target", required_argument, 0, 'F'},
99 {"verbose", no_argument, 0, 'v'},
100 {"version", no_argument, 0, 'V'},
101 {0, no_argument, 0, 0}
105 extern char *program_name;
106 extern char *program_version;
108 /* This flag distinguishes between strip and objcopy:
109 1 means this is 'strip'; 0 means this is 'objcopy'.
110 -1 means if we should use argv[0] to decide. */
115 copy_usage (stream, status)
120 Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
121 [-i interleave] [--interleave=interleave] [--byte=byte]\n\
122 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
123 [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
124 [--verbose] [--version] [--help] in-file [out-file]\n",
130 strip_usage (stream, status)
135 Usage: %s [-vVsSgxX] [-I bfdname] [-O bfdname] [-F bfdname]\n\
136 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
137 [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
138 [--verbose] [--version] [--help] file...\n",
144 /* Return the name of a temporary file in the same directory as FILENAME. */
147 make_tempname (filename)
150 static char template[] = "stXXXXXX";
152 char *slash = strrchr (filename, '/');
154 if (slash != (char *) NULL)
157 tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
158 strcpy (tmpname, filename);
159 strcat (tmpname, "/");
160 strcat (tmpname, template);
166 tmpname = xmalloc (sizeof (template));
167 strcpy (tmpname, template);
173 /* Choose which symbol entries to copy; put the result in OSYMS.
174 We don't copy in place, because that confuses the relocs.
175 Return the number of symbols to print. */
178 filter_symbols (abfd, osyms, isyms, symcount)
180 asymbol **osyms, **isyms;
181 unsigned long symcount;
183 register asymbol **from = isyms, **to = osyms;
184 unsigned int src_count = 0, dst_count = 0;
186 for (; src_count < symcount; src_count++)
188 asymbol *sym = from[src_count];
189 flagword flags = sym->flags;
192 if ((flags & BSF_GLOBAL) /* Keep if external. */
193 || (flags & BSF_KEEP) /* Keep if used in a relocation. */
194 || bfd_get_section (sym) == &bfd_und_section
195 || bfd_is_com_section (bfd_get_section (sym)))
197 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
198 keep = strip_symbols != strip_debug;
199 else /* Local symbol. */
200 keep = discard_locals != locals_all
201 && (discard_locals != locals_start_L ||
202 ! bfd_is_local_label (abfd, sym));
204 to[dst_count++] = sym;
210 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
214 filter_bytes (memhunk, size)
218 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
220 for (; from < end; from += interleave)
225 /* Copy object file IBFD onto OBFD. */
228 copy_object (ibfd, obfd)
232 unsigned int symcount;
234 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
236 nonfatal (bfd_get_filename (obfd));
240 printf ("copy from %s(%s) to %s(%s)\n",
241 bfd_get_filename(ibfd), bfd_get_target(ibfd),
242 bfd_get_filename(obfd), bfd_get_target(obfd));
244 if (!bfd_set_start_address (obfd, bfd_get_start_address (ibfd))
245 || !bfd_set_file_flags (obfd,
246 (bfd_get_file_flags (ibfd)
247 & bfd_applicable_file_flags (obfd))))
249 nonfatal (bfd_get_filename (ibfd));
252 /* Copy architecture of input file to output file */
253 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
254 bfd_get_mach (ibfd)))
256 fprintf (stderr, "Output file cannot represent architecture %s\n",
257 bfd_printable_arch_mach (bfd_get_arch (ibfd),
258 bfd_get_mach (ibfd)));
260 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
262 nonfatal (bfd_get_filename(ibfd));
267 if (osympp != isympp)
270 /* Allow the BFD backend to copy any private data it understands
271 from the input BFD to the output BFD. */
272 if (!bfd_copy_private_bfd_data (ibfd, obfd))
274 fprintf (stderr, "%s: %s: error copying private BFD data: %s\n",
275 program_name, bfd_errmsg (bfd_get_error ()));
280 /* bfd mandates that all output sections be created and sizes set before
281 any output is done. Thus, we traverse all sections multiple times. */
282 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
284 /* Symbol filtering must happen after the output sections have
285 been created, but before their contents are set. */
286 if (strip_symbols == strip_all && discard_locals == locals_undef)
288 osympp = isympp = NULL;
293 osympp = isympp = (asymbol **) xmalloc (get_symtab_upper_bound (ibfd));
294 symcount = bfd_canonicalize_symtab (ibfd, isympp);
296 if (strip_symbols == strip_debug || discard_locals != locals_undef)
298 /* Mark symbols used in output relocations so that they
299 are kept, even if they are local labels or static symbols.
301 Note we iterate over the input sections examining their
302 relocations since the relocations for the output sections
303 haven't been set yet. mark_symbols_used_in_relocations will
304 ignore input sections which have no corresponding output
306 bfd_map_over_sections (ibfd,
307 mark_symbols_used_in_relocations,
309 osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
310 symcount = filter_symbols (ibfd, osympp, isympp, symcount);
314 bfd_set_symtab (obfd, osympp, symcount);
316 /* This has to happen after the symbol table has been set. */
317 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
326 size_t size = strlen (a) + strlen (b) + strlen (c);
327 char *r = xmalloc (size + 1);
335 /* Read each archive element in turn from IBFD, copy the
336 contents to temp file, and keep the temp file handle. */
339 copy_archive (ibfd, obfd, output_target)
344 bfd **ptr = &obfd->archive_head;
346 char *dir = cat ("./#", make_tempname (""), "cd");
348 /* Make a temp directory to hold the contents. */
350 obfd->has_armap = ibfd->has_armap;
352 this_element = bfd_openr_next_archived_file (ibfd, NULL);
353 ibfd->archive_head = this_element;
354 while (this_element != (bfd *) NULL)
356 /* Create an output file for this member. */
357 char *output_name = cat (dir, "/", bfd_get_filename(this_element));
358 bfd *output_bfd = bfd_openw (output_name, output_target);
360 if (output_bfd == (bfd *) NULL)
362 nonfatal (output_name);
364 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
366 nonfatal (bfd_get_filename (obfd));
369 if (bfd_check_format (this_element, bfd_object) == true)
371 copy_object (this_element, output_bfd);
374 bfd_close (output_bfd);
375 /* Open the newly output file and attatch to our list. */
376 output_bfd = bfd_openr (output_name, output_target);
378 /* Mark it for deletion. */
380 ptr = &output_bfd->next;
381 this_element->next = bfd_openr_next_archived_file (ibfd, this_element);
382 this_element = this_element->next;
386 if (!bfd_close (obfd))
388 nonfatal (bfd_get_filename (obfd));
391 /* Delete all the files that we opened.
392 Construct their names again, unfortunately, but
393 we're about to exit anyway. */
394 for (this_element = ibfd->archive_head;
395 this_element != (bfd *) NULL;
396 this_element = this_element->next)
398 unlink (cat (dir, "/", bfd_get_filename (this_element)));
401 if (!bfd_close (ibfd))
403 nonfatal (bfd_get_filename (ibfd));
407 /* The top-level control. */
410 copy_file (input_filename, output_filename, input_target, output_target)
411 char *input_filename;
412 char *output_filename;
419 /* To allow us to do "strip *" without dying on the first
420 non-object file, failures are nonfatal. */
422 ibfd = bfd_openr (input_filename, input_target);
425 nonfatal (input_filename);
428 if (bfd_check_format (ibfd, bfd_archive))
430 bfd *obfd = bfd_openw (output_filename, output_target);
433 nonfatal (output_filename);
435 copy_archive (ibfd, obfd, output_target);
437 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
439 bfd *obfd = bfd_openw (output_filename, output_target);
442 nonfatal (output_filename);
445 copy_object (ibfd, obfd);
447 if (!bfd_close (obfd))
449 nonfatal (output_filename);
452 if (!bfd_close (ibfd))
454 nonfatal (input_filename);
459 bfd_nonfatal (input_filename);
460 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
462 list_matching_formats (matching);
469 /* Create a section in OBFD with the same name and attributes
470 as ISECTION in IBFD. */
473 setup_section (ibfd, isection, obfd)
481 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
482 && (strip_symbols == strip_debug
483 || strip_symbols == strip_all
484 || discard_locals == locals_all))
487 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
488 if (osection == NULL)
494 if (!bfd_set_section_size (obfd,
496 bfd_section_size (ibfd, isection)))
502 if (bfd_set_section_vma (obfd,
504 bfd_section_vma (ibfd, isection))
511 if (bfd_set_section_alignment (obfd,
513 bfd_section_alignment (ibfd, isection))
520 if (!bfd_set_section_flags (obfd, osection,
521 bfd_get_section_flags (ibfd, isection)))
527 /* This used to be mangle_section; we do here to avoid using
528 bfd_get_section_by_name since some formats allow multiple
529 sections with the same name. */
530 isection->output_section = osection;
531 isection->output_offset = 0;
533 /* Allow the BFD backend to copy any private data it understands
534 from the input section to the output section. */
535 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
537 err = "private data";
545 fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
547 bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
548 err, bfd_errmsg (bfd_get_error ()));
552 /* Copy the data of input section ISECTION of IBFD
553 to an output section with the same name in OBFD.
554 If stripping then don't copy any relocation info. */
557 copy_section (ibfd, isection, obfd)
567 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
568 && (strip_symbols == strip_debug
569 || strip_symbols == strip_all
570 || discard_locals == locals_all))
575 osection = isection->output_section;
576 size = bfd_get_section_size_before_reloc (isection);
578 if (size == 0 || osection == 0)
581 if (strip_symbols == strip_all
582 || bfd_get_reloc_upper_bound (ibfd, isection) == 0)
584 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
588 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (ibfd, isection));
589 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
590 bfd_set_reloc (obfd, osection, relpp, relcount);
593 isection->_cooked_size = isection->_raw_size;
594 isection->reloc_done = true;
596 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
598 PTR memhunk = (PTR) xmalloc ((unsigned) size);
600 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
603 nonfatal (bfd_get_filename (ibfd));
607 filter_bytes (memhunk, &size);
609 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
612 nonfatal (bfd_get_filename (obfd));
618 /* Mark all the symbols which will be used in output relocations with
619 the BSF_KEEP flag so that those symbols will not be stripped.
621 Ignore relocations which will not appear in the output file. */
624 mark_symbols_used_in_relocations (ibfd, isection, symbols)
630 unsigned int relcount, i;
632 /* Ignore an input section with no corresponding output section. */
633 if (isection->output_section == NULL)
636 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (ibfd, isection));
637 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
639 /* Examine each symbol used in a relocation. If it's not one of the
640 special bfd section symbols, then mark it with BSF_KEEP. */
641 for (i = 0; i < relcount; i++)
643 if (*relpp[i]->sym_ptr_ptr != bfd_com_section.symbol
644 && *relpp[i]->sym_ptr_ptr != bfd_abs_section.symbol
645 && *relpp[i]->sym_ptr_ptr != bfd_und_section.symbol)
646 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
653 /* The number of bytes to copy at once. */
654 #define COPY_BUF 8192
656 /* Copy file FROM to file TO, performing no translations.
657 Return 0 if ok, -1 if error. */
660 simple_copy (from, to)
663 int fromfd, tofd, nread;
666 fromfd = open (from, O_RDONLY);
669 tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
675 while ((nread = read (fromfd, buf, sizeof buf)) > 0)
677 if (write (tofd, buf, nread) != nread)
693 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
700 /* Rename FROM to TO, copying if TO is a link.
701 Assumes that TO already exists, because FROM is a temp file.
702 Return 0 if ok, -1 if error. */
705 smart_rename (from, to)
714 /* Use rename only if TO is not a symbolic link and has
715 only one hard link. */
716 if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
718 ret = rename (from, to);
721 /* Try to preserve the permission bits and ownership of TO. */
722 chmod (to, s.st_mode & 07777);
723 chown (to, s.st_uid, s.st_gid);
728 ret = simple_copy (from, to);
736 strip_main (argc, argv)
740 char *input_target = NULL, *output_target = NULL;
741 boolean show_version = false;
744 while ((c = getopt_long (argc, argv, "I:O:F:sSgxXVv",
745 strip_options, (int *) 0)) != EOF)
750 input_target = optarg;
753 output_target = optarg;
756 input_target = output_target = optarg;
759 strip_symbols = strip_all;
763 strip_symbols = strip_debug;
766 discard_locals = locals_all;
769 discard_locals = locals_start_L;
778 break; /* we've been given a long option */
780 strip_usage (stdout, 0);
782 strip_usage (stderr, 1);
788 printf ("GNU %s version %s\n", program_name, program_version);
792 /* Default is to strip all symbols. */
793 if (strip_symbols == strip_undef && discard_locals == locals_undef)
794 strip_symbols = strip_all;
796 if (output_target == (char *) NULL)
797 output_target = input_target;
801 strip_usage (stderr, 1);
803 for (; i < argc; i++)
805 int hold_status = status;
807 char *tmpname = make_tempname (argv[i]);
809 copy_file (argv[i], tmpname, input_target, output_target);
812 smart_rename (tmpname, argv[i]);
813 status = hold_status;
824 copy_main (argc, argv)
828 char *input_filename, *output_filename;
829 char *input_target = NULL, *output_target = NULL;
830 boolean show_version = false;
833 while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
834 copy_options, (int *) 0)) != EOF)
839 copy_byte = atoi(optarg);
842 fprintf (stderr, "%s: byte number must be non-negative\n",
848 interleave = atoi(optarg);
851 fprintf(stderr, "%s: interleave must be positive\n",
857 case 's': /* "source" - 'I' is preferred */
858 input_target = optarg;
861 case 'd': /* "destination" - 'O' is preferred */
862 output_target = optarg;
865 input_target = output_target = optarg;
868 strip_symbols = strip_all;
871 strip_symbols = strip_debug;
874 discard_locals = locals_all;
877 discard_locals = locals_start_L;
886 break; /* we've been given a long option */
888 copy_usage (stdout, 0);
890 copy_usage (stderr, 1);
896 printf ("GNU %s version %s\n", program_name, program_version);
900 if (copy_byte >= interleave)
902 fprintf (stderr, "%s: byte number must be less than interleave\n",
907 if (optind == argc || optind + 2 < argc)
908 copy_usage (stderr, 1);
910 input_filename = argv[optind];
911 if (optind + 1 < argc)
912 output_filename = argv[optind + 1];
914 /* Default is to strip no symbols. */
915 if (strip_symbols == strip_undef && discard_locals == locals_undef)
916 strip_symbols = strip_none;
918 if (output_target == (char *) NULL)
919 output_target = input_target;
921 /* If there is no destination file then create a temp and rename
922 the result into the input. */
924 if (output_filename == (char *) NULL)
926 char *tmpname = make_tempname (input_filename);
927 copy_file (input_filename, tmpname, input_target, output_target);
929 smart_rename (tmpname, input_filename);
935 copy_file (input_filename, output_filename, input_target, output_target);
946 program_name = argv[0];
947 xmalloc_set_program_name (program_name);
948 strip_symbols = strip_undef;
949 discard_locals = locals_undef;
955 int i = strlen (program_name);
956 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip"));
960 strip_main (argc, argv);
962 copy_main (argc, argv);