* ppc-dis.c (print_insn_powerpc): Don't skip optional operands
[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 static void mangle_section ();
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 unsigned long symcount;
182 {
183 register asymbol **from = isyms, **to = osyms;
184 char locals_prefix = bfd_get_symbol_leading_char (abfd) == '_' ? 'L' : '.';
185 unsigned int src_count = 0, dst_count = 0;
186
187 for (; src_count < symcount; src_count++)
188 {
189 asymbol *sym = from[src_count];
190 flagword flags = sym->flags;
191 int keep;
192
193 if ((flags & BSF_GLOBAL) /* Keep if external. */
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_asymbol_name (sym)[0] != locals_prefix);
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 unsigned int 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 if (strip_symbols == strip_all && discard_locals == locals_undef)
271 {
272 osympp = isympp = NULL;
273 symcount = 0;
274 }
275 else
276 {
277 osympp = isympp = (asymbol **) xmalloc (get_symtab_upper_bound (ibfd));
278 symcount = bfd_canonicalize_symtab (ibfd, isympp);
279
280 if (strip_symbols == strip_debug || discard_locals != locals_undef)
281 {
282 osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
283 symcount = filter_symbols (ibfd, osympp, isympp, symcount);
284 }
285 }
286
287 bfd_set_symtab (obfd, osympp, symcount);
288
289 /* bfd mandates that all output sections be created and sizes set before
290 any output is done. Thus, we traverse all sections multiple times. */
291 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
292 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
293 bfd_map_over_sections (ibfd, mangle_section, (void *) obfd);
294 }
295
296 static char *
297 cat (a, b, c)
298 char *a;
299 char *b;
300 char *c;
301 {
302 size_t size = strlen (a) + strlen (b) + strlen (c);
303 char *r = xmalloc (size + 1);
304
305 strcpy (r, a);
306 strcat (r, b);
307 strcat (r, c);
308 return r;
309 }
310
311 /* Read each archive element in turn from IBFD, copy the
312 contents to temp file, and keep the temp file handle. */
313
314 static void
315 copy_archive (ibfd, obfd, output_target)
316 bfd *ibfd;
317 bfd *obfd;
318 char *output_target;
319 {
320 bfd **ptr = &obfd->archive_head;
321 bfd *this_element;
322 char *dir = cat ("./#", make_tempname (""), "cd");
323
324 /* Make a temp directory to hold the contents. */
325 mkdir (dir, 0777);
326 obfd->has_armap = ibfd->has_armap;
327
328 this_element = bfd_openr_next_archived_file (ibfd, NULL);
329 ibfd->archive_head = this_element;
330 while (this_element != (bfd *) NULL)
331 {
332 /* Create an output file for this member. */
333 char *output_name = cat (dir, "/", bfd_get_filename(this_element));
334 bfd *output_bfd = bfd_openw (output_name, output_target);
335
336 if (output_bfd == (bfd *) NULL)
337 {
338 nonfatal (output_name);
339 }
340 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
341 {
342 nonfatal (bfd_get_filename (obfd));
343 }
344
345 if (bfd_check_format (this_element, bfd_object) == true)
346 {
347 copy_object (this_element, output_bfd);
348 }
349
350 bfd_close (output_bfd);
351 /* Open the newly output file and attatch to our list. */
352 output_bfd = bfd_openr (output_name, output_target);
353
354 /* Mark it for deletion. */
355 *ptr = output_bfd;
356 ptr = &output_bfd->next;
357 this_element->next = bfd_openr_next_archived_file (ibfd, this_element);
358 this_element = this_element->next;
359 }
360 *ptr = (bfd *) NULL;
361
362 if (!bfd_close (obfd))
363 {
364 nonfatal (bfd_get_filename (obfd));
365 }
366
367 /* Delete all the files that we opened.
368 Construct their names again, unfortunately, but
369 we're about to exit anyway. */
370 for (this_element = ibfd->archive_head;
371 this_element != (bfd *) NULL;
372 this_element = this_element->next)
373 {
374 unlink (cat (dir, "/", bfd_get_filename (this_element)));
375 }
376 rmdir (dir);
377 if (!bfd_close (ibfd))
378 {
379 nonfatal (bfd_get_filename (ibfd));
380 }
381 }
382
383 /* The top-level control. */
384
385 static void
386 copy_file (input_filename, output_filename, input_target, output_target)
387 char *input_filename;
388 char *output_filename;
389 char *input_target;
390 char *output_target;
391 {
392 bfd *ibfd;
393 char **matching;
394
395 /* To allow us to do "strip *" without dying on the first
396 non-object file, failures are nonfatal. */
397
398 ibfd = bfd_openr (input_filename, input_target);
399 if (ibfd == NULL)
400 {
401 nonfatal (input_filename);
402 }
403
404 if (bfd_check_format (ibfd, bfd_archive))
405 {
406 bfd *obfd = bfd_openw (output_filename, output_target);
407 if (obfd == NULL)
408 {
409 nonfatal (output_filename);
410 }
411 copy_archive (ibfd, obfd, output_target);
412 }
413 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
414 {
415 bfd *obfd = bfd_openw (output_filename, output_target);
416 if (obfd == NULL)
417 {
418 nonfatal (output_filename);
419 }
420
421 copy_object (ibfd, obfd);
422
423 if (!bfd_close (obfd))
424 {
425 nonfatal (output_filename);
426 }
427
428 if (!bfd_close (ibfd))
429 {
430 nonfatal (input_filename);
431 }
432 }
433 else
434 {
435 bfd_nonfatal (input_filename);
436 if (bfd_error == file_ambiguously_recognized)
437 {
438 list_matching_formats (matching);
439 free (matching);
440 }
441 status = 1;
442 }
443 }
444
445 /* Create a section in OBFD with the same name and attributes
446 as ISECTION in IBFD. */
447
448 static void
449 setup_section (ibfd, isection, obfd)
450 bfd *ibfd;
451 sec_ptr isection;
452 bfd *obfd;
453 {
454 sec_ptr osection;
455 char *err;
456
457 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
458 && (strip_symbols == strip_debug
459 || strip_symbols == strip_all
460 || discard_locals == locals_all))
461 return;
462
463 osection = bfd_get_section_by_name (obfd, bfd_section_name (ibfd, isection));
464 if (osection == NULL)
465 {
466 osection = bfd_make_section (obfd, bfd_section_name (ibfd, isection));
467 if (osection == NULL)
468 {
469 err = "making";
470 goto loser;
471 }
472 }
473
474 if (!bfd_set_section_size (obfd,
475 osection,
476 bfd_section_size (ibfd, isection)))
477 {
478 err = "size";
479 goto loser;
480 }
481
482 if (bfd_set_section_vma (obfd,
483 osection,
484 bfd_section_vma (ibfd, isection))
485 == false)
486 {
487 err = "vma";
488 goto loser;
489 }
490
491 if (bfd_set_section_alignment (obfd,
492 osection,
493 bfd_section_alignment (ibfd, isection))
494 == false)
495 {
496 err = "alignment";
497 goto loser;
498 }
499
500 if (!bfd_set_section_flags (obfd, osection,
501 bfd_get_section_flags (ibfd, isection)))
502 {
503 err = "flags";
504 goto loser;
505 }
506
507 /* All went well */
508 return;
509
510 loser:
511 fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
512 program_name,
513 bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
514 err, bfd_errmsg (bfd_error));
515 status = 1;
516 }
517
518 /* Copy the data of input section ISECTION of IBFD
519 to an output section with the same name in OBFD.
520 If stripping then don't copy any relocation info. */
521
522 static void
523 copy_section (ibfd, isection, obfd)
524 bfd *ibfd;
525 sec_ptr isection;
526 bfd *obfd;
527 {
528 arelent **relpp;
529 int relcount;
530 sec_ptr osection;
531 bfd_size_type size;
532
533 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
534 && (strip_symbols == strip_debug
535 || strip_symbols == strip_all
536 || discard_locals == locals_all))
537 {
538 return;
539 }
540
541 osection = bfd_get_section_by_name (obfd,
542 bfd_section_name (ibfd, isection));
543
544 size = bfd_get_section_size_before_reloc (isection);
545
546 if (size == 0)
547 return;
548
549 if (strip_symbols == strip_all
550 || bfd_get_reloc_upper_bound (ibfd, isection) == 0)
551 {
552 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
553 }
554 else
555 {
556 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (ibfd, isection));
557 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
558 bfd_set_reloc (obfd, osection, relpp, relcount);
559 }
560
561 isection->_cooked_size = isection->_raw_size;
562 isection->reloc_done = true;
563
564 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
565 {
566 PTR memhunk = (PTR) xmalloc ((unsigned) size);
567
568 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
569 size))
570 {
571 nonfatal (bfd_get_filename (ibfd));
572 }
573
574 if (copy_byte >= 0)
575 filter_bytes (memhunk, &size);
576
577 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
578 size))
579 {
580 nonfatal (bfd_get_filename (obfd));
581 }
582 free (memhunk);
583 }
584 }
585
586 /* All the symbols have been read in and point to their owning input section.
587 They have been relocated so that they are all relative to the base of
588 their owning section. On the way out, all the symbols will be relocated to
589 their new location in the output file, through some complex sums. */
590
591 static void
592 mangle_section (ibfd, p, obfd)
593 bfd *ibfd;
594 asection *p;
595 bfd *obfd;
596 {
597 p->output_section = bfd_get_section_by_name (obfd, p->name);
598 p->output_offset = 0;
599 }
600
601 /* The number of bytes to copy at once. */
602 #define COPY_BUF 8192
603
604 /* Copy file FROM to file TO, performing no translations.
605 Return 0 if ok, -1 if error. */
606
607 static int
608 simple_copy (from, to)
609 char *from, *to;
610 {
611 int fromfd, tofd, nread;
612 char buf[COPY_BUF];
613
614 fromfd = open (from, O_RDONLY);
615 if (fromfd < 0)
616 return -1;
617 tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
618 if (tofd < 0)
619 {
620 close (fromfd);
621 return -1;
622 }
623 while ((nread = read (fromfd, buf, sizeof buf)) > 0)
624 {
625 if (write (tofd, buf, nread) != nread)
626 {
627 close (fromfd);
628 close (tofd);
629 return -1;
630 }
631 }
632 close (fromfd);
633 close (tofd);
634 if (nread < 0)
635 return -1;
636 return 0;
637 }
638
639 #ifndef S_ISLNK
640 #ifdef S_IFLNK
641 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
642 #else
643 #define S_ISLNK(m) 0
644 #define lstat stat
645 #endif
646 #endif
647
648 /* Rename FROM to TO, copying if TO is a link.
649 Assumes that TO already exists, because FROM is a temp file.
650 Return 0 if ok, -1 if error. */
651
652 static int
653 smart_rename (from, to)
654 char *from, *to;
655 {
656 struct stat s;
657 int ret = 0;
658
659 if (lstat (to, &s))
660 return -1;
661
662 /* Use rename only if TO is not a symbolic link and has
663 only one hard link. */
664 if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
665 {
666 ret = rename (from, to);
667 if (ret == 0)
668 {
669 /* Try to preserve the permission bits and ownership of TO. */
670 chmod (to, s.st_mode & 07777);
671 chown (to, s.st_uid, s.st_gid);
672 }
673 }
674 else
675 {
676 ret = simple_copy (from, to);
677 if (ret == 0)
678 unlink (from);
679 }
680 return ret;
681 }
682
683 static int
684 strip_main (argc, argv)
685 int argc;
686 char *argv[];
687 {
688 char *input_target = NULL, *output_target = NULL;
689 boolean show_version = false;
690 int c, i;
691
692 while ((c = getopt_long (argc, argv, "I:O:F:sSgxXVv",
693 strip_options, (int *) 0)) != EOF)
694 {
695 switch (c)
696 {
697 case 'I':
698 input_target = optarg;
699 case 'O':
700 output_target = optarg;
701 break;
702 case 'F':
703 input_target = output_target = optarg;
704 break;
705 case 's':
706 strip_symbols = strip_all;
707 break;
708 case 'S':
709 case 'g':
710 strip_symbols = strip_debug;
711 break;
712 case 'x':
713 discard_locals = locals_all;
714 break;
715 case 'X':
716 discard_locals = locals_start_L;
717 break;
718 case 'v':
719 verbose = true;
720 break;
721 case 'V':
722 show_version = true;
723 break;
724 case 0:
725 break; /* we've been given a long option */
726 case 'h':
727 strip_usage (stdout, 0);
728 default:
729 strip_usage (stderr, 1);
730 }
731 }
732
733 if (show_version)
734 {
735 printf ("GNU %s version %s\n", program_name, program_version);
736 exit (0);
737 }
738
739 /* Default is to strip all symbols. */
740 if (strip_symbols == strip_undef && discard_locals == locals_undef)
741 strip_symbols = strip_all;
742
743 if (output_target == (char *) NULL)
744 output_target = input_target;
745
746 i = optind;
747 if (i == argc)
748 strip_usage (stderr, 1);
749
750 for (; i < argc; i++)
751 {
752 int hold_status = status;
753
754 char *tmpname = make_tempname (argv[i]);
755 status = 0;
756 copy_file (argv[i], tmpname, input_target, output_target);
757 if (status == 0)
758 {
759 smart_rename (tmpname, argv[i]);
760 status = hold_status;
761 }
762 else
763 unlink (tmpname);
764 free (tmpname);
765 }
766
767 return 0;
768 }
769
770 static int
771 copy_main (argc, argv)
772 int argc;
773 char *argv[];
774 {
775 char *input_filename, *output_filename;
776 char *input_target = NULL, *output_target = NULL;
777 boolean show_version = false;
778 int c;
779
780 while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
781 copy_options, (int *) 0)) != EOF)
782 {
783 switch (c)
784 {
785 case 'b':
786 copy_byte = atoi(optarg);
787 if (copy_byte < 0)
788 {
789 fprintf (stderr, "%s: byte number must be non-negative\n",
790 program_name);
791 exit (1);
792 }
793 break;
794 case 'i':
795 interleave = atoi(optarg);
796 if (interleave < 1)
797 {
798 fprintf(stderr, "%s: interleave must be positive\n",
799 program_name);
800 exit (1);
801 }
802 break;
803 case 'I':
804 case 's': /* "source" - 'I' is preferred */
805 input_target = optarg;
806 case 'O':
807 case 'd': /* "destination" - 'O' is preferred */
808 output_target = optarg;
809 break;
810 case 'F':
811 input_target = output_target = optarg;
812 break;
813 case 'S':
814 strip_symbols = strip_all;
815 break;
816 case 'g':
817 strip_symbols = strip_debug;
818 break;
819 case 'x':
820 discard_locals = locals_all;
821 break;
822 case 'X':
823 discard_locals = locals_start_L;
824 break;
825 case 'v':
826 verbose = true;
827 break;
828 case 'V':
829 show_version = true;
830 break;
831 case 0:
832 break; /* we've been given a long option */
833 case 'h':
834 copy_usage (stdout, 0);
835 default:
836 copy_usage (stderr, 1);
837 }
838 }
839
840 if (show_version)
841 {
842 printf ("GNU %s version %s\n", program_name, program_version);
843 exit (0);
844 }
845
846 if (copy_byte >= interleave)
847 {
848 fprintf (stderr, "%s: byte number must be less than interleave\n",
849 program_name);
850 exit (1);
851 }
852
853 if (optind == argc || optind + 2 < argc)
854 copy_usage (stderr, 1);
855
856 input_filename = argv[optind];
857 if (optind + 1 < argc)
858 output_filename = argv[optind + 1];
859
860 /* Default is to strip no symbols. */
861 if (strip_symbols == strip_undef && discard_locals == locals_undef)
862 strip_symbols = strip_none;
863
864 if (output_target == (char *) NULL)
865 output_target = input_target;
866
867 /* If there is no destination file then create a temp and rename
868 the result into the input. */
869
870 if (output_filename == (char *) NULL)
871 {
872 char *tmpname = make_tempname (input_filename);
873 copy_file (input_filename, tmpname, input_target, output_target);
874 if (status == 0)
875 smart_rename (tmpname, input_filename);
876 else
877 unlink (tmpname);
878 }
879 else
880 {
881 copy_file (input_filename, output_filename, input_target, output_target);
882 }
883
884 return 0;
885 }
886
887 int
888 main (argc, argv)
889 int argc;
890 char *argv[];
891 {
892 program_name = argv[0];
893 strip_symbols = strip_undef;
894 discard_locals = locals_undef;
895
896 bfd_init ();
897
898 if (is_strip < 0)
899 {
900 int i = strlen (program_name);
901 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip"));
902 }
903
904 if (is_strip)
905 strip_main (argc, argv);
906 else
907 copy_main (argc, argv);
908
909 return status;
910 }
This page took 0.066081 seconds and 4 git commands to generate.