bfd/
[external/binutils.git] / binutils / objcopy.c
1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation, Inc.
5
6    This file is part of GNU Binutils.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22 \f
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "progress.h"
26 #include "getopt.h"
27 #include "libiberty.h"
28 #include "bucomm.h"
29 #include "budbg.h"
30 #include "filenames.h"
31 #include "fnmatch.h"
32 #include "elf-bfd.h"
33 #include <sys/stat.h>
34 #include "libbfd.h"
35
36 /* A list of symbols to explicitly strip out, or to keep.  A linked
37    list is good enough for a small number from the command line, but
38    this will slow things down a lot if many symbols are being
39    deleted.  */
40
41 struct symlist
42 {
43   const char *name;
44   struct symlist *next;
45 };
46
47 /* A list to support redefine_sym.  */
48 struct redefine_node
49 {
50   char *source;
51   char *target;
52   struct redefine_node *next;
53 };
54
55 typedef struct section_rename
56 {
57   const char *            old_name;
58   const char *            new_name;
59   flagword                flags;
60   struct section_rename * next;
61 }
62 section_rename;
63
64 /* List of sections to be renamed.  */
65 static section_rename *section_rename_list;
66
67 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
68
69 static asymbol **isympp = NULL; /* Input symbols.  */
70 static asymbol **osympp = NULL; /* Output symbols that survive stripping.  */
71
72 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes.  */
73 static int copy_byte = -1;
74 static int interleave = 4;
75
76 static bfd_boolean verbose;             /* Print file and target names.  */
77 static bfd_boolean preserve_dates;      /* Preserve input file timestamp.  */
78 static int status = 0;          /* Exit status.  */
79
80 enum strip_action
81   {
82     STRIP_UNDEF,
83     STRIP_NONE,                 /* Don't strip.  */
84     STRIP_DEBUG,                /* Strip all debugger symbols.  */
85     STRIP_UNNEEDED,             /* Strip unnecessary symbols.  */
86     STRIP_NONDEBUG,             /* Strip everything but debug info.  */
87     STRIP_ALL                   /* Strip all symbols.  */
88   };
89
90 /* Which symbols to remove.  */
91 static enum strip_action strip_symbols;
92
93 enum locals_action
94   {
95     LOCALS_UNDEF,
96     LOCALS_START_L,             /* Discard locals starting with L.  */
97     LOCALS_ALL                  /* Discard all locals.  */
98   };
99
100 /* Which local symbols to remove.  Overrides STRIP_ALL.  */
101 static enum locals_action discard_locals;
102
103 /* What kind of change to perform.  */
104 enum change_action
105 {
106   CHANGE_IGNORE,
107   CHANGE_MODIFY,
108   CHANGE_SET
109 };
110
111 /* Structure used to hold lists of sections and actions to take.  */
112 struct section_list
113 {
114   struct section_list * next;      /* Next section to change.  */
115   const char *          name;      /* Section name.  */
116   bfd_boolean           used;      /* Whether this entry was used.  */
117   bfd_boolean           remove;    /* Whether to remove this section.  */
118   bfd_boolean           copy;      /* Whether to copy this section.  */
119   enum change_action    change_vma;/* Whether to change or set VMA.  */
120   bfd_vma               vma_val;   /* Amount to change by or set to.  */
121   enum change_action    change_lma;/* Whether to change or set LMA.  */
122   bfd_vma               lma_val;   /* Amount to change by or set to.  */
123   bfd_boolean           set_flags; /* Whether to set the section flags.  */
124   flagword              flags;     /* What to set the section flags to.  */
125 };
126
127 static struct section_list *change_sections;
128
129 /* TRUE if some sections are to be removed.  */
130 static bfd_boolean sections_removed;
131
132 /* TRUE if only some sections are to be copied.  */
133 static bfd_boolean sections_copied;
134
135 /* Changes to the start address.  */
136 static bfd_vma change_start = 0;
137 static bfd_boolean set_start_set = FALSE;
138 static bfd_vma set_start;
139
140 /* Changes to section addresses.  */
141 static bfd_vma change_section_address = 0;
142
143 /* Filling gaps between sections.  */
144 static bfd_boolean gap_fill_set = FALSE;
145 static bfd_byte gap_fill = 0;
146
147 /* Pad to a given address.  */
148 static bfd_boolean pad_to_set = FALSE;
149 static bfd_vma pad_to;
150
151 /* Use alternative machine code?  */
152 static unsigned long use_alt_mach_code = 0;
153
154 /* Output BFD flags user wants to set or clear */
155 static flagword bfd_flags_to_set;
156 static flagword bfd_flags_to_clear;
157
158 /* List of sections to add.  */
159 struct section_add
160 {
161   /* Next section to add.  */
162   struct section_add *next;
163   /* Name of section to add.  */
164   const char *name;
165   /* Name of file holding section contents.  */
166   const char *filename;
167   /* Size of file.  */
168   size_t size;
169   /* Contents of file.  */
170   bfd_byte *contents;
171   /* BFD section, after it has been added.  */
172   asection *section;
173 };
174
175 /* List of sections to add to the output BFD.  */
176 static struct section_add *add_sections;
177
178 /* If non-NULL the argument to --add-gnu-debuglink.
179    This should be the filename to store in the .gnu_debuglink section.  */
180 static const char * gnu_debuglink_filename = NULL;
181
182 /* Whether to convert debugging information.  */
183 static bfd_boolean convert_debugging = FALSE;
184
185 /* Whether to change the leading character in symbol names.  */
186 static bfd_boolean change_leading_char = FALSE;
187
188 /* Whether to remove the leading character from global symbol names.  */
189 static bfd_boolean remove_leading_char = FALSE;
190
191 /* Whether to permit wildcard in symbol comparison.  */
192 static bfd_boolean wildcard = FALSE;
193
194 /* True if --localize-hidden is in effect.  */
195 static bfd_boolean localize_hidden = FALSE;
196
197 /* List of symbols to strip, keep, localize, keep-global, weaken,
198    or redefine.  */
199 static struct symlist *strip_specific_list = NULL;
200 static struct symlist *strip_unneeded_list = NULL;
201 static struct symlist *keep_specific_list = NULL;
202 static struct symlist *localize_specific_list = NULL;
203 static struct symlist *globalize_specific_list = NULL;
204 static struct symlist *keepglobal_specific_list = NULL;
205 static struct symlist *weaken_specific_list = NULL;
206 static struct redefine_node *redefine_sym_list = NULL;
207
208 /* If this is TRUE, we weaken global symbols (set BSF_WEAK).  */
209 static bfd_boolean weaken = FALSE;
210
211 /* If this is TRUE, we retain BSF_FILE symbols.  */
212 static bfd_boolean keep_file_symbols = FALSE;
213
214 /* Prefix symbols/sections.  */
215 static char *prefix_symbols_string = 0;
216 static char *prefix_sections_string = 0;
217 static char *prefix_alloc_sections_string = 0;
218
219 /* True if --extract-symbol was passed on the command line.  */
220 static bfd_boolean extract_symbol = FALSE;
221
222 /* If `reverse_bytes' is nonzero, then reverse the order of every chunk
223    of <reverse_bytes> bytes within each output section.  */
224 static int reverse_bytes = 0;
225
226
227 /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
228 enum command_line_switch
229   {
230     OPTION_ADD_SECTION=150,
231     OPTION_CHANGE_ADDRESSES,
232     OPTION_CHANGE_LEADING_CHAR,
233     OPTION_CHANGE_START,
234     OPTION_CHANGE_SECTION_ADDRESS,
235     OPTION_CHANGE_SECTION_LMA,
236     OPTION_CHANGE_SECTION_VMA,
237     OPTION_CHANGE_WARNINGS,
238     OPTION_DEBUGGING,
239     OPTION_GAP_FILL,
240     OPTION_NO_CHANGE_WARNINGS,
241     OPTION_PAD_TO,
242     OPTION_REMOVE_LEADING_CHAR,
243     OPTION_SET_SECTION_FLAGS,
244     OPTION_SET_START,
245     OPTION_STRIP_UNNEEDED,
246     OPTION_WEAKEN,
247     OPTION_REDEFINE_SYM,
248     OPTION_REDEFINE_SYMS,
249     OPTION_SREC_LEN,
250     OPTION_SREC_FORCES3,
251     OPTION_STRIP_SYMBOLS,
252     OPTION_STRIP_UNNEEDED_SYMBOL,
253     OPTION_STRIP_UNNEEDED_SYMBOLS,
254     OPTION_KEEP_SYMBOLS,
255     OPTION_LOCALIZE_HIDDEN,
256     OPTION_LOCALIZE_SYMBOLS,
257     OPTION_GLOBALIZE_SYMBOL,
258     OPTION_GLOBALIZE_SYMBOLS,
259     OPTION_KEEPGLOBAL_SYMBOLS,
260     OPTION_WEAKEN_SYMBOLS,
261     OPTION_RENAME_SECTION,
262     OPTION_ALT_MACH_CODE,
263     OPTION_PREFIX_SYMBOLS,
264     OPTION_PREFIX_SECTIONS,
265     OPTION_PREFIX_ALLOC_SECTIONS,
266     OPTION_FORMATS_INFO,
267     OPTION_ADD_GNU_DEBUGLINK,
268     OPTION_ONLY_KEEP_DEBUG,
269     OPTION_KEEP_FILE_SYMBOLS,
270     OPTION_READONLY_TEXT,
271     OPTION_WRITABLE_TEXT,
272     OPTION_PURE,
273     OPTION_IMPURE,
274     OPTION_EXTRACT_SYMBOL,
275     OPTION_REVERSE_BYTES
276   };
277
278 /* Options to handle if running as "strip".  */
279
280 static struct option strip_options[] =
281 {
282   {"discard-all", no_argument, 0, 'x'},
283   {"discard-locals", no_argument, 0, 'X'},
284   {"format", required_argument, 0, 'F'}, /* Obsolete */
285   {"help", no_argument, 0, 'h'},
286   {"info", no_argument, 0, OPTION_FORMATS_INFO},
287   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
288   {"input-target", required_argument, 0, 'I'},
289   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
290   {"keep-symbol", required_argument, 0, 'K'},
291   {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
292   {"output-format", required_argument, 0, 'O'}, /* Obsolete */
293   {"output-target", required_argument, 0, 'O'},
294   {"output-file", required_argument, 0, 'o'},
295   {"preserve-dates", no_argument, 0, 'p'},
296   {"remove-section", required_argument, 0, 'R'},
297   {"strip-all", no_argument, 0, 's'},
298   {"strip-debug", no_argument, 0, 'S'},
299   {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
300   {"strip-symbol", required_argument, 0, 'N'},
301   {"target", required_argument, 0, 'F'},
302   {"verbose", no_argument, 0, 'v'},
303   {"version", no_argument, 0, 'V'},
304   {"wildcard", no_argument, 0, 'w'},
305   {0, no_argument, 0, 0}
306 };
307
308 /* Options to handle if running as "objcopy".  */
309
310 static struct option copy_options[] =
311 {
312   {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
313   {"add-section", required_argument, 0, OPTION_ADD_SECTION},
314   {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
315   {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
316   {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
317   {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
318   {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
319   {"binary-architecture", required_argument, 0, 'B'},
320   {"byte", required_argument, 0, 'b'},
321   {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
322   {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
323   {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
324   {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
325   {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
326   {"change-start", required_argument, 0, OPTION_CHANGE_START},
327   {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
328   {"debugging", no_argument, 0, OPTION_DEBUGGING},
329   {"discard-all", no_argument, 0, 'x'},
330   {"discard-locals", no_argument, 0, 'X'},
331   {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
332   {"format", required_argument, 0, 'F'}, /* Obsolete */
333   {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
334   {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
335   {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
336   {"help", no_argument, 0, 'h'},
337   {"impure", no_argument, 0, OPTION_IMPURE},
338   {"info", no_argument, 0, OPTION_FORMATS_INFO},
339   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
340   {"input-target", required_argument, 0, 'I'},
341   {"interleave", required_argument, 0, 'i'},
342   {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
343   {"keep-global-symbol", required_argument, 0, 'G'},
344   {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
345   {"keep-symbol", required_argument, 0, 'K'},
346   {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
347   {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
348   {"localize-symbol", required_argument, 0, 'L'},
349   {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
350   {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
351   {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
352   {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
353   {"only-section", required_argument, 0, 'j'},
354   {"output-format", required_argument, 0, 'O'}, /* Obsolete */
355   {"output-target", required_argument, 0, 'O'},
356   {"pad-to", required_argument, 0, OPTION_PAD_TO},
357   {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
358   {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
359   {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
360   {"preserve-dates", no_argument, 0, 'p'},
361   {"pure", no_argument, 0, OPTION_PURE},
362   {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
363   {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
364   {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
365   {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
366   {"remove-section", required_argument, 0, 'R'},
367   {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
368   {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
369   {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
370   {"set-start", required_argument, 0, OPTION_SET_START},
371   {"srec-len", required_argument, 0, OPTION_SREC_LEN},
372   {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
373   {"strip-all", no_argument, 0, 'S'},
374   {"strip-debug", no_argument, 0, 'g'},
375   {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
376   {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
377   {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
378   {"strip-symbol", required_argument, 0, 'N'},
379   {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
380   {"target", required_argument, 0, 'F'},
381   {"verbose", no_argument, 0, 'v'},
382   {"version", no_argument, 0, 'V'},
383   {"weaken", no_argument, 0, OPTION_WEAKEN},
384   {"weaken-symbol", required_argument, 0, 'W'},
385   {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
386   {"wildcard", no_argument, 0, 'w'},
387   {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
388   {0, no_argument, 0, 0}
389 };
390
391 /* IMPORTS */
392 extern char *program_name;
393
394 /* This flag distinguishes between strip and objcopy:
395    1 means this is 'strip'; 0 means this is 'objcopy'.
396    -1 means if we should use argv[0] to decide.  */
397 extern int is_strip;
398
399 /* The maximum length of an S record.  This variable is declared in srec.c
400    and can be modified by the --srec-len parameter.  */
401 extern unsigned int Chunk;
402
403 /* Restrict the generation of Srecords to type S3 only.
404    This variable is declare in bfd/srec.c and can be toggled
405    on by the --srec-forceS3 command line switch.  */
406 extern bfd_boolean S3Forced;
407
408 /* Defined in bfd/binary.c.  Used to set architecture and machine of input
409    binary files.  */
410 extern enum bfd_architecture  bfd_external_binary_architecture;
411 extern unsigned long          bfd_external_machine;
412
413 /* Forward declarations.  */
414 static void setup_section (bfd *, asection *, void *);
415 static void setup_bfd_headers (bfd *, bfd *);
416 static void copy_section (bfd *, asection *, void *);
417 static void get_sections (bfd *, asection *, void *);
418 static int compare_section_lma (const void *, const void *);
419 static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
420 static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
421 static const char *lookup_sym_redefinition (const char *);
422 \f
423 static void
424 copy_usage (FILE *stream, int exit_status)
425 {
426   fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
427   fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
428   fprintf (stream, _(" The options are:\n"));
429   fprintf (stream, _("\
430   -I --input-target <bfdname>      Assume input file is in format <bfdname>\n\
431   -O --output-target <bfdname>     Create an output file in format <bfdname>\n\
432   -B --binary-architecture <arch>  Set arch of output file, when input is binary\n\
433   -F --target <bfdname>            Set both input and output format to <bfdname>\n\
434      --debugging                   Convert debugging information, if possible\n\
435   -p --preserve-dates              Copy modified/access timestamps to the output\n\
436   -j --only-section <name>         Only copy section <name> into the output\n\
437      --add-gnu-debuglink=<file>    Add section .gnu_debuglink linking to <file>\n\
438   -R --remove-section <name>       Remove section <name> from the output\n\
439   -S --strip-all                   Remove all symbol and relocation information\n\
440   -g --strip-debug                 Remove all debugging symbols & sections\n\
441      --strip-unneeded              Remove all symbols not needed by relocations\n\
442   -N --strip-symbol <name>         Do not copy symbol <name>\n\
443      --strip-unneeded-symbol <name>\n\
444                                    Do not copy symbol <name> unless needed by\n\
445                                      relocations\n\
446      --only-keep-debug             Strip everything but the debug information\n\
447      --extract-symbol              Remove section contents but keep symbols\n\
448   -K --keep-symbol <name>          Do not strip symbol <name>\n\
449      --keep-file-symbols           Do not strip file symbol(s)\n\
450      --localize-hidden             Turn all ELF hidden symbols into locals\n\
451   -L --localize-symbol <name>      Force symbol <name> to be marked as a local\n\
452      --globalize-symbol <name>     Force symbol <name> to be marked as a global\n\
453   -G --keep-global-symbol <name>   Localize all symbols except <name>\n\
454   -W --weaken-symbol <name>        Force symbol <name> to be marked as a weak\n\
455      --weaken                      Force all global symbols to be marked as weak\n\
456   -w --wildcard                    Permit wildcard in symbol comparison\n\
457   -x --discard-all                 Remove all non-global symbols\n\
458   -X --discard-locals              Remove any compiler-generated symbols\n\
459   -i --interleave <number>         Only copy one out of every <number> bytes\n\
460   -b --byte <num>                  Select byte <num> in every interleaved block\n\
461      --gap-fill <val>              Fill gaps between sections with <val>\n\
462      --pad-to <addr>               Pad the last section up to address <addr>\n\
463      --set-start <addr>            Set the start address to <addr>\n\
464     {--change-start|--adjust-start} <incr>\n\
465                                    Add <incr> to the start address\n\
466     {--change-addresses|--adjust-vma} <incr>\n\
467                                    Add <incr> to LMA, VMA and start addresses\n\
468     {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
469                                    Change LMA and VMA of section <name> by <val>\n\
470      --change-section-lma <name>{=|+|-}<val>\n\
471                                    Change the LMA of section <name> by <val>\n\
472      --change-section-vma <name>{=|+|-}<val>\n\
473                                    Change the VMA of section <name> by <val>\n\
474     {--[no-]change-warnings|--[no-]adjust-warnings}\n\
475                                    Warn if a named section does not exist\n\
476      --set-section-flags <name>=<flags>\n\
477                                    Set section <name>'s properties to <flags>\n\
478      --add-section <name>=<file>   Add section <name> found in <file> to output\n\
479      --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
480      --change-leading-char         Force output format's leading character style\n\
481      --remove-leading-char         Remove leading character from global symbols\n\
482      --reverse-bytes=<num>         Reverse <num> bytes at a time, in output sections with content\n\
483      --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
484      --redefine-syms <file>        --redefine-sym for all symbol pairs \n\
485                                      listed in <file>\n\
486      --srec-len <number>           Restrict the length of generated Srecords\n\
487      --srec-forceS3                Restrict the type of generated Srecords to S3\n\
488      --strip-symbols <file>        -N for all symbols listed in <file>\n\
489      --strip-unneeded-symbols <file>\n\
490                                    --strip-unneeded-symbol for all symbols listed\n\
491                                      in <file>\n\
492      --keep-symbols <file>         -K for all symbols listed in <file>\n\
493      --localize-symbols <file>     -L for all symbols listed in <file>\n\
494      --globalize-symbols <file>    --globalize-symbol for all in <file>\n\
495      --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
496      --weaken-symbols <file>       -W for all symbols listed in <file>\n\
497      --alt-machine-code <index>    Use the target's <index>'th alternative machine\n\
498      --writable-text               Mark the output text as writable\n\
499      --readonly-text               Make the output text write protected\n\
500      --pure                        Mark the output file as demand paged\n\
501      --impure                      Mark the output file as impure\n\
502      --prefix-symbols <prefix>     Add <prefix> to start of every symbol name\n\
503      --prefix-sections <prefix>    Add <prefix> to start of every section name\n\
504      --prefix-alloc-sections <prefix>\n\
505                                    Add <prefix> to start of every allocatable\n\
506                                      section name\n\
507   -v --verbose                     List all object files modified\n\
508   @<file>                          Read options from <file>\n\
509   -V --version                     Display this program's version number\n\
510   -h --help                        Display this output\n\
511      --info                        List object formats & architectures supported\n\
512 "));
513   list_supported_targets (program_name, stream);
514   if (REPORT_BUGS_TO[0] && exit_status == 0)
515     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
516   exit (exit_status);
517 }
518
519 static void
520 strip_usage (FILE *stream, int exit_status)
521 {
522   fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
523   fprintf (stream, _(" Removes symbols and sections from files\n"));
524   fprintf (stream, _(" The options are:\n"));
525   fprintf (stream, _("\
526   -I --input-target=<bfdname>      Assume input file is in format <bfdname>\n\
527   -O --output-target=<bfdname>     Create an output file in format <bfdname>\n\
528   -F --target=<bfdname>            Set both input and output format to <bfdname>\n\
529   -p --preserve-dates              Copy modified/access timestamps to the output\n\
530   -R --remove-section=<name>       Remove section <name> from the output\n\
531   -s --strip-all                   Remove all symbol and relocation information\n\
532   -g -S -d --strip-debug           Remove all debugging symbols & sections\n\
533      --strip-unneeded              Remove all symbols not needed by relocations\n\
534      --only-keep-debug             Strip everything but the debug information\n\
535   -N --strip-symbol=<name>         Do not copy symbol <name>\n\
536   -K --keep-symbol=<name>          Do not strip symbol <name>\n\
537      --keep-file-symbols           Do not strip file symbol(s)\n\
538   -w --wildcard                    Permit wildcard in symbol comparison\n\
539   -x --discard-all                 Remove all non-global symbols\n\
540   -X --discard-locals              Remove any compiler-generated symbols\n\
541   -v --verbose                     List all object files modified\n\
542   -V --version                     Display this program's version number\n\
543   -h --help                        Display this output\n\
544      --info                        List object formats & architectures supported\n\
545   -o <file>                        Place stripped output into <file>\n\
546 "));
547
548   list_supported_targets (program_name, stream);
549   if (REPORT_BUGS_TO[0] && exit_status == 0)
550     fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
551   exit (exit_status);
552 }
553
554 /* Parse section flags into a flagword, with a fatal error if the
555    string can't be parsed.  */
556
557 static flagword
558 parse_flags (const char *s)
559 {
560   flagword ret;
561   const char *snext;
562   int len;
563
564   ret = SEC_NO_FLAGS;
565
566   do
567     {
568       snext = strchr (s, ',');
569       if (snext == NULL)
570         len = strlen (s);
571       else
572         {
573           len = snext - s;
574           ++snext;
575         }
576
577       if (0) ;
578 #define PARSE_FLAG(fname,fval) \
579   else if (strncasecmp (fname, s, len) == 0) ret |= fval
580       PARSE_FLAG ("alloc", SEC_ALLOC);
581       PARSE_FLAG ("load", SEC_LOAD);
582       PARSE_FLAG ("noload", SEC_NEVER_LOAD);
583       PARSE_FLAG ("readonly", SEC_READONLY);
584       PARSE_FLAG ("debug", SEC_DEBUGGING);
585       PARSE_FLAG ("code", SEC_CODE);
586       PARSE_FLAG ("data", SEC_DATA);
587       PARSE_FLAG ("rom", SEC_ROM);
588       PARSE_FLAG ("share", SEC_COFF_SHARED);
589       PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
590 #undef PARSE_FLAG
591       else
592         {
593           char *copy;
594
595           copy = xmalloc (len + 1);
596           strncpy (copy, s, len);
597           copy[len] = '\0';
598           non_fatal (_("unrecognized section flag `%s'"), copy);
599           fatal (_("supported flags: %s"),
600                  "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
601         }
602
603       s = snext;
604     }
605   while (s != NULL);
606
607   return ret;
608 }
609
610 /* Find and optionally add an entry in the change_sections list.  */
611
612 static struct section_list *
613 find_section_list (const char *name, bfd_boolean add)
614 {
615   struct section_list *p;
616
617   for (p = change_sections; p != NULL; p = p->next)
618     if (strcmp (p->name, name) == 0)
619       return p;
620
621   if (! add)
622     return NULL;
623
624   p = xmalloc (sizeof (struct section_list));
625   p->name = name;
626   p->used = FALSE;
627   p->remove = FALSE;
628   p->copy = FALSE;
629   p->change_vma = CHANGE_IGNORE;
630   p->change_lma = CHANGE_IGNORE;
631   p->vma_val = 0;
632   p->lma_val = 0;
633   p->set_flags = FALSE;
634   p->flags = 0;
635
636   p->next = change_sections;
637   change_sections = p;
638
639   return p;
640 }
641
642 /* Add a symbol to strip_specific_list.  */
643
644 static void
645 add_specific_symbol (const char *name, struct symlist **list)
646 {
647   struct symlist *tmp_list;
648
649   tmp_list = xmalloc (sizeof (struct symlist));
650   tmp_list->name = name;
651   tmp_list->next = *list;
652   *list = tmp_list;
653 }
654
655 /* Add symbols listed in `filename' to strip_specific_list.  */
656
657 #define IS_WHITESPACE(c)      ((c) == ' ' || (c) == '\t')
658 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
659
660 static void
661 add_specific_symbols (const char *filename, struct symlist **list)
662 {
663   off_t  size;
664   FILE * f;
665   char * line;
666   char * buffer;
667   unsigned int line_count;
668
669   size = get_file_size (filename);
670   if (size == 0)
671     {
672       status = 1;
673       return;
674     }
675
676   buffer = xmalloc (size + 2);
677   f = fopen (filename, FOPEN_RT);
678   if (f == NULL)
679     fatal (_("cannot open '%s': %s"), filename, strerror (errno));
680
681   if (fread (buffer, 1, size, f) == 0 || ferror (f))
682     fatal (_("%s: fread failed"), filename);
683
684   fclose (f);
685   buffer [size] = '\n';
686   buffer [size + 1] = '\0';
687
688   line_count = 1;
689
690   for (line = buffer; * line != '\0'; line ++)
691     {
692       char * eol;
693       char * name;
694       char * name_end;
695       int finished = FALSE;
696
697       for (eol = line;; eol ++)
698         {
699           switch (* eol)
700             {
701             case '\n':
702               * eol = '\0';
703               /* Cope with \n\r.  */
704               if (eol[1] == '\r')
705                 ++ eol;
706               finished = TRUE;
707               break;
708
709             case '\r':
710               * eol = '\0';
711               /* Cope with \r\n.  */
712               if (eol[1] == '\n')
713                 ++ eol;
714               finished = TRUE;
715               break;
716
717             case 0:
718               finished = TRUE;
719               break;
720
721             case '#':
722               /* Line comment, Terminate the line here, in case a
723                  name is present and then allow the rest of the
724                  loop to find the real end of the line.  */
725               * eol = '\0';
726               break;
727
728             default:
729               break;
730             }
731
732           if (finished)
733             break;
734         }
735
736       /* A name may now exist somewhere between 'line' and 'eol'.
737          Strip off leading whitespace and trailing whitespace,
738          then add it to the list.  */
739       for (name = line; IS_WHITESPACE (* name); name ++)
740         ;
741       for (name_end = name;
742            (! IS_WHITESPACE (* name_end))
743            && (! IS_LINE_TERMINATOR (* name_end));
744            name_end ++)
745         ;
746
747       if (! IS_LINE_TERMINATOR (* name_end))
748         {
749           char * extra;
750
751           for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
752             ;
753
754           if (! IS_LINE_TERMINATOR (* extra))
755             non_fatal (_("%s:%d: Ignoring rubbish found on this line"),
756                        filename, line_count);
757         }
758
759       * name_end = '\0';
760
761       if (name_end > name)
762         add_specific_symbol (name, list);
763
764       /* Advance line pointer to end of line.  The 'eol ++' in the for
765          loop above will then advance us to the start of the next line.  */
766       line = eol;
767       line_count ++;
768     }
769 }
770
771 /* See whether a symbol should be stripped or kept based on
772    strip_specific_list and keep_symbols.  */
773
774 static bfd_boolean
775 is_specified_symbol (const char *name, struct symlist *list)
776 {
777   struct symlist *tmp_list;
778
779   if (wildcard)
780     {
781       for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
782         if (*(tmp_list->name) != '!')
783           {
784             if (!fnmatch (tmp_list->name, name, 0))
785               return TRUE;
786           }
787         else
788           {
789             if (fnmatch (tmp_list->name + 1, name, 0))
790               return TRUE;
791           }
792     }
793   else
794     {
795       for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
796         if (strcmp (name, tmp_list->name) == 0)
797           return TRUE;
798     }
799
800   return FALSE;
801 }
802
803 /* Return a pointer to the symbol used as a signature for GROUP.  */
804
805 static asymbol *
806 group_signature (asection *group)
807 {
808   bfd *abfd = group->owner;
809   Elf_Internal_Shdr *ghdr;
810
811   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
812     return NULL;
813
814   ghdr = &elf_section_data (group)->this_hdr;
815   if (ghdr->sh_link < elf_numsections (abfd))
816     {
817       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
818       Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link];
819
820       if (symhdr->sh_type == SHT_SYMTAB
821           && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym)
822         return isympp[ghdr->sh_info - 1];
823     }
824   return NULL;
825 }
826
827 /* See if a section is being removed.  */
828
829 static bfd_boolean
830 is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
831 {
832   if (sections_removed || sections_copied)
833     {
834       struct section_list *p;
835
836       p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
837
838       if (sections_removed && p != NULL && p->remove)
839         return TRUE;
840       if (sections_copied && (p == NULL || ! p->copy))
841         return TRUE;
842     }
843
844   if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
845     {
846       if (strip_symbols == STRIP_DEBUG
847           || strip_symbols == STRIP_UNNEEDED
848           || strip_symbols == STRIP_ALL
849           || discard_locals == LOCALS_ALL
850           || convert_debugging)
851         return TRUE;
852
853       if (strip_symbols == STRIP_NONDEBUG)
854         return FALSE;
855     }
856
857   if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0)
858     {
859       asymbol *gsym;
860       const char *gname;
861
862       /* PR binutils/3166
863          Group sections look like debugging sections but they are not.
864          (They have a non-zero size but they are not ALLOCated).  */
865       if (strip_symbols == STRIP_NONDEBUG)
866         return TRUE;
867
868       /* PR binutils/3181
869          If we are going to strip the group signature symbol, then
870          strip the group section too.  */
871       gsym = group_signature (sec);
872       if (gsym != NULL)
873         gname = gsym->name;
874       else
875         gname = sec->name;
876       if ((strip_symbols == STRIP_ALL
877            && !is_specified_symbol (gname, keep_specific_list))
878           || is_specified_symbol (gname, strip_specific_list))
879         return TRUE;
880     }
881
882   return FALSE;
883 }
884
885 /* Return true if SYM is a hidden symbol.  */
886
887 static bfd_boolean
888 is_hidden_symbol (asymbol *sym)
889 {
890   elf_symbol_type *elf_sym;
891
892   elf_sym = elf_symbol_from (sym->the_bfd, sym);
893   if (elf_sym != NULL)
894     switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other))
895       {
896       case STV_HIDDEN:
897       case STV_INTERNAL:
898         return TRUE;
899       }
900   return FALSE;
901 }
902
903 /* Choose which symbol entries to copy; put the result in OSYMS.
904    We don't copy in place, because that confuses the relocs.
905    Return the number of symbols to print.  */
906
907 static unsigned int
908 filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
909                 asymbol **isyms, long symcount)
910 {
911   asymbol **from = isyms, **to = osyms;
912   long src_count = 0, dst_count = 0;
913   int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
914                     == HAS_RELOC;
915
916   for (; src_count < symcount; src_count++)
917     {
918       asymbol *sym = from[src_count];
919       flagword flags = sym->flags;
920       char *name = (char *) bfd_asymbol_name (sym);
921       bfd_boolean keep;
922       bfd_boolean used_in_reloc = FALSE;
923       bfd_boolean undefined;
924       bfd_boolean rem_leading_char;
925       bfd_boolean add_leading_char;
926
927       undefined = bfd_is_und_section (bfd_get_section (sym));
928
929       if (redefine_sym_list)
930         {
931           char *old_name, *new_name;
932
933           old_name = (char *) bfd_asymbol_name (sym);
934           new_name = (char *) lookup_sym_redefinition (old_name);
935           bfd_asymbol_name (sym) = new_name;
936           name = new_name;
937         }
938
939       /* Check if we will remove the current leading character.  */
940       rem_leading_char =
941         (name[0] == bfd_get_symbol_leading_char (abfd))
942         && (change_leading_char
943             || (remove_leading_char
944                 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
945                     || undefined
946                     || bfd_is_com_section (bfd_get_section (sym)))));
947
948       /* Check if we will add a new leading character.  */
949       add_leading_char =
950         change_leading_char
951         && (bfd_get_symbol_leading_char (obfd) != '\0')
952         && (bfd_get_symbol_leading_char (abfd) == '\0'
953             || (name[0] == bfd_get_symbol_leading_char (abfd)));
954
955       /* Short circuit for change_leading_char if we can do it in-place.  */
956       if (rem_leading_char && add_leading_char && !prefix_symbols_string)
957         {
958           name[0] = bfd_get_symbol_leading_char (obfd);
959           bfd_asymbol_name (sym) = name;
960           rem_leading_char = FALSE;
961           add_leading_char = FALSE;
962         }
963
964       /* Remove leading char.  */
965       if (rem_leading_char)
966         bfd_asymbol_name (sym) = ++name;
967
968       /* Add new leading char and/or prefix.  */
969       if (add_leading_char || prefix_symbols_string)
970         {
971           char *n, *ptr;
972
973           ptr = n = xmalloc (1 + strlen (prefix_symbols_string)
974                              + strlen (name) + 1);
975           if (add_leading_char)
976             *ptr++ = bfd_get_symbol_leading_char (obfd);
977
978           if (prefix_symbols_string)
979             {
980               strcpy (ptr, prefix_symbols_string);
981               ptr += strlen (prefix_symbols_string);
982            }
983
984           strcpy (ptr, name);
985           bfd_asymbol_name (sym) = n;
986           name = n;
987         }
988
989       if (strip_symbols == STRIP_ALL)
990         keep = FALSE;
991       else if ((flags & BSF_KEEP) != 0          /* Used in relocation.  */
992                || ((flags & BSF_SECTION_SYM) != 0
993                    && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
994                        & BSF_KEEP) != 0))
995         {
996           keep = TRUE;
997           used_in_reloc = TRUE;
998         }
999       else if (relocatable                      /* Relocatable file.  */
1000                && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
1001         keep = TRUE;
1002       else if (bfd_decode_symclass (sym) == 'I')
1003         /* Global symbols in $idata sections need to be retained
1004            even if relocatable is FALSE.  External users of the
1005            library containing the $idata section may reference these
1006            symbols.  */
1007         keep = TRUE;
1008       else if ((flags & BSF_GLOBAL) != 0        /* Global symbol.  */
1009                || (flags & BSF_WEAK) != 0
1010                || undefined
1011                || bfd_is_com_section (bfd_get_section (sym)))
1012         keep = strip_symbols != STRIP_UNNEEDED;
1013       else if ((flags & BSF_DEBUGGING) != 0)    /* Debugging symbol.  */
1014         keep = (strip_symbols != STRIP_DEBUG
1015                 && strip_symbols != STRIP_UNNEEDED
1016                 && ! convert_debugging);
1017       else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
1018         /* COMDAT sections store special information in local
1019            symbols, so we cannot risk stripping any of them.  */
1020         keep = TRUE;
1021       else                      /* Local symbol.  */
1022         keep = (strip_symbols != STRIP_UNNEEDED
1023                 && (discard_locals != LOCALS_ALL
1024                     && (discard_locals != LOCALS_START_L
1025                         || ! bfd_is_local_label (abfd, sym))));
1026
1027       if (keep && is_specified_symbol (name, strip_specific_list))
1028         {
1029           /* There are multiple ways to set 'keep' above, but if it
1030              was the relocatable symbol case, then that's an error.  */
1031           if (used_in_reloc)
1032             {
1033               non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name);
1034               status = 1;
1035             }
1036           else
1037             keep = FALSE;
1038         }
1039
1040       if (keep
1041           && !(flags & BSF_KEEP)
1042           && is_specified_symbol (name, strip_unneeded_list))
1043         keep = FALSE;
1044
1045       if (!keep
1046           && ((keep_file_symbols && (flags & BSF_FILE))
1047               || is_specified_symbol (name, keep_specific_list)))
1048         keep = TRUE;
1049
1050       if (keep && is_strip_section (abfd, bfd_get_section (sym)))
1051         keep = FALSE;
1052
1053       if (keep)
1054         {
1055           if ((flags & BSF_GLOBAL) != 0
1056               && (weaken || is_specified_symbol (name, weaken_specific_list)))
1057             {
1058               sym->flags &= ~ BSF_GLOBAL;
1059               sym->flags |= BSF_WEAK;
1060             }
1061
1062           if (!undefined
1063               && (flags & (BSF_GLOBAL | BSF_WEAK))
1064               && (is_specified_symbol (name, localize_specific_list)
1065                   || (keepglobal_specific_list != NULL
1066                       && ! is_specified_symbol (name, keepglobal_specific_list))
1067                   || (localize_hidden && is_hidden_symbol (sym))))
1068             {
1069               sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
1070               sym->flags |= BSF_LOCAL;
1071             }
1072
1073           if (!undefined
1074               && (flags & BSF_LOCAL) 
1075               && is_specified_symbol (name, globalize_specific_list))
1076             {
1077               sym->flags &= ~ BSF_LOCAL;
1078               sym->flags |= BSF_GLOBAL;
1079             }
1080
1081           to[dst_count++] = sym;
1082         }
1083     }
1084
1085   to[dst_count] = NULL;
1086
1087   return dst_count;
1088 }
1089
1090 /* Find the redefined name of symbol SOURCE.  */
1091
1092 static const char *
1093 lookup_sym_redefinition (const char *source)
1094 {
1095   struct redefine_node *list;
1096
1097   for (list = redefine_sym_list; list != NULL; list = list->next)
1098     if (strcmp (source, list->source) == 0)
1099       return list->target;
1100
1101   return source;
1102 }
1103
1104 /* Add a node to a symbol redefine list.  */
1105
1106 static void
1107 redefine_list_append (const char *cause, const char *source, const char *target)
1108 {
1109   struct redefine_node **p;
1110   struct redefine_node *list;
1111   struct redefine_node *new_node;
1112
1113   for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
1114     {
1115       if (strcmp (source, list->source) == 0)
1116         fatal (_("%s: Multiple redefinition of symbol \"%s\""),
1117                cause, source);
1118
1119       if (strcmp (target, list->target) == 0)
1120         fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
1121                cause, target);
1122     }
1123
1124   new_node = xmalloc (sizeof (struct redefine_node));
1125
1126   new_node->source = strdup (source);
1127   new_node->target = strdup (target);
1128   new_node->next = NULL;
1129
1130   *p = new_node;
1131 }
1132
1133 /* Handle the --redefine-syms option.  Read lines containing "old new"
1134    from the file, and add them to the symbol redefine list.  */
1135
1136 static void
1137 add_redefine_syms_file (const char *filename)
1138 {
1139   FILE *file;
1140   char *buf;
1141   size_t bufsize;
1142   size_t len;
1143   size_t outsym_off;
1144   int c, lineno;
1145
1146   file = fopen (filename, "r");
1147   if (file == NULL)
1148     fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
1149            filename, strerror (errno));
1150
1151   bufsize = 100;
1152   buf = xmalloc (bufsize);
1153
1154   lineno = 1;
1155   c = getc (file);
1156   len = 0;
1157   outsym_off = 0;
1158   while (c != EOF)
1159     {
1160       /* Collect the input symbol name.  */
1161       while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1162         {
1163           if (c == '#')
1164             goto comment;
1165           buf[len++] = c;
1166           if (len >= bufsize)
1167             {
1168               bufsize *= 2;
1169               buf = xrealloc (buf, bufsize);
1170             }
1171           c = getc (file);
1172         }
1173       buf[len++] = '\0';
1174       if (c == EOF)
1175         break;
1176
1177       /* Eat white space between the symbol names.  */
1178       while (IS_WHITESPACE (c))
1179         c = getc (file);
1180       if (c == '#' || IS_LINE_TERMINATOR (c))
1181         goto comment;
1182       if (c == EOF)
1183         break;
1184
1185       /* Collect the output symbol name.  */
1186       outsym_off = len;
1187       while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1188         {
1189           if (c == '#')
1190             goto comment;
1191           buf[len++] = c;
1192           if (len >= bufsize)
1193             {
1194               bufsize *= 2;
1195               buf = xrealloc (buf, bufsize);
1196             }
1197           c = getc (file);
1198         }
1199       buf[len++] = '\0';
1200       if (c == EOF)
1201         break;
1202
1203       /* Eat white space at end of line.  */
1204       while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1205         c = getc (file);
1206       if (c == '#')
1207         goto comment;
1208       /* Handle \r\n.  */
1209       if ((c == '\r' && (c = getc (file)) == '\n')
1210           || c == '\n' || c == EOF)
1211         {
1212  end_of_line:
1213           /* Append the redefinition to the list.  */
1214           if (buf[0] != '\0')
1215             redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1216
1217           lineno++;     
1218           len = 0;
1219           outsym_off = 0;
1220           if (c == EOF)
1221             break;
1222           c = getc (file);
1223           continue;
1224         }
1225       else
1226         fatal (_("%s:%d: garbage found at end of line"), filename, lineno);
1227  comment:
1228       if (len != 0 && (outsym_off == 0 || outsym_off == len))
1229         fatal (_("%s:%d: missing new symbol name"), filename, lineno);
1230       buf[len++] = '\0';
1231
1232       /* Eat the rest of the line and finish it.  */
1233       while (c != '\n' && c != EOF)
1234         c = getc (file);
1235       goto end_of_line;
1236     }
1237
1238   if (len != 0)
1239     fatal (_("%s:%d: premature end of file"), filename, lineno);
1240
1241   free (buf);
1242 }
1243
1244 /* Copy unkown object file IBFD onto OBFD.
1245    Returns TRUE upon success, FALSE otherwise.  */
1246
1247 static bfd_boolean
1248 copy_unknown_object (bfd *ibfd, bfd *obfd)
1249 {
1250   char *cbuf;
1251   int tocopy;
1252   long ncopied;
1253   long size;
1254   struct stat buf;
1255
1256   if (bfd_stat_arch_elt (ibfd, &buf) != 0)
1257     {
1258       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1259       return FALSE;
1260     }
1261
1262   size = buf.st_size;
1263   if (size < 0)
1264     {
1265       non_fatal (_("stat returns negative size for `%s'"),
1266                  bfd_get_archive_filename (ibfd));
1267       return FALSE;
1268     }
1269
1270   if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
1271     {
1272       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1273       return FALSE;
1274     }
1275
1276   if (verbose)
1277     printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"),
1278             bfd_get_archive_filename (ibfd), bfd_get_filename (obfd));
1279
1280   cbuf = xmalloc (BUFSIZE);
1281   ncopied = 0;
1282   while (ncopied < size)
1283     {
1284       tocopy = size - ncopied;
1285       if (tocopy > BUFSIZE)
1286         tocopy = BUFSIZE;
1287
1288       if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd)
1289           != (bfd_size_type) tocopy)
1290         {
1291           bfd_nonfatal (bfd_get_archive_filename (ibfd));
1292           free (cbuf);
1293           return FALSE;
1294         }
1295
1296       if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
1297           != (bfd_size_type) tocopy)
1298         {
1299           bfd_nonfatal (bfd_get_filename (obfd));
1300           free (cbuf);
1301           return FALSE;
1302         }
1303
1304       ncopied += tocopy;
1305     }
1306
1307   chmod (bfd_get_filename (obfd), buf.st_mode);
1308   free (cbuf);
1309   return TRUE;
1310 }
1311
1312 /* Copy object file IBFD onto OBFD.
1313    Returns TRUE upon success, FALSE otherwise.  */
1314
1315 static bfd_boolean
1316 copy_object (bfd *ibfd, bfd *obfd)
1317 {
1318   bfd_vma start;
1319   long symcount;
1320   asection **osections = NULL;
1321   asection *gnu_debuglink_section = NULL;
1322   bfd_size_type *gaps = NULL;
1323   bfd_size_type max_gap = 0;
1324   long symsize;
1325   void *dhandle;
1326   enum bfd_architecture iarch;
1327   unsigned int imach;
1328
1329   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1330       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1331       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1332     fatal (_("Unable to change endianness of input file(s)"));
1333
1334   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1335     {
1336       bfd_nonfatal (bfd_get_filename (obfd));
1337       return FALSE;
1338     }
1339
1340   if (verbose)
1341     printf (_("copy from `%s' [%s] to `%s' [%s]\n"),
1342             bfd_get_archive_filename (ibfd), bfd_get_target (ibfd),
1343             bfd_get_filename (obfd), bfd_get_target (obfd));
1344
1345   if (extract_symbol)
1346     start = 0;
1347   else
1348     {
1349       if (set_start_set)
1350         start = set_start;
1351       else
1352         start = bfd_get_start_address (ibfd);
1353       start += change_start;
1354     }
1355
1356   /* Neither the start address nor the flags
1357      need to be set for a core file.  */
1358   if (bfd_get_format (obfd) != bfd_core)
1359     {
1360       flagword flags;
1361
1362       flags = bfd_get_file_flags (ibfd);
1363       flags |= bfd_flags_to_set;
1364       flags &= ~bfd_flags_to_clear;
1365       flags &= bfd_applicable_file_flags (obfd);
1366
1367       if (!bfd_set_start_address (obfd, start)
1368           || !bfd_set_file_flags (obfd, flags))
1369         {
1370           bfd_nonfatal (bfd_get_archive_filename (ibfd));
1371           return FALSE;
1372         }
1373     }
1374
1375   /* Copy architecture of input file to output file.  */
1376   iarch = bfd_get_arch (ibfd);
1377   imach = bfd_get_mach (ibfd);
1378   if (!bfd_set_arch_mach (obfd, iarch, imach)
1379       && (ibfd->target_defaulted
1380           || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1381     {
1382       if (bfd_get_arch (ibfd) == bfd_arch_unknown)
1383         non_fatal (_("Unable to recognise the format of the input file `%s'"),
1384                    bfd_get_archive_filename (ibfd));
1385       else
1386         non_fatal (_("Warning: Output file cannot represent architecture `%s'"),
1387                    bfd_printable_arch_mach (bfd_get_arch (ibfd),
1388                                             bfd_get_mach (ibfd)));
1389       return FALSE;
1390     }
1391
1392   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1393     {
1394       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1395       return FALSE;
1396     }
1397
1398   if (isympp)
1399     free (isympp);
1400
1401   if (osympp != isympp)
1402     free (osympp);
1403
1404   isympp = NULL;
1405   osympp = NULL;
1406
1407   symsize = bfd_get_symtab_upper_bound (ibfd);
1408   if (symsize < 0)
1409     {
1410       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1411       return FALSE;
1412     }
1413
1414   osympp = isympp = xmalloc (symsize);
1415   symcount = bfd_canonicalize_symtab (ibfd, isympp);
1416   if (symcount < 0)
1417     {
1418       bfd_nonfatal (bfd_get_filename (ibfd));
1419       return FALSE;
1420     }
1421
1422   /* BFD mandates that all output sections be created and sizes set before
1423      any output is done.  Thus, we traverse all sections multiple times.  */
1424   bfd_map_over_sections (ibfd, setup_section, obfd);
1425
1426   setup_bfd_headers (ibfd, obfd);
1427
1428   if (add_sections != NULL)
1429     {
1430       struct section_add *padd;
1431       struct section_list *pset;
1432
1433       for (padd = add_sections; padd != NULL; padd = padd->next)
1434         {
1435           flagword flags;
1436
1437           pset = find_section_list (padd->name, FALSE);
1438           if (pset != NULL)
1439             pset->used = TRUE;
1440
1441           flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1442           if (pset != NULL && pset->set_flags)
1443             flags = pset->flags | SEC_HAS_CONTENTS;
1444
1445           /* bfd_make_section_with_flags() does not return very helpful
1446              error codes, so check for the most likely user error first.  */
1447           if (bfd_get_section_by_name (obfd, padd->name))
1448             {
1449               non_fatal (_("can't add section '%s' - it already exists!"), padd->name);
1450               return FALSE;
1451             }
1452           else
1453             {
1454               padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
1455               if (padd->section == NULL)
1456                 {
1457                   non_fatal (_("can't create section `%s': %s"),
1458                              padd->name, bfd_errmsg (bfd_get_error ()));
1459                   return FALSE;
1460                 }
1461             }
1462
1463           if (! bfd_set_section_size (obfd, padd->section, padd->size))
1464             {
1465               bfd_nonfatal (bfd_get_filename (obfd));
1466               return FALSE;
1467             }
1468
1469           if (pset != NULL)
1470             {
1471               if (pset->change_vma != CHANGE_IGNORE)
1472                 if (! bfd_set_section_vma (obfd, padd->section,
1473                                            pset->vma_val))
1474                   {
1475                     bfd_nonfatal (bfd_get_filename (obfd));
1476                     return FALSE;
1477                   }
1478
1479               if (pset->change_lma != CHANGE_IGNORE)
1480                 {
1481                   padd->section->lma = pset->lma_val;
1482
1483                   if (! bfd_set_section_alignment
1484                       (obfd, padd->section,
1485                        bfd_section_alignment (obfd, padd->section)))
1486                     {
1487                       bfd_nonfatal (bfd_get_filename (obfd));
1488                       return FALSE;
1489                     }
1490                 }
1491             }
1492         }
1493     }
1494
1495   if (gnu_debuglink_filename != NULL)
1496     {
1497       gnu_debuglink_section = bfd_create_gnu_debuglink_section
1498         (obfd, gnu_debuglink_filename);
1499
1500       if (gnu_debuglink_section == NULL)
1501         {
1502           bfd_nonfatal (gnu_debuglink_filename);
1503           return FALSE;
1504         }
1505
1506       /* Special processing for PE format files.  We
1507          have no way to distinguish PE from COFF here.  */
1508       if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1509         {
1510           bfd_vma debuglink_vma;
1511           asection * highest_section;
1512           asection * sec;
1513
1514           /* The PE spec requires that all sections be adjacent and sorted
1515              in ascending order of VMA.  It also specifies that debug
1516              sections should be last.  This is despite the fact that debug
1517              sections are not loaded into memory and so in theory have no
1518              use for a VMA.
1519
1520              This means that the debuglink section must be given a non-zero
1521              VMA which makes it contiguous with other debug sections.  So
1522              walk the current section list, find the section with the
1523              highest VMA and start the debuglink section after that one.  */
1524           for (sec = obfd->sections, highest_section = NULL;
1525                sec != NULL;
1526                sec = sec->next)
1527             if (sec->vma > 0
1528                 && (highest_section == NULL
1529                     || sec->vma > highest_section->vma))
1530               highest_section = sec;
1531
1532           if (highest_section)
1533             debuglink_vma = BFD_ALIGN (highest_section->vma
1534                                        + highest_section->size,
1535                                        /* FIXME: We ought to be using
1536                                           COFF_PAGE_SIZE here or maybe
1537                                           bfd_get_section_alignment() (if it
1538                                           was set) but since this is for PE
1539                                           and we know the required alignment
1540                                           it is easier just to hard code it.  */
1541                                        0x1000);
1542           else
1543             /* Umm, not sure what to do in this case.  */
1544             debuglink_vma = 0x1000;
1545
1546           bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
1547         }
1548     }
1549
1550   if (bfd_count_sections (obfd) != 0
1551       && (gap_fill_set || pad_to_set))
1552     {
1553       asection **set;
1554       unsigned int c, i;
1555
1556       /* We must fill in gaps between the sections and/or we must pad
1557          the last section to a specified address.  We do this by
1558          grabbing a list of the sections, sorting them by VMA, and
1559          increasing the section sizes as required to fill the gaps.
1560          We write out the gap contents below.  */
1561
1562       c = bfd_count_sections (obfd);
1563       osections = xmalloc (c * sizeof (asection *));
1564       set = osections;
1565       bfd_map_over_sections (obfd, get_sections, &set);
1566
1567       qsort (osections, c, sizeof (asection *), compare_section_lma);
1568
1569       gaps = xmalloc (c * sizeof (bfd_size_type));
1570       memset (gaps, 0, c * sizeof (bfd_size_type));
1571
1572       if (gap_fill_set)
1573         {
1574           for (i = 0; i < c - 1; i++)
1575             {
1576               flagword flags;
1577               bfd_size_type size;
1578               bfd_vma gap_start, gap_stop;
1579
1580               flags = bfd_get_section_flags (obfd, osections[i]);
1581               if ((flags & SEC_HAS_CONTENTS) == 0
1582                   || (flags & SEC_LOAD) == 0)
1583                 continue;
1584
1585               size = bfd_section_size (obfd, osections[i]);
1586               gap_start = bfd_section_lma (obfd, osections[i]) + size;
1587               gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1588               if (gap_start < gap_stop)
1589                 {
1590                   if (! bfd_set_section_size (obfd, osections[i],
1591                                               size + (gap_stop - gap_start)))
1592                     {
1593                       non_fatal (_("Can't fill gap after %s: %s"),
1594                                  bfd_get_section_name (obfd, osections[i]),
1595                                  bfd_errmsg (bfd_get_error ()));
1596                       status = 1;
1597                       break;
1598                     }
1599                   gaps[i] = gap_stop - gap_start;
1600                   if (max_gap < gap_stop - gap_start)
1601                     max_gap = gap_stop - gap_start;
1602                 }
1603             }
1604         }
1605
1606       if (pad_to_set)
1607         {
1608           bfd_vma lma;
1609           bfd_size_type size;
1610
1611           lma = bfd_section_lma (obfd, osections[c - 1]);
1612           size = bfd_section_size (obfd, osections[c - 1]);
1613           if (lma + size < pad_to)
1614             {
1615               if (! bfd_set_section_size (obfd, osections[c - 1],
1616                                           pad_to - lma))
1617                 {
1618                   non_fatal (_("Can't add padding to %s: %s"),
1619                              bfd_get_section_name (obfd, osections[c - 1]),
1620                              bfd_errmsg (bfd_get_error ()));
1621                   status = 1;
1622                 }
1623               else
1624                 {
1625                   gaps[c - 1] = pad_to - (lma + size);
1626                   if (max_gap < pad_to - (lma + size))
1627                     max_gap = pad_to - (lma + size);
1628                 }
1629             }
1630         }
1631     }
1632
1633   /* Symbol filtering must happen after the output sections
1634      have been created, but before their contents are set.  */
1635   dhandle = NULL;
1636   if (convert_debugging)
1637     dhandle = read_debugging_info (ibfd, isympp, symcount);
1638
1639   if (strip_symbols == STRIP_DEBUG
1640       || strip_symbols == STRIP_ALL
1641       || strip_symbols == STRIP_UNNEEDED
1642       || strip_symbols == STRIP_NONDEBUG
1643       || discard_locals != LOCALS_UNDEF
1644       || localize_hidden
1645       || strip_specific_list != NULL
1646       || keep_specific_list != NULL
1647       || localize_specific_list != NULL
1648       || globalize_specific_list != NULL
1649       || keepglobal_specific_list != NULL
1650       || weaken_specific_list != NULL
1651       || prefix_symbols_string
1652       || sections_removed
1653       || sections_copied
1654       || convert_debugging
1655       || change_leading_char
1656       || remove_leading_char
1657       || redefine_sym_list
1658       || weaken)
1659     {
1660       /* Mark symbols used in output relocations so that they
1661          are kept, even if they are local labels or static symbols.
1662
1663          Note we iterate over the input sections examining their
1664          relocations since the relocations for the output sections
1665          haven't been set yet.  mark_symbols_used_in_relocations will
1666          ignore input sections which have no corresponding output
1667          section.  */
1668       if (strip_symbols != STRIP_ALL)
1669         bfd_map_over_sections (ibfd,
1670                                mark_symbols_used_in_relocations,
1671                                isympp);
1672       osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1673       symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1674     }
1675
1676   if (convert_debugging && dhandle != NULL)
1677     {
1678       if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1679         {
1680           status = 1;
1681           return FALSE;
1682         }
1683     }
1684
1685   bfd_set_symtab (obfd, osympp, symcount);
1686
1687   /* This has to happen after the symbol table has been set.  */
1688   bfd_map_over_sections (ibfd, copy_section, obfd);
1689
1690   if (add_sections != NULL)
1691     {
1692       struct section_add *padd;
1693
1694       for (padd = add_sections; padd != NULL; padd = padd->next)
1695         {
1696           if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1697                                           0, padd->size))
1698             {
1699               bfd_nonfatal (bfd_get_filename (obfd));
1700               return FALSE;
1701             }
1702         }
1703     }
1704
1705   if (gnu_debuglink_filename != NULL)
1706     {
1707       if (! bfd_fill_in_gnu_debuglink_section
1708           (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1709         {
1710           bfd_nonfatal (gnu_debuglink_filename);
1711           return FALSE;
1712         }
1713     }
1714
1715   if (gap_fill_set || pad_to_set)
1716     {
1717       bfd_byte *buf;
1718       int c, i;
1719
1720       /* Fill in the gaps.  */
1721       if (max_gap > 8192)
1722         max_gap = 8192;
1723       buf = xmalloc (max_gap);
1724       memset (buf, gap_fill, max_gap);
1725
1726       c = bfd_count_sections (obfd);
1727       for (i = 0; i < c; i++)
1728         {
1729           if (gaps[i] != 0)
1730             {
1731               bfd_size_type left;
1732               file_ptr off;
1733
1734               left = gaps[i];
1735               off = bfd_section_size (obfd, osections[i]) - left;
1736
1737               while (left > 0)
1738                 {
1739                   bfd_size_type now;
1740
1741                   if (left > 8192)
1742                     now = 8192;
1743                   else
1744                     now = left;
1745
1746                   if (! bfd_set_section_contents (obfd, osections[i], buf,
1747                                                   off, now))
1748                     {
1749                       bfd_nonfatal (bfd_get_filename (obfd));
1750                       return FALSE;
1751                     }
1752
1753                   left -= now;
1754                   off += now;
1755                 }
1756             }
1757         }
1758     }
1759
1760   /* Do not copy backend data if --extract-symbol is passed; anything
1761      that needs to look at the section contents will fail.  */
1762   if (extract_symbol)
1763     return TRUE;
1764
1765   /* Allow the BFD backend to copy any private data it understands
1766      from the input BFD to the output BFD.  This is done last to
1767      permit the routine to look at the filtered symbol table, which is
1768      important for the ECOFF code at least.  */
1769   if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1770       && strip_symbols == STRIP_NONDEBUG)
1771     /* Do not copy the private data when creating an ELF format
1772        debug info file.  We do not want the program headers.  */
1773     ;
1774   else if (! bfd_copy_private_bfd_data (ibfd, obfd))
1775     {
1776       non_fatal (_("%s: error copying private BFD data: %s"),
1777                  bfd_get_filename (obfd),
1778                  bfd_errmsg (bfd_get_error ()));
1779       return FALSE;
1780     }
1781
1782   /* Switch to the alternate machine code.  We have to do this at the
1783      very end, because we only initialize the header when we create
1784      the first section.  */
1785   if (use_alt_mach_code != 0)
1786     {
1787       if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
1788         {
1789           non_fatal (_("this target does not support %lu alternative machine codes"),
1790                      use_alt_mach_code);
1791           if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1792             {
1793               non_fatal (_("treating that number as an absolute e_machine value instead"));
1794               elf_elfheader (obfd)->e_machine = use_alt_mach_code;
1795             }
1796           else
1797             non_fatal (_("ignoring the alternative value"));
1798         }
1799     }
1800
1801   return TRUE;
1802 }
1803
1804 /* Read each archive element in turn from IBFD, copy the
1805    contents to temp file, and keep the temp file handle.
1806    If 'force_output_target' is TRUE then make sure that
1807    all elements in the new archive are of the type
1808    'output_target'.  */
1809
1810 static void
1811 copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
1812               bfd_boolean force_output_target)
1813 {
1814   struct name_list
1815     {
1816       struct name_list *next;
1817       const char *name;
1818       bfd *obfd;
1819     } *list, *l;
1820   bfd **ptr = &obfd->archive_head;
1821   bfd *this_element;
1822   char * dir;
1823
1824   /* Make a temp directory to hold the contents.  */
1825   dir = make_tempdir (bfd_get_filename (obfd));
1826   if (dir == NULL)
1827       fatal (_("cannot create tempdir for archive copying (error: %s)"),
1828            strerror (errno));
1829
1830   obfd->has_armap = ibfd->has_armap;
1831
1832   list = NULL;
1833
1834   this_element = bfd_openr_next_archived_file (ibfd, NULL);
1835
1836   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1837     RETURN_NONFATAL (bfd_get_filename (obfd));
1838
1839   while (!status && this_element != NULL)
1840     {
1841       char *output_name;
1842       bfd *output_bfd;
1843       bfd *last_element;
1844       struct stat buf;
1845       int stat_status = 0;
1846       bfd_boolean delete = TRUE;
1847
1848       /* Create an output file for this member.  */
1849       output_name = concat (dir, "/",
1850                             bfd_get_filename (this_element), (char *) 0);
1851
1852       /* If the file already exists, make another temp dir.  */
1853       if (stat (output_name, &buf) >= 0)
1854         {
1855           output_name = make_tempdir (output_name);
1856           if (output_name == NULL)
1857             fatal (_("cannot create tempdir for archive copying (error: %s)"),
1858                    strerror (errno));
1859
1860           l = xmalloc (sizeof (struct name_list));
1861           l->name = output_name;
1862           l->next = list;
1863           l->obfd = NULL;
1864           list = l;
1865           output_name = concat (output_name, "/",
1866                                 bfd_get_filename (this_element), (char *) 0);
1867         }
1868
1869       if (preserve_dates)
1870         {
1871           stat_status = bfd_stat_arch_elt (this_element, &buf);
1872
1873           if (stat_status != 0)
1874             non_fatal (_("internal stat error on %s"),
1875                        bfd_get_filename (this_element));
1876         }
1877
1878       l = xmalloc (sizeof (struct name_list));
1879       l->name = output_name;
1880       l->next = list;
1881       l->obfd = NULL;
1882       list = l;
1883
1884       if (bfd_check_format (this_element, bfd_object))
1885         {
1886           /* PR binutils/3110: Cope with archives
1887              containing multiple target types.  */
1888           if (force_output_target)
1889             output_bfd = bfd_openw (output_name, output_target);
1890           else
1891             output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
1892
1893           if (output_bfd == NULL)
1894             RETURN_NONFATAL (output_name);
1895
1896           delete = ! copy_object (this_element, output_bfd);
1897
1898           if (! delete
1899               || bfd_get_arch (this_element) != bfd_arch_unknown)
1900             {
1901               if (!bfd_close (output_bfd))
1902                 {
1903                   bfd_nonfatal (bfd_get_filename (output_bfd));
1904                   /* Error in new object file. Don't change archive.  */
1905                   status = 1;
1906                 }
1907             }
1908           else
1909             goto copy_unknown_element;
1910         }
1911       else
1912         {
1913           non_fatal (_("Unable to recognise the format of the input file `%s'"),
1914                      bfd_get_archive_filename (this_element));
1915
1916           output_bfd = bfd_openw (output_name, output_target);
1917 copy_unknown_element:
1918           delete = !copy_unknown_object (this_element, output_bfd);
1919           if (!bfd_close_all_done (output_bfd))
1920             {
1921               bfd_nonfatal (bfd_get_filename (output_bfd));
1922               /* Error in new object file. Don't change archive.  */
1923               status = 1;
1924             }
1925         }
1926
1927       if (delete)
1928         {
1929           unlink (output_name);
1930           status = 1;
1931         }
1932       else
1933         {
1934           if (preserve_dates && stat_status == 0)
1935             set_times (output_name, &buf);
1936
1937           /* Open the newly output file and attach to our list.  */
1938           output_bfd = bfd_openr (output_name, output_target);
1939
1940           l->obfd = output_bfd;
1941
1942           *ptr = output_bfd;
1943           ptr = &output_bfd->next;
1944
1945           last_element = this_element;
1946
1947           this_element = bfd_openr_next_archived_file (ibfd, last_element);
1948
1949           bfd_close (last_element);
1950         }
1951     }
1952   *ptr = NULL;
1953
1954   if (!bfd_close (obfd))
1955     RETURN_NONFATAL (bfd_get_filename (obfd));
1956
1957   if (!bfd_close (ibfd))
1958     RETURN_NONFATAL (bfd_get_filename (ibfd));
1959
1960   /* Delete all the files that we opened.  */
1961   for (l = list; l != NULL; l = l->next)
1962     {
1963       if (l->obfd == NULL)
1964         rmdir (l->name);
1965       else
1966         {
1967           bfd_close (l->obfd);
1968           unlink (l->name);
1969         }
1970     }
1971   rmdir (dir);
1972 }
1973
1974 /* The top-level control.  */
1975
1976 static void
1977 copy_file (const char *input_filename, const char *output_filename,
1978            const char *input_target,   const char *output_target)
1979 {
1980   bfd *ibfd;
1981   char **obj_matching;
1982   char **core_matching;
1983
1984   if (get_file_size (input_filename) < 1)
1985     {
1986       status = 1;
1987       return;
1988     }
1989
1990   /* To allow us to do "strip *" without dying on the first
1991      non-object file, failures are nonfatal.  */
1992   ibfd = bfd_openr (input_filename, input_target);
1993   if (ibfd == NULL)
1994     RETURN_NONFATAL (input_filename);
1995
1996   if (bfd_check_format (ibfd, bfd_archive))
1997     {
1998       bfd_boolean force_output_target;
1999       bfd *obfd;
2000
2001       /* bfd_get_target does not return the correct value until
2002          bfd_check_format succeeds.  */
2003       if (output_target == NULL)
2004         {
2005           output_target = bfd_get_target (ibfd);
2006           force_output_target = FALSE;
2007         }
2008       else
2009         force_output_target = TRUE;
2010
2011       obfd = bfd_openw (output_filename, output_target);
2012       if (obfd == NULL)
2013         RETURN_NONFATAL (output_filename);
2014
2015       copy_archive (ibfd, obfd, output_target, force_output_target);
2016     }
2017   else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
2018     {
2019       bfd *obfd;
2020     do_copy:
2021
2022       /* bfd_get_target does not return the correct value until
2023          bfd_check_format succeeds.  */
2024       if (output_target == NULL)
2025         output_target = bfd_get_target (ibfd);
2026
2027       obfd = bfd_openw (output_filename, output_target);
2028       if (obfd == NULL)
2029         RETURN_NONFATAL (output_filename);
2030
2031       if (! copy_object (ibfd, obfd))
2032         status = 1;
2033
2034       if (!bfd_close (obfd))
2035         RETURN_NONFATAL (output_filename);
2036
2037       if (!bfd_close (ibfd))
2038         RETURN_NONFATAL (input_filename);
2039
2040     }
2041   else
2042     {
2043       bfd_error_type obj_error = bfd_get_error ();
2044       bfd_error_type core_error;
2045
2046       if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
2047         {
2048           /* This probably can't happen..  */
2049           if (obj_error == bfd_error_file_ambiguously_recognized)
2050             free (obj_matching);
2051           goto do_copy;
2052         }
2053
2054       core_error = bfd_get_error ();
2055       /* Report the object error in preference to the core error.  */
2056       if (obj_error != core_error)
2057         bfd_set_error (obj_error);
2058
2059       bfd_nonfatal (input_filename);
2060
2061       if (obj_error == bfd_error_file_ambiguously_recognized)
2062         {
2063           list_matching_formats (obj_matching);
2064           free (obj_matching);
2065         }
2066       if (core_error == bfd_error_file_ambiguously_recognized)
2067         {
2068           list_matching_formats (core_matching);
2069           free (core_matching);
2070         }
2071
2072       status = 1;
2073     }
2074 }
2075
2076 /* Add a name to the section renaming list.  */
2077
2078 static void
2079 add_section_rename (const char * old_name, const char * new_name,
2080                     flagword flags)
2081 {
2082   section_rename * rename;
2083
2084   /* Check for conflicts first.  */
2085   for (rename = section_rename_list; rename != NULL; rename = rename->next)
2086     if (strcmp (rename->old_name, old_name) == 0)
2087       {
2088         /* Silently ignore duplicate definitions.  */
2089         if (strcmp (rename->new_name, new_name) == 0
2090             && rename->flags == flags)
2091           return;
2092
2093         fatal (_("Multiple renames of section %s"), old_name);
2094       }
2095
2096   rename = xmalloc (sizeof (* rename));
2097
2098   rename->old_name = old_name;
2099   rename->new_name = new_name;
2100   rename->flags    = flags;
2101   rename->next     = section_rename_list;
2102
2103   section_rename_list = rename;
2104 }
2105
2106 /* Check the section rename list for a new name of the input section
2107    ISECTION.  Return the new name if one is found.
2108    Also set RETURNED_FLAGS to the flags to be used for this section.  */
2109
2110 static const char *
2111 find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
2112                      flagword * returned_flags)
2113 {
2114   const char * old_name = bfd_section_name (ibfd, isection);
2115   section_rename * rename;
2116
2117   /* Default to using the flags of the input section.  */
2118   * returned_flags = bfd_get_section_flags (ibfd, isection);
2119
2120   for (rename = section_rename_list; rename != NULL; rename = rename->next)
2121     if (strcmp (rename->old_name, old_name) == 0)
2122       {
2123         if (rename->flags != (flagword) -1)
2124           * returned_flags = rename->flags;
2125
2126         return rename->new_name;
2127       }
2128
2129   return old_name;
2130 }
2131
2132 /* Once each of the sections is copied, we may still need to do some
2133    finalization work for private section headers.  Do that here.  */
2134
2135 static void
2136 setup_bfd_headers (bfd *ibfd, bfd *obfd)
2137 {
2138   const char *err;
2139
2140   /* Allow the BFD backend to copy any private data it understands
2141      from the input section to the output section.  */
2142   if (! bfd_copy_private_header_data (ibfd, obfd))
2143     {
2144       err = _("private header data");
2145       goto loser;
2146     }
2147
2148   /* All went well.  */
2149   return;
2150
2151 loser:
2152   non_fatal (_("%s: error in %s: %s"),
2153              bfd_get_filename (ibfd),
2154              err, bfd_errmsg (bfd_get_error ()));
2155   status = 1;
2156 }
2157
2158 /* Create a section in OBFD with the same
2159    name and attributes as ISECTION in IBFD.  */
2160
2161 static void
2162 setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2163 {
2164   bfd *obfd = obfdarg;
2165   struct section_list *p;
2166   sec_ptr osection;
2167   bfd_size_type size;
2168   bfd_vma vma;
2169   bfd_vma lma;
2170   flagword flags;
2171   const char *err;
2172   const char * name;
2173   char *prefix = NULL;
2174
2175   if (is_strip_section (ibfd, isection))
2176     return;
2177
2178   p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
2179   if (p != NULL)
2180     p->used = TRUE;
2181
2182   /* Get the, possibly new, name of the output section.  */
2183   name = find_section_rename (ibfd, isection, & flags);
2184
2185   /* Prefix sections.  */
2186   if ((prefix_alloc_sections_string)
2187       && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
2188     prefix = prefix_alloc_sections_string;
2189   else if (prefix_sections_string)
2190     prefix = prefix_sections_string;
2191
2192   if (prefix)
2193     {
2194       char *n;
2195
2196       n = xmalloc (strlen (prefix) + strlen (name) + 1);
2197       strcpy (n, prefix);
2198       strcat (n, name);
2199       name = n;
2200     }
2201
2202   if (p != NULL && p->set_flags)
2203     flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
2204   else if (strip_symbols == STRIP_NONDEBUG && (flags & SEC_ALLOC) != 0)
2205     flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2206
2207   osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
2208
2209   if (osection == NULL)
2210     {
2211       err = _("making");
2212       goto loser;
2213     }
2214
2215   if (strip_symbols == STRIP_NONDEBUG
2216       && obfd->xvec->flavour == bfd_target_elf_flavour
2217       && (flags & SEC_ALLOC) != 0
2218       && (p == NULL || !p->set_flags))
2219     elf_section_type (osection) = SHT_NOBITS;
2220
2221   size = bfd_section_size (ibfd, isection);
2222   if (copy_byte >= 0)
2223     size = (size + interleave - 1) / interleave;
2224   else if (extract_symbol)
2225     size = 0;
2226   if (! bfd_set_section_size (obfd, osection, size))
2227     {
2228       err = _("size");
2229       goto loser;
2230     }
2231
2232   vma = bfd_section_vma (ibfd, isection);
2233   if (p != NULL && p->change_vma == CHANGE_MODIFY)
2234     vma += p->vma_val;
2235   else if (p != NULL && p->change_vma == CHANGE_SET)
2236     vma = p->vma_val;
2237   else
2238     vma += change_section_address;
2239
2240   if (! bfd_set_section_vma (obfd, osection, extract_symbol ? 0 : vma))
2241     {
2242       err = _("vma");
2243       goto loser;
2244     }
2245
2246   lma = isection->lma;
2247   if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2248     {
2249       if (p->change_lma == CHANGE_MODIFY)
2250         lma += p->lma_val;
2251       else if (p->change_lma == CHANGE_SET)
2252         lma = p->lma_val;
2253       else
2254         abort ();
2255     }
2256   else
2257     lma += change_section_address;
2258
2259   osection->lma = extract_symbol ? 0 : lma;
2260
2261   /* FIXME: This is probably not enough.  If we change the LMA we
2262      may have to recompute the header for the file as well.  */
2263   if (!bfd_set_section_alignment (obfd,
2264                                   osection,
2265                                   bfd_section_alignment (ibfd, isection)))
2266     {
2267       err = _("alignment");
2268       goto loser;
2269     }
2270
2271   /* Copy merge entity size.  */
2272   osection->entsize = isection->entsize;
2273
2274   /* This used to be mangle_section; we do here to avoid using
2275      bfd_get_section_by_name since some formats allow multiple
2276      sections with the same name.  */
2277   isection->output_section = osection;
2278   isection->output_offset = extract_symbol ? vma : 0;
2279
2280   /* Do not copy backend data if --extract-symbol is passed; anything
2281      that needs to look at the section contents will fail.  */
2282   if (extract_symbol)
2283     return;
2284
2285   /* Allow the BFD backend to copy any private data it understands
2286      from the input section to the output section.  */
2287   if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
2288       && strip_symbols == STRIP_NONDEBUG)
2289     /* Do not copy the private data when creating an ELF format
2290        debug info file.  We do not want the program headers.  */
2291     ;
2292   else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
2293     {
2294       err = _("private data");
2295       goto loser;
2296     }
2297   else if ((isection->flags & SEC_GROUP) != 0)
2298     {
2299       asymbol *gsym = group_signature (isection);
2300
2301       if (gsym != NULL)
2302         gsym->flags |= BSF_KEEP;
2303     }
2304
2305   /* All went well.  */
2306   return;
2307
2308 loser:
2309   non_fatal (_("%s: section `%s': error in %s: %s"),
2310              bfd_get_filename (ibfd),
2311              bfd_section_name (ibfd, isection),
2312              err, bfd_errmsg (bfd_get_error ()));
2313   status = 1;
2314 }
2315
2316 /* Copy the data of input section ISECTION of IBFD
2317    to an output section with the same name in OBFD.
2318    If stripping then don't copy any relocation info.  */
2319
2320 static void
2321 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2322 {
2323   bfd *obfd = obfdarg;
2324   struct section_list *p;
2325   arelent **relpp;
2326   long relcount;
2327   sec_ptr osection;
2328   bfd_size_type size;
2329   long relsize;
2330   flagword flags;
2331
2332   /* If we have already failed earlier on,
2333      do not keep on generating complaints now.  */
2334   if (status != 0)
2335     return;
2336
2337   if (is_strip_section (ibfd, isection))
2338     return;
2339
2340   flags = bfd_get_section_flags (ibfd, isection);
2341   if ((flags & SEC_GROUP) != 0)
2342     return;
2343
2344   osection = isection->output_section;
2345   size = bfd_get_section_size (isection);
2346
2347   if (size == 0 || osection == 0)
2348     return;
2349
2350   p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2351
2352   /* Core files do not need to be relocated.  */
2353   if (bfd_get_format (obfd) == bfd_core)
2354     relsize = 0;
2355   else
2356     {
2357       relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2358
2359       if (relsize < 0)
2360         {
2361           /* Do not complain if the target does not support relocations.  */
2362           if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2363             relsize = 0;
2364           else
2365             RETURN_NONFATAL (bfd_get_filename (ibfd));
2366         }
2367     }
2368
2369   if (relsize == 0)
2370     bfd_set_reloc (obfd, osection, NULL, 0);
2371   else
2372     {
2373       relpp = xmalloc (relsize);
2374       relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2375       if (relcount < 0)
2376         RETURN_NONFATAL (bfd_get_filename (ibfd));
2377
2378       if (strip_symbols == STRIP_ALL)
2379         {
2380           /* Remove relocations which are not in
2381              keep_strip_specific_list.  */
2382           arelent **temp_relpp;
2383           long temp_relcount = 0;
2384           long i;
2385
2386           temp_relpp = xmalloc (relsize);
2387           for (i = 0; i < relcount; i++)
2388             if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
2389                                      keep_specific_list))
2390               temp_relpp [temp_relcount++] = relpp [i];
2391           relcount = temp_relcount;
2392           free (relpp);
2393           relpp = temp_relpp;
2394         }
2395
2396       bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
2397       if (relcount == 0)
2398         free (relpp);
2399     }
2400
2401   if (extract_symbol)
2402     return;
2403
2404   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
2405       && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
2406     {
2407       void *memhunk = xmalloc (size);
2408
2409       if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2410         RETURN_NONFATAL (bfd_get_filename (ibfd));
2411
2412       if (reverse_bytes)
2413         {
2414           /* We don't handle leftover bytes (too many possible behaviors,
2415              and we don't know what the user wants).  The section length
2416              must be a multiple of the number of bytes to swap.  */
2417           if ((size % reverse_bytes) == 0)
2418             {
2419               unsigned long i, j;
2420               bfd_byte b;
2421
2422               for (i = 0; i < size; i += reverse_bytes)
2423                 for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2424                   {
2425                     bfd_byte *m = (bfd_byte *) memhunk;
2426
2427                     b = m[i + j];
2428                     m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2429                     m[(i + reverse_bytes) - (j + 1)] = b;
2430                   }
2431             }
2432           else
2433             /* User must pad the section up in order to do this.  */
2434             fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2435                    bfd_section_name (ibfd, isection), reverse_bytes);
2436         }
2437
2438       if (copy_byte >= 0)
2439         {
2440           /* Keep only every `copy_byte'th byte in MEMHUNK.  */
2441           char *from = (char *) memhunk + copy_byte;
2442           char *to = memhunk;
2443           char *end = (char *) memhunk + size;
2444
2445           for (; from < end; from += interleave)
2446             *to++ = *from;
2447
2448           size = (size + interleave - 1 - copy_byte) / interleave;
2449           osection->lma /= interleave;
2450         }
2451
2452       if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2453         RETURN_NONFATAL (bfd_get_filename (obfd));
2454
2455       free (memhunk);
2456     }
2457   else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2458     {
2459       void *memhunk = xmalloc (size);
2460
2461       /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2462          flag--they can just remove the section entirely and add it
2463          back again.  However, we do permit them to turn on the
2464          SEC_HAS_CONTENTS flag, and take it to mean that the section
2465          contents should be zeroed out.  */
2466
2467       memset (memhunk, 0, size);
2468       if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2469         RETURN_NONFATAL (bfd_get_filename (obfd));
2470       free (memhunk);
2471     }
2472 }
2473
2474 /* Get all the sections.  This is used when --gap-fill or --pad-to is
2475    used.  */
2476
2477 static void
2478 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2479 {
2480   asection ***secppp = secppparg;
2481
2482   **secppp = osection;
2483   ++(*secppp);
2484 }
2485
2486 /* Sort sections by VMA.  This is called via qsort, and is used when
2487    --gap-fill or --pad-to is used.  We force non loadable or empty
2488    sections to the front, where they are easier to ignore.  */
2489
2490 static int
2491 compare_section_lma (const void *arg1, const void *arg2)
2492 {
2493   const asection *const *sec1 = arg1;
2494   const asection *const *sec2 = arg2;
2495   flagword flags1, flags2;
2496
2497   /* Sort non loadable sections to the front.  */
2498   flags1 = (*sec1)->flags;
2499   flags2 = (*sec2)->flags;
2500   if ((flags1 & SEC_HAS_CONTENTS) == 0
2501       || (flags1 & SEC_LOAD) == 0)
2502     {
2503       if ((flags2 & SEC_HAS_CONTENTS) != 0
2504           && (flags2 & SEC_LOAD) != 0)
2505         return -1;
2506     }
2507   else
2508     {
2509       if ((flags2 & SEC_HAS_CONTENTS) == 0
2510           || (flags2 & SEC_LOAD) == 0)
2511         return 1;
2512     }
2513
2514   /* Sort sections by LMA.  */
2515   if ((*sec1)->lma > (*sec2)->lma)
2516     return 1;
2517   else if ((*sec1)->lma < (*sec2)->lma)
2518     return -1;
2519
2520   /* Sort sections with the same LMA by size.  */
2521   if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
2522     return 1;
2523   else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
2524     return -1;
2525
2526   return 0;
2527 }
2528
2529 /* Mark all the symbols which will be used in output relocations with
2530    the BSF_KEEP flag so that those symbols will not be stripped.
2531
2532    Ignore relocations which will not appear in the output file.  */
2533
2534 static void
2535 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2536 {
2537   asymbol **symbols = symbolsarg;
2538   long relsize;
2539   arelent **relpp;
2540   long relcount, i;
2541
2542   /* Ignore an input section with no corresponding output section.  */
2543   if (isection->output_section == NULL)
2544     return;
2545
2546   relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2547   if (relsize < 0)
2548     {
2549       /* Do not complain if the target does not support relocations.  */
2550       if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2551         return;
2552       bfd_fatal (bfd_get_filename (ibfd));
2553     }
2554
2555   if (relsize == 0)
2556     return;
2557
2558   relpp = xmalloc (relsize);
2559   relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2560   if (relcount < 0)
2561     bfd_fatal (bfd_get_filename (ibfd));
2562
2563   /* Examine each symbol used in a relocation.  If it's not one of the
2564      special bfd section symbols, then mark it with BSF_KEEP.  */
2565   for (i = 0; i < relcount; i++)
2566     {
2567       if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2568           && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2569           && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2570         (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2571     }
2572
2573   if (relpp != NULL)
2574     free (relpp);
2575 }
2576
2577 /* Write out debugging information.  */
2578
2579 static bfd_boolean
2580 write_debugging_info (bfd *obfd, void *dhandle,
2581                       long *symcountp ATTRIBUTE_UNUSED,
2582                       asymbol ***symppp ATTRIBUTE_UNUSED)
2583 {
2584   if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2585     return write_ieee_debugging_info (obfd, dhandle);
2586
2587   if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2588       || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2589     {
2590       bfd_byte *syms, *strings;
2591       bfd_size_type symsize, stringsize;
2592       asection *stabsec, *stabstrsec;
2593       flagword flags;
2594
2595       if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2596                                                     &symsize, &strings,
2597                                                     &stringsize))
2598         return FALSE;
2599
2600       flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2601       stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2602       stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
2603       if (stabsec == NULL
2604           || stabstrsec == NULL
2605           || ! bfd_set_section_size (obfd, stabsec, symsize)
2606           || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2607           || ! bfd_set_section_alignment (obfd, stabsec, 2)
2608           || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
2609         {
2610           non_fatal (_("%s: can't create debugging section: %s"),
2611                      bfd_get_filename (obfd),
2612                      bfd_errmsg (bfd_get_error ()));
2613           return FALSE;
2614         }
2615
2616       /* We can get away with setting the section contents now because
2617          the next thing the caller is going to do is copy over the
2618          real sections.  We may someday have to split the contents
2619          setting out of this function.  */
2620       if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2621           || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2622                                          stringsize))
2623         {
2624           non_fatal (_("%s: can't set debugging section contents: %s"),
2625                      bfd_get_filename (obfd),
2626                      bfd_errmsg (bfd_get_error ()));
2627           return FALSE;
2628         }
2629
2630       return TRUE;
2631     }
2632
2633   non_fatal (_("%s: don't know how to write debugging information for %s"),
2634              bfd_get_filename (obfd), bfd_get_target (obfd));
2635   return FALSE;
2636 }
2637
2638 static int
2639 strip_main (int argc, char *argv[])
2640 {
2641   char *input_target = NULL;
2642   char *output_target = NULL;
2643   bfd_boolean show_version = FALSE;
2644   bfd_boolean formats_info = FALSE;
2645   int c;
2646   int i;
2647   struct section_list *p;
2648   char *output_file = NULL;
2649
2650   while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2651                            strip_options, (int *) 0)) != EOF)
2652     {
2653       switch (c)
2654         {
2655         case 'I':
2656           input_target = optarg;
2657           break;
2658         case 'O':
2659           output_target = optarg;
2660           break;
2661         case 'F':
2662           input_target = output_target = optarg;
2663           break;
2664         case 'R':
2665           p = find_section_list (optarg, TRUE);
2666           p->remove = TRUE;
2667           sections_removed = TRUE;
2668           break;
2669         case 's':
2670           strip_symbols = STRIP_ALL;
2671           break;
2672         case 'S':
2673         case 'g':
2674         case 'd':       /* Historic BSD alias for -g.  Used by early NetBSD.  */
2675           strip_symbols = STRIP_DEBUG;
2676           break;
2677         case OPTION_STRIP_UNNEEDED:
2678           strip_symbols = STRIP_UNNEEDED;
2679           break;
2680         case 'K':
2681           add_specific_symbol (optarg, &keep_specific_list);
2682           break;
2683         case 'N':
2684           add_specific_symbol (optarg, &strip_specific_list);
2685           break;
2686         case 'o':
2687           output_file = optarg;
2688           break;
2689         case 'p':
2690           preserve_dates = TRUE;
2691           break;
2692         case 'x':
2693           discard_locals = LOCALS_ALL;
2694           break;
2695         case 'X':
2696           discard_locals = LOCALS_START_L;
2697           break;
2698         case 'v':
2699           verbose = TRUE;
2700           break;
2701         case 'V':
2702           show_version = TRUE;
2703           break;
2704         case OPTION_FORMATS_INFO:
2705           formats_info = TRUE;
2706           break;
2707         case OPTION_ONLY_KEEP_DEBUG:
2708           strip_symbols = STRIP_NONDEBUG;
2709           break;
2710         case OPTION_KEEP_FILE_SYMBOLS:
2711           keep_file_symbols = 1;
2712           break;
2713         case 0:
2714           /* We've been given a long option.  */
2715           break;
2716         case 'w':
2717           wildcard = TRUE;
2718           break;
2719         case 'H':
2720         case 'h':
2721           strip_usage (stdout, 0);
2722         default:
2723           strip_usage (stderr, 1);
2724         }
2725     }
2726
2727   if (formats_info)
2728     {
2729       display_info ();
2730       return 0;
2731     }
2732  
2733   if (show_version)
2734     print_version ("strip");
2735
2736   /* Default is to strip all symbols.  */
2737   if (strip_symbols == STRIP_UNDEF
2738       && discard_locals == LOCALS_UNDEF
2739       && strip_specific_list == NULL)
2740     strip_symbols = STRIP_ALL;
2741
2742   if (output_target == NULL)
2743     output_target = input_target;
2744
2745   i = optind;
2746   if (i == argc
2747       || (output_file != NULL && (i + 1) < argc))
2748     strip_usage (stderr, 1);
2749
2750   for (; i < argc; i++)
2751     {
2752       int hold_status = status;
2753       struct stat statbuf;
2754       char *tmpname;
2755
2756       if (get_file_size (argv[i]) < 1)
2757         {
2758           status = 1;
2759           continue;
2760         }
2761
2762       if (preserve_dates)
2763         /* No need to check the return value of stat().
2764            It has already been checked in get_file_size().  */
2765         stat (argv[i], &statbuf);
2766
2767       if (output_file != NULL)
2768         tmpname = output_file;
2769       else
2770         tmpname = make_tempname (argv[i]);
2771
2772       if (tmpname == NULL)
2773         {
2774           non_fatal (_("could not create temporary file to hold stripped copy of '%s'"),
2775                      argv[i]);
2776           status = 1;
2777           continue;
2778         }
2779
2780       status = 0;
2781       copy_file (argv[i], tmpname, input_target, output_target);
2782       if (status == 0)
2783         {
2784           if (preserve_dates)
2785             set_times (tmpname, &statbuf);
2786           if (output_file == NULL)
2787             smart_rename (tmpname, argv[i], preserve_dates);
2788           status = hold_status;
2789         }
2790       else
2791         unlink_if_ordinary (tmpname);
2792       if (output_file == NULL)
2793         free (tmpname);
2794     }
2795
2796   return status;
2797 }
2798
2799 static int
2800 copy_main (int argc, char *argv[])
2801 {
2802   char * binary_architecture = NULL;
2803   char *input_filename = NULL;
2804   char *output_filename = NULL;
2805   char *input_target = NULL;
2806   char *output_target = NULL;
2807   bfd_boolean show_version = FALSE;
2808   bfd_boolean change_warn = TRUE;
2809   bfd_boolean formats_info = FALSE;
2810   int c;
2811   struct section_list *p;
2812   struct stat statbuf;
2813
2814   while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2815                            copy_options, (int *) 0)) != EOF)
2816     {
2817       switch (c)
2818         {
2819         case 'b':
2820           copy_byte = atoi (optarg);
2821           if (copy_byte < 0)
2822             fatal (_("byte number must be non-negative"));
2823           break;
2824
2825         case 'B':
2826           binary_architecture = optarg;
2827           break;
2828
2829         case 'i':
2830           interleave = atoi (optarg);
2831           if (interleave < 1)
2832             fatal (_("interleave must be positive"));
2833           break;
2834
2835         case 'I':
2836         case 's':               /* "source" - 'I' is preferred */
2837           input_target = optarg;
2838           break;
2839
2840         case 'O':
2841         case 'd':               /* "destination" - 'O' is preferred */
2842           output_target = optarg;
2843           break;
2844
2845         case 'F':
2846           input_target = output_target = optarg;
2847           break;
2848
2849         case 'j':
2850           p = find_section_list (optarg, TRUE);
2851           if (p->remove)
2852             fatal (_("%s both copied and removed"), optarg);
2853           p->copy = TRUE;
2854           sections_copied = TRUE;
2855           break;
2856
2857         case 'R':
2858           p = find_section_list (optarg, TRUE);
2859           if (p->copy)
2860             fatal (_("%s both copied and removed"), optarg);
2861           p->remove = TRUE;
2862           sections_removed = TRUE;
2863           break;
2864
2865         case 'S':
2866           strip_symbols = STRIP_ALL;
2867           break;
2868
2869         case 'g':
2870           strip_symbols = STRIP_DEBUG;
2871           break;
2872
2873         case OPTION_STRIP_UNNEEDED:
2874           strip_symbols = STRIP_UNNEEDED;
2875           break;
2876
2877         case OPTION_ONLY_KEEP_DEBUG:
2878           strip_symbols = STRIP_NONDEBUG;
2879           break;
2880
2881         case OPTION_KEEP_FILE_SYMBOLS:
2882           keep_file_symbols = 1;
2883           break;
2884
2885         case OPTION_ADD_GNU_DEBUGLINK:
2886           gnu_debuglink_filename = optarg;
2887           break;
2888
2889         case 'K':
2890           add_specific_symbol (optarg, &keep_specific_list);
2891           break;
2892
2893         case 'N':
2894           add_specific_symbol (optarg, &strip_specific_list);
2895           break;
2896
2897         case OPTION_STRIP_UNNEEDED_SYMBOL:
2898           add_specific_symbol (optarg, &strip_unneeded_list);
2899           break;
2900
2901         case 'L':
2902           add_specific_symbol (optarg, &localize_specific_list);
2903           break;
2904
2905         case OPTION_GLOBALIZE_SYMBOL:
2906           add_specific_symbol (optarg, &globalize_specific_list);
2907           break;
2908
2909         case 'G':
2910           add_specific_symbol (optarg, &keepglobal_specific_list);
2911           break;
2912
2913         case 'W':
2914           add_specific_symbol (optarg, &weaken_specific_list);
2915           break;
2916
2917         case 'p':
2918           preserve_dates = TRUE;
2919           break;
2920
2921         case 'w':
2922           wildcard = TRUE;
2923           break;
2924
2925         case 'x':
2926           discard_locals = LOCALS_ALL;
2927           break;
2928
2929         case 'X':
2930           discard_locals = LOCALS_START_L;
2931           break;
2932
2933         case 'v':
2934           verbose = TRUE;
2935           break;
2936
2937         case 'V':
2938           show_version = TRUE;
2939           break;
2940
2941         case OPTION_FORMATS_INFO:
2942           formats_info = TRUE;
2943           break;
2944
2945         case OPTION_WEAKEN:
2946           weaken = TRUE;
2947           break;
2948
2949         case OPTION_ADD_SECTION:
2950           {
2951             const char *s;
2952             off_t size;
2953             struct section_add *pa;
2954             int len;
2955             char *name;
2956             FILE *f;
2957
2958             s = strchr (optarg, '=');
2959
2960             if (s == NULL)
2961               fatal (_("bad format for %s"), "--add-section");
2962
2963             size = get_file_size (s + 1);
2964             if (size < 1)
2965               {
2966                 status = 1;
2967                 break;
2968               }
2969
2970             pa = xmalloc (sizeof (struct section_add));
2971
2972             len = s - optarg;
2973             name = xmalloc (len + 1);
2974             strncpy (name, optarg, len);
2975             name[len] = '\0';
2976             pa->name = name;
2977
2978             pa->filename = s + 1;
2979             pa->size = size;
2980             pa->contents = xmalloc (size);
2981
2982             f = fopen (pa->filename, FOPEN_RB);
2983
2984             if (f == NULL)
2985               fatal (_("cannot open: %s: %s"),
2986                      pa->filename, strerror (errno));
2987
2988             if (fread (pa->contents, 1, pa->size, f) == 0
2989                 || ferror (f))
2990               fatal (_("%s: fread failed"), pa->filename);
2991
2992             fclose (f);
2993
2994             pa->next = add_sections;
2995             add_sections = pa;
2996           }
2997           break;
2998
2999         case OPTION_CHANGE_START:
3000           change_start = parse_vma (optarg, "--change-start");
3001           break;
3002
3003         case OPTION_CHANGE_SECTION_ADDRESS:
3004         case OPTION_CHANGE_SECTION_LMA:
3005         case OPTION_CHANGE_SECTION_VMA:
3006           {
3007             const char *s;
3008             int len;
3009             char *name;
3010             char *option = NULL;
3011             bfd_vma val;
3012             enum change_action what = CHANGE_IGNORE;
3013
3014             switch (c)
3015               {
3016               case OPTION_CHANGE_SECTION_ADDRESS:
3017                 option = "--change-section-address";
3018                 break;
3019               case OPTION_CHANGE_SECTION_LMA:
3020                 option = "--change-section-lma";
3021                 break;
3022               case OPTION_CHANGE_SECTION_VMA:
3023                 option = "--change-section-vma";
3024                 break;
3025               }
3026
3027             s = strchr (optarg, '=');
3028             if (s == NULL)
3029               {
3030                 s = strchr (optarg, '+');
3031                 if (s == NULL)
3032                   {
3033                     s = strchr (optarg, '-');
3034                     if (s == NULL)
3035                       fatal (_("bad format for %s"), option);
3036                   }
3037               }
3038
3039             len = s - optarg;
3040             name = xmalloc (len + 1);
3041             strncpy (name, optarg, len);
3042             name[len] = '\0';
3043
3044             p = find_section_list (name, TRUE);
3045
3046             val = parse_vma (s + 1, option);
3047
3048             switch (*s)
3049               {
3050               case '=': what = CHANGE_SET; break;
3051               case '-': val  = - val; /* Drop through.  */
3052               case '+': what = CHANGE_MODIFY; break;
3053               }
3054
3055             switch (c)
3056               {
3057               case OPTION_CHANGE_SECTION_ADDRESS:
3058                 p->change_vma = what;
3059                 p->vma_val    = val;
3060                 /* Drop through.  */
3061
3062               case OPTION_CHANGE_SECTION_LMA:
3063                 p->change_lma = what;
3064                 p->lma_val    = val;
3065                 break;
3066
3067               case OPTION_CHANGE_SECTION_VMA:
3068                 p->change_vma = what;
3069                 p->vma_val    = val;
3070                 break;
3071               }
3072           }
3073           break;
3074
3075         case OPTION_CHANGE_ADDRESSES:
3076           change_section_address = parse_vma (optarg, "--change-addresses");
3077           change_start = change_section_address;
3078           break;
3079
3080         case OPTION_CHANGE_WARNINGS:
3081           change_warn = TRUE;
3082           break;
3083
3084         case OPTION_CHANGE_LEADING_CHAR:
3085           change_leading_char = TRUE;
3086           break;
3087
3088         case OPTION_DEBUGGING:
3089           convert_debugging = TRUE;
3090           break;
3091
3092         case OPTION_GAP_FILL:
3093           {
3094             bfd_vma gap_fill_vma;
3095
3096             gap_fill_vma = parse_vma (optarg, "--gap-fill");
3097             gap_fill = (bfd_byte) gap_fill_vma;
3098             if ((bfd_vma) gap_fill != gap_fill_vma)
3099               {
3100                 char buff[20];
3101
3102                 sprintf_vma (buff, gap_fill_vma);
3103
3104                 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3105                            buff, gap_fill);
3106               }
3107             gap_fill_set = TRUE;
3108           }
3109           break;
3110
3111         case OPTION_NO_CHANGE_WARNINGS:
3112           change_warn = FALSE;
3113           break;
3114
3115         case OPTION_PAD_TO:
3116           pad_to = parse_vma (optarg, "--pad-to");
3117           pad_to_set = TRUE;
3118           break;
3119
3120         case OPTION_REMOVE_LEADING_CHAR:
3121           remove_leading_char = TRUE;
3122           break;
3123
3124         case OPTION_REDEFINE_SYM:
3125           {
3126             /* Push this redefinition onto redefine_symbol_list.  */
3127
3128             int len;
3129             const char *s;
3130             const char *nextarg;
3131             char *source, *target;
3132
3133             s = strchr (optarg, '=');
3134             if (s == NULL)
3135               fatal (_("bad format for %s"), "--redefine-sym");
3136
3137             len = s - optarg;
3138             source = xmalloc (len + 1);
3139             strncpy (source, optarg, len);
3140             source[len] = '\0';
3141
3142             nextarg = s + 1;
3143             len = strlen (nextarg);
3144             target = xmalloc (len + 1);
3145             strcpy (target, nextarg);
3146
3147             redefine_list_append ("--redefine-sym", source, target);
3148
3149             free (source);
3150             free (target);
3151           }
3152           break;
3153
3154         case OPTION_REDEFINE_SYMS:
3155           add_redefine_syms_file (optarg);
3156           break;
3157
3158         case OPTION_SET_SECTION_FLAGS:
3159           {
3160             const char *s;
3161             int len;
3162             char *name;
3163
3164             s = strchr (optarg, '=');
3165             if (s == NULL)
3166               fatal (_("bad format for %s"), "--set-section-flags");
3167
3168             len = s - optarg;
3169             name = xmalloc (len + 1);
3170             strncpy (name, optarg, len);
3171             name[len] = '\0';
3172
3173             p = find_section_list (name, TRUE);
3174
3175             p->set_flags = TRUE;
3176             p->flags = parse_flags (s + 1);
3177           }
3178           break;
3179
3180         case OPTION_RENAME_SECTION:
3181           {
3182             flagword flags;
3183             const char *eq, *fl;
3184             char *old_name;
3185             char *new_name;
3186             unsigned int len;
3187
3188             eq = strchr (optarg, '=');
3189             if (eq == NULL)
3190               fatal (_("bad format for %s"), "--rename-section");
3191
3192             len = eq - optarg;
3193             if (len == 0)
3194               fatal (_("bad format for %s"), "--rename-section");
3195
3196             old_name = xmalloc (len + 1);
3197             strncpy (old_name, optarg, len);
3198             old_name[len] = 0;
3199
3200             eq++;
3201             fl = strchr (eq, ',');
3202             if (fl)
3203               {
3204                 flags = parse_flags (fl + 1);
3205                 len = fl - eq;
3206               }
3207             else
3208               {
3209                 flags = -1;
3210                 len = strlen (eq);
3211               }
3212
3213             if (len == 0)
3214               fatal (_("bad format for %s"), "--rename-section");
3215
3216             new_name = xmalloc (len + 1);
3217             strncpy (new_name, eq, len);
3218             new_name[len] = 0;
3219
3220             add_section_rename (old_name, new_name, flags);
3221           }
3222           break;
3223
3224         case OPTION_SET_START:
3225           set_start = parse_vma (optarg, "--set-start");
3226           set_start_set = TRUE;
3227           break;
3228
3229         case OPTION_SREC_LEN:
3230           Chunk = parse_vma (optarg, "--srec-len");
3231           break;
3232
3233         case OPTION_SREC_FORCES3:
3234           S3Forced = TRUE;
3235           break;
3236
3237         case OPTION_STRIP_SYMBOLS:
3238           add_specific_symbols (optarg, &strip_specific_list);
3239           break;
3240
3241         case OPTION_STRIP_UNNEEDED_SYMBOLS:
3242           add_specific_symbols (optarg, &strip_unneeded_list);
3243           break;
3244
3245         case OPTION_KEEP_SYMBOLS:
3246           add_specific_symbols (optarg, &keep_specific_list);
3247           break;
3248
3249         case OPTION_LOCALIZE_HIDDEN:
3250           localize_hidden = TRUE;
3251           break;
3252
3253         case OPTION_LOCALIZE_SYMBOLS:
3254           add_specific_symbols (optarg, &localize_specific_list);
3255           break;
3256
3257         case OPTION_GLOBALIZE_SYMBOLS:
3258           add_specific_symbols (optarg, &globalize_specific_list);
3259           break;
3260
3261         case OPTION_KEEPGLOBAL_SYMBOLS:
3262           add_specific_symbols (optarg, &keepglobal_specific_list);
3263           break;
3264
3265         case OPTION_WEAKEN_SYMBOLS:
3266           add_specific_symbols (optarg, &weaken_specific_list);
3267           break;
3268
3269         case OPTION_ALT_MACH_CODE:
3270           use_alt_mach_code = strtoul (optarg, NULL, 0);
3271           if (use_alt_mach_code == 0)
3272             fatal (_("unable to parse alternative machine code"));
3273           break;
3274
3275         case OPTION_PREFIX_SYMBOLS:
3276           prefix_symbols_string = optarg;
3277           break;
3278
3279         case OPTION_PREFIX_SECTIONS:
3280           prefix_sections_string = optarg;
3281           break;
3282
3283         case OPTION_PREFIX_ALLOC_SECTIONS:
3284           prefix_alloc_sections_string = optarg;
3285           break;
3286
3287         case OPTION_READONLY_TEXT:
3288           bfd_flags_to_set |= WP_TEXT;
3289           bfd_flags_to_clear &= ~WP_TEXT;
3290           break;
3291
3292         case OPTION_WRITABLE_TEXT:
3293           bfd_flags_to_clear |= WP_TEXT;
3294           bfd_flags_to_set &= ~WP_TEXT;
3295           break;
3296
3297         case OPTION_PURE:
3298           bfd_flags_to_set |= D_PAGED;
3299           bfd_flags_to_clear &= ~D_PAGED;
3300           break;
3301
3302         case OPTION_IMPURE:
3303           bfd_flags_to_clear |= D_PAGED;
3304           bfd_flags_to_set &= ~D_PAGED;
3305           break;
3306
3307         case OPTION_EXTRACT_SYMBOL:
3308           extract_symbol = TRUE;
3309           break;
3310
3311         case OPTION_REVERSE_BYTES:
3312           {
3313             int prev = reverse_bytes;
3314
3315             reverse_bytes = atoi (optarg);
3316             if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3317               fatal (_("number of bytes to reverse must be positive and even"));
3318
3319             if (prev && prev != reverse_bytes)
3320               non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3321                          prev);
3322             break;
3323           }
3324
3325         case 0:
3326           /* We've been given a long option.  */
3327           break;
3328
3329         case 'H':
3330         case 'h':
3331           copy_usage (stdout, 0);
3332
3333         default:
3334           copy_usage (stderr, 1);
3335         }
3336     }
3337
3338   if (formats_info)
3339     {
3340       display_info ();
3341       return 0;
3342     }
3343  
3344   if (show_version)
3345     print_version ("objcopy");
3346
3347   if (copy_byte >= interleave)
3348     fatal (_("byte number must be less than interleave"));
3349
3350   if (optind == argc || optind + 2 < argc)
3351     copy_usage (stderr, 1);
3352
3353   input_filename = argv[optind];
3354   if (optind + 1 < argc)
3355     output_filename = argv[optind + 1];
3356
3357   /* Default is to strip no symbols.  */
3358   if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3359     strip_symbols = STRIP_NONE;
3360
3361   if (output_target == NULL)
3362     output_target = input_target;
3363
3364   if (binary_architecture != NULL)
3365     {
3366       if (input_target && strcmp (input_target, "binary") == 0)
3367         {
3368           const bfd_arch_info_type * temp_arch_info;
3369
3370           temp_arch_info = bfd_scan_arch (binary_architecture);
3371
3372           if (temp_arch_info != NULL)
3373             {
3374               bfd_external_binary_architecture = temp_arch_info->arch;
3375               bfd_external_machine             = temp_arch_info->mach;
3376             }
3377           else
3378             fatal (_("architecture %s unknown"), binary_architecture);
3379         }
3380       else
3381         {
3382           non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
3383           non_fatal (_(" Argument %s ignored"), binary_architecture);
3384         }
3385     }
3386
3387   if (preserve_dates)
3388     if (stat (input_filename, & statbuf) < 0)
3389       fatal (_("warning: could not locate '%s'.  System error message: %s"),
3390              input_filename, strerror (errno));
3391
3392   /* If there is no destination file, or the source and destination files
3393      are the same, then create a temp and rename the result into the input.  */
3394   if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
3395     {
3396       char *tmpname = make_tempname (input_filename);
3397
3398       if (tmpname == NULL)
3399         fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3400                input_filename, strerror (errno));
3401
3402       copy_file (input_filename, tmpname, input_target, output_target);
3403       if (status == 0)
3404         {
3405           if (preserve_dates)
3406             set_times (tmpname, &statbuf);
3407           smart_rename (tmpname, input_filename, preserve_dates);
3408         }
3409       else
3410         unlink (tmpname);
3411     }
3412   else
3413     {
3414       copy_file (input_filename, output_filename, input_target, output_target);
3415
3416       if (status == 0 && preserve_dates)
3417         set_times (output_filename, &statbuf);
3418       else if (status != 0)
3419         unlink_if_ordinary (output_filename);
3420     }
3421
3422   if (change_warn)
3423     {
3424       for (p = change_sections; p != NULL; p = p->next)
3425         {
3426           if (! p->used)
3427             {
3428               if (p->change_vma != CHANGE_IGNORE)
3429                 {
3430                   char buff [20];
3431
3432                   sprintf_vma (buff, p->vma_val);
3433
3434                   /* xgettext:c-format */
3435                   non_fatal (_("%s %s%c0x%s never used"),
3436                              "--change-section-vma",
3437                              p->name,
3438                              p->change_vma == CHANGE_SET ? '=' : '+',
3439                              buff);
3440                 }
3441
3442               if (p->change_lma != CHANGE_IGNORE)
3443                 {
3444                   char buff [20];
3445
3446                   sprintf_vma (buff, p->lma_val);
3447
3448                   /* xgettext:c-format */
3449                   non_fatal (_("%s %s%c0x%s never used"),
3450                              "--change-section-lma",
3451                              p->name,
3452                              p->change_lma == CHANGE_SET ? '=' : '+',
3453                              buff);
3454                 }
3455             }
3456         }
3457     }
3458
3459   return 0;
3460 }
3461
3462 int
3463 main (int argc, char *argv[])
3464 {
3465 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3466   setlocale (LC_MESSAGES, "");
3467 #endif
3468 #if defined (HAVE_SETLOCALE)
3469   setlocale (LC_CTYPE, "");
3470 #endif
3471   bindtextdomain (PACKAGE, LOCALEDIR);
3472   textdomain (PACKAGE);
3473
3474   program_name = argv[0];
3475   xmalloc_set_program_name (program_name);
3476
3477   START_PROGRESS (program_name, 0);
3478
3479   expandargv (&argc, &argv);
3480
3481   strip_symbols = STRIP_UNDEF;
3482   discard_locals = LOCALS_UNDEF;
3483
3484   bfd_init ();
3485   set_default_bfd_target ();
3486
3487   if (is_strip < 0)
3488     {
3489       int i = strlen (program_name);
3490 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
3491       /* Drop the .exe suffix, if any.  */
3492       if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3493         {
3494           i -= 4;
3495           program_name[i] = '\0';
3496         }
3497 #endif
3498       is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
3499     }
3500
3501   if (is_strip)
3502     strip_main (argc, argv);
3503   else
3504     copy_main (argc, argv);
3505
3506   END_PROGRESS (program_name);
3507
3508   return status;
3509 }