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