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
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
41struct symlist
42{
43  const char *name;
44  struct symlist *next;
45};
46
47/* A list to support redefine_sym.  */
48struct redefine_node
49{
50  char *source;
51  char *target;
52  struct redefine_node *next;
53};
54
55typedef struct section_rename
56{
57  const char *            old_name;
58  const char *            new_name;
59  flagword                flags;
60  struct section_rename * next;
61}
62section_rename;
63
64/* List of sections to be renamed.  */
65static section_rename *section_rename_list;
66
67#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
68
69static asymbol **isympp = NULL;	/* Input symbols.  */
70static asymbol **osympp = NULL;	/* Output symbols that survive stripping.  */
71
72/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes.  */
73static int copy_byte = -1;
74static int interleave = 4;
75
76static bfd_boolean verbose;		/* Print file and target names.  */
77static bfd_boolean preserve_dates;	/* Preserve input file timestamp.  */
78static int status = 0;		/* Exit status.  */
79
80enum 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.  */
91static enum strip_action strip_symbols;
92
93enum 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.  */
101static enum locals_action discard_locals;
102
103/* What kind of change to perform.  */
104enum 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.  */
112struct 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
127static struct section_list *change_sections;
128
129/* TRUE if some sections are to be removed.  */
130static bfd_boolean sections_removed;
131
132/* TRUE if only some sections are to be copied.  */
133static bfd_boolean sections_copied;
134
135/* Changes to the start address.  */
136static bfd_vma change_start = 0;
137static bfd_boolean set_start_set = FALSE;
138static bfd_vma set_start;
139
140/* Changes to section addresses.  */
141static bfd_vma change_section_address = 0;
142
143/* Filling gaps between sections.  */
144static bfd_boolean gap_fill_set = FALSE;
145static bfd_byte gap_fill = 0;
146
147/* Pad to a given address.  */
148static bfd_boolean pad_to_set = FALSE;
149static bfd_vma pad_to;
150
151/* Use alternative machine code?  */
152static unsigned long use_alt_mach_code = 0;
153
154/* Output BFD flags user wants to set or clear */
155static flagword bfd_flags_to_set;
156static flagword bfd_flags_to_clear;
157
158/* List of sections to add.  */
159struct 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.  */
176static 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.  */
180static const char * gnu_debuglink_filename = NULL;
181
182/* Whether to convert debugging information.  */
183static bfd_boolean convert_debugging = FALSE;
184
185/* Whether to change the leading character in symbol names.  */
186static bfd_boolean change_leading_char = FALSE;
187
188/* Whether to remove the leading character from global symbol names.  */
189static bfd_boolean remove_leading_char = FALSE;
190
191/* Whether to permit wildcard in symbol comparison.  */
192static bfd_boolean wildcard = FALSE;
193
194/* True if --localize-hidden is in effect.  */
195static bfd_boolean localize_hidden = FALSE;
196
197/* List of symbols to strip, keep, localize, keep-global, weaken,
198   or redefine.  */
199static struct symlist *strip_specific_list = NULL;
200static struct symlist *strip_unneeded_list = NULL;
201static struct symlist *keep_specific_list = NULL;
202static struct symlist *localize_specific_list = NULL;
203static struct symlist *globalize_specific_list = NULL;
204static struct symlist *keepglobal_specific_list = NULL;
205static struct symlist *weaken_specific_list = NULL;
206static struct redefine_node *redefine_sym_list = NULL;
207
208/* If this is TRUE, we weaken global symbols (set BSF_WEAK).  */
209static bfd_boolean weaken = FALSE;
210
211/* If this is TRUE, we retain BSF_FILE symbols.  */
212static bfd_boolean keep_file_symbols = FALSE;
213
214/* Prefix symbols/sections.  */
215static char *prefix_symbols_string = 0;
216static char *prefix_sections_string = 0;
217static char *prefix_alloc_sections_string = 0;
218
219/* True if --extract-symbol was passed on the command line.  */
220static 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.  */
224static int reverse_bytes = 0;
225
226
227/* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
228enum 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
280static 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
310static 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 */
392extern 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.  */
397extern 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.  */
401extern 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.  */
406extern bfd_boolean S3Forced;
407
408/* Defined in bfd/binary.c.  Used to set architecture and machine of input
409   binary files.  */
410extern enum bfd_architecture  bfd_external_binary_architecture;
411extern unsigned long          bfd_external_machine;
412
413/* Forward declarations.  */
414static void setup_section (bfd *, asection *, void *);
415static void setup_bfd_headers (bfd *, bfd *);
416static void copy_section (bfd *, asection *, void *);
417static void get_sections (bfd *, asection *, void *);
418static int compare_section_lma (const void *, const void *);
419static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
420static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
421static const char *lookup_sym_redefinition (const char *);
422
423static void
424copy_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
519static void
520strip_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
557static flagword
558parse_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
612static struct section_list *
613find_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
644static void
645add_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
660static void
661add_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
774static bfd_boolean
775is_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
805static asymbol *
806group_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
829static bfd_boolean
830is_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
887static bfd_boolean
888is_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
907static unsigned int
908filter_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
1091static const char *
1092lookup_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
1105static void
1106redefine_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
1135static void
1136add_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
1246static bfd_boolean
1247copy_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
1314static bfd_boolean
1315copy_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
1805static void
1806copy_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);
1912copy_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
1971static void
1972copy_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
2073static void
2074add_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
2105static const char *
2106find_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
2130static void
2131setup_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
2146loser:
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
2156static void
2157setup_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
2303loser:
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
2315static void
2316copy_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
2472static void
2473get_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
2485static int
2486compare_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
2529static void
2530mark_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
2574static bfd_boolean
2575write_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
2633static int
2634strip_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
2795static int
2796copy_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
3451int
3452main (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}
3499