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