Display the contents of a .debug.macinfo section
[platform/upstream/binutils.git] / binutils / objcopy.c
1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2001
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       boolean undefined;
727
728       if (redefine_sym_list)
729         {
730           const char *old_name, *new_name;
731
732           old_name = bfd_asymbol_name (sym);
733           new_name = lookup_sym_redefinition (old_name);
734           name = bfd_asymbol_name (sym) = new_name;
735         }
736
737       if (change_leading_char
738           && (bfd_get_symbol_leading_char (abfd)
739               != bfd_get_symbol_leading_char (obfd))
740           && (bfd_get_symbol_leading_char (abfd) == '\0'
741               || (name[0] == bfd_get_symbol_leading_char (abfd))))
742         {
743           if (bfd_get_symbol_leading_char (obfd) == '\0')
744             name = bfd_asymbol_name (sym) = name + 1;
745           else
746             {
747               char *n;
748
749               n = xmalloc (strlen (name) + 2);
750               n[0] = bfd_get_symbol_leading_char (obfd);
751               if (bfd_get_symbol_leading_char (abfd) == '\0')
752                 strcpy (n + 1, name);
753               else
754                 strcpy (n + 1, name + 1);
755               name = bfd_asymbol_name (sym) = n;
756             }
757         }
758
759       undefined = bfd_is_und_section (bfd_get_section (sym));
760
761       if (remove_leading_char
762           && ((flags & BSF_GLOBAL) != 0
763               || (flags & BSF_WEAK) != 0
764               || undefined
765               || bfd_is_com_section (bfd_get_section (sym)))
766           && name[0] == bfd_get_symbol_leading_char (abfd))
767         name = bfd_asymbol_name (sym) = name + 1;
768
769       if (strip_symbols == STRIP_ALL)
770         keep = 0;
771       else if ((flags & BSF_KEEP) != 0          /* Used in relocation.  */
772                || ((flags & BSF_SECTION_SYM) != 0
773                    && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
774                        & BSF_KEEP) != 0))
775         keep = 1;
776       else if (relocatable                      /* Relocatable file. */
777                && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
778         keep = 1;
779       else if (bfd_decode_symclass (sym) == 'I')
780         /* Global symbols in $idata sections need to be retained
781            even if relocatable is false.  External users of the
782            library containing the $idata section may reference these
783            symbols.  */
784         keep = 1;
785       else if ((flags & BSF_GLOBAL) != 0        /* Global symbol.  */
786                || (flags & BSF_WEAK) != 0
787                || undefined
788                || bfd_is_com_section (bfd_get_section (sym)))
789         keep = strip_symbols != STRIP_UNNEEDED;
790       else if ((flags & BSF_DEBUGGING) != 0)    /* Debugging symbol.  */
791         keep = (strip_symbols != STRIP_DEBUG
792                 && strip_symbols != STRIP_UNNEEDED
793                 && ! convert_debugging);
794       else if (bfd_get_section (sym)->comdat)
795         /* COMDAT sections store special information in local
796            symbols, so we cannot risk stripping any of them.  */
797         keep = 1;
798       else                      /* Local symbol.  */
799         keep = (strip_symbols != STRIP_UNNEEDED
800                 && (discard_locals != LOCALS_ALL
801                     && (discard_locals != LOCALS_START_L
802                         || ! bfd_is_local_label (abfd, sym))));
803
804       if (keep && is_specified_symbol (name, strip_specific_list))
805         keep = 0;
806       if (!keep && is_specified_symbol (name, keep_specific_list))
807         keep = 1;
808       if (keep && is_strip_section (abfd, bfd_get_section (sym)))
809         keep = 0;
810
811       if (keep && (flags & BSF_GLOBAL) != 0
812           && (weaken || is_specified_symbol (name, weaken_specific_list)))
813         {
814           sym->flags &=~ BSF_GLOBAL;
815           sym->flags |= BSF_WEAK;
816         }
817       if (keep && !undefined && (flags & (BSF_GLOBAL | BSF_WEAK))
818           && (is_specified_symbol (name, localize_specific_list)
819               || (keepglobal_specific_list != NULL
820                   && ! is_specified_symbol (name, keepglobal_specific_list))))
821         {
822           sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
823           sym->flags |= BSF_LOCAL;
824         }
825
826       if (keep)
827         to[dst_count++] = sym;
828     }
829
830   to[dst_count] = NULL;
831
832   return dst_count;
833 }
834
835 static const char *
836 lookup_sym_redefinition (source)
837      const char *source;
838 {
839   const char *result;
840   struct redefine_node *list;
841
842   result = source;
843
844   for (list = redefine_sym_list; list != NULL; list = list->next)
845     {
846       if (strcmp (source, list->source) == 0)
847         {
848           result = list->target;
849           break;
850         }
851     }
852   return result;
853 }
854
855 /* Add a node to a symbol redefine list */
856
857 static void
858 redefine_list_append (source, target)
859      const char *source;
860      const char *target;
861 {
862   struct redefine_node **p;
863   struct redefine_node *list;
864   struct redefine_node *new_node;
865
866   for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
867     {
868       if (strcmp (source, list->source) == 0)
869         {
870           fatal (_("%s: Multiple redefinition of symbol \"%s\""),
871                  "--redefine-sym",
872                   source);
873         }
874
875       if (strcmp (target, list->target) == 0)
876         {
877           fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
878                  "--redefine-sym",
879                   target);
880         }
881     }
882
883   new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
884
885   new_node->source = strdup (source);
886   new_node->target = strdup (target);
887   new_node->next = NULL;
888
889   *p = new_node;
890 }
891
892
893 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
894    Adjust *SIZE.  */
895
896 static void
897 filter_bytes (memhunk, size)
898      char *memhunk;
899      bfd_size_type *size;
900 {
901   char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
902
903   for (; from < end; from += interleave)
904     *to++ = *from;
905   if (*size % interleave > (bfd_size_type) copy_byte)
906     *size = (*size / interleave) + 1;
907   else
908     *size /= interleave;
909 }
910
911 /* Copy object file IBFD onto OBFD.  */
912
913 static void
914 copy_object (ibfd, obfd)
915      bfd *ibfd;
916      bfd *obfd;
917 {
918   bfd_vma start;
919   long symcount;
920   asection **osections = NULL;
921   bfd_size_type *gaps = NULL;
922   bfd_size_type max_gap = 0;
923   long symsize;
924   PTR dhandle;
925
926   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
927       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
928       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
929     {
930       fatal (_("Unable to change endianness of input file(s)"));
931       return;
932     }
933
934   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
935     RETURN_NONFATAL (bfd_get_filename (obfd));
936
937   if (verbose)
938     printf (_("copy from %s(%s) to %s(%s)\n"),
939             bfd_get_filename (ibfd), bfd_get_target (ibfd),
940             bfd_get_filename (obfd), bfd_get_target (obfd));
941
942   if (set_start_set)
943     start = set_start;
944   else
945     start = bfd_get_start_address (ibfd);
946   start += change_start;
947
948   if (!bfd_set_start_address (obfd, start)
949       || !bfd_set_file_flags (obfd,
950                               (bfd_get_file_flags (ibfd)
951                                & bfd_applicable_file_flags (obfd))))
952     RETURN_NONFATAL (bfd_get_filename (ibfd));
953
954   /* Copy architecture of input file to output file */
955   if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
956                           bfd_get_mach (ibfd)))
957     non_fatal (_("Warning: Output file cannot represent architecture %s"),
958                bfd_printable_arch_mach (bfd_get_arch (ibfd),
959                                         bfd_get_mach (ibfd)));
960
961   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
962     RETURN_NONFATAL (bfd_get_filename (ibfd));
963
964   if (isympp)
965     free (isympp);
966
967   if (osympp != isympp)
968     free (osympp);
969
970   /* BFD mandates that all output sections be created and sizes set before
971      any output is done.  Thus, we traverse all sections multiple times.  */
972   bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
973
974   if (add_sections != NULL)
975     {
976       struct section_add *padd;
977       struct section_list *pset;
978
979       for (padd = add_sections; padd != NULL; padd = padd->next)
980         {
981           padd->section = bfd_make_section (obfd, padd->name);
982           if (padd->section == NULL)
983             {
984               non_fatal (_("can't create section `%s': %s"),
985                        padd->name, bfd_errmsg (bfd_get_error ()));
986               status = 1;
987               return;
988             }
989           else
990             {
991               flagword flags;
992
993               if (! bfd_set_section_size (obfd, padd->section, padd->size))
994                 RETURN_NONFATAL (bfd_get_filename (obfd));
995
996               pset = find_section_list (padd->name, false);
997               if (pset != NULL)
998                 pset->used = true;
999
1000               if (pset != NULL && pset->set_flags)
1001                 flags = pset->flags | SEC_HAS_CONTENTS;
1002               else
1003                 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1004
1005               if (! bfd_set_section_flags (obfd, padd->section, flags))
1006                 RETURN_NONFATAL (bfd_get_filename (obfd));
1007
1008               if (pset != NULL)
1009                 {
1010                   if (pset->change_vma != CHANGE_IGNORE)
1011                     if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
1012                       RETURN_NONFATAL (bfd_get_filename (obfd));
1013
1014                   if (pset->change_lma != CHANGE_IGNORE)
1015                     {
1016                       padd->section->lma = pset->lma_val;
1017
1018                       if (! bfd_set_section_alignment
1019                           (obfd, padd->section,
1020                            bfd_section_alignment (obfd, padd->section)))
1021                         RETURN_NONFATAL (bfd_get_filename (obfd));
1022                     }
1023                 }
1024             }
1025         }
1026     }
1027
1028   if (gap_fill_set || pad_to_set)
1029     {
1030       asection **set;
1031       unsigned int c, i;
1032
1033       /* We must fill in gaps between the sections and/or we must pad
1034          the last section to a specified address.  We do this by
1035          grabbing a list of the sections, sorting them by VMA, and
1036          increasing the section sizes as required to fill the gaps.
1037          We write out the gap contents below.  */
1038
1039       c = bfd_count_sections (obfd);
1040       osections = (asection **) xmalloc (c * sizeof (asection *));
1041       set = osections;
1042       bfd_map_over_sections (obfd, get_sections, (void *) &set);
1043
1044       qsort (osections, c, sizeof (asection *), compare_section_lma);
1045
1046       gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
1047       memset (gaps, 0, c * sizeof (bfd_size_type));
1048
1049       if (gap_fill_set)
1050         {
1051           for (i = 0; i < c - 1; i++)
1052             {
1053               flagword flags;
1054               bfd_size_type size;
1055               bfd_vma gap_start, gap_stop;
1056
1057               flags = bfd_get_section_flags (obfd, osections[i]);
1058               if ((flags & SEC_HAS_CONTENTS) == 0
1059                   || (flags & SEC_LOAD) == 0)
1060                 continue;
1061
1062               size = bfd_section_size (obfd, osections[i]);
1063               gap_start = bfd_section_lma (obfd, osections[i]) + size;
1064               gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1065               if (gap_start < gap_stop)
1066                 {
1067                   if (! bfd_set_section_size (obfd, osections[i],
1068                                               size + (gap_stop - gap_start)))
1069                     {
1070                       non_fatal (_("Can't fill gap after %s: %s"),
1071                                bfd_get_section_name (obfd, osections[i]),
1072                                bfd_errmsg (bfd_get_error ()));
1073                       status = 1;
1074                       break;
1075                     }
1076                   gaps[i] = gap_stop - gap_start;
1077                   if (max_gap < gap_stop - gap_start)
1078                     max_gap = gap_stop - gap_start;
1079                 }
1080             }
1081         }
1082
1083       if (pad_to_set)
1084         {
1085           bfd_vma lma;
1086           bfd_size_type size;
1087
1088           lma = bfd_section_lma (obfd, osections[c - 1]);
1089           size = bfd_section_size (obfd, osections[c - 1]);
1090           if (lma + size < pad_to)
1091             {
1092               if (! bfd_set_section_size (obfd, osections[c - 1],
1093                                           pad_to - lma))
1094                 {
1095                   non_fatal (_("Can't add padding to %s: %s"),
1096                            bfd_get_section_name (obfd, osections[c - 1]),
1097                            bfd_errmsg (bfd_get_error ()));
1098                   status = 1;
1099                 }
1100               else
1101                 {
1102                   gaps[c - 1] = pad_to - (lma + size);
1103                   if (max_gap < pad_to - (lma + size))
1104                     max_gap = pad_to - (lma + size);
1105                 }
1106             }
1107         }
1108     }
1109
1110   /* Symbol filtering must happen after the output sections have
1111      been created, but before their contents are set.  */
1112   dhandle = NULL;
1113   symsize = bfd_get_symtab_upper_bound (ibfd);
1114   if (symsize < 0)
1115     RETURN_NONFATAL (bfd_get_filename (ibfd));
1116
1117   osympp = isympp = (asymbol **) xmalloc (symsize);
1118   symcount = bfd_canonicalize_symtab (ibfd, isympp);
1119   if (symcount < 0)
1120     RETURN_NONFATAL (bfd_get_filename (ibfd));
1121
1122   if (convert_debugging)
1123     dhandle = read_debugging_info (ibfd, isympp, symcount);
1124
1125   if (strip_symbols == STRIP_DEBUG
1126       || strip_symbols == STRIP_ALL
1127       || strip_symbols == STRIP_UNNEEDED
1128       || discard_locals != LOCALS_UNDEF
1129       || strip_specific_list != NULL
1130       || keep_specific_list != NULL
1131       || localize_specific_list != NULL
1132       || keepglobal_specific_list != NULL
1133       || weaken_specific_list != NULL
1134       || sections_removed
1135       || sections_copied
1136       || convert_debugging
1137       || change_leading_char
1138       || remove_leading_char
1139       || redefine_sym_list
1140       || weaken)
1141     {
1142       /* Mark symbols used in output relocations so that they
1143          are kept, even if they are local labels or static symbols.
1144
1145          Note we iterate over the input sections examining their
1146          relocations since the relocations for the output sections
1147          haven't been set yet.  mark_symbols_used_in_relocations will
1148          ignore input sections which have no corresponding output
1149          section.  */
1150       if (strip_symbols != STRIP_ALL)
1151         bfd_map_over_sections (ibfd,
1152                                mark_symbols_used_in_relocations,
1153                                (PTR)isympp);
1154       osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
1155       symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1156     }
1157
1158   if (convert_debugging && dhandle != NULL)
1159     {
1160       if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1161         {
1162           status = 1;
1163           return;
1164         }
1165     }
1166
1167   bfd_set_symtab (obfd, osympp, symcount);
1168
1169   /* This has to happen after the symbol table has been set.  */
1170   bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1171
1172   if (add_sections != NULL)
1173     {
1174       struct section_add *padd;
1175
1176       for (padd = add_sections; padd != NULL; padd = padd->next)
1177         {
1178           if (! bfd_set_section_contents (obfd, padd->section,
1179                                           (PTR) padd->contents,
1180                                           (file_ptr) 0,
1181                                           (bfd_size_type) padd->size))
1182             RETURN_NONFATAL (bfd_get_filename (obfd));
1183         }
1184     }
1185
1186   if (gap_fill_set || pad_to_set)
1187     {
1188       bfd_byte *buf;
1189       int c, i;
1190
1191       /* Fill in the gaps.  */
1192
1193       if (max_gap > 8192)
1194         max_gap = 8192;
1195       buf = (bfd_byte *) xmalloc (max_gap);
1196       memset (buf, gap_fill, (size_t) max_gap);
1197
1198       c = bfd_count_sections (obfd);
1199       for (i = 0; i < c; i++)
1200         {
1201           if (gaps[i] != 0)
1202             {
1203               bfd_size_type left;
1204               file_ptr off;
1205
1206               left = gaps[i];
1207               off = bfd_section_size (obfd, osections[i]) - left;
1208               while (left > 0)
1209                 {
1210                   bfd_size_type now;
1211
1212                   if (left > 8192)
1213                     now = 8192;
1214                   else
1215                     now = left;
1216
1217                   if (! bfd_set_section_contents (obfd, osections[i], buf,
1218                                                   off, now))
1219                     RETURN_NONFATAL (bfd_get_filename (obfd));
1220
1221                   left -= now;
1222                   off += now;
1223                 }
1224             }
1225         }
1226     }
1227
1228   /* Allow the BFD backend to copy any private data it understands
1229      from the input BFD to the output BFD.  This is done last to
1230      permit the routine to look at the filtered symbol table, which is
1231      important for the ECOFF code at least.  */
1232   if (!bfd_copy_private_bfd_data (ibfd, obfd))
1233     {
1234       non_fatal (_("%s: error copying private BFD data: %s"),
1235                  bfd_get_filename (obfd),
1236                  bfd_errmsg (bfd_get_error ()));
1237       status = 1;
1238       return;
1239     }
1240 }
1241
1242 /* Read each archive element in turn from IBFD, copy the
1243    contents to temp file, and keep the temp file handle.  */
1244
1245 static void
1246 copy_archive (ibfd, obfd, output_target)
1247      bfd *ibfd;
1248      bfd *obfd;
1249      const char *output_target;
1250 {
1251   struct name_list
1252     {
1253       struct name_list *next;
1254       char *name;
1255       bfd *obfd;
1256     } *list, *l;
1257   bfd **ptr = &obfd->archive_head;
1258   bfd *this_element;
1259   char *dir = make_tempname (bfd_get_filename (obfd));
1260
1261   /* Make a temp directory to hold the contents.  */
1262 #if defined (_WIN32) && !defined (__CYGWIN32__)
1263   if (mkdir (dir) != 0)
1264 #else
1265   if (mkdir (dir, 0700) != 0)
1266 #endif
1267     {
1268       fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1269              dir, strerror (errno));
1270     }
1271   obfd->has_armap = ibfd->has_armap;
1272
1273   list = NULL;
1274
1275   this_element = bfd_openr_next_archived_file (ibfd, NULL);
1276   while (!status && this_element != (bfd *) NULL)
1277     {
1278       /* Create an output file for this member.  */
1279       char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1280                                   (char *) NULL);
1281       bfd *output_bfd = bfd_openw (output_name, output_target);
1282       bfd *last_element;
1283       struct stat buf;
1284       int stat_status = 0;
1285
1286       if (preserve_dates)
1287         {
1288           stat_status = bfd_stat_arch_elt (this_element, &buf);
1289           if (stat_status != 0)
1290             non_fatal (_("internal stat error on %s"),
1291                        bfd_get_filename (this_element));
1292         }
1293
1294       l = (struct name_list *) xmalloc (sizeof (struct name_list));
1295       l->name = output_name;
1296       l->next = list;
1297       list = l;
1298
1299       if (output_bfd == (bfd *) NULL)
1300         RETURN_NONFATAL (output_name);
1301
1302       if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1303         RETURN_NONFATAL (bfd_get_filename (obfd));
1304
1305       if (bfd_check_format (this_element, bfd_object) == true)
1306         copy_object (this_element, output_bfd);
1307
1308       if (!bfd_close (output_bfd))
1309         {
1310           bfd_nonfatal (bfd_get_filename (output_bfd));
1311           /* Error in new object file. Don't change archive. */
1312           status = 1;
1313         }
1314
1315       if (preserve_dates && stat_status == 0)
1316         set_times (output_name, &buf);
1317
1318       /* Open the newly output file and attach to our list.  */
1319       output_bfd = bfd_openr (output_name, output_target);
1320
1321       l->obfd = output_bfd;
1322
1323       *ptr = output_bfd;
1324       ptr = &output_bfd->next;
1325
1326       last_element = this_element;
1327
1328       this_element = bfd_openr_next_archived_file (ibfd, last_element);
1329
1330       bfd_close (last_element);
1331     }
1332   *ptr = (bfd *) NULL;
1333
1334   if (!bfd_close (obfd))
1335     RETURN_NONFATAL (bfd_get_filename (obfd));
1336
1337   if (!bfd_close (ibfd))
1338     RETURN_NONFATAL (bfd_get_filename (ibfd));
1339
1340   /* Delete all the files that we opened.  */
1341   for (l = list; l != NULL; l = l->next)
1342     {
1343       bfd_close (l->obfd);
1344       unlink (l->name);
1345     }
1346   rmdir (dir);
1347 }
1348
1349 /* The top-level control.  */
1350
1351 static void
1352 copy_file (input_filename, output_filename, input_target, output_target)
1353      const char *input_filename;
1354      const char *output_filename;
1355      const char *input_target;
1356      const char *output_target;
1357 {
1358   bfd *ibfd;
1359   char **matching;
1360
1361   /* To allow us to do "strip *" without dying on the first
1362      non-object file, failures are nonfatal.  */
1363
1364   ibfd = bfd_openr (input_filename, input_target);
1365   if (ibfd == NULL)
1366     RETURN_NONFATAL (input_filename);
1367
1368   if (bfd_check_format (ibfd, bfd_archive))
1369     {
1370       bfd *obfd;
1371
1372       /* bfd_get_target does not return the correct value until
1373          bfd_check_format succeeds.  */
1374       if (output_target == NULL)
1375         output_target = bfd_get_target (ibfd);
1376
1377       obfd = bfd_openw (output_filename, output_target);
1378       if (obfd == NULL)
1379         RETURN_NONFATAL (output_filename);
1380
1381       copy_archive (ibfd, obfd, output_target);
1382     }
1383   else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1384     {
1385       bfd *obfd;
1386
1387       /* bfd_get_target does not return the correct value until
1388          bfd_check_format succeeds.  */
1389       if (output_target == NULL)
1390         output_target = bfd_get_target (ibfd);
1391
1392       obfd = bfd_openw (output_filename, output_target);
1393       if (obfd == NULL)
1394         RETURN_NONFATAL (output_filename);
1395
1396       copy_object (ibfd, obfd);
1397
1398       if (!bfd_close (obfd))
1399         RETURN_NONFATAL (output_filename);
1400
1401       if (!bfd_close (ibfd))
1402         RETURN_NONFATAL (input_filename);
1403     }
1404   else
1405     {
1406       bfd_nonfatal (input_filename);
1407
1408       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1409         {
1410           list_matching_formats (matching);
1411           free (matching);
1412         }
1413
1414       status = 1;
1415     }
1416 }
1417
1418 /* Create a section in OBFD with the same name and attributes
1419    as ISECTION in IBFD.  */
1420
1421 static void
1422 setup_section (ibfd, isection, obfdarg)
1423      bfd *ibfd;
1424      sec_ptr isection;
1425      PTR obfdarg;
1426 {
1427   bfd *obfd = (bfd *) obfdarg;
1428   struct section_list *p;
1429   sec_ptr osection;
1430   bfd_size_type size;
1431   bfd_vma vma;
1432   bfd_vma lma;
1433   flagword flags;
1434   const char *err;
1435
1436   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1437       && (strip_symbols == STRIP_DEBUG
1438           || strip_symbols == STRIP_UNNEEDED
1439           || strip_symbols == STRIP_ALL
1440           || discard_locals == LOCALS_ALL
1441           || convert_debugging))
1442     return;
1443
1444   p = find_section_list (bfd_section_name (ibfd, isection), false);
1445   if (p != NULL)
1446     p->used = true;
1447
1448   if (sections_removed && p != NULL && p->remove)
1449     return;
1450   if (sections_copied && (p == NULL || ! p->copy))
1451     return;
1452
1453   osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1454
1455   if (osection == NULL)
1456     {
1457       err = _("making");
1458       goto loser;
1459     }
1460
1461   size = bfd_section_size (ibfd, isection);
1462   if (copy_byte >= 0)
1463     size = (size + interleave - 1) / interleave;
1464   if (! bfd_set_section_size (obfd, osection, size))
1465     {
1466       err = _("size");
1467       goto loser;
1468     }
1469
1470   vma = bfd_section_vma (ibfd, isection);
1471   if (p != NULL && p->change_vma == CHANGE_MODIFY)
1472     vma += p->vma_val;
1473   else if (p != NULL && p->change_vma == CHANGE_SET)
1474     vma = p->vma_val;
1475   else
1476     vma += change_section_address;
1477
1478   if (! bfd_set_section_vma (obfd, osection, vma))
1479     {
1480       err = _("vma");
1481       goto loser;
1482     }
1483
1484   lma = isection->lma;
1485   if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1486     {
1487       if (p->change_lma == CHANGE_MODIFY)
1488         lma += p->lma_val;
1489       else if (p->change_lma == CHANGE_SET)
1490         lma = p->lma_val;
1491       else
1492         abort ();
1493     }
1494   else
1495     lma += change_section_address;
1496
1497   osection->lma = lma;
1498
1499   /* FIXME: This is probably not enough.  If we change the LMA we
1500      may have to recompute the header for the file as well.  */
1501   if (bfd_set_section_alignment (obfd,
1502                                  osection,
1503                                  bfd_section_alignment (ibfd, isection))
1504       == false)
1505     {
1506       err = _("alignment");
1507       goto loser;
1508     }
1509
1510   flags = bfd_get_section_flags (ibfd, isection);
1511   if (p != NULL && p->set_flags)
1512     flags = p->flags | (flags & SEC_HAS_CONTENTS);
1513   if (!bfd_set_section_flags (obfd, osection, flags))
1514     {
1515       err = _("flags");
1516       goto loser;
1517     }
1518
1519   /* This used to be mangle_section; we do here to avoid using
1520      bfd_get_section_by_name since some formats allow multiple
1521      sections with the same name.  */
1522   isection->output_section = osection;
1523   isection->output_offset = 0;
1524
1525   /* Allow the BFD backend to copy any private data it understands
1526      from the input section to the output section.  */
1527   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1528     {
1529       err = _("private data");
1530       goto loser;
1531     }
1532
1533   /* All went well */
1534   return;
1535
1536 loser:
1537   non_fatal (_("%s: section `%s': error in %s: %s"),
1538              bfd_get_filename (ibfd),
1539              bfd_section_name (ibfd, isection),
1540              err, bfd_errmsg (bfd_get_error ()));
1541   status = 1;
1542 }
1543
1544 /* Copy the data of input section ISECTION of IBFD
1545    to an output section with the same name in OBFD.
1546    If stripping then don't copy any relocation info.  */
1547
1548 static void
1549 copy_section (ibfd, isection, obfdarg)
1550      bfd *ibfd;
1551      sec_ptr isection;
1552      PTR obfdarg;
1553 {
1554   bfd *obfd = (bfd *) obfdarg;
1555   struct section_list *p;
1556   arelent **relpp;
1557   long relcount;
1558   sec_ptr osection;
1559   bfd_size_type size;
1560   long relsize;
1561
1562   /* If we have already failed earlier on, do not keep on generating
1563      complaints now.  */
1564   if (status != 0)
1565     return;
1566
1567   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1568       && (strip_symbols == STRIP_DEBUG
1569           || strip_symbols == STRIP_UNNEEDED
1570           || strip_symbols == STRIP_ALL
1571           || discard_locals == LOCALS_ALL
1572           || convert_debugging))
1573     return;
1574
1575   p = find_section_list (bfd_section_name (ibfd, isection), false);
1576
1577   if (sections_removed && p != NULL && p->remove)
1578     return;
1579   if (sections_copied && (p == NULL || ! p->copy))
1580     return;
1581
1582   osection = isection->output_section;
1583   size = bfd_get_section_size_before_reloc (isection);
1584
1585   if (size == 0 || osection == 0)
1586     return;
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       else if (sections_removed)
1620         {
1621           /* Remove relocations which are against symbols
1622              in sections that have been removed, unless
1623              the symbols are going to be preserved.  */
1624           arelent ** temp_relpp;
1625           asymbol *  sym;
1626           long temp_relcount = 0;
1627           long i;
1628
1629           temp_relpp = (arelent **) xmalloc (relsize);
1630           for (i = 0; i < relcount; i++)
1631             {
1632               sym = *relpp [i]->sym_ptr_ptr;
1633
1634               /* FIXME: Should we warn about deleted relocs ?  */
1635               if (is_specified_symbol (bfd_asymbol_name (sym),
1636                                        keep_specific_list)
1637                   || bfd_get_output_section (sym) != NULL)
1638                 temp_relpp [temp_relcount++] = relpp [i];
1639             }
1640
1641           relcount = temp_relcount;
1642           free (relpp);
1643           relpp = temp_relpp;
1644         }
1645
1646       bfd_set_reloc (obfd, osection,
1647                      (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1648     }
1649
1650   isection->_cooked_size = isection->_raw_size;
1651   isection->reloc_done = true;
1652
1653   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1654     {
1655       PTR memhunk = (PTR) xmalloc ((unsigned) size);
1656
1657       if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1658                                      size))
1659         RETURN_NONFATAL (bfd_get_filename (ibfd));
1660
1661       if (copy_byte >= 0)
1662         filter_bytes (memhunk, &size);
1663
1664       if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1665                                      size))
1666         RETURN_NONFATAL (bfd_get_filename (obfd));
1667
1668       free (memhunk);
1669     }
1670   else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1671     {
1672       PTR memhunk = (PTR) xmalloc ((unsigned) size);
1673
1674       /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1675          flag--they can just remove the section entirely and add it
1676          back again.  However, we do permit them to turn on the
1677          SEC_HAS_CONTENTS flag, and take it to mean that the section
1678          contents should be zeroed out.  */
1679
1680       memset (memhunk, 0, size);
1681       if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1682                                       size))
1683         RETURN_NONFATAL (bfd_get_filename (obfd));
1684       free (memhunk);
1685     }
1686 }
1687
1688 /* Get all the sections.  This is used when --gap-fill or --pad-to is
1689    used.  */
1690
1691 static void
1692 get_sections (obfd, osection, secppparg)
1693      bfd *obfd ATTRIBUTE_UNUSED;
1694      asection *osection;
1695      PTR secppparg;
1696 {
1697   asection ***secppp = (asection ***) secppparg;
1698
1699   **secppp = osection;
1700   ++(*secppp);
1701 }
1702
1703 /* Sort sections by VMA.  This is called via qsort, and is used when
1704    --gap-fill or --pad-to is used.  We force non loadable or empty
1705    sections to the front, where they are easier to ignore.  */
1706
1707 static int
1708 compare_section_lma (arg1, arg2)
1709      const PTR arg1;
1710      const PTR arg2;
1711 {
1712   const asection **sec1 = (const asection **) arg1;
1713   const asection **sec2 = (const asection **) arg2;
1714   flagword flags1, flags2;
1715
1716   /* Sort non loadable sections to the front.  */
1717   flags1 = (*sec1)->flags;
1718   flags2 = (*sec2)->flags;
1719   if ((flags1 & SEC_HAS_CONTENTS) == 0
1720       || (flags1 & SEC_LOAD) == 0)
1721     {
1722       if ((flags2 & SEC_HAS_CONTENTS) != 0
1723           && (flags2 & SEC_LOAD) != 0)
1724         return -1;
1725     }
1726   else
1727     {
1728       if ((flags2 & SEC_HAS_CONTENTS) == 0
1729           || (flags2 & SEC_LOAD) == 0)
1730         return 1;
1731     }
1732
1733   /* Sort sections by LMA.  */
1734   if ((*sec1)->lma > (*sec2)->lma)
1735     return 1;
1736   else if ((*sec1)->lma < (*sec2)->lma)
1737     return -1;
1738
1739   /* Sort sections with the same LMA by size.  */
1740   if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1741     return 1;
1742   else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1743     return -1;
1744
1745   return 0;
1746 }
1747
1748 /* Mark all the symbols which will be used in output relocations with
1749    the BSF_KEEP flag so that those symbols will not be stripped.
1750
1751    Ignore relocations which will not appear in the output file.  */
1752
1753 static void
1754 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1755      bfd *ibfd;
1756      sec_ptr isection;
1757      PTR symbolsarg;
1758 {
1759   asymbol **symbols = (asymbol **) symbolsarg;
1760   long relsize;
1761   arelent **relpp;
1762   long relcount, i;
1763
1764   /* Ignore an input section with no corresponding output section.  */
1765   if (isection->output_section == NULL)
1766     return;
1767
1768   relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1769   if (relsize < 0)
1770     bfd_fatal (bfd_get_filename (ibfd));
1771
1772   if (relsize == 0)
1773     return;
1774
1775   relpp = (arelent **) xmalloc (relsize);
1776   relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1777   if (relcount < 0)
1778     bfd_fatal (bfd_get_filename (ibfd));
1779
1780   /* Examine each symbol used in a relocation.  */
1781   for (i = 0; i < relcount; i++)
1782     {
1783       asymbol * sym = * relpp[i]->sym_ptr_ptr;
1784       
1785       /* If the symbol's output section does not exist (because it
1786          has been removed with -R) then do not keep the symbol.  */
1787       if (bfd_get_output_section (sym) == NULL)
1788         continue;
1789       
1790       /* If the symbols is not one of the special bfd
1791          section symbols, then mark it with BSF_KEEP.  */
1792       if (sym != bfd_com_section_ptr->symbol
1793           && sym != bfd_abs_section_ptr->symbol
1794           && sym != bfd_und_section_ptr->symbol)
1795         sym->flags |= BSF_KEEP;
1796     }
1797
1798   if (relpp != NULL)
1799     free (relpp);
1800 }
1801
1802 /* Write out debugging information.  */
1803
1804 static boolean
1805 write_debugging_info (obfd, dhandle, symcountp, symppp)
1806      bfd *obfd;
1807      PTR dhandle;
1808      long *symcountp ATTRIBUTE_UNUSED;
1809      asymbol ***symppp ATTRIBUTE_UNUSED;
1810 {
1811   if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1812     return write_ieee_debugging_info (obfd, dhandle);
1813
1814   if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1815       || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1816     {
1817       bfd_byte *syms, *strings;
1818       bfd_size_type symsize, stringsize;
1819       asection *stabsec, *stabstrsec;
1820
1821       if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1822                                                     &symsize, &strings,
1823                                                     &stringsize))
1824         return false;
1825
1826       stabsec = bfd_make_section (obfd, ".stab");
1827       stabstrsec = bfd_make_section (obfd, ".stabstr");
1828       if (stabsec == NULL
1829           || stabstrsec == NULL
1830           || ! bfd_set_section_size (obfd, stabsec, symsize)
1831           || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1832           || ! bfd_set_section_alignment (obfd, stabsec, 2)
1833           || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1834           || ! bfd_set_section_flags (obfd, stabsec,
1835                                    (SEC_HAS_CONTENTS
1836                                     | SEC_READONLY
1837                                     | SEC_DEBUGGING))
1838           || ! bfd_set_section_flags (obfd, stabstrsec,
1839                                       (SEC_HAS_CONTENTS
1840                                        | SEC_READONLY
1841                                        | SEC_DEBUGGING)))
1842         {
1843           non_fatal (_("%s: can't create debugging section: %s"),
1844                      bfd_get_filename (obfd),
1845                      bfd_errmsg (bfd_get_error ()));
1846           return false;
1847         }
1848
1849       /* We can get away with setting the section contents now because
1850          the next thing the caller is going to do is copy over the
1851          real sections.  We may someday have to split the contents
1852          setting out of this function.  */
1853       if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1854                                       symsize)
1855           || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1856                                          (file_ptr) 0, stringsize))
1857         {
1858           non_fatal (_("%s: can't set debugging section contents: %s"),
1859                      bfd_get_filename (obfd),
1860                      bfd_errmsg (bfd_get_error ()));
1861           return false;
1862         }
1863
1864       return true;
1865     }
1866
1867   non_fatal (_("%s: don't know how to write debugging information for %s"),
1868              bfd_get_filename (obfd), bfd_get_target (obfd));
1869   return false;
1870 }
1871
1872 static int
1873 strip_main (argc, argv)
1874      int argc;
1875      char *argv[];
1876 {
1877   char *input_target = NULL, *output_target = NULL;
1878   boolean show_version = false;
1879   int c, i;
1880   struct section_list *p;
1881   char *output_file = NULL;
1882
1883   while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1884                            strip_options, (int *) 0)) != EOF)
1885     {
1886       switch (c)
1887         {
1888         case 'I':
1889           input_target = optarg;
1890           break;
1891         case 'O':
1892           output_target = optarg;
1893           break;
1894         case 'F':
1895           input_target = output_target = optarg;
1896           break;
1897         case 'R':
1898           p = find_section_list (optarg, true);
1899           p->remove = true;
1900           sections_removed = true;
1901           break;
1902         case 's':
1903           strip_symbols = STRIP_ALL;
1904           break;
1905         case 'S':
1906         case 'g':
1907         case 'd':       /* Historic BSD alias for -g.  Used by early NetBSD.  */
1908           strip_symbols = STRIP_DEBUG;
1909           break;
1910         case OPTION_STRIP_UNNEEDED:
1911           strip_symbols = STRIP_UNNEEDED;
1912           break;
1913         case 'K':
1914           add_specific_symbol (optarg, &keep_specific_list);
1915           break;
1916         case 'N':
1917           add_specific_symbol (optarg, &strip_specific_list);
1918           break;
1919         case 'o':
1920           output_file = optarg;
1921           break;
1922         case 'p':
1923           preserve_dates = true;
1924           break;
1925         case 'x':
1926           discard_locals = LOCALS_ALL;
1927           break;
1928         case 'X':
1929           discard_locals = LOCALS_START_L;
1930           break;
1931         case 'v':
1932           verbose = true;
1933           break;
1934         case 'V':
1935           show_version = true;
1936           break;
1937         case 0:
1938           break;                /* we've been given a long option */
1939         case 'h':
1940           strip_usage (stdout, 0);
1941         default:
1942           strip_usage (stderr, 1);
1943         }
1944     }
1945
1946   if (show_version)
1947     print_version ("strip");
1948
1949   /* Default is to strip all symbols.  */
1950   if (strip_symbols == STRIP_UNDEF
1951       && discard_locals == LOCALS_UNDEF
1952       && strip_specific_list == NULL)
1953     strip_symbols = STRIP_ALL;
1954
1955   if (output_target == (char *) NULL)
1956     output_target = input_target;
1957
1958   i = optind;
1959   if (i == argc
1960       || (output_file != NULL && (i + 1) < argc))
1961     strip_usage (stderr, 1);
1962
1963   for (; i < argc; i++)
1964     {
1965       int hold_status = status;
1966       struct stat statbuf;
1967       char *tmpname;
1968
1969       if (preserve_dates)
1970         {
1971           if (stat (argv[i], &statbuf) < 0)
1972             {
1973               non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1974               continue;
1975             }
1976         }
1977
1978       if (output_file != NULL)
1979         tmpname = output_file;
1980       else
1981         tmpname = make_tempname (argv[i]);
1982       status = 0;
1983
1984       copy_file (argv[i], tmpname, input_target, output_target);
1985       if (status == 0)
1986         {
1987           if (preserve_dates)
1988             set_times (tmpname, &statbuf);
1989           if (output_file == NULL)
1990             smart_rename (tmpname, argv[i], preserve_dates);
1991           status = hold_status;
1992         }
1993       else
1994         unlink (tmpname);
1995       if (output_file == NULL)
1996         free (tmpname);
1997     }
1998
1999   return 0;
2000 }
2001
2002 static int
2003 copy_main (argc, argv)
2004      int argc;
2005      char *argv[];
2006 {
2007   char * binary_architecture = NULL;
2008   char *input_filename = NULL, *output_filename = NULL;
2009   char *input_target = NULL, *output_target = NULL;
2010   boolean show_version = false;
2011   boolean change_warn = true;
2012   int c;
2013   struct section_list *p;
2014   struct stat statbuf;
2015
2016   while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
2017                            copy_options, (int *) 0)) != EOF)
2018     {
2019       switch (c)
2020         {
2021         case 'b':
2022           copy_byte = atoi (optarg);
2023           if (copy_byte < 0)
2024             fatal (_("byte number must be non-negative"));
2025           break;
2026
2027         case 'B':
2028           binary_architecture = optarg;
2029           break;
2030
2031         case 'i':
2032           interleave = atoi (optarg);
2033           if (interleave < 1)
2034             fatal (_("interleave must be positive"));
2035           break;
2036
2037         case 'I':
2038         case 's':               /* "source" - 'I' is preferred */
2039           input_target = optarg;
2040           break;
2041
2042         case 'O':
2043         case 'd':               /* "destination" - 'O' is preferred */
2044           output_target = optarg;
2045           break;
2046
2047         case 'F':
2048           input_target = output_target = optarg;
2049           break;
2050
2051         case 'j':
2052           p = find_section_list (optarg, true);
2053           if (p->remove)
2054             fatal (_("%s both copied and removed"), optarg);
2055           p->copy = true;
2056           sections_copied = true;
2057           break;
2058
2059         case 'R':
2060           p = find_section_list (optarg, true);
2061           if (p->copy)
2062             fatal (_("%s both copied and removed"), optarg);
2063           p->remove = true;
2064           sections_removed = true;
2065           break;
2066
2067         case 'S':
2068           strip_symbols = STRIP_ALL;
2069           break;
2070
2071         case 'g':
2072           strip_symbols = STRIP_DEBUG;
2073           break;
2074
2075         case OPTION_STRIP_UNNEEDED:
2076           strip_symbols = STRIP_UNNEEDED;
2077           break;
2078
2079         case 'K':
2080           add_specific_symbol (optarg, &keep_specific_list);
2081           break;
2082
2083         case 'N':
2084           add_specific_symbol (optarg, &strip_specific_list);
2085           break;
2086
2087         case 'L':
2088           add_specific_symbol (optarg, &localize_specific_list);
2089           break;
2090
2091         case 'G':
2092           add_specific_symbol (optarg, &keepglobal_specific_list);
2093           break;
2094
2095         case 'W':
2096           add_specific_symbol (optarg, &weaken_specific_list);
2097           break;
2098
2099         case 'p':
2100           preserve_dates = true;
2101           break;
2102
2103         case 'x':
2104           discard_locals = LOCALS_ALL;
2105           break;
2106
2107         case 'X':
2108           discard_locals = LOCALS_START_L;
2109           break;
2110
2111         case 'v':
2112           verbose = true;
2113           break;
2114
2115         case 'V':
2116           show_version = true;
2117           break;
2118
2119         case OPTION_WEAKEN:
2120           weaken = true;
2121           break;
2122
2123         case OPTION_ADD_SECTION:
2124           {
2125             const char *s;
2126             struct stat st;
2127             struct section_add *pa;
2128             int len;
2129             char *name;
2130             FILE *f;
2131
2132             s = strchr (optarg, '=');
2133
2134             if (s == NULL)
2135               fatal (_("bad format for %s"), "--add-section");
2136
2137             if (stat (s + 1, & st) < 0)
2138               fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
2139
2140             pa = (struct section_add *) xmalloc (sizeof (struct section_add));
2141
2142             len = s - optarg;
2143             name = (char *) xmalloc (len + 1);
2144             strncpy (name, optarg, len);
2145             name[len] = '\0';
2146             pa->name = name;
2147
2148             pa->filename = s + 1;
2149
2150             pa->size = st.st_size;
2151
2152             pa->contents = (bfd_byte *) xmalloc (pa->size);
2153             f = fopen (pa->filename, FOPEN_RB);
2154
2155             if (f == NULL)
2156               fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
2157
2158             if (fread (pa->contents, 1, pa->size, f) == 0
2159                 || ferror (f))
2160               fatal (_("%s: fread failed"), pa->filename);
2161
2162             fclose (f);
2163
2164             pa->next = add_sections;
2165             add_sections = pa;
2166           }
2167           break;
2168
2169         case OPTION_CHANGE_START:
2170           change_start = parse_vma (optarg, "--change-start");
2171           break;
2172
2173         case OPTION_CHANGE_SECTION_ADDRESS:
2174         case OPTION_CHANGE_SECTION_LMA:
2175         case OPTION_CHANGE_SECTION_VMA:
2176           {
2177             const char *s;
2178             int len;
2179             char *name;
2180             char *option = NULL;
2181             bfd_vma val;
2182             enum change_action what = CHANGE_IGNORE;
2183
2184             switch (c)
2185               {
2186               case OPTION_CHANGE_SECTION_ADDRESS:
2187                 option = "--change-section-address";
2188                 break;
2189               case OPTION_CHANGE_SECTION_LMA:
2190                 option = "--change-section-lma";
2191                 break;
2192               case OPTION_CHANGE_SECTION_VMA:
2193                 option = "--change-section-vma";
2194                 break;
2195               }
2196
2197             s = strchr (optarg, '=');
2198             if (s == NULL)
2199               {
2200                 s = strchr (optarg, '+');
2201                 if (s == NULL)
2202                   {
2203                     s = strchr (optarg, '-');
2204                     if (s == NULL)
2205                       fatal (_("bad format for %s"), option);
2206                   }
2207               }
2208
2209             len = s - optarg;
2210             name = (char *) xmalloc (len + 1);
2211             strncpy (name, optarg, len);
2212             name[len] = '\0';
2213
2214             p = find_section_list (name, true);
2215
2216             val = parse_vma (s + 1, option);
2217
2218             switch (*s)
2219               {
2220               case '=': what = CHANGE_SET; break;
2221               case '-': val  = - val; /* Drop through.  */
2222               case '+': what = CHANGE_MODIFY; break;
2223               }
2224
2225             switch (c)
2226               {
2227               case OPTION_CHANGE_SECTION_ADDRESS:
2228                 p->change_vma = what;
2229                 p->vma_val    = val;
2230                 /* Drop through.  */
2231
2232               case OPTION_CHANGE_SECTION_LMA:
2233                 p->change_lma = what;
2234                 p->lma_val    = val;
2235                 break;
2236
2237               case OPTION_CHANGE_SECTION_VMA:
2238                 p->change_vma = what;
2239                 p->vma_val    = val;
2240                 break;
2241               }
2242           }
2243           break;
2244
2245         case OPTION_CHANGE_ADDRESSES:
2246           change_section_address = parse_vma (optarg, "--change-addresses");
2247           change_start = change_section_address;
2248           break;
2249
2250         case OPTION_CHANGE_WARNINGS:
2251           change_warn = true;
2252           break;
2253
2254         case OPTION_CHANGE_LEADING_CHAR:
2255           change_leading_char = true;
2256           break;
2257
2258         case OPTION_DEBUGGING:
2259           convert_debugging = true;
2260           break;
2261
2262         case OPTION_GAP_FILL:
2263           {
2264             bfd_vma gap_fill_vma;
2265
2266             gap_fill_vma = parse_vma (optarg, "--gap-fill");
2267             gap_fill = (bfd_byte) gap_fill_vma;
2268             if ((bfd_vma) gap_fill != gap_fill_vma)
2269               {
2270                 char buff[20];
2271
2272                 sprintf_vma (buff, gap_fill_vma);
2273
2274                 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2275                            buff, gap_fill);
2276               }
2277             gap_fill_set = true;
2278           }
2279           break;
2280
2281         case OPTION_NO_CHANGE_WARNINGS:
2282           change_warn = false;
2283           break;
2284
2285         case OPTION_PAD_TO:
2286           pad_to = parse_vma (optarg, "--pad-to");
2287           pad_to_set = true;
2288           break;
2289
2290         case OPTION_REMOVE_LEADING_CHAR:
2291           remove_leading_char = true;
2292           break;
2293
2294         case OPTION_REDEFINE_SYM:
2295           {
2296             /* Push this redefinition onto redefine_symbol_list.  */
2297
2298             int len;
2299             const char *s;
2300             const char *nextarg;
2301             char *source, *target;
2302
2303             s = strchr (optarg, '=');
2304             if (s == NULL)
2305               {
2306                 fatal (_("bad format for %s"), "--redefine-sym");
2307               }
2308
2309             len = s - optarg;
2310             source = (char *) xmalloc (len + 1);
2311             strncpy (source, optarg, len);
2312             source[len] = '\0';
2313
2314             nextarg = s + 1;
2315             len = strlen (nextarg);
2316             target = (char *) xmalloc (len + 1);
2317             strcpy (target, nextarg);
2318
2319             redefine_list_append (source, target);
2320
2321             free (source);
2322             free (target);
2323           }
2324           break;
2325
2326         case OPTION_SET_SECTION_FLAGS:
2327           {
2328             const char *s;
2329             int len;
2330             char *name;
2331
2332             s = strchr (optarg, '=');
2333             if (s == NULL)
2334               fatal (_("bad format for %s"), "--set-section-flags");
2335
2336             len = s - optarg;
2337             name = (char *) xmalloc (len + 1);
2338             strncpy (name, optarg, len);
2339             name[len] = '\0';
2340
2341             p = find_section_list (name, true);
2342
2343             p->set_flags = true;
2344             p->flags = parse_flags (s + 1);
2345           }
2346           break;
2347
2348         case OPTION_SET_START:
2349           set_start = parse_vma (optarg, "--set-start");
2350           set_start_set = true;
2351           break;
2352
2353         case OPTION_SREC_LEN:
2354           Chunk = parse_vma (optarg, "--srec-len");
2355           break;
2356
2357         case OPTION_SREC_FORCES3:
2358           S3Forced = true;
2359           break;
2360
2361         case OPTION_STRIP_SYMBOLS:
2362           add_specific_symbols (optarg, &strip_specific_list);
2363           break;
2364
2365         case OPTION_KEEP_SYMBOLS:
2366           add_specific_symbols (optarg, &keep_specific_list);
2367           break;
2368
2369         case OPTION_LOCALIZE_SYMBOLS:
2370           add_specific_symbols (optarg, &localize_specific_list);
2371           break;
2372
2373         case OPTION_KEEPGLOBAL_SYMBOLS:
2374           add_specific_symbols (optarg, &keepglobal_specific_list);
2375           break;
2376
2377         case OPTION_WEAKEN_SYMBOLS:
2378           add_specific_symbols (optarg, &weaken_specific_list);
2379           break;
2380
2381         case 0:
2382           break;                /* we've been given a long option */
2383
2384         case 'h':
2385           copy_usage (stdout, 0);
2386
2387         default:
2388           copy_usage (stderr, 1);
2389         }
2390     }
2391
2392   if (show_version)
2393     print_version ("objcopy");
2394
2395   if (copy_byte >= interleave)
2396     fatal (_("byte number must be less than interleave"));
2397
2398   if (optind == argc || optind + 2 < argc)
2399     copy_usage (stderr, 1);
2400
2401   input_filename = argv[optind];
2402   if (optind + 1 < argc)
2403     output_filename = argv[optind + 1];
2404
2405   /* Default is to strip no symbols.  */
2406   if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2407     strip_symbols = STRIP_NONE;
2408
2409   if (output_target == (char *) NULL)
2410     output_target = input_target;
2411
2412   if (binary_architecture != (char *) NULL)
2413     {
2414       if (input_target && strcmp (input_target, "binary") == 0)
2415         {
2416           const bfd_arch_info_type * temp_arch_info;
2417
2418           temp_arch_info = bfd_scan_arch (binary_architecture);
2419
2420           if (temp_arch_info != NULL)
2421             bfd_external_binary_architecture = temp_arch_info->arch;
2422           else
2423             fatal (_("architecture %s unknown"), binary_architecture);
2424         }
2425       else
2426         {
2427           non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2428           non_fatal (_(" Argument %s ignored"), binary_architecture);
2429         }
2430     }
2431
2432   if (preserve_dates)
2433     if (stat (input_filename, & statbuf) < 0)
2434       fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2435
2436   /* If there is no destination file then create a temp and rename
2437      the result into the input.  */
2438
2439   if (output_filename == (char *) NULL)
2440     {
2441       char *tmpname = make_tempname (input_filename);
2442
2443       copy_file (input_filename, tmpname, input_target, output_target);
2444       if (status == 0)
2445         {
2446           if (preserve_dates)
2447             set_times (tmpname, &statbuf);
2448           smart_rename (tmpname, input_filename, preserve_dates);
2449         }
2450       else
2451         unlink (tmpname);
2452     }
2453   else
2454     {
2455       copy_file (input_filename, output_filename, input_target, output_target);
2456       if (status == 0 && preserve_dates)
2457         set_times (output_filename, &statbuf);
2458     }
2459
2460   if (change_warn)
2461     {
2462       for (p = change_sections; p != NULL; p = p->next)
2463         {
2464           if (! p->used)
2465             {
2466               if (p->change_vma != CHANGE_IGNORE)
2467                 {
2468                   char buff [20];
2469
2470                   sprintf_vma (buff, p->vma_val);
2471
2472                   /* xgettext:c-format */
2473                   non_fatal (_("%s %s%c0x%s never used"),
2474                              "--change-section-vma",
2475                              p->name,
2476                              p->change_vma == CHANGE_SET ? '=' : '+',
2477                              buff);
2478                 }
2479
2480               if (p->change_lma != CHANGE_IGNORE)
2481                 {
2482                   char buff [20];
2483
2484                   sprintf_vma (buff, p->lma_val);
2485
2486                   /* xgettext:c-format */
2487                   non_fatal (_("%s %s%c0x%s never used"),
2488                              "--change-section-lma",
2489                              p->name,
2490                              p->change_lma == CHANGE_SET ? '=' : '+',
2491                              buff);
2492                 }
2493             }
2494         }
2495     }
2496
2497   return 0;
2498 }
2499
2500 int
2501 main (argc, argv)
2502      int argc;
2503      char *argv[];
2504 {
2505 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2506   setlocale (LC_MESSAGES, "");
2507 #endif
2508   bindtextdomain (PACKAGE, LOCALEDIR);
2509   textdomain (PACKAGE);
2510
2511   program_name = argv[0];
2512   xmalloc_set_program_name (program_name);
2513
2514   START_PROGRESS (program_name, 0);
2515
2516   strip_symbols = STRIP_UNDEF;
2517   discard_locals = LOCALS_UNDEF;
2518
2519   bfd_init ();
2520   set_default_bfd_target ();
2521
2522   if (is_strip < 0)
2523     {
2524       int i = strlen (program_name);
2525 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2526       /* Drop the .exe suffix, if any.  */
2527       if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2528         {
2529           i -= 4;
2530           program_name[i] = '\0';
2531         }
2532 #endif
2533       is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2534     }
2535
2536   if (is_strip)
2537     strip_main (argc, argv);
2538   else
2539     copy_main (argc, argv);
2540
2541   END_PROGRESS (program_name);
2542
2543   return status;
2544 }