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