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