OSDN Git Service

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