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