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