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