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