673511fc17158d113c67ad3c62be8a7df77e6ea0
[platform/upstream/binutils.git] / binutils / objcopy.c
1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2    Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
3
4    This file is part of GNU Binutils.
5
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.
10
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.
15
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.  */
19 \f
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "bucomm.h"
23 #include <getopt.h>
24
25 static void setup_section ();
26 static void copy_section ();
27 static void mark_symbols_used_in_relocations ();
28
29 #define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
30
31 static asymbol **isympp = NULL; /* Input symbols */
32 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
33
34 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes.  */
35 static int copy_byte = -1;
36 static int interleave = 4;
37
38 static boolean verbose;         /* Print file and target names. */
39 static int status = 0;          /* Exit status.  */
40
41 enum strip_action
42   {
43     strip_undef,
44     strip_none,                 /* don't strip */
45     strip_debug,                /* strip all debugger symbols */
46     strip_all                   /* strip all symbols */
47   };
48
49 /* Which symbols to remove. */
50 static enum strip_action strip_symbols;
51
52 enum locals_action
53   {
54     locals_undef,
55     locals_start_L,             /* discard locals starting with L */
56     locals_all                  /* discard all locals */
57   };
58
59 /* Which local symbols to remove.  Overrides strip_all.  */
60 static enum locals_action discard_locals;
61
62 /* Options to handle if running as "strip".  */
63
64 static struct option strip_options[] =
65 {
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}
80 };
81
82 /* Options to handle if running as "objcopy".  */
83
84 static struct option copy_options[] =
85 {
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}
102 };
103
104 /* IMPORTS */
105 extern char *program_name;
106 extern char *program_version;
107
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. */
111 extern int is_strip;
112
113
114 static void
115 copy_usage (stream, status)
116      FILE *stream;
117      int status;
118 {
119   fprintf (stream, "\
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",
125            program_name);
126   exit (status);
127 }
128
129 static void
130 strip_usage (stream, status)
131      FILE *stream;
132      int status;
133 {
134   fprintf (stream, "\
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",
139            program_name);
140   exit (status);
141 }
142
143
144 /* Return the name of a temporary file in the same directory as FILENAME.  */
145
146 static char *
147 make_tempname (filename)
148      char *filename;
149 {
150   static char template[] = "stXXXXXX";
151   char *tmpname;
152   char *slash = strrchr (filename, '/');
153
154   if (slash != (char *) NULL)
155     {
156       *slash = 0;
157       tmpname = xmalloc (strlen (filename) + sizeof (template) + 1);
158       strcpy (tmpname, filename);
159       strcat (tmpname, "/");
160       strcat (tmpname, template);
161       mktemp (tmpname);
162       *slash = '/';
163     }
164   else
165     {
166       tmpname = xmalloc (sizeof (template));
167       strcpy (tmpname, template);
168       mktemp (tmpname);
169     }
170   return tmpname;
171 }
172
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.  */
176
177 static unsigned int
178 filter_symbols (abfd, osyms, isyms, symcount)
179      bfd *abfd;
180      asymbol **osyms, **isyms;
181      long symcount;
182 {
183   register asymbol **from = isyms, **to = osyms;
184   long src_count = 0, dst_count = 0;
185
186   for (; src_count < symcount; src_count++)
187     {
188       asymbol *sym = from[src_count];
189       flagword flags = sym->flags;
190       int keep;
191
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)))
196         keep = 1;
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));
203       if (keep)
204         to[dst_count++] = sym;
205     }
206
207   return dst_count;
208 }
209
210 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
211    Adjust *SIZE.  */
212
213 void
214 filter_bytes (memhunk, size)
215      char *memhunk;
216      bfd_size_type *size;
217 {
218   char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
219
220   for (; from < end; from += interleave)
221     *to++ = *from;
222   *size /= interleave;
223 }
224
225 /* Copy object file IBFD onto OBFD.  */
226
227 static void
228 copy_object (ibfd, obfd)
229      bfd *ibfd;
230      bfd *obfd;
231 {
232   long symcount;
233
234   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
235     {
236       nonfatal (bfd_get_filename (obfd));
237     }
238
239   if (verbose)
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));
243
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))))
248     {
249       nonfatal (bfd_get_filename (ibfd));
250     }
251
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)))
255     {
256       fprintf (stderr, "Output file cannot represent architecture %s\n",
257                bfd_printable_arch_mach (bfd_get_arch (ibfd),
258                                         bfd_get_mach (ibfd)));
259     }
260   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
261     {
262       nonfatal (bfd_get_filename(ibfd));
263     }
264
265   if (isympp)
266     free (isympp);
267   if (osympp != isympp)
268     free (osympp);
269
270   /* bfd mandates that all output sections be created and sizes set before
271      any output is done.  Thus, we traverse all sections multiple times.  */
272   bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
273
274   /* Symbol filtering must happen after the output sections have
275      been created, but before their contents are set.  */
276   if (strip_symbols == strip_all && discard_locals == locals_undef)
277     {
278       osympp = isympp = NULL;
279       symcount = 0;
280     }
281   else
282     {
283       long symsize;
284
285       symsize = bfd_get_symtab_upper_bound (ibfd);
286       if (symsize < 0)
287         {
288           nonfatal (bfd_get_filename (ibfd));
289         }
290
291       osympp = isympp = (asymbol **) xmalloc (symsize);
292       symcount = bfd_canonicalize_symtab (ibfd, isympp);
293       if (symcount < 0)
294         {
295           nonfatal (bfd_get_filename (ibfd));
296         }
297
298       if (strip_symbols == strip_debug || discard_locals != locals_undef)
299         {
300           /* Mark symbols used in output relocations so that they
301              are kept, even if they are local labels or static symbols.
302
303              Note we iterate over the input sections examining their
304              relocations since the relocations for the output sections
305              haven't been set yet.  mark_symbols_used_in_relocations will
306              ignore input sections which have no corresponding output
307              section.  */
308           bfd_map_over_sections (ibfd,
309                                  mark_symbols_used_in_relocations,
310                                  (void *)isympp);
311           osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
312           symcount = filter_symbols (ibfd, osympp, isympp, symcount);
313         }
314     }
315
316   bfd_set_symtab (obfd, osympp, symcount);
317
318   /* This has to happen after the symbol table has been set.  */
319   bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
320
321   /* Allow the BFD backend to copy any private data it understands
322      from the input BFD to the output BFD.  This is done last to
323      permit the routine to look at the filtered symbol table, which is
324      important for the ECOFF code at least.  */
325   if (!bfd_copy_private_bfd_data (ibfd, obfd))
326     {
327       fprintf (stderr, "%s: %s: error copying private BFD data: %s\n",
328                program_name, bfd_get_filename (obfd),
329                bfd_errmsg (bfd_get_error ()));
330       status = 1;
331       return;
332     }
333 }
334
335 static char *
336 cat (a, b, c)
337      char *a;
338      char *b;
339      char *c;
340 {
341   size_t size = strlen (a) + strlen (b) + strlen (c);
342   char *r = xmalloc (size + 1);
343
344   strcpy (r, a);
345   strcat (r, b);
346   strcat (r, c);
347   return r;
348 }
349
350 /* Read each archive element in turn from IBFD, copy the
351    contents to temp file, and keep the temp file handle.  */
352
353 static void
354 copy_archive (ibfd, obfd, output_target)
355      bfd *ibfd;
356      bfd *obfd;
357      char *output_target;
358 {
359   bfd **ptr = &obfd->archive_head;
360   bfd *this_element;
361   char *dir = make_tempname (bfd_get_filename (obfd));
362
363   /* Make a temp directory to hold the contents.  */
364   mkdir (dir, 0700);
365   obfd->has_armap = ibfd->has_armap;
366
367   this_element = bfd_openr_next_archived_file (ibfd, NULL);
368   ibfd->archive_head = this_element;
369   while (this_element != (bfd *) NULL)
370     {
371       /* Create an output file for this member.  */
372       char *output_name = cat (dir, "/", bfd_get_filename(this_element));
373       bfd *output_bfd = bfd_openw (output_name, output_target);
374
375       if (output_bfd == (bfd *) NULL)
376         {
377           nonfatal (output_name);
378         }
379       if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
380         {
381           nonfatal (bfd_get_filename (obfd));
382         }
383
384       if (bfd_check_format (this_element, bfd_object) == true)
385         {
386           copy_object (this_element, output_bfd);
387         }
388
389       bfd_close (output_bfd);
390       /* Open the newly output file and attatch to our list.  */
391       output_bfd = bfd_openr (output_name, output_target);
392
393       /* Mark it for deletion.  */
394       *ptr = output_bfd;
395       ptr = &output_bfd->next;
396       this_element->next = bfd_openr_next_archived_file (ibfd, this_element);
397       this_element = this_element->next;
398     }
399   *ptr = (bfd *) NULL;
400
401   if (!bfd_close (obfd))
402     {
403       nonfatal (bfd_get_filename (obfd));
404     }
405
406   /* Delete all the files that we opened.
407      Construct their names again, unfortunately, but
408      we're about to exit anyway.  */
409   for (this_element = ibfd->archive_head;
410        this_element != (bfd *) NULL;
411        this_element = this_element->next)
412     {
413       unlink (cat (dir, "/", bfd_get_filename (this_element)));
414     }
415   rmdir (dir);
416   if (!bfd_close (ibfd))
417     {
418       nonfatal (bfd_get_filename (ibfd));
419     }
420 }
421
422 /* The top-level control.  */
423
424 static void
425 copy_file (input_filename, output_filename, input_target, output_target)
426      char *input_filename;
427      char *output_filename;
428      char *input_target;
429      char *output_target;
430 {
431   bfd *ibfd;
432   char **matching;
433
434   /* To allow us to do "strip *" without dying on the first
435      non-object file, failures are nonfatal.  */
436
437   ibfd = bfd_openr (input_filename, input_target);
438   if (ibfd == NULL)
439     {
440       nonfatal (input_filename);
441     }
442
443   if (bfd_check_format (ibfd, bfd_archive))
444     {
445       bfd *obfd = bfd_openw (output_filename, output_target);
446       if (obfd == NULL)
447         {
448           nonfatal (output_filename);
449         }
450       copy_archive (ibfd, obfd, output_target);
451     }
452   else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
453     {
454       bfd *obfd = bfd_openw (output_filename, output_target);
455       if (obfd == NULL)
456         {
457           nonfatal (output_filename);
458         }
459
460       copy_object (ibfd, obfd);
461
462       if (!bfd_close (obfd))
463         {
464           nonfatal (output_filename);
465         }
466
467       if (!bfd_close (ibfd))
468         {
469           nonfatal (input_filename);
470         }
471     }
472   else
473     {
474       bfd_nonfatal (input_filename);
475       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
476         {
477           list_matching_formats (matching);
478           free (matching);
479         }
480       status = 1;
481     }
482 }
483
484 /* Create a section in OBFD with the same name and attributes
485    as ISECTION in IBFD.  */
486
487 static void
488 setup_section (ibfd, isection, obfd)
489      bfd *ibfd;
490      sec_ptr isection;
491      bfd *obfd;
492 {
493   sec_ptr osection;
494   char *err;
495
496   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
497       && (strip_symbols == strip_debug
498           || strip_symbols == strip_all
499           || discard_locals == locals_all))
500     return;
501
502   osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
503   if (osection == NULL)
504     {
505       err = "making";
506       goto loser;
507     }
508
509   if (!bfd_set_section_size (obfd,
510                              osection,
511                              bfd_section_size (ibfd, isection)))
512     {
513       err = "size";
514       goto loser;
515     }
516
517   if (bfd_set_section_vma (obfd,
518                            osection,
519                            bfd_section_vma (ibfd, isection))
520       == false)
521     {
522       err = "vma";
523       goto loser;
524     }
525
526   if (bfd_set_section_alignment (obfd,
527                                  osection,
528                                  bfd_section_alignment (ibfd, isection))
529       == false)
530     {
531       err = "alignment";
532       goto loser;
533     }
534
535   if (!bfd_set_section_flags (obfd, osection,
536                               bfd_get_section_flags (ibfd, isection)))
537     {
538       err = "flags";
539       goto loser;
540     }
541
542   /* This used to be mangle_section; we do here to avoid using
543      bfd_get_section_by_name since some formats allow multiple
544      sections with the same name.  */
545   isection->output_section = osection;
546   isection->output_offset = 0;
547
548   /* Allow the BFD backend to copy any private data it understands
549      from the input section to the output section.  */
550   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
551     {
552       err = "private data";
553       goto loser;
554     }
555
556   /* All went well */
557   return;
558
559 loser:
560   fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
561            program_name,
562            bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
563            err, bfd_errmsg (bfd_get_error ()));
564   status = 1;
565 }
566
567 /* Copy the data of input section ISECTION of IBFD
568    to an output section with the same name in OBFD.
569    If stripping then don't copy any relocation info.  */
570
571 static void
572 copy_section (ibfd, isection, obfd)
573      bfd *ibfd;
574      sec_ptr isection;
575      bfd *obfd;
576 {
577   arelent **relpp;
578   long relcount;
579   sec_ptr osection;
580   bfd_size_type size;
581
582   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
583       && (strip_symbols == strip_debug
584           || strip_symbols == strip_all
585           || discard_locals == locals_all))
586     {
587       return;
588     }
589
590   osection = isection->output_section;
591   size = bfd_get_section_size_before_reloc (isection);
592
593   if (size == 0 || osection == 0)
594     return;
595
596   if (strip_symbols == strip_all)
597     bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
598   else
599     {
600       long relsize;
601
602       relsize = bfd_get_reloc_upper_bound (ibfd, isection);
603       if (relsize < 0)
604         {
605           nonfatal (bfd_get_filename (ibfd));
606         }
607       if (relsize == 0)
608         bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
609       else
610         {
611           relpp = (arelent **) xmalloc (relsize);
612           relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
613           if (relcount < 0)
614             {
615               nonfatal (bfd_get_filename (ibfd));
616             }
617           bfd_set_reloc (obfd, osection, relpp, relcount);
618         }
619     }
620
621   isection->_cooked_size = isection->_raw_size;
622   isection->reloc_done = true;
623
624   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
625     {
626       PTR memhunk = (PTR) xmalloc ((unsigned) size);
627
628       if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
629                                      size))
630         {
631           nonfatal (bfd_get_filename (ibfd));
632         }
633
634       if (copy_byte >= 0) 
635         {
636           filter_bytes (memhunk, &size);
637               /* The section has gotten smaller. */
638           if (!bfd_set_section_size (obfd, osection, size))
639             nonfatal (bfd_get_filename (obfd));
640         }
641
642       if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
643                                      size))
644         {
645           nonfatal (bfd_get_filename (obfd));
646         }
647       free (memhunk);
648     }
649 }
650
651 /* Mark all the symbols which will be used in output relocations with
652    the BSF_KEEP flag so that those symbols will not be stripped.
653
654    Ignore relocations which will not appear in the output file.  */
655
656 static void
657 mark_symbols_used_in_relocations (ibfd, isection, symbols)
658      bfd *ibfd;
659      sec_ptr isection;
660      asymbol **symbols;
661 {
662   long relsize;
663   arelent **relpp;
664   long relcount, i;
665
666   /* Ignore an input section with no corresponding output section.  */
667   if (isection->output_section == NULL)
668     return;
669
670   relsize = bfd_get_reloc_upper_bound (ibfd, isection);
671   if (relsize < 0)
672     bfd_fatal (bfd_get_filename (ibfd));
673
674   relpp = (arelent **) xmalloc (relsize);
675   relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
676   if (relcount < 0)
677     bfd_fatal (bfd_get_filename (ibfd));
678
679   /* Examine each symbol used in a relocation.  If it's not one of the
680      special bfd section symbols, then mark it with BSF_KEEP.  */
681   for (i = 0; i < relcount; i++)
682     {
683       if (*relpp[i]->sym_ptr_ptr != bfd_com_section.symbol
684           && *relpp[i]->sym_ptr_ptr != bfd_abs_section.symbol
685           && *relpp[i]->sym_ptr_ptr != bfd_und_section.symbol)
686         (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
687     }
688
689   if (relpp != NULL)
690     free (relpp);
691 }
692
693 /* The number of bytes to copy at once.  */
694 #define COPY_BUF 8192
695
696 /* Copy file FROM to file TO, performing no translations.
697    Return 0 if ok, -1 if error.  */
698
699 static int
700 simple_copy (from, to)
701      char *from, *to;
702 {
703   int fromfd, tofd, nread;
704   char buf[COPY_BUF];
705
706   fromfd = open (from, O_RDONLY);
707   if (fromfd < 0)
708     return -1;
709   tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
710   if (tofd < 0)
711     {
712       close (fromfd);
713       return -1;
714     }
715   while ((nread = read (fromfd, buf, sizeof buf)) > 0)
716     {
717       if (write (tofd, buf, nread) != nread)
718         {
719           close (fromfd);
720           close (tofd);
721           return -1;
722         }
723     }
724   close (fromfd);
725   close (tofd);
726   if (nread < 0)
727     return -1;
728   return 0;
729 }
730
731 #ifndef S_ISLNK
732 #ifdef S_IFLNK
733 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
734 #else
735 #define S_ISLNK(m) 0
736 #define lstat stat
737 #endif
738 #endif
739
740 /* Rename FROM to TO, copying if TO is a link.
741    Assumes that TO already exists, because FROM is a temp file.
742    Return 0 if ok, -1 if error.  */
743
744 static int
745 smart_rename (from, to)
746      char *from, *to;
747 {
748   struct stat s;
749   int ret = 0;
750
751   if (lstat (to, &s))
752     return -1;
753
754   /* Use rename only if TO is not a symbolic link and has
755      only one hard link.  */
756   if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
757     {
758       ret = rename (from, to);
759       if (ret == 0)
760         {
761           /* Try to preserve the permission bits and ownership of TO.  */
762           chmod (to, s.st_mode & 07777);
763           chown (to, s.st_uid, s.st_gid);
764         }
765     }
766   else
767     {
768       ret = simple_copy (from, to);
769       if (ret == 0)
770         unlink (from);
771     }
772   return ret;
773 }
774
775 static int
776 strip_main (argc, argv)
777      int argc;
778      char *argv[];
779 {
780   char *input_target = NULL, *output_target = NULL;
781   boolean show_version = false;
782   int c, i;
783
784   while ((c = getopt_long (argc, argv, "I:O:F:sSgxXVv",
785                            strip_options, (int *) 0)) != EOF)
786     {
787       switch (c)
788         {
789         case 'I':
790           input_target = optarg;
791           break;
792         case 'O':
793           output_target = optarg;
794           break;
795         case 'F':
796           input_target = output_target = optarg;
797           break;
798         case 's':
799           strip_symbols = strip_all;
800           break;
801         case 'S':
802         case 'g':
803           strip_symbols = strip_debug;
804           break;
805         case 'x':
806           discard_locals = locals_all;
807           break;
808         case 'X':
809           discard_locals = locals_start_L;
810           break;
811         case 'v':
812           verbose = true;
813           break;
814         case 'V':
815           show_version = true;
816           break;
817         case 0:
818           break;                /* we've been given a long option */
819         case 'h':
820           strip_usage (stdout, 0);
821         default:
822           strip_usage (stderr, 1);
823         }
824     }
825
826   if (show_version)
827     {
828       printf ("GNU %s version %s\n", program_name, program_version);
829       exit (0);
830     }
831
832   /* Default is to strip all symbols.  */
833   if (strip_symbols == strip_undef && discard_locals == locals_undef)
834     strip_symbols = strip_all;
835
836   if (output_target == (char *) NULL)
837     output_target = input_target;
838
839   i = optind;
840   if (i == argc)
841     strip_usage (stderr, 1);
842
843   for (; i < argc; i++)
844     {
845       int hold_status = status;
846
847       char *tmpname = make_tempname (argv[i]);
848       status = 0;
849       copy_file (argv[i], tmpname, input_target, output_target);
850       if (status == 0)
851         {
852           smart_rename (tmpname, argv[i]);
853           status = hold_status;
854         }
855       else
856         unlink (tmpname);
857       free (tmpname);
858     }
859
860   return 0;
861 }
862
863 static int
864 copy_main (argc, argv)
865      int argc;
866      char *argv[];
867 {
868   char *input_filename, *output_filename;
869   char *input_target = NULL, *output_target = NULL;
870   boolean show_version = false;
871   int c;
872
873   while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
874                            copy_options, (int *) 0)) != EOF)
875     {
876       switch (c)
877         {
878         case 'b':
879           copy_byte = atoi(optarg);
880           if (copy_byte < 0)
881             {
882               fprintf (stderr, "%s: byte number must be non-negative\n",
883                        program_name);
884               exit (1);
885             }
886           break;
887         case 'i':
888           interleave = atoi(optarg);
889           if (interleave < 1)
890             {
891               fprintf(stderr, "%s: interleave must be positive\n",
892                       program_name);
893               exit (1);
894             }
895           break;
896         case 'I':
897         case 's':               /* "source" - 'I' is preferred */
898           input_target = optarg;
899           break;
900         case 'O':
901         case 'd':               /* "destination" - 'O' is preferred */
902           output_target = optarg;
903           break;
904         case 'F':
905           input_target = output_target = optarg;
906           break;
907         case 'S':
908           strip_symbols = strip_all;
909           break;
910         case 'g':
911           strip_symbols = strip_debug;
912           break;
913         case 'x':
914           discard_locals = locals_all;
915           break;
916         case 'X':
917           discard_locals = locals_start_L;
918           break;
919         case 'v':
920           verbose = true;
921           break;
922         case 'V':
923           show_version = true;
924           break;
925         case 0:
926           break;                /* we've been given a long option */
927         case 'h':
928           copy_usage (stdout, 0);
929         default:
930           copy_usage (stderr, 1);
931         }
932     }
933
934   if (show_version)
935     {
936       printf ("GNU %s version %s\n", program_name, program_version);
937       exit (0);
938     }
939
940   if (copy_byte >= interleave)
941     {
942       fprintf (stderr, "%s: byte number must be less than interleave\n",
943                program_name);
944       exit (1);
945     }
946
947   if (optind == argc || optind + 2 < argc)
948     copy_usage (stderr, 1);
949
950   input_filename = argv[optind];
951   if (optind + 1 < argc)
952     output_filename = argv[optind + 1];
953
954   /* Default is to strip no symbols.  */
955   if (strip_symbols == strip_undef && discard_locals == locals_undef)
956     strip_symbols = strip_none;
957
958   if (output_target == (char *) NULL)
959     output_target = input_target;
960
961   /* If there is no destination file then create a temp and rename
962      the result into the input.  */
963
964   if (output_filename == (char *) NULL)
965     {
966       char *tmpname = make_tempname (input_filename);
967       copy_file (input_filename, tmpname, input_target, output_target);
968       if (status == 0)
969         smart_rename (tmpname, input_filename);
970       else
971         unlink (tmpname);
972     }
973   else
974     {
975       copy_file (input_filename, output_filename, input_target, output_target);
976     }
977
978   return 0;
979 }
980
981 int
982 main (argc, argv)
983      int argc;
984      char *argv[];
985 {
986   program_name = argv[0];
987   xmalloc_set_program_name (program_name);
988   strip_symbols = strip_undef;
989   discard_locals = locals_undef;
990
991   bfd_init ();
992
993   if (is_strip < 0)
994     {
995       int i = strlen (program_name);
996       is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip"));
997     }
998
999   if (is_strip)
1000     strip_main (argc, argv);
1001   else
1002     copy_main (argc, argv);
1003
1004   return status;
1005 }