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