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;
183 register asymbol **from = isyms, **to = osyms;
184 long 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)
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_get_filename (obfd),
276 bfd_errmsg (bfd_get_error ()));
281 /* bfd mandates that all output sections be created and sizes set before
282 any output is done. Thus, we traverse all sections multiple times. */
283 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
285 /* Symbol filtering must happen after the output sections have
286 been created, but before their contents are set. */
287 if (strip_symbols == strip_all && discard_locals == locals_undef)
289 osympp = isympp = NULL;
296 symsize = bfd_get_symtab_upper_bound (ibfd);
299 nonfatal (bfd_get_filename (ibfd));
302 osympp = isympp = (asymbol **) xmalloc (symsize);
303 symcount = bfd_canonicalize_symtab (ibfd, isympp);
306 nonfatal (bfd_get_filename (ibfd));
309 if (strip_symbols == strip_debug || discard_locals != locals_undef)
311 /* Mark symbols used in output relocations so that they
312 are kept, even if they are local labels or static symbols.
314 Note we iterate over the input sections examining their
315 relocations since the relocations for the output sections
316 haven't been set yet. mark_symbols_used_in_relocations will
317 ignore input sections which have no corresponding output
319 bfd_map_over_sections (ibfd,
320 mark_symbols_used_in_relocations,
322 osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
323 symcount = filter_symbols (ibfd, osympp, isympp, symcount);
327 bfd_set_symtab (obfd, osympp, symcount);
329 /* This has to happen after the symbol table has been set. */
330 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
339 size_t size = strlen (a) + strlen (b) + strlen (c);
340 char *r = xmalloc (size + 1);
348 /* Read each archive element in turn from IBFD, copy the
349 contents to temp file, and keep the temp file handle. */
352 copy_archive (ibfd, obfd, output_target)
357 bfd **ptr = &obfd->archive_head;
359 char *dir = cat ("./#", make_tempname (""), "cd");
361 /* Make a temp directory to hold the contents. */
363 obfd->has_armap = ibfd->has_armap;
365 this_element = bfd_openr_next_archived_file (ibfd, NULL);
366 ibfd->archive_head = this_element;
367 while (this_element != (bfd *) NULL)
369 /* Create an output file for this member. */
370 char *output_name = cat (dir, "/", bfd_get_filename(this_element));
371 bfd *output_bfd = bfd_openw (output_name, output_target);
373 if (output_bfd == (bfd *) NULL)
375 nonfatal (output_name);
377 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
379 nonfatal (bfd_get_filename (obfd));
382 if (bfd_check_format (this_element, bfd_object) == true)
384 copy_object (this_element, output_bfd);
387 bfd_close (output_bfd);
388 /* Open the newly output file and attatch to our list. */
389 output_bfd = bfd_openr (output_name, output_target);
391 /* Mark it for deletion. */
393 ptr = &output_bfd->next;
394 this_element->next = bfd_openr_next_archived_file (ibfd, this_element);
395 this_element = this_element->next;
399 if (!bfd_close (obfd))
401 nonfatal (bfd_get_filename (obfd));
404 /* Delete all the files that we opened.
405 Construct their names again, unfortunately, but
406 we're about to exit anyway. */
407 for (this_element = ibfd->archive_head;
408 this_element != (bfd *) NULL;
409 this_element = this_element->next)
411 unlink (cat (dir, "/", bfd_get_filename (this_element)));
414 if (!bfd_close (ibfd))
416 nonfatal (bfd_get_filename (ibfd));
420 /* The top-level control. */
423 copy_file (input_filename, output_filename, input_target, output_target)
424 char *input_filename;
425 char *output_filename;
432 /* To allow us to do "strip *" without dying on the first
433 non-object file, failures are nonfatal. */
435 ibfd = bfd_openr (input_filename, input_target);
438 nonfatal (input_filename);
441 if (bfd_check_format (ibfd, bfd_archive))
443 bfd *obfd = bfd_openw (output_filename, output_target);
446 nonfatal (output_filename);
448 copy_archive (ibfd, obfd, output_target);
450 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
452 bfd *obfd = bfd_openw (output_filename, output_target);
455 nonfatal (output_filename);
458 copy_object (ibfd, obfd);
460 if (!bfd_close (obfd))
462 nonfatal (output_filename);
465 if (!bfd_close (ibfd))
467 nonfatal (input_filename);
472 bfd_nonfatal (input_filename);
473 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
475 list_matching_formats (matching);
482 /* Create a section in OBFD with the same name and attributes
483 as ISECTION in IBFD. */
486 setup_section (ibfd, isection, obfd)
494 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
495 && (strip_symbols == strip_debug
496 || strip_symbols == strip_all
497 || discard_locals == locals_all))
500 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
501 if (osection == NULL)
507 if (!bfd_set_section_size (obfd,
509 bfd_section_size (ibfd, isection)))
515 if (bfd_set_section_vma (obfd,
517 bfd_section_vma (ibfd, isection))
524 if (bfd_set_section_alignment (obfd,
526 bfd_section_alignment (ibfd, isection))
533 if (!bfd_set_section_flags (obfd, osection,
534 bfd_get_section_flags (ibfd, isection)))
540 /* This used to be mangle_section; we do here to avoid using
541 bfd_get_section_by_name since some formats allow multiple
542 sections with the same name. */
543 isection->output_section = osection;
544 isection->output_offset = 0;
546 /* Allow the BFD backend to copy any private data it understands
547 from the input section to the output section. */
548 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
550 err = "private data";
558 fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
560 bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
561 err, bfd_errmsg (bfd_get_error ()));
565 /* Copy the data of input section ISECTION of IBFD
566 to an output section with the same name in OBFD.
567 If stripping then don't copy any relocation info. */
570 copy_section (ibfd, isection, obfd)
580 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
581 && (strip_symbols == strip_debug
582 || strip_symbols == strip_all
583 || discard_locals == locals_all))
588 osection = isection->output_section;
589 size = bfd_get_section_size_before_reloc (isection);
591 if (size == 0 || osection == 0)
594 if (strip_symbols == strip_all)
595 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
600 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
603 nonfatal (bfd_get_filename (ibfd));
606 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
609 relpp = (arelent **) xmalloc (relsize);
610 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
613 nonfatal (bfd_get_filename (ibfd));
615 bfd_set_reloc (obfd, osection, relpp, relcount);
619 isection->_cooked_size = isection->_raw_size;
620 isection->reloc_done = true;
622 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
624 PTR memhunk = (PTR) xmalloc ((unsigned) size);
626 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
629 nonfatal (bfd_get_filename (ibfd));
633 filter_bytes (memhunk, &size);
635 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
638 nonfatal (bfd_get_filename (obfd));
644 /* Mark all the symbols which will be used in output relocations with
645 the BSF_KEEP flag so that those symbols will not be stripped.
647 Ignore relocations which will not appear in the output file. */
650 mark_symbols_used_in_relocations (ibfd, isection, symbols)
659 /* Ignore an input section with no corresponding output section. */
660 if (isection->output_section == NULL)
663 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
665 bfd_fatal (bfd_get_filename (ibfd));
667 relpp = (arelent **) xmalloc (relsize);
668 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
670 bfd_fatal (bfd_get_filename (ibfd));
672 /* Examine each symbol used in a relocation. If it's not one of the
673 special bfd section symbols, then mark it with BSF_KEEP. */
674 for (i = 0; i < relcount; i++)
676 if (*relpp[i]->sym_ptr_ptr != bfd_com_section.symbol
677 && *relpp[i]->sym_ptr_ptr != bfd_abs_section.symbol
678 && *relpp[i]->sym_ptr_ptr != bfd_und_section.symbol)
679 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
686 /* The number of bytes to copy at once. */
687 #define COPY_BUF 8192
689 /* Copy file FROM to file TO, performing no translations.
690 Return 0 if ok, -1 if error. */
693 simple_copy (from, to)
696 int fromfd, tofd, nread;
699 fromfd = open (from, O_RDONLY);
702 tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
708 while ((nread = read (fromfd, buf, sizeof buf)) > 0)
710 if (write (tofd, buf, nread) != nread)
726 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
733 /* Rename FROM to TO, copying if TO is a link.
734 Assumes that TO already exists, because FROM is a temp file.
735 Return 0 if ok, -1 if error. */
738 smart_rename (from, to)
747 /* Use rename only if TO is not a symbolic link and has
748 only one hard link. */
749 if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
751 ret = rename (from, to);
754 /* Try to preserve the permission bits and ownership of TO. */
755 chmod (to, s.st_mode & 07777);
756 chown (to, s.st_uid, s.st_gid);
761 ret = simple_copy (from, to);
769 strip_main (argc, argv)
773 char *input_target = NULL, *output_target = NULL;
774 boolean show_version = false;
777 while ((c = getopt_long (argc, argv, "I:O:F:sSgxXVv",
778 strip_options, (int *) 0)) != EOF)
783 input_target = optarg;
786 output_target = optarg;
789 input_target = output_target = optarg;
792 strip_symbols = strip_all;
796 strip_symbols = strip_debug;
799 discard_locals = locals_all;
802 discard_locals = locals_start_L;
811 break; /* we've been given a long option */
813 strip_usage (stdout, 0);
815 strip_usage (stderr, 1);
821 printf ("GNU %s version %s\n", program_name, program_version);
825 /* Default is to strip all symbols. */
826 if (strip_symbols == strip_undef && discard_locals == locals_undef)
827 strip_symbols = strip_all;
829 if (output_target == (char *) NULL)
830 output_target = input_target;
834 strip_usage (stderr, 1);
836 for (; i < argc; i++)
838 int hold_status = status;
840 char *tmpname = make_tempname (argv[i]);
842 copy_file (argv[i], tmpname, input_target, output_target);
845 smart_rename (tmpname, argv[i]);
846 status = hold_status;
857 copy_main (argc, argv)
861 char *input_filename, *output_filename;
862 char *input_target = NULL, *output_target = NULL;
863 boolean show_version = false;
866 while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
867 copy_options, (int *) 0)) != EOF)
872 copy_byte = atoi(optarg);
875 fprintf (stderr, "%s: byte number must be non-negative\n",
881 interleave = atoi(optarg);
884 fprintf(stderr, "%s: interleave must be positive\n",
890 case 's': /* "source" - 'I' is preferred */
891 input_target = optarg;
894 case 'd': /* "destination" - 'O' is preferred */
895 output_target = optarg;
898 input_target = output_target = optarg;
901 strip_symbols = strip_all;
904 strip_symbols = strip_debug;
907 discard_locals = locals_all;
910 discard_locals = locals_start_L;
919 break; /* we've been given a long option */
921 copy_usage (stdout, 0);
923 copy_usage (stderr, 1);
929 printf ("GNU %s version %s\n", program_name, program_version);
933 if (copy_byte >= interleave)
935 fprintf (stderr, "%s: byte number must be less than interleave\n",
940 if (optind == argc || optind + 2 < argc)
941 copy_usage (stderr, 1);
943 input_filename = argv[optind];
944 if (optind + 1 < argc)
945 output_filename = argv[optind + 1];
947 /* Default is to strip no symbols. */
948 if (strip_symbols == strip_undef && discard_locals == locals_undef)
949 strip_symbols = strip_none;
951 if (output_target == (char *) NULL)
952 output_target = input_target;
954 /* If there is no destination file then create a temp and rename
955 the result into the input. */
957 if (output_filename == (char *) NULL)
959 char *tmpname = make_tempname (input_filename);
960 copy_file (input_filename, tmpname, input_target, output_target);
962 smart_rename (tmpname, input_filename);
968 copy_file (input_filename, output_filename, input_target, output_target);
979 program_name = argv[0];
980 xmalloc_set_program_name (program_name);
981 strip_symbols = strip_undef;
982 discard_locals = locals_undef;
988 int i = strlen (program_name);
989 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip"));
993 strip_main (argc, argv);
995 copy_main (argc, argv);