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