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. */
24 #include "libiberty.h"
26 static bfd_vma parse_vma PARAMS ((const char *, const char *));
27 static void setup_section PARAMS ((bfd *, asection *, PTR));
28 static void copy_section PARAMS ((bfd *, asection *, PTR));
29 static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
31 #define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
33 static asymbol **isympp = NULL; /* Input symbols */
34 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
36 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
37 static int copy_byte = -1;
38 static int interleave = 4;
40 static boolean verbose; /* Print file and target names. */
41 static int status = 0; /* Exit status. */
46 strip_none, /* don't strip */
47 strip_debug, /* strip all debugger symbols */
48 strip_all /* strip all symbols */
51 /* Which symbols to remove. */
52 static enum strip_action strip_symbols;
57 locals_start_L, /* discard locals starting with L */
58 locals_all /* discard all locals */
61 /* Which local symbols to remove. Overrides strip_all. */
62 static enum locals_action discard_locals;
64 /* Structure used to hold lists of sections and actions to take. */
68 /* Next section to adjust. */
69 struct section_list *next;
72 /* Whether this entry was used. */
74 /* Remaining fields only used if not on remove_sections list. */
75 /* Whether to adjust or set VMA. */
77 /* Amount to adjust by or set to. */
81 /* List of sections to remove. */
83 static struct section_list *remove_sections;
85 /* Adjustments to the start address. */
86 static bfd_vma adjust_start = 0;
87 static boolean set_start_set = false;
88 static bfd_vma set_start;
90 /* Adjustments to section VMA's. */
91 static bfd_vma adjust_section_vma = 0;
92 static struct section_list *adjust_sections;
94 /* Options to handle if running as "strip". */
96 static struct option strip_options[] =
98 {"discard-all", no_argument, 0, 'x'},
99 {"discard-locals", no_argument, 0, 'X'},
100 {"format", required_argument, 0, 'F'}, /* Obsolete */
101 {"help", no_argument, 0, 'h'},
102 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
103 {"input-target", required_argument, 0, 'I'},
104 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
105 {"output-target", required_argument, 0, 'O'},
106 {"remove-section", required_argument, 0, 'R'},
107 {"strip-all", no_argument, 0, 's'},
108 {"strip-debug", no_argument, 0, 'S'},
109 {"target", required_argument, 0, 'F'},
110 {"verbose", no_argument, 0, 'v'},
111 {"version", no_argument, 0, 'V'},
112 {0, no_argument, 0, 0}
115 /* Options to handle if running as "objcopy". */
117 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
119 #define OPTION_ADJUST_START 150
120 #define OPTION_ADJUST_VMA (OPTION_ADJUST_START + 1)
121 #define OPTION_ADJUST_SECTION_VMA (OPTION_ADJUST_VMA + 1)
122 #define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1)
123 #define OPTION_NO_ADJUST_WARNINGS (OPTION_ADJUST_WARNINGS + 1)
124 #define OPTION_SET_START (OPTION_NO_ADJUST_WARNINGS + 1)
126 static struct option copy_options[] =
128 {"adjust-start", required_argument, 0, OPTION_ADJUST_START},
129 {"adjust-vma", required_argument, 0, OPTION_ADJUST_VMA},
130 {"adjust-section-vma", required_argument, 0, OPTION_ADJUST_SECTION_VMA},
131 {"adjust-warnings", no_argument, 0, OPTION_ADJUST_WARNINGS},
132 {"byte", required_argument, 0, 'b'},
133 {"discard-all", no_argument, 0, 'x'},
134 {"discard-locals", no_argument, 0, 'X'},
135 {"format", required_argument, 0, 'F'}, /* Obsolete */
136 {"help", no_argument, 0, 'h'},
137 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
138 {"input-target", required_argument, 0, 'I'},
139 {"interleave", required_argument, 0, 'i'},
140 {"no-adjust-warnings", no_argument, 0, OPTION_NO_ADJUST_WARNINGS},
141 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
142 {"output-target", required_argument, 0, 'O'},
143 {"remove-section", required_argument, 0, 'R'},
144 {"set-start", required_argument, 0, OPTION_SET_START},
145 {"strip-all", no_argument, 0, 'S'},
146 {"strip-debug", no_argument, 0, 'g'},
147 {"target", required_argument, 0, 'F'},
148 {"verbose", no_argument, 0, 'v'},
149 {"version", no_argument, 0, 'V'},
150 {0, no_argument, 0, 0}
154 extern char *program_name;
155 extern char *program_version;
157 /* This flag distinguishes between strip and objcopy:
158 1 means this is 'strip'; 0 means this is 'objcopy'.
159 -1 means if we should use argv[0] to decide. */
164 copy_usage (stream, status)
169 Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
170 [-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
171 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
172 [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
173 [--remove-section=section] [--set-start=val] [--adjust-start=incr]\n\
174 [--adjust-vma=incr] [--adjust-section-vma=section{=,+,-}val]\n\
175 [--adjust-warnings] [--no-adjust-warnings] [--verbose] [--version]\n\
176 [--help] in-file [out-file]\n",
182 strip_usage (stream, status)
187 Usage: %s [-vVsSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-R section]\n\
188 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
189 [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
190 [--remove-section=section] [--verbose] [--version] [--help] file...\n",
195 /* Parse a string into a VMA, with a fatal error if it can't be
206 ret = bfd_scan_vma (s, &end, 0);
209 fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s);
215 /* Return the name of a temporary file in the same directory as FILENAME. */
218 make_tempname (filename)
221 static char template[] = "stXXXXXX";
223 char *slash = strrchr (filename, '/');
225 if (slash != (char *) NULL)
228 tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
229 strcpy (tmpname, filename);
230 strcat (tmpname, "/");
231 strcat (tmpname, template);
237 tmpname = xmalloc (sizeof (template));
238 strcpy (tmpname, template);
244 /* Choose which symbol entries to copy; put the result in OSYMS.
245 We don't copy in place, because that confuses the relocs.
246 Return the number of symbols to print. */
249 filter_symbols (abfd, osyms, isyms, symcount)
251 asymbol **osyms, **isyms;
254 register asymbol **from = isyms, **to = osyms;
255 long src_count = 0, dst_count = 0;
257 for (; src_count < symcount; src_count++)
259 asymbol *sym = from[src_count];
260 flagword flags = sym->flags;
263 if ((flags & BSF_GLOBAL) /* Keep if external. */
264 || (flags & BSF_KEEP) /* Keep if used in a relocation. */
265 || bfd_is_und_section (bfd_get_section (sym))
266 || bfd_is_com_section (bfd_get_section (sym)))
268 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
269 keep = strip_symbols != strip_debug;
270 else /* Local symbol. */
271 keep = discard_locals != locals_all
272 && (discard_locals != locals_start_L ||
273 ! bfd_is_local_label (abfd, sym));
275 to[dst_count++] = sym;
281 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
285 filter_bytes (memhunk, size)
289 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
291 for (; from < end; from += interleave)
296 /* Copy object file IBFD onto OBFD. */
299 copy_object (ibfd, obfd)
306 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
308 nonfatal (bfd_get_filename (obfd));
312 printf ("copy from %s(%s) to %s(%s)\n",
313 bfd_get_filename(ibfd), bfd_get_target(ibfd),
314 bfd_get_filename(obfd), bfd_get_target(obfd));
319 start = bfd_get_start_address (ibfd);
320 start += adjust_start;
322 if (!bfd_set_start_address (obfd, start)
323 || !bfd_set_file_flags (obfd,
324 (bfd_get_file_flags (ibfd)
325 & bfd_applicable_file_flags (obfd))))
327 nonfatal (bfd_get_filename (ibfd));
330 /* Copy architecture of input file to output file */
331 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
332 bfd_get_mach (ibfd)))
334 fprintf (stderr, "Output file cannot represent architecture %s\n",
335 bfd_printable_arch_mach (bfd_get_arch (ibfd),
336 bfd_get_mach (ibfd)));
338 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
340 nonfatal (bfd_get_filename(ibfd));
345 if (osympp != isympp)
348 /* bfd mandates that all output sections be created and sizes set before
349 any output is done. Thus, we traverse all sections multiple times. */
350 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
352 /* Symbol filtering must happen after the output sections have
353 been created, but before their contents are set. */
354 if (strip_symbols == strip_all && discard_locals == locals_undef)
356 osympp = isympp = NULL;
363 symsize = bfd_get_symtab_upper_bound (ibfd);
366 nonfatal (bfd_get_filename (ibfd));
369 osympp = isympp = (asymbol **) xmalloc (symsize);
370 symcount = bfd_canonicalize_symtab (ibfd, isympp);
373 nonfatal (bfd_get_filename (ibfd));
376 if (strip_symbols == strip_debug || discard_locals != locals_undef)
378 /* Mark symbols used in output relocations so that they
379 are kept, even if they are local labels or static symbols.
381 Note we iterate over the input sections examining their
382 relocations since the relocations for the output sections
383 haven't been set yet. mark_symbols_used_in_relocations will
384 ignore input sections which have no corresponding output
386 bfd_map_over_sections (ibfd,
387 mark_symbols_used_in_relocations,
389 osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
390 symcount = filter_symbols (ibfd, osympp, isympp, symcount);
394 bfd_set_symtab (obfd, osympp, symcount);
396 /* This has to happen after the symbol table has been set. */
397 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
399 /* Allow the BFD backend to copy any private data it understands
400 from the input BFD to the output BFD. This is done last to
401 permit the routine to look at the filtered symbol table, which is
402 important for the ECOFF code at least. */
403 if (!bfd_copy_private_bfd_data (ibfd, obfd))
405 fprintf (stderr, "%s: %s: error copying private BFD data: %s\n",
406 program_name, bfd_get_filename (obfd),
407 bfd_errmsg (bfd_get_error ()));
419 size_t size = strlen (a) + strlen (b) + strlen (c);
420 char *r = xmalloc (size + 1);
428 /* Read each archive element in turn from IBFD, copy the
429 contents to temp file, and keep the temp file handle. */
432 copy_archive (ibfd, obfd, output_target)
437 bfd **ptr = &obfd->archive_head;
439 char *dir = make_tempname (bfd_get_filename (obfd));
441 /* Make a temp directory to hold the contents. */
443 obfd->has_armap = ibfd->has_armap;
445 this_element = bfd_openr_next_archived_file (ibfd, NULL);
446 ibfd->archive_head = this_element;
447 while (this_element != (bfd *) NULL)
449 /* Create an output file for this member. */
450 char *output_name = cat (dir, "/", bfd_get_filename(this_element));
451 bfd *output_bfd = bfd_openw (output_name, output_target);
453 if (output_bfd == (bfd *) NULL)
455 nonfatal (output_name);
457 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
459 nonfatal (bfd_get_filename (obfd));
462 if (bfd_check_format (this_element, bfd_object) == true)
464 copy_object (this_element, output_bfd);
467 bfd_close (output_bfd);
468 /* Open the newly output file and attatch to our list. */
469 output_bfd = bfd_openr (output_name, output_target);
471 /* Mark it for deletion. */
473 ptr = &output_bfd->next;
474 this_element->next = bfd_openr_next_archived_file (ibfd, this_element);
475 this_element = this_element->next;
479 if (!bfd_close (obfd))
481 nonfatal (bfd_get_filename (obfd));
484 /* Delete all the files that we opened.
485 Construct their names again, unfortunately, but
486 we're about to exit anyway. */
487 for (this_element = ibfd->archive_head;
488 this_element != (bfd *) NULL;
489 this_element = this_element->next)
491 unlink (cat (dir, "/", bfd_get_filename (this_element)));
494 if (!bfd_close (ibfd))
496 nonfatal (bfd_get_filename (ibfd));
500 /* The top-level control. */
503 copy_file (input_filename, output_filename, input_target, output_target)
504 char *input_filename;
505 char *output_filename;
512 /* To allow us to do "strip *" without dying on the first
513 non-object file, failures are nonfatal. */
515 ibfd = bfd_openr (input_filename, input_target);
518 nonfatal (input_filename);
521 if (bfd_check_format (ibfd, bfd_archive))
525 /* bfd_get_target does not return the correct value until
526 bfd_check_format succeeds. */
527 if (output_target == NULL)
528 output_target = bfd_get_target (ibfd);
530 obfd = bfd_openw (output_filename, output_target);
533 nonfatal (output_filename);
535 copy_archive (ibfd, obfd, output_target);
537 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
541 /* bfd_get_target does not return the correct value until
542 bfd_check_format succeeds. */
543 if (output_target == NULL)
544 output_target = bfd_get_target (ibfd);
546 obfd = bfd_openw (output_filename, output_target);
549 nonfatal (output_filename);
552 copy_object (ibfd, obfd);
554 if (!bfd_close (obfd))
556 nonfatal (output_filename);
559 if (!bfd_close (ibfd))
561 nonfatal (input_filename);
566 bfd_nonfatal (input_filename);
567 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
569 list_matching_formats (matching);
576 /* Create a section in OBFD with the same name and attributes
577 as ISECTION in IBFD. */
580 setup_section (ibfd, isection, obfdarg)
585 bfd *obfd = (bfd *) obfdarg;
586 struct section_list *p;
591 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
592 && (strip_symbols == strip_debug
593 || strip_symbols == strip_all
594 || discard_locals == locals_all))
597 for (p = remove_sections; p != NULL; p = p->next)
599 if (strcmp (p->name, bfd_section_name (ibfd, isection)) == 0)
606 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
607 if (osection == NULL)
613 if (!bfd_set_section_size (obfd,
615 bfd_section_size (ibfd, isection)))
621 vma = bfd_section_vma (ibfd, isection);
622 for (p = adjust_sections; p != NULL; p = p->next)
624 if (strcmp (p->name, bfd_section_name (ibfd, isection)) == 0)
635 vma += adjust_section_vma;
637 if (! bfd_set_section_vma (obfd, osection, vma))
643 if (bfd_set_section_alignment (obfd,
645 bfd_section_alignment (ibfd, isection))
652 if (!bfd_set_section_flags (obfd, osection,
653 bfd_get_section_flags (ibfd, isection)))
659 /* This used to be mangle_section; we do here to avoid using
660 bfd_get_section_by_name since some formats allow multiple
661 sections with the same name. */
662 isection->output_section = osection;
663 isection->output_offset = 0;
665 /* Allow the BFD backend to copy any private data it understands
666 from the input section to the output section. */
667 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
669 err = "private data";
677 fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
679 bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
680 err, bfd_errmsg (bfd_get_error ()));
684 /* Copy the data of input section ISECTION of IBFD
685 to an output section with the same name in OBFD.
686 If stripping then don't copy any relocation info. */
689 copy_section (ibfd, isection, obfdarg)
694 bfd *obfd = (bfd *) obfdarg;
695 struct section_list *p;
701 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
702 && (strip_symbols == strip_debug
703 || strip_symbols == strip_all
704 || discard_locals == locals_all))
709 for (p = remove_sections; p != NULL; p = p->next)
710 if (strcmp (p->name, bfd_section_name (ibfd, isection)) == 0)
713 osection = isection->output_section;
714 size = bfd_get_section_size_before_reloc (isection);
716 if (size == 0 || osection == 0)
719 if (strip_symbols == strip_all)
720 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
725 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
728 nonfatal (bfd_get_filename (ibfd));
731 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
734 relpp = (arelent **) xmalloc (relsize);
735 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
738 nonfatal (bfd_get_filename (ibfd));
740 bfd_set_reloc (obfd, osection, relpp, relcount);
744 isection->_cooked_size = isection->_raw_size;
745 isection->reloc_done = true;
747 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
749 PTR memhunk = (PTR) xmalloc ((unsigned) size);
751 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
754 nonfatal (bfd_get_filename (ibfd));
759 filter_bytes (memhunk, &size);
760 /* The section has gotten smaller. */
761 if (!bfd_set_section_size (obfd, osection, size))
762 nonfatal (bfd_get_filename (obfd));
765 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
768 nonfatal (bfd_get_filename (obfd));
774 /* Mark all the symbols which will be used in output relocations with
775 the BSF_KEEP flag so that those symbols will not be stripped.
777 Ignore relocations which will not appear in the output file. */
780 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
785 asymbol **symbols = (asymbol **) symbolsarg;
790 /* Ignore an input section with no corresponding output section. */
791 if (isection->output_section == NULL)
794 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
796 bfd_fatal (bfd_get_filename (ibfd));
798 relpp = (arelent **) xmalloc (relsize);
799 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
801 bfd_fatal (bfd_get_filename (ibfd));
803 /* Examine each symbol used in a relocation. If it's not one of the
804 special bfd section symbols, then mark it with BSF_KEEP. */
805 for (i = 0; i < relcount; i++)
807 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
808 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
809 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
810 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
817 /* The number of bytes to copy at once. */
818 #define COPY_BUF 8192
820 /* Copy file FROM to file TO, performing no translations.
821 Return 0 if ok, -1 if error. */
824 simple_copy (from, to)
827 int fromfd, tofd, nread;
830 fromfd = open (from, O_RDONLY);
833 tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
839 while ((nread = read (fromfd, buf, sizeof buf)) > 0)
841 if (write (tofd, buf, nread) != nread)
857 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
864 /* Rename FROM to TO, copying if TO is a link.
865 Assumes that TO already exists, because FROM is a temp file.
866 Return 0 if ok, -1 if error. */
869 smart_rename (from, to)
878 /* Use rename only if TO is not a symbolic link and has
879 only one hard link. */
880 if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
882 ret = rename (from, to);
885 /* Try to preserve the permission bits and ownership of TO. */
886 chmod (to, s.st_mode & 07777);
887 chown (to, s.st_uid, s.st_gid);
892 ret = simple_copy (from, to);
900 strip_main (argc, argv)
904 char *input_target = NULL, *output_target = NULL;
905 boolean show_version = false;
908 while ((c = getopt_long (argc, argv, "I:O:F:R:sSgxXVv",
909 strip_options, (int *) 0)) != EOF)
914 input_target = optarg;
917 output_target = optarg;
920 input_target = output_target = optarg;
924 struct section_list *n;
926 n = (struct section_list *) xmalloc (sizeof (struct section_list));
929 n->next = remove_sections;
934 strip_symbols = strip_all;
938 strip_symbols = strip_debug;
941 discard_locals = locals_all;
944 discard_locals = locals_start_L;
953 break; /* we've been given a long option */
955 strip_usage (stdout, 0);
957 strip_usage (stderr, 1);
963 printf ("GNU %s version %s\n", program_name, program_version);
967 /* Default is to strip all symbols. */
968 if (strip_symbols == strip_undef && discard_locals == locals_undef)
969 strip_symbols = strip_all;
971 if (output_target == (char *) NULL)
972 output_target = input_target;
976 strip_usage (stderr, 1);
978 for (; i < argc; i++)
980 int hold_status = status;
982 char *tmpname = make_tempname (argv[i]);
984 copy_file (argv[i], tmpname, input_target, output_target);
987 smart_rename (tmpname, argv[i]);
988 status = hold_status;
999 copy_main (argc, argv)
1003 char *input_filename = NULL, *output_filename = NULL;
1004 char *input_target = NULL, *output_target = NULL;
1005 boolean show_version = false;
1006 boolean adjust_warn = true;
1008 struct section_list *p;
1010 while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:R:SgxXVv",
1011 copy_options, (int *) 0)) != EOF)
1016 copy_byte = atoi(optarg);
1019 fprintf (stderr, "%s: byte number must be non-negative\n",
1025 interleave = atoi(optarg);
1028 fprintf(stderr, "%s: interleave must be positive\n",
1034 case 's': /* "source" - 'I' is preferred */
1035 input_target = optarg;
1038 case 'd': /* "destination" - 'O' is preferred */
1039 output_target = optarg;
1042 input_target = output_target = optarg;
1045 p = (struct section_list *) xmalloc (sizeof (struct section_list));
1048 p->next = remove_sections;
1049 remove_sections = p;
1052 strip_symbols = strip_all;
1055 strip_symbols = strip_debug;
1058 discard_locals = locals_all;
1061 discard_locals = locals_start_L;
1067 show_version = true;
1069 case OPTION_ADJUST_START:
1070 adjust_start = parse_vma (optarg, "--adjust-start");
1072 case OPTION_ADJUST_SECTION_VMA:
1078 p = (struct section_list *) xmalloc (sizeof (struct section_list));
1079 s = strchr (optarg, '=');
1083 p->val = parse_vma (s + 1, "--adjust-section-vma");
1087 s = strchr (optarg, '+');
1090 s = strchr (optarg, '-');
1094 "%s: bad format for --adjust-section-vma\n",
1100 p->val = parse_vma (s + 1, "--adjust-section-vma");
1106 name = (char *) xmalloc (len + 1);
1107 strncpy (name, optarg, len);
1113 p->next = adjust_sections;
1114 adjust_sections = p;
1117 case OPTION_ADJUST_VMA:
1118 adjust_section_vma = parse_vma (optarg, "--adjust-vma");
1119 adjust_start = adjust_section_vma;
1121 case OPTION_ADJUST_WARNINGS:
1124 case OPTION_NO_ADJUST_WARNINGS:
1125 adjust_warn = false;
1127 case OPTION_SET_START:
1128 set_start = parse_vma (optarg, "--set-start");
1129 set_start_set = true;
1132 break; /* we've been given a long option */
1134 copy_usage (stdout, 0);
1136 copy_usage (stderr, 1);
1142 printf ("GNU %s version %s\n", program_name, program_version);
1146 if (copy_byte >= interleave)
1148 fprintf (stderr, "%s: byte number must be less than interleave\n",
1153 if (optind == argc || optind + 2 < argc)
1154 copy_usage (stderr, 1);
1156 input_filename = argv[optind];
1157 if (optind + 1 < argc)
1158 output_filename = argv[optind + 1];
1160 /* Default is to strip no symbols. */
1161 if (strip_symbols == strip_undef && discard_locals == locals_undef)
1162 strip_symbols = strip_none;
1164 if (output_target == (char *) NULL)
1165 output_target = input_target;
1167 /* If there is no destination file then create a temp and rename
1168 the result into the input. */
1170 if (output_filename == (char *) NULL)
1172 char *tmpname = make_tempname (input_filename);
1173 copy_file (input_filename, tmpname, input_target, output_target);
1175 smart_rename (tmpname, input_filename);
1181 copy_file (input_filename, output_filename, input_target, output_target);
1186 for (p = adjust_sections; p != NULL; p = p->next)
1190 fprintf (stderr, "%s: warning: --adjust-section-vma %s%c0x",
1191 program_name, p->name,
1192 p->adjust ? '=' : '+');
1193 fprintf_vma (stderr, p->val);
1194 fprintf (stderr, " never used\n");
1199 /* We could issue similar warnings for remove_sections, but I don't
1200 think that would be as useful. */
1210 program_name = argv[0];
1211 xmalloc_set_program_name (program_name);
1212 strip_symbols = strip_undef;
1213 discard_locals = locals_undef;
1219 int i = strlen (program_name);
1220 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip"));
1224 strip_main (argc, argv);
1226 copy_main (argc, argv);