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