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