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