]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/binutils/binutils/objcopy.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / binutils / 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 & (EXEC_P | DYNAMIC)) == 0;
914
915   for (; src_count < symcount; src_count++)
916     {
917       asymbol *sym = from[src_count];
918       flagword flags = sym->flags;
919       char *name = (char *) bfd_asymbol_name (sym);
920       bfd_boolean keep;
921       bfd_boolean used_in_reloc = FALSE;
922       bfd_boolean undefined;
923       bfd_boolean rem_leading_char;
924       bfd_boolean add_leading_char;
925
926       undefined = bfd_is_und_section (bfd_get_section (sym));
927
928       if (redefine_sym_list)
929         {
930           char *old_name, *new_name;
931
932           old_name = (char *) bfd_asymbol_name (sym);
933           new_name = (char *) lookup_sym_redefinition (old_name);
934           bfd_asymbol_name (sym) = new_name;
935           name = new_name;
936         }
937
938       /* Check if we will remove the current leading character.  */
939       rem_leading_char =
940         (name[0] == bfd_get_symbol_leading_char (abfd))
941         && (change_leading_char
942             || (remove_leading_char
943                 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
944                     || undefined
945                     || bfd_is_com_section (bfd_get_section (sym)))));
946
947       /* Check if we will add a new leading character.  */
948       add_leading_char =
949         change_leading_char
950         && (bfd_get_symbol_leading_char (obfd) != '\0')
951         && (bfd_get_symbol_leading_char (abfd) == '\0'
952             || (name[0] == bfd_get_symbol_leading_char (abfd)));
953
954       /* Short circuit for change_leading_char if we can do it in-place.  */
955       if (rem_leading_char && add_leading_char && !prefix_symbols_string)
956         {
957           name[0] = bfd_get_symbol_leading_char (obfd);
958           bfd_asymbol_name (sym) = name;
959           rem_leading_char = FALSE;
960           add_leading_char = FALSE;
961         }
962
963       /* Remove leading char.  */
964       if (rem_leading_char)
965         bfd_asymbol_name (sym) = ++name;
966
967       /* Add new leading char and/or prefix.  */
968       if (add_leading_char || prefix_symbols_string)
969         {
970           char *n, *ptr;
971
972           ptr = n = xmalloc (1 + strlen (prefix_symbols_string)
973                              + strlen (name) + 1);
974           if (add_leading_char)
975             *ptr++ = bfd_get_symbol_leading_char (obfd);
976
977           if (prefix_symbols_string)
978             {
979               strcpy (ptr, prefix_symbols_string);
980               ptr += strlen (prefix_symbols_string);
981            }
982
983           strcpy (ptr, name);
984           bfd_asymbol_name (sym) = n;
985           name = n;
986         }
987
988       if (strip_symbols == STRIP_ALL)
989         keep = FALSE;
990       else if ((flags & BSF_KEEP) != 0          /* Used in relocation.  */
991                || ((flags & BSF_SECTION_SYM) != 0
992                    && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
993                        & BSF_KEEP) != 0))
994         {
995           keep = TRUE;
996           used_in_reloc = TRUE;
997         }
998       else if (relocatable                      /* Relocatable file.  */
999                && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
1000         keep = TRUE;
1001       else if (bfd_decode_symclass (sym) == 'I')
1002         /* Global symbols in $idata sections need to be retained
1003            even if relocatable is FALSE.  External users of the
1004            library containing the $idata section may reference these
1005            symbols.  */
1006         keep = TRUE;
1007       else if ((flags & BSF_GLOBAL) != 0        /* Global symbol.  */
1008                || (flags & BSF_WEAK) != 0
1009                || undefined
1010                || bfd_is_com_section (bfd_get_section (sym)))
1011         keep = strip_symbols != STRIP_UNNEEDED;
1012       else if ((flags & BSF_DEBUGGING) != 0)    /* Debugging symbol.  */
1013         keep = (strip_symbols != STRIP_DEBUG
1014                 && strip_symbols != STRIP_UNNEEDED
1015                 && ! convert_debugging);
1016       else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
1017         /* COMDAT sections store special information in local
1018            symbols, so we cannot risk stripping any of them.  */
1019         keep = TRUE;
1020       else                      /* Local symbol.  */
1021         keep = (strip_symbols != STRIP_UNNEEDED
1022                 && (discard_locals != LOCALS_ALL
1023                     && (discard_locals != LOCALS_START_L
1024                         || ! bfd_is_local_label (abfd, sym))));
1025
1026       if (keep && is_specified_symbol (name, strip_specific_list))
1027         {
1028           /* There are multiple ways to set 'keep' above, but if it
1029              was the relocatable symbol case, then that's an error.  */
1030           if (used_in_reloc)
1031             {
1032               non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name);
1033               status = 1;
1034             }
1035           else
1036             keep = FALSE;
1037         }
1038
1039       if (keep
1040           && !(flags & BSF_KEEP)
1041           && is_specified_symbol (name, strip_unneeded_list))
1042         keep = FALSE;
1043
1044       if (!keep
1045           && ((keep_file_symbols && (flags & BSF_FILE))
1046               || is_specified_symbol (name, keep_specific_list)))
1047         keep = TRUE;
1048
1049       if (keep && is_strip_section (abfd, bfd_get_section (sym)))
1050         keep = FALSE;
1051
1052       if (keep)
1053         {
1054           if ((flags & BSF_GLOBAL) != 0
1055               && (weaken || is_specified_symbol (name, weaken_specific_list)))
1056             {
1057               sym->flags &= ~ BSF_GLOBAL;
1058               sym->flags |= BSF_WEAK;
1059             }
1060
1061           if (!undefined
1062               && (flags & (BSF_GLOBAL | BSF_WEAK))
1063               && (is_specified_symbol (name, localize_specific_list)
1064                   || (keepglobal_specific_list != NULL
1065                       && ! is_specified_symbol (name, keepglobal_specific_list))
1066                   || (localize_hidden && is_hidden_symbol (sym))))
1067             {
1068               sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
1069               sym->flags |= BSF_LOCAL;
1070             }
1071
1072           if (!undefined
1073               && (flags & BSF_LOCAL)
1074               && is_specified_symbol (name, globalize_specific_list))
1075             {
1076               sym->flags &= ~ BSF_LOCAL;
1077               sym->flags |= BSF_GLOBAL;
1078             }
1079
1080           to[dst_count++] = sym;
1081         }
1082     }
1083
1084   to[dst_count] = NULL;
1085
1086   return dst_count;
1087 }
1088
1089 /* Find the redefined name of symbol SOURCE.  */
1090
1091 static const char *
1092 lookup_sym_redefinition (const char *source)
1093 {
1094   struct redefine_node *list;
1095
1096   for (list = redefine_sym_list; list != NULL; list = list->next)
1097     if (strcmp (source, list->source) == 0)
1098       return list->target;
1099
1100   return source;
1101 }
1102
1103 /* Add a node to a symbol redefine list.  */
1104
1105 static void
1106 redefine_list_append (const char *cause, const char *source, const char *target)
1107 {
1108   struct redefine_node **p;
1109   struct redefine_node *list;
1110   struct redefine_node *new_node;
1111
1112   for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
1113     {
1114       if (strcmp (source, list->source) == 0)
1115         fatal (_("%s: Multiple redefinition of symbol \"%s\""),
1116                cause, source);
1117
1118       if (strcmp (target, list->target) == 0)
1119         fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
1120                cause, target);
1121     }
1122
1123   new_node = xmalloc (sizeof (struct redefine_node));
1124
1125   new_node->source = strdup (source);
1126   new_node->target = strdup (target);
1127   new_node->next = NULL;
1128
1129   *p = new_node;
1130 }
1131
1132 /* Handle the --redefine-syms option.  Read lines containing "old new"
1133    from the file, and add them to the symbol redefine list.  */
1134
1135 static void
1136 add_redefine_syms_file (const char *filename)
1137 {
1138   FILE *file;
1139   char *buf;
1140   size_t bufsize;
1141   size_t len;
1142   size_t outsym_off;
1143   int c, lineno;
1144
1145   file = fopen (filename, "r");
1146   if (file == NULL)
1147     fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
1148            filename, strerror (errno));
1149
1150   bufsize = 100;
1151   buf = xmalloc (bufsize);
1152
1153   lineno = 1;
1154   c = getc (file);
1155   len = 0;
1156   outsym_off = 0;
1157   while (c != EOF)
1158     {
1159       /* Collect the input symbol name.  */
1160       while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1161         {
1162           if (c == '#')
1163             goto comment;
1164           buf[len++] = c;
1165           if (len >= bufsize)
1166             {
1167               bufsize *= 2;
1168               buf = xrealloc (buf, bufsize);
1169             }
1170           c = getc (file);
1171         }
1172       buf[len++] = '\0';
1173       if (c == EOF)
1174         break;
1175
1176       /* Eat white space between the symbol names.  */
1177       while (IS_WHITESPACE (c))
1178         c = getc (file);
1179       if (c == '#' || IS_LINE_TERMINATOR (c))
1180         goto comment;
1181       if (c == EOF)
1182         break;
1183
1184       /* Collect the output symbol name.  */
1185       outsym_off = len;
1186       while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1187         {
1188           if (c == '#')
1189             goto comment;
1190           buf[len++] = c;
1191           if (len >= bufsize)
1192             {
1193               bufsize *= 2;
1194               buf = xrealloc (buf, bufsize);
1195             }
1196           c = getc (file);
1197         }
1198       buf[len++] = '\0';
1199       if (c == EOF)
1200         break;
1201
1202       /* Eat white space at end of line.  */
1203       while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1204         c = getc (file);
1205       if (c == '#')
1206         goto comment;
1207       /* Handle \r\n.  */
1208       if ((c == '\r' && (c = getc (file)) == '\n')
1209           || c == '\n' || c == EOF)
1210         {
1211  end_of_line:
1212           /* Append the redefinition to the list.  */
1213           if (buf[0] != '\0')
1214             redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1215
1216           lineno++;
1217           len = 0;
1218           outsym_off = 0;
1219           if (c == EOF)
1220             break;
1221           c = getc (file);
1222           continue;
1223         }
1224       else
1225         fatal (_("%s:%d: garbage found at end of line"), filename, lineno);
1226  comment:
1227       if (len != 0 && (outsym_off == 0 || outsym_off == len))
1228         fatal (_("%s:%d: missing new symbol name"), filename, lineno);
1229       buf[len++] = '\0';
1230
1231       /* Eat the rest of the line and finish it.  */
1232       while (c != '\n' && c != EOF)
1233         c = getc (file);
1234       goto end_of_line;
1235     }
1236
1237   if (len != 0)
1238     fatal (_("%s:%d: premature end of file"), filename, lineno);
1239
1240   free (buf);
1241 }
1242
1243 /* Copy unkown object file IBFD onto OBFD.
1244    Returns TRUE upon success, FALSE otherwise.  */
1245
1246 static bfd_boolean
1247 copy_unknown_object (bfd *ibfd, bfd *obfd)
1248 {
1249   char *cbuf;
1250   int tocopy;
1251   long ncopied;
1252   long size;
1253   struct stat buf;
1254
1255   if (bfd_stat_arch_elt (ibfd, &buf) != 0)
1256     {
1257       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1258       return FALSE;
1259     }
1260
1261   size = buf.st_size;
1262   if (size < 0)
1263     {
1264       non_fatal (_("stat returns negative size for `%s'"),
1265                  bfd_get_archive_filename (ibfd));
1266       return FALSE;
1267     }
1268
1269   if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
1270     {
1271       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1272       return FALSE;
1273     }
1274
1275   if (verbose)
1276     printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"),
1277             bfd_get_archive_filename (ibfd), bfd_get_filename (obfd));
1278
1279   cbuf = xmalloc (BUFSIZE);
1280   ncopied = 0;
1281   while (ncopied < size)
1282     {
1283       tocopy = size - ncopied;
1284       if (tocopy > BUFSIZE)
1285         tocopy = BUFSIZE;
1286
1287       if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd)
1288           != (bfd_size_type) tocopy)
1289         {
1290           bfd_nonfatal (bfd_get_archive_filename (ibfd));
1291           free (cbuf);
1292           return FALSE;
1293         }
1294
1295       if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
1296           != (bfd_size_type) tocopy)
1297         {
1298           bfd_nonfatal (bfd_get_filename (obfd));
1299           free (cbuf);
1300           return FALSE;
1301         }
1302
1303       ncopied += tocopy;
1304     }
1305
1306   chmod (bfd_get_filename (obfd), buf.st_mode);
1307   free (cbuf);
1308   return TRUE;
1309 }
1310
1311 /* Copy object file IBFD onto OBFD.
1312    Returns TRUE upon success, FALSE otherwise.  */
1313
1314 static bfd_boolean
1315 copy_object (bfd *ibfd, bfd *obfd)
1316 {
1317   bfd_vma start;
1318   long symcount;
1319   asection **osections = NULL;
1320   asection *gnu_debuglink_section = NULL;
1321   bfd_size_type *gaps = NULL;
1322   bfd_size_type max_gap = 0;
1323   long symsize;
1324   void *dhandle;
1325   enum bfd_architecture iarch;
1326   unsigned int imach;
1327
1328   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1329       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1330       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1331     fatal (_("Unable to change endianness of input file(s)"));
1332
1333   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1334     {
1335       bfd_nonfatal (bfd_get_filename (obfd));
1336       return FALSE;
1337     }
1338
1339   if (verbose)
1340     printf (_("copy from `%s' [%s] to `%s' [%s]\n"),
1341             bfd_get_archive_filename (ibfd), bfd_get_target (ibfd),
1342             bfd_get_filename (obfd), bfd_get_target (obfd));
1343
1344   if (extract_symbol)
1345     start = 0;
1346   else
1347     {
1348       if (set_start_set)
1349         start = set_start;
1350       else
1351         start = bfd_get_start_address (ibfd);
1352       start += change_start;
1353     }
1354
1355   /* Neither the start address nor the flags
1356      need to be set for a core file.  */
1357   if (bfd_get_format (obfd) != bfd_core)
1358     {
1359       flagword flags;
1360
1361       flags = bfd_get_file_flags (ibfd);
1362       flags |= bfd_flags_to_set;
1363       flags &= ~bfd_flags_to_clear;
1364       flags &= bfd_applicable_file_flags (obfd);
1365
1366       if (!bfd_set_start_address (obfd, start)
1367           || !bfd_set_file_flags (obfd, flags))
1368         {
1369           bfd_nonfatal (bfd_get_archive_filename (ibfd));
1370           return FALSE;
1371         }
1372     }
1373
1374   /* Copy architecture of input file to output file.  */
1375   iarch = bfd_get_arch (ibfd);
1376   imach = bfd_get_mach (ibfd);
1377   if (!bfd_set_arch_mach (obfd, iarch, imach)
1378       && (ibfd->target_defaulted
1379           || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1380     {
1381       if (bfd_get_arch (ibfd) == bfd_arch_unknown)
1382         non_fatal (_("Unable to recognise the format of the input file `%s'"),
1383                    bfd_get_archive_filename (ibfd));
1384       else
1385         non_fatal (_("Warning: Output file cannot represent architecture `%s'"),
1386                    bfd_printable_arch_mach (bfd_get_arch (ibfd),
1387                                             bfd_get_mach (ibfd)));
1388       return FALSE;
1389     }
1390
1391   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1392     {
1393       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1394       return FALSE;
1395     }
1396
1397   if (isympp)
1398     free (isympp);
1399
1400   if (osympp != isympp)
1401     free (osympp);
1402
1403   isympp = NULL;
1404   osympp = NULL;
1405
1406   symsize = bfd_get_symtab_upper_bound (ibfd);
1407   if (symsize < 0)
1408     {
1409       bfd_nonfatal (bfd_get_archive_filename (ibfd));
1410       return FALSE;
1411     }
1412
1413   osympp = isympp = xmalloc (symsize);
1414   symcount = bfd_canonicalize_symtab (ibfd, isympp);
1415   if (symcount < 0)
1416     {
1417       bfd_nonfatal (bfd_get_filename (ibfd));
1418       return FALSE;
1419     }
1420
1421   /* BFD mandates that all output sections be created and sizes set before
1422      any output is done.  Thus, we traverse all sections multiple times.  */
1423   bfd_map_over_sections (ibfd, setup_section, obfd);
1424
1425   setup_bfd_headers (ibfd, obfd);
1426
1427   if (add_sections != NULL)
1428     {
1429       struct section_add *padd;
1430       struct section_list *pset;
1431
1432       for (padd = add_sections; padd != NULL; padd = padd->next)
1433         {
1434           flagword flags;
1435
1436           pset = find_section_list (padd->name, FALSE);
1437           if (pset != NULL)
1438             pset->used = TRUE;
1439
1440           flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1441           if (pset != NULL && pset->set_flags)
1442             flags = pset->flags | SEC_HAS_CONTENTS;
1443
1444           /* bfd_make_section_with_flags() does not return very helpful
1445              error codes, so check for the most likely user error first.  */
1446           if (bfd_get_section_by_name (obfd, padd->name))
1447             {
1448               non_fatal (_("can't add section '%s' - it already exists!"), padd->name);
1449               return FALSE;
1450             }
1451           else
1452             {
1453               padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
1454               if (padd->section == NULL)
1455                 {
1456                   non_fatal (_("can't create section `%s': %s"),
1457                              padd->name, bfd_errmsg (bfd_get_error ()));
1458                   return FALSE;
1459                 }
1460             }
1461
1462           if (! bfd_set_section_size (obfd, padd->section, padd->size))
1463             {
1464               bfd_nonfatal (bfd_get_filename (obfd));
1465               return FALSE;
1466             }
1467
1468           if (pset != NULL)
1469             {
1470               if (pset->change_vma != CHANGE_IGNORE)
1471                 if (! bfd_set_section_vma (obfd, padd->section,
1472                                            pset->vma_val))
1473                   {
1474                     bfd_nonfatal (bfd_get_filename (obfd));
1475                     return FALSE;
1476                   }
1477
1478               if (pset->change_lma != CHANGE_IGNORE)
1479                 {
1480                   padd->section->lma = pset->lma_val;
1481
1482                   if (! bfd_set_section_alignment
1483                       (obfd, padd->section,
1484                        bfd_section_alignment (obfd, padd->section)))
1485                     {
1486                       bfd_nonfatal (bfd_get_filename (obfd));
1487                       return FALSE;
1488                     }
1489                 }
1490             }
1491         }
1492     }
1493
1494   if (gnu_debuglink_filename != NULL)
1495     {
1496       gnu_debuglink_section = bfd_create_gnu_debuglink_section
1497         (obfd, gnu_debuglink_filename);
1498
1499       if (gnu_debuglink_section == NULL)
1500         {
1501           bfd_nonfatal (gnu_debuglink_filename);
1502           return FALSE;
1503         }
1504
1505       /* Special processing for PE format files.  We
1506          have no way to distinguish PE from COFF here.  */
1507       if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1508         {
1509           bfd_vma debuglink_vma;
1510           asection * highest_section;
1511           asection * sec;
1512
1513           /* The PE spec requires that all sections be adjacent and sorted
1514              in ascending order of VMA.  It also specifies that debug
1515              sections should be last.  This is despite the fact that debug
1516              sections are not loaded into memory and so in theory have no
1517              use for a VMA.
1518
1519              This means that the debuglink section must be given a non-zero
1520              VMA which makes it contiguous with other debug sections.  So
1521              walk the current section list, find the section with the
1522              highest VMA and start the debuglink section after that one.  */
1523           for (sec = obfd->sections, highest_section = NULL;
1524                sec != NULL;
1525                sec = sec->next)
1526             if (sec->vma > 0
1527                 && (highest_section == NULL
1528                     || sec->vma > highest_section->vma))
1529               highest_section = sec;
1530
1531           if (highest_section)
1532             debuglink_vma = BFD_ALIGN (highest_section->vma
1533                                        + highest_section->size,
1534                                        /* FIXME: We ought to be using
1535                                           COFF_PAGE_SIZE here or maybe
1536                                           bfd_get_section_alignment() (if it
1537                                           was set) but since this is for PE
1538                                           and we know the required alignment
1539                                           it is easier just to hard code it.  */
1540                                        0x1000);
1541           else
1542             /* Umm, not sure what to do in this case.  */
1543             debuglink_vma = 0x1000;
1544
1545           (void) bfd_set_section_vma (obfd, gnu_debuglink_section,
1546                                       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       && elf_section_type (osection) != SHT_NOTE
2216       && (ibfd->xvec->flavour != bfd_target_elf_flavour
2217           || elf_section_type (isection) != SHT_NOTE)
2218       && (p == NULL || !p->set_flags))
2219     elf_section_type (osection) = SHT_NOBITS;
2220
2221   size = bfd_section_size (ibfd, isection);
2222   if (copy_byte >= 0)
2223     size = (size + interleave - 1) / interleave;
2224   else if (extract_symbol)
2225     size = 0;
2226   if (! bfd_set_section_size (obfd, osection, size))
2227     {
2228       err = _("size");
2229       goto loser;
2230     }
2231
2232   vma = bfd_section_vma (ibfd, isection);
2233   if (p != NULL && p->change_vma == CHANGE_MODIFY)
2234     vma += p->vma_val;
2235   else if (p != NULL && p->change_vma == CHANGE_SET)
2236     vma = p->vma_val;
2237   else
2238     vma += change_section_address;
2239
2240   if (! bfd_set_section_vma (obfd, osection, extract_symbol ? 0 : vma))
2241     {
2242       err = _("vma");
2243       goto loser;
2244     }
2245
2246   lma = isection->lma;
2247   if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2248     {
2249       if (p->change_lma == CHANGE_MODIFY)
2250         lma += p->lma_val;
2251       else if (p->change_lma == CHANGE_SET)
2252         lma = p->lma_val;
2253       else
2254         abort ();
2255     }
2256   else
2257     lma += change_section_address;
2258
2259   osection->lma = extract_symbol ? 0 : lma;
2260
2261   /* FIXME: This is probably not enough.  If we change the LMA we
2262      may have to recompute the header for the file as well.  */
2263   if (!bfd_set_section_alignment (obfd,
2264                                   osection,
2265                                   bfd_section_alignment (ibfd, isection)))
2266     {
2267       err = _("alignment");
2268       goto loser;
2269     }
2270
2271   /* Copy merge entity size.  */
2272   osection->entsize = isection->entsize;
2273
2274   /* This used to be mangle_section; we do here to avoid using
2275      bfd_get_section_by_name since some formats allow multiple
2276      sections with the same name.  */
2277   isection->output_section = osection;
2278   isection->output_offset = extract_symbol ? vma : 0;
2279
2280   /* Do not copy backend data if --extract-symbol is passed; anything
2281      that needs to look at the section contents will fail.  */
2282   if (extract_symbol)
2283     return;
2284
2285   /* Allow the BFD backend to copy any private data it understands
2286      from the input section to the output section.  */
2287   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
2288     {
2289       err = _("private data");
2290       goto loser;
2291     }
2292   else if ((isection->flags & SEC_GROUP) != 0)
2293     {
2294       asymbol *gsym = group_signature (isection);
2295
2296       if (gsym != NULL)
2297         gsym->flags |= BSF_KEEP;
2298     }
2299
2300   /* All went well.  */
2301   return;
2302
2303 loser:
2304   non_fatal (_("%s: section `%s': error in %s: %s"),
2305              bfd_get_filename (ibfd),
2306              bfd_section_name (ibfd, isection),
2307              err, bfd_errmsg (bfd_get_error ()));
2308   status = 1;
2309 }
2310
2311 /* Copy the data of input section ISECTION of IBFD
2312    to an output section with the same name in OBFD.
2313    If stripping then don't copy any relocation info.  */
2314
2315 static void
2316 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2317 {
2318   bfd *obfd = obfdarg;
2319   struct section_list *p;
2320   arelent **relpp;
2321   long relcount;
2322   sec_ptr osection;
2323   bfd_size_type size;
2324   long relsize;
2325   flagword flags;
2326
2327   /* If we have already failed earlier on,
2328      do not keep on generating complaints now.  */
2329   if (status != 0)
2330     return;
2331
2332   if (is_strip_section (ibfd, isection))
2333     return;
2334
2335   flags = bfd_get_section_flags (ibfd, isection);
2336   if ((flags & SEC_GROUP) != 0)
2337     return;
2338
2339   osection = isection->output_section;
2340   size = bfd_get_section_size (isection);
2341
2342   if (size == 0 || osection == 0)
2343     return;
2344
2345   p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2346
2347   /* Core files do not need to be relocated.  */
2348   if (bfd_get_format (obfd) == bfd_core)
2349     relsize = 0;
2350   else
2351     {
2352       relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2353
2354       if (relsize < 0)
2355         {
2356           /* Do not complain if the target does not support relocations.  */
2357           if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2358             relsize = 0;
2359           else
2360             RETURN_NONFATAL (bfd_get_filename (ibfd));
2361         }
2362     }
2363
2364   if (relsize == 0)
2365     bfd_set_reloc (obfd, osection, NULL, 0);
2366   else
2367     {
2368       relpp = xmalloc (relsize);
2369       relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2370       if (relcount < 0)
2371         RETURN_NONFATAL (bfd_get_filename (ibfd));
2372
2373       if (strip_symbols == STRIP_ALL)
2374         {
2375           /* Remove relocations which are not in
2376              keep_strip_specific_list.  */
2377           arelent **temp_relpp;
2378           long temp_relcount = 0;
2379           long i;
2380
2381           temp_relpp = xmalloc (relsize);
2382           for (i = 0; i < relcount; i++)
2383             if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
2384                                      keep_specific_list))
2385               temp_relpp [temp_relcount++] = relpp [i];
2386           relcount = temp_relcount;
2387           free (relpp);
2388           relpp = temp_relpp;
2389         }
2390
2391       bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
2392       if (relcount == 0)
2393         free (relpp);
2394     }
2395
2396   if (extract_symbol)
2397     return;
2398
2399   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
2400       && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
2401     {
2402       void *memhunk = xmalloc (size);
2403
2404       if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2405         RETURN_NONFATAL (bfd_get_filename (ibfd));
2406
2407       if (reverse_bytes)
2408         {
2409           /* We don't handle leftover bytes (too many possible behaviors,
2410              and we don't know what the user wants).  The section length
2411              must be a multiple of the number of bytes to swap.  */
2412           if ((size % reverse_bytes) == 0)
2413             {
2414               unsigned long i, j;
2415               bfd_byte b;
2416
2417               for (i = 0; i < size; i += reverse_bytes)
2418                 for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2419                   {
2420                     bfd_byte *m = (bfd_byte *) memhunk;
2421
2422                     b = m[i + j];
2423                     m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2424                     m[(i + reverse_bytes) - (j + 1)] = b;
2425                   }
2426             }
2427           else
2428             /* User must pad the section up in order to do this.  */
2429             fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2430                    bfd_section_name (ibfd, isection), reverse_bytes);
2431         }
2432
2433       if (copy_byte >= 0)
2434         {
2435           /* Keep only every `copy_byte'th byte in MEMHUNK.  */
2436           char *from = (char *) memhunk + copy_byte;
2437           char *to = memhunk;
2438           char *end = (char *) memhunk + size;
2439
2440           for (; from < end; from += interleave)
2441             *to++ = *from;
2442
2443           size = (size + interleave - 1 - copy_byte) / interleave;
2444           osection->lma /= interleave;
2445         }
2446
2447       if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2448         RETURN_NONFATAL (bfd_get_filename (obfd));
2449
2450       free (memhunk);
2451     }
2452   else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2453     {
2454       void *memhunk = xmalloc (size);
2455
2456       /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2457          flag--they can just remove the section entirely and add it
2458          back again.  However, we do permit them to turn on the
2459          SEC_HAS_CONTENTS flag, and take it to mean that the section
2460          contents should be zeroed out.  */
2461
2462       memset (memhunk, 0, size);
2463       if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2464         RETURN_NONFATAL (bfd_get_filename (obfd));
2465       free (memhunk);
2466     }
2467 }
2468
2469 /* Get all the sections.  This is used when --gap-fill or --pad-to is
2470    used.  */
2471
2472 static void
2473 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2474 {
2475   asection ***secppp = secppparg;
2476
2477   **secppp = osection;
2478   ++(*secppp);
2479 }
2480
2481 /* Sort sections by VMA.  This is called via qsort, and is used when
2482    --gap-fill or --pad-to is used.  We force non loadable or empty
2483    sections to the front, where they are easier to ignore.  */
2484
2485 static int
2486 compare_section_lma (const void *arg1, const void *arg2)
2487 {
2488   const asection *const *sec1 = arg1;
2489   const asection *const *sec2 = arg2;
2490   flagword flags1, flags2;
2491
2492   /* Sort non loadable sections to the front.  */
2493   flags1 = (*sec1)->flags;
2494   flags2 = (*sec2)->flags;
2495   if ((flags1 & SEC_HAS_CONTENTS) == 0
2496       || (flags1 & SEC_LOAD) == 0)
2497     {
2498       if ((flags2 & SEC_HAS_CONTENTS) != 0
2499           && (flags2 & SEC_LOAD) != 0)
2500         return -1;
2501     }
2502   else
2503     {
2504       if ((flags2 & SEC_HAS_CONTENTS) == 0
2505           || (flags2 & SEC_LOAD) == 0)
2506         return 1;
2507     }
2508
2509   /* Sort sections by LMA.  */
2510   if ((*sec1)->lma > (*sec2)->lma)
2511     return 1;
2512   else if ((*sec1)->lma < (*sec2)->lma)
2513     return -1;
2514
2515   /* Sort sections with the same LMA by size.  */
2516   if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
2517     return 1;
2518   else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
2519     return -1;
2520
2521   return 0;
2522 }
2523
2524 /* Mark all the symbols which will be used in output relocations with
2525    the BSF_KEEP flag so that those symbols will not be stripped.
2526
2527    Ignore relocations which will not appear in the output file.  */
2528
2529 static void
2530 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2531 {
2532   asymbol **symbols = symbolsarg;
2533   long relsize;
2534   arelent **relpp;
2535   long relcount, i;
2536
2537   /* Ignore an input section with no corresponding output section.  */
2538   if (isection->output_section == NULL)
2539     return;
2540
2541   relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2542   if (relsize < 0)
2543     {
2544       /* Do not complain if the target does not support relocations.  */
2545       if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2546         return;
2547       bfd_fatal (bfd_get_filename (ibfd));
2548     }
2549
2550   if (relsize == 0)
2551     return;
2552
2553   relpp = xmalloc (relsize);
2554   relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2555   if (relcount < 0)
2556     bfd_fatal (bfd_get_filename (ibfd));
2557
2558   /* Examine each symbol used in a relocation.  If it's not one of the
2559      special bfd section symbols, then mark it with BSF_KEEP.  */
2560   for (i = 0; i < relcount; i++)
2561     {
2562       if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2563           && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2564           && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2565         (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2566     }
2567
2568   if (relpp != NULL)
2569     free (relpp);
2570 }
2571
2572 /* Write out debugging information.  */
2573
2574 static bfd_boolean
2575 write_debugging_info (bfd *obfd, void *dhandle,
2576                       long *symcountp ATTRIBUTE_UNUSED,
2577                       asymbol ***symppp ATTRIBUTE_UNUSED)
2578 {
2579   if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2580     return write_ieee_debugging_info (obfd, dhandle);
2581
2582   if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2583       || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2584     {
2585       bfd_byte *syms, *strings;
2586       bfd_size_type symsize, stringsize;
2587       asection *stabsec, *stabstrsec;
2588       flagword flags;
2589
2590       if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2591                                                     &symsize, &strings,
2592                                                     &stringsize))
2593         return FALSE;
2594
2595       flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2596       stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2597       stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
2598       if (stabsec == NULL
2599           || stabstrsec == NULL
2600           || ! bfd_set_section_size (obfd, stabsec, symsize)
2601           || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2602           || ! bfd_set_section_alignment (obfd, stabsec, 2)
2603           || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
2604         {
2605           non_fatal (_("%s: can't create debugging section: %s"),
2606                      bfd_get_filename (obfd),
2607                      bfd_errmsg (bfd_get_error ()));
2608           return FALSE;
2609         }
2610
2611       /* We can get away with setting the section contents now because
2612          the next thing the caller is going to do is copy over the
2613          real sections.  We may someday have to split the contents
2614          setting out of this function.  */
2615       if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2616           || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2617                                          stringsize))
2618         {
2619           non_fatal (_("%s: can't set debugging section contents: %s"),
2620                      bfd_get_filename (obfd),
2621                      bfd_errmsg (bfd_get_error ()));
2622           return FALSE;
2623         }
2624
2625       return TRUE;
2626     }
2627
2628   non_fatal (_("%s: don't know how to write debugging information for %s"),
2629              bfd_get_filename (obfd), bfd_get_target (obfd));
2630   return FALSE;
2631 }
2632
2633 static int
2634 strip_main (int argc, char *argv[])
2635 {
2636   char *input_target = NULL;
2637   char *output_target = NULL;
2638   bfd_boolean show_version = FALSE;
2639   bfd_boolean formats_info = FALSE;
2640   int c;
2641   int i;
2642   struct section_list *p;
2643   char *output_file = NULL;
2644
2645   while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2646                            strip_options, (int *) 0)) != EOF)
2647     {
2648       switch (c)
2649         {
2650         case 'I':
2651           input_target = optarg;
2652           break;
2653         case 'O':
2654           output_target = optarg;
2655           break;
2656         case 'F':
2657           input_target = output_target = optarg;
2658           break;
2659         case 'R':
2660           p = find_section_list (optarg, TRUE);
2661           p->remove = TRUE;
2662           sections_removed = TRUE;
2663           break;
2664         case 's':
2665           strip_symbols = STRIP_ALL;
2666           break;
2667         case 'S':
2668         case 'g':
2669         case 'd':       /* Historic BSD alias for -g.  Used by early NetBSD.  */
2670           strip_symbols = STRIP_DEBUG;
2671           break;
2672         case OPTION_STRIP_UNNEEDED:
2673           strip_symbols = STRIP_UNNEEDED;
2674           break;
2675         case 'K':
2676           add_specific_symbol (optarg, &keep_specific_list);
2677           break;
2678         case 'N':
2679           add_specific_symbol (optarg, &strip_specific_list);
2680           break;
2681         case 'o':
2682           output_file = optarg;
2683           break;
2684         case 'p':
2685           preserve_dates = TRUE;
2686           break;
2687         case 'x':
2688           discard_locals = LOCALS_ALL;
2689           break;
2690         case 'X':
2691           discard_locals = LOCALS_START_L;
2692           break;
2693         case 'v':
2694           verbose = TRUE;
2695           break;
2696         case 'V':
2697           show_version = TRUE;
2698           break;
2699         case OPTION_FORMATS_INFO:
2700           formats_info = TRUE;
2701           break;
2702         case OPTION_ONLY_KEEP_DEBUG:
2703           strip_symbols = STRIP_NONDEBUG;
2704           break;
2705         case OPTION_KEEP_FILE_SYMBOLS:
2706           keep_file_symbols = 1;
2707           break;
2708         case 0:
2709           /* We've been given a long option.  */
2710           break;
2711         case 'w':
2712           wildcard = TRUE;
2713           break;
2714         case 'H':
2715         case 'h':
2716           strip_usage (stdout, 0);
2717         default:
2718           strip_usage (stderr, 1);
2719         }
2720     }
2721
2722   if (formats_info)
2723     {
2724       display_info ();
2725       return 0;
2726     }
2727
2728   if (show_version)
2729     print_version ("strip");
2730
2731   /* Default is to strip all symbols.  */
2732   if (strip_symbols == STRIP_UNDEF
2733       && discard_locals == LOCALS_UNDEF
2734       && strip_specific_list == NULL)
2735     strip_symbols = STRIP_ALL;
2736
2737   if (output_target == NULL)
2738     output_target = input_target;
2739
2740   i = optind;
2741   if (i == argc
2742       || (output_file != NULL && (i + 1) < argc))
2743     strip_usage (stderr, 1);
2744
2745   for (; i < argc; i++)
2746     {
2747       int hold_status = status;
2748       struct stat statbuf;
2749       char *tmpname;
2750
2751       if (get_file_size (argv[i]) < 1)
2752         {
2753           status = 1;
2754           continue;
2755         }
2756
2757       if (preserve_dates)
2758         /* No need to check the return value of stat().
2759            It has already been checked in get_file_size().  */
2760         stat (argv[i], &statbuf);
2761
2762       if (output_file == NULL || strcmp (argv[i], output_file) == 0)
2763         tmpname = make_tempname (argv[i]);
2764       else
2765         tmpname = output_file;
2766
2767       if (tmpname == NULL)
2768         {
2769           non_fatal (_("could not create temporary file to hold stripped copy of '%s'"),
2770                      argv[i]);
2771           status = 1;
2772           continue;
2773         }
2774
2775       status = 0;
2776       copy_file (argv[i], tmpname, input_target, output_target);
2777       if (status == 0)
2778         {
2779           if (preserve_dates)
2780             set_times (tmpname, &statbuf);
2781           if (output_file != tmpname)
2782             smart_rename (tmpname, output_file ? output_file : argv[i],
2783                           preserve_dates);
2784           status = hold_status;
2785         }
2786       else
2787         unlink_if_ordinary (tmpname);
2788       if (output_file != tmpname)
2789         free (tmpname);
2790     }
2791
2792   return status;
2793 }
2794
2795 static int
2796 copy_main (int argc, char *argv[])
2797 {
2798   char * binary_architecture = NULL;
2799   char *input_filename = NULL;
2800   char *output_filename = NULL;
2801   char *tmpname;
2802   char *input_target = NULL;
2803   char *output_target = NULL;
2804   bfd_boolean show_version = FALSE;
2805   bfd_boolean change_warn = TRUE;
2806   bfd_boolean formats_info = FALSE;
2807   int c;
2808   struct section_list *p;
2809   struct stat statbuf;
2810
2811   while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2812                            copy_options, (int *) 0)) != EOF)
2813     {
2814       switch (c)
2815         {
2816         case 'b':
2817           copy_byte = atoi (optarg);
2818           if (copy_byte < 0)
2819             fatal (_("byte number must be non-negative"));
2820           break;
2821
2822         case 'B':
2823           binary_architecture = optarg;
2824           break;
2825
2826         case 'i':
2827           interleave = atoi (optarg);
2828           if (interleave < 1)
2829             fatal (_("interleave must be positive"));
2830           break;
2831
2832         case 'I':
2833         case 's':               /* "source" - 'I' is preferred */
2834           input_target = optarg;
2835           break;
2836
2837         case 'O':
2838         case 'd':               /* "destination" - 'O' is preferred */
2839           output_target = optarg;
2840           break;
2841
2842         case 'F':
2843           input_target = output_target = optarg;
2844           break;
2845
2846         case 'j':
2847           p = find_section_list (optarg, TRUE);
2848           if (p->remove)
2849             fatal (_("%s both copied and removed"), optarg);
2850           p->copy = TRUE;
2851           sections_copied = TRUE;
2852           break;
2853
2854         case 'R':
2855           p = find_section_list (optarg, TRUE);
2856           if (p->copy)
2857             fatal (_("%s both copied and removed"), optarg);
2858           p->remove = TRUE;
2859           sections_removed = TRUE;
2860           break;
2861
2862         case 'S':
2863           strip_symbols = STRIP_ALL;
2864           break;
2865
2866         case 'g':
2867           strip_symbols = STRIP_DEBUG;
2868           break;
2869
2870         case OPTION_STRIP_UNNEEDED:
2871           strip_symbols = STRIP_UNNEEDED;
2872           break;
2873
2874         case OPTION_ONLY_KEEP_DEBUG:
2875           strip_symbols = STRIP_NONDEBUG;
2876           break;
2877
2878         case OPTION_KEEP_FILE_SYMBOLS:
2879           keep_file_symbols = 1;
2880           break;
2881
2882         case OPTION_ADD_GNU_DEBUGLINK:
2883           gnu_debuglink_filename = optarg;
2884           break;
2885
2886         case 'K':
2887           add_specific_symbol (optarg, &keep_specific_list);
2888           break;
2889
2890         case 'N':
2891           add_specific_symbol (optarg, &strip_specific_list);
2892           break;
2893
2894         case OPTION_STRIP_UNNEEDED_SYMBOL:
2895           add_specific_symbol (optarg, &strip_unneeded_list);
2896           break;
2897
2898         case 'L':
2899           add_specific_symbol (optarg, &localize_specific_list);
2900           break;
2901
2902         case OPTION_GLOBALIZE_SYMBOL:
2903           add_specific_symbol (optarg, &globalize_specific_list);
2904           break;
2905
2906         case 'G':
2907           add_specific_symbol (optarg, &keepglobal_specific_list);
2908           break;
2909
2910         case 'W':
2911           add_specific_symbol (optarg, &weaken_specific_list);
2912           break;
2913
2914         case 'p':
2915           preserve_dates = TRUE;
2916           break;
2917
2918         case 'w':
2919           wildcard = TRUE;
2920           break;
2921
2922         case 'x':
2923           discard_locals = LOCALS_ALL;
2924           break;
2925
2926         case 'X':
2927           discard_locals = LOCALS_START_L;
2928           break;
2929
2930         case 'v':
2931           verbose = TRUE;
2932           break;
2933
2934         case 'V':
2935           show_version = TRUE;
2936           break;
2937
2938         case OPTION_FORMATS_INFO:
2939           formats_info = TRUE;
2940           break;
2941
2942         case OPTION_WEAKEN:
2943           weaken = TRUE;
2944           break;
2945
2946         case OPTION_ADD_SECTION:
2947           {
2948             const char *s;
2949             off_t size;
2950             struct section_add *pa;
2951             int len;
2952             char *name;
2953             FILE *f;
2954
2955             s = strchr (optarg, '=');
2956
2957             if (s == NULL)
2958               fatal (_("bad format for %s"), "--add-section");
2959
2960             size = get_file_size (s + 1);
2961             if (size < 1)
2962               {
2963                 status = 1;
2964                 break;
2965               }
2966
2967             pa = xmalloc (sizeof (struct section_add));
2968
2969             len = s - optarg;
2970             name = xmalloc (len + 1);
2971             strncpy (name, optarg, len);
2972             name[len] = '\0';
2973             pa->name = name;
2974
2975             pa->filename = s + 1;
2976             pa->size = size;
2977             pa->contents = xmalloc (size);
2978
2979             f = fopen (pa->filename, FOPEN_RB);
2980
2981             if (f == NULL)
2982               fatal (_("cannot open: %s: %s"),
2983                      pa->filename, strerror (errno));
2984
2985             if (fread (pa->contents, 1, pa->size, f) == 0
2986                 || ferror (f))
2987               fatal (_("%s: fread failed"), pa->filename);
2988
2989             fclose (f);
2990
2991             pa->next = add_sections;
2992             add_sections = pa;
2993           }
2994           break;
2995
2996         case OPTION_CHANGE_START:
2997           change_start = parse_vma (optarg, "--change-start");
2998           break;
2999
3000         case OPTION_CHANGE_SECTION_ADDRESS:
3001         case OPTION_CHANGE_SECTION_LMA:
3002         case OPTION_CHANGE_SECTION_VMA:
3003           {
3004             const char *s;
3005             int len;
3006             char *name;
3007             char *option = NULL;
3008             bfd_vma val;
3009             enum change_action what = CHANGE_IGNORE;
3010
3011             switch (c)
3012               {
3013               case OPTION_CHANGE_SECTION_ADDRESS:
3014                 option = "--change-section-address";
3015                 break;
3016               case OPTION_CHANGE_SECTION_LMA:
3017                 option = "--change-section-lma";
3018                 break;
3019               case OPTION_CHANGE_SECTION_VMA:
3020                 option = "--change-section-vma";
3021                 break;
3022               }
3023
3024             s = strchr (optarg, '=');
3025             if (s == NULL)
3026               {
3027                 s = strchr (optarg, '+');
3028                 if (s == NULL)
3029                   {
3030                     s = strchr (optarg, '-');
3031                     if (s == NULL)
3032                       fatal (_("bad format for %s"), option);
3033                   }
3034               }
3035
3036             len = s - optarg;
3037             name = xmalloc (len + 1);
3038             strncpy (name, optarg, len);
3039             name[len] = '\0';
3040
3041             p = find_section_list (name, TRUE);
3042
3043             val = parse_vma (s + 1, option);
3044
3045             switch (*s)
3046               {
3047               case '=': what = CHANGE_SET; break;
3048               case '-': val  = - val; /* Drop through.  */
3049               case '+': what = CHANGE_MODIFY; break;
3050               }
3051
3052             switch (c)
3053               {
3054               case OPTION_CHANGE_SECTION_ADDRESS:
3055                 p->change_vma = what;
3056                 p->vma_val    = val;
3057                 /* Drop through.  */
3058
3059               case OPTION_CHANGE_SECTION_LMA:
3060                 p->change_lma = what;
3061                 p->lma_val    = val;
3062                 break;
3063
3064               case OPTION_CHANGE_SECTION_VMA:
3065                 p->change_vma = what;
3066                 p->vma_val    = val;
3067                 break;
3068               }
3069           }
3070           break;
3071
3072         case OPTION_CHANGE_ADDRESSES:
3073           change_section_address = parse_vma (optarg, "--change-addresses");
3074           change_start = change_section_address;
3075           break;
3076
3077         case OPTION_CHANGE_WARNINGS:
3078           change_warn = TRUE;
3079           break;
3080
3081         case OPTION_CHANGE_LEADING_CHAR:
3082           change_leading_char = TRUE;
3083           break;
3084
3085         case OPTION_DEBUGGING:
3086           convert_debugging = TRUE;
3087           break;
3088
3089         case OPTION_GAP_FILL:
3090           {
3091             bfd_vma gap_fill_vma;
3092
3093             gap_fill_vma = parse_vma (optarg, "--gap-fill");
3094             gap_fill = (bfd_byte) gap_fill_vma;
3095             if ((bfd_vma) gap_fill != gap_fill_vma)
3096               {
3097                 char buff[20];
3098
3099                 sprintf_vma (buff, gap_fill_vma);
3100
3101                 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3102                            buff, gap_fill);
3103               }
3104             gap_fill_set = TRUE;
3105           }
3106           break;
3107
3108         case OPTION_NO_CHANGE_WARNINGS:
3109           change_warn = FALSE;
3110           break;
3111
3112         case OPTION_PAD_TO:
3113           pad_to = parse_vma (optarg, "--pad-to");
3114           pad_to_set = TRUE;
3115           break;
3116
3117         case OPTION_REMOVE_LEADING_CHAR:
3118           remove_leading_char = TRUE;
3119           break;
3120
3121         case OPTION_REDEFINE_SYM:
3122           {
3123             /* Push this redefinition onto redefine_symbol_list.  */
3124
3125             int len;
3126             const char *s;
3127             const char *nextarg;
3128             char *source, *target;
3129
3130             s = strchr (optarg, '=');
3131             if (s == NULL)
3132               fatal (_("bad format for %s"), "--redefine-sym");
3133
3134             len = s - optarg;
3135             source = xmalloc (len + 1);
3136             strncpy (source, optarg, len);
3137             source[len] = '\0';
3138
3139             nextarg = s + 1;
3140             len = strlen (nextarg);
3141             target = xmalloc (len + 1);
3142             strcpy (target, nextarg);
3143
3144             redefine_list_append ("--redefine-sym", source, target);
3145
3146             free (source);
3147             free (target);
3148           }
3149           break;
3150
3151         case OPTION_REDEFINE_SYMS:
3152           add_redefine_syms_file (optarg);
3153           break;
3154
3155         case OPTION_SET_SECTION_FLAGS:
3156           {
3157             const char *s;
3158             int len;
3159             char *name;
3160
3161             s = strchr (optarg, '=');
3162             if (s == NULL)
3163               fatal (_("bad format for %s"), "--set-section-flags");
3164
3165             len = s - optarg;
3166             name = xmalloc (len + 1);
3167             strncpy (name, optarg, len);
3168             name[len] = '\0';
3169
3170             p = find_section_list (name, TRUE);
3171
3172             p->set_flags = TRUE;
3173             p->flags = parse_flags (s + 1);
3174           }
3175           break;
3176
3177         case OPTION_RENAME_SECTION:
3178           {
3179             flagword flags;
3180             const char *eq, *fl;
3181             char *old_name;
3182             char *new_name;
3183             unsigned int len;
3184
3185             eq = strchr (optarg, '=');
3186             if (eq == NULL)
3187               fatal (_("bad format for %s"), "--rename-section");
3188
3189             len = eq - optarg;
3190             if (len == 0)
3191               fatal (_("bad format for %s"), "--rename-section");
3192
3193             old_name = xmalloc (len + 1);
3194             strncpy (old_name, optarg, len);
3195             old_name[len] = 0;
3196
3197             eq++;
3198             fl = strchr (eq, ',');
3199             if (fl)
3200               {
3201                 flags = parse_flags (fl + 1);
3202                 len = fl - eq;
3203               }
3204             else
3205               {
3206                 flags = -1;
3207                 len = strlen (eq);
3208               }
3209
3210             if (len == 0)
3211               fatal (_("bad format for %s"), "--rename-section");
3212
3213             new_name = xmalloc (len + 1);
3214             strncpy (new_name, eq, len);
3215             new_name[len] = 0;
3216
3217             add_section_rename (old_name, new_name, flags);
3218           }
3219           break;
3220
3221         case OPTION_SET_START:
3222           set_start = parse_vma (optarg, "--set-start");
3223           set_start_set = TRUE;
3224           break;
3225
3226         case OPTION_SREC_LEN:
3227           Chunk = parse_vma (optarg, "--srec-len");
3228           break;
3229
3230         case OPTION_SREC_FORCES3:
3231           S3Forced = TRUE;
3232           break;
3233
3234         case OPTION_STRIP_SYMBOLS:
3235           add_specific_symbols (optarg, &strip_specific_list);
3236           break;
3237
3238         case OPTION_STRIP_UNNEEDED_SYMBOLS:
3239           add_specific_symbols (optarg, &strip_unneeded_list);
3240           break;
3241
3242         case OPTION_KEEP_SYMBOLS:
3243           add_specific_symbols (optarg, &keep_specific_list);
3244           break;
3245
3246         case OPTION_LOCALIZE_HIDDEN:
3247           localize_hidden = TRUE;
3248           break;
3249
3250         case OPTION_LOCALIZE_SYMBOLS:
3251           add_specific_symbols (optarg, &localize_specific_list);
3252           break;
3253
3254         case OPTION_GLOBALIZE_SYMBOLS:
3255           add_specific_symbols (optarg, &globalize_specific_list);
3256           break;
3257
3258         case OPTION_KEEPGLOBAL_SYMBOLS:
3259           add_specific_symbols (optarg, &keepglobal_specific_list);
3260           break;
3261
3262         case OPTION_WEAKEN_SYMBOLS:
3263           add_specific_symbols (optarg, &weaken_specific_list);
3264           break;
3265
3266         case OPTION_ALT_MACH_CODE:
3267           use_alt_mach_code = strtoul (optarg, NULL, 0);
3268           if (use_alt_mach_code == 0)
3269             fatal (_("unable to parse alternative machine code"));
3270           break;
3271
3272         case OPTION_PREFIX_SYMBOLS:
3273           prefix_symbols_string = optarg;
3274           break;
3275
3276         case OPTION_PREFIX_SECTIONS:
3277           prefix_sections_string = optarg;
3278           break;
3279
3280         case OPTION_PREFIX_ALLOC_SECTIONS:
3281           prefix_alloc_sections_string = optarg;
3282           break;
3283
3284         case OPTION_READONLY_TEXT:
3285           bfd_flags_to_set |= WP_TEXT;
3286           bfd_flags_to_clear &= ~WP_TEXT;
3287           break;
3288
3289         case OPTION_WRITABLE_TEXT:
3290           bfd_flags_to_clear |= WP_TEXT;
3291           bfd_flags_to_set &= ~WP_TEXT;
3292           break;
3293
3294         case OPTION_PURE:
3295           bfd_flags_to_set |= D_PAGED;
3296           bfd_flags_to_clear &= ~D_PAGED;
3297           break;
3298
3299         case OPTION_IMPURE:
3300           bfd_flags_to_clear |= D_PAGED;
3301           bfd_flags_to_set &= ~D_PAGED;
3302           break;
3303
3304         case OPTION_EXTRACT_SYMBOL:
3305           extract_symbol = TRUE;
3306           break;
3307
3308         case OPTION_REVERSE_BYTES:
3309           {
3310             int prev = reverse_bytes;
3311
3312             reverse_bytes = atoi (optarg);
3313             if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3314               fatal (_("number of bytes to reverse must be positive and even"));
3315
3316             if (prev && prev != reverse_bytes)
3317               non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3318                          prev);
3319             break;
3320           }
3321
3322         case 0:
3323           /* We've been given a long option.  */
3324           break;
3325
3326         case 'H':
3327         case 'h':
3328           copy_usage (stdout, 0);
3329
3330         default:
3331           copy_usage (stderr, 1);
3332         }
3333     }
3334
3335   if (formats_info)
3336     {
3337       display_info ();
3338       return 0;
3339     }
3340
3341   if (show_version)
3342     print_version ("objcopy");
3343
3344   if (copy_byte >= interleave)
3345     fatal (_("byte number must be less than interleave"));
3346
3347   if (optind == argc || optind + 2 < argc)
3348     copy_usage (stderr, 1);
3349
3350   input_filename = argv[optind];
3351   if (optind + 1 < argc)
3352     output_filename = argv[optind + 1];
3353
3354   /* Default is to strip no symbols.  */
3355   if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3356     strip_symbols = STRIP_NONE;
3357
3358   if (output_target == NULL)
3359     output_target = input_target;
3360
3361   if (binary_architecture != NULL)
3362     {
3363       if (input_target && strcmp (input_target, "binary") == 0)
3364         {
3365           const bfd_arch_info_type * temp_arch_info;
3366
3367           temp_arch_info = bfd_scan_arch (binary_architecture);
3368
3369           if (temp_arch_info != NULL)
3370             {
3371               bfd_external_binary_architecture = temp_arch_info->arch;
3372               bfd_external_machine             = temp_arch_info->mach;
3373             }
3374           else
3375             fatal (_("architecture %s unknown"), binary_architecture);
3376         }
3377       else
3378         {
3379           non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
3380           non_fatal (_(" Argument %s ignored"), binary_architecture);
3381         }
3382     }
3383
3384   if (preserve_dates)
3385     if (stat (input_filename, & statbuf) < 0)
3386       fatal (_("warning: could not locate '%s'.  System error message: %s"),
3387              input_filename, strerror (errno));
3388
3389   /* If there is no destination file, or the source and destination files
3390      are the same, then create a temp and rename the result into the input.  */
3391   if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
3392     tmpname = make_tempname (input_filename);
3393   else
3394     tmpname = output_filename;
3395
3396   if (tmpname == NULL)
3397     fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3398            input_filename, strerror (errno));
3399
3400   copy_file (input_filename, tmpname, input_target, output_target);
3401   if (status == 0)
3402     {
3403       if (preserve_dates)
3404         set_times (tmpname, &statbuf);
3405       if (tmpname != output_filename)
3406         smart_rename (tmpname, input_filename, preserve_dates);
3407     }
3408   else
3409     unlink_if_ordinary (tmpname);
3410
3411   if (change_warn)
3412     {
3413       for (p = change_sections; p != NULL; p = p->next)
3414         {
3415           if (! p->used)
3416             {
3417               if (p->change_vma != CHANGE_IGNORE)
3418                 {
3419                   char buff [20];
3420
3421                   sprintf_vma (buff, p->vma_val);
3422
3423                   /* xgettext:c-format */
3424                   non_fatal (_("%s %s%c0x%s never used"),
3425                              "--change-section-vma",
3426                              p->name,
3427                              p->change_vma == CHANGE_SET ? '=' : '+',
3428                              buff);
3429                 }
3430
3431               if (p->change_lma != CHANGE_IGNORE)
3432                 {
3433                   char buff [20];
3434
3435                   sprintf_vma (buff, p->lma_val);
3436
3437                   /* xgettext:c-format */
3438                   non_fatal (_("%s %s%c0x%s never used"),
3439                              "--change-section-lma",
3440                              p->name,
3441                              p->change_lma == CHANGE_SET ? '=' : '+',
3442                              buff);
3443                 }
3444             }
3445         }
3446     }
3447
3448   return 0;
3449 }
3450
3451 int
3452 main (int argc, char *argv[])
3453 {
3454 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3455   setlocale (LC_MESSAGES, "");
3456 #endif
3457 #if defined (HAVE_SETLOCALE)
3458   setlocale (LC_CTYPE, "");
3459 #endif
3460   bindtextdomain (PACKAGE, LOCALEDIR);
3461   textdomain (PACKAGE);
3462
3463   program_name = argv[0];
3464   xmalloc_set_program_name (program_name);
3465
3466   START_PROGRESS (program_name, 0);
3467
3468   expandargv (&argc, &argv);
3469
3470   strip_symbols = STRIP_UNDEF;
3471   discard_locals = LOCALS_UNDEF;
3472
3473   bfd_init ();
3474   set_default_bfd_target ();
3475
3476   if (is_strip < 0)
3477     {
3478       int i = strlen (program_name);
3479 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
3480       /* Drop the .exe suffix, if any.  */
3481       if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3482         {
3483           i -= 4;
3484           program_name[i] = '\0';
3485         }
3486 #endif
3487       is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
3488     }
3489
3490   if (is_strip)
3491     strip_main (argc, argv);
3492   else
3493     copy_main (argc, argv);
3494
3495   END_PROGRESS (program_name);
3496
3497   return status;
3498 }