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