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