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