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