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