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