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