PR binutils/6034
[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 setup_bfd_headers (ibfd, obfd);
1465
1466 if (add_sections != NULL)
1467 {
1468 struct section_add *padd;
1469 struct section_list *pset;
1470
1471 for (padd = add_sections; padd != NULL; padd = padd->next)
1472 {
1473 flagword flags;
1474
1475 pset = find_section_list (padd->name, FALSE);
1476 if (pset != NULL)
1477 pset->used = TRUE;
1478
1479 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1480 if (pset != NULL && pset->set_flags)
1481 flags = pset->flags | SEC_HAS_CONTENTS;
1482
1483 /* bfd_make_section_with_flags() does not return very helpful
1484 error codes, so check for the most likely user error first. */
1485 if (bfd_get_section_by_name (obfd, padd->name))
1486 {
1487 bfd_nonfatal_message (NULL, obfd, NULL,
1488 _("can't add section '%s'"), padd->name);
1489 return FALSE;
1490 }
1491 else
1492 {
1493 padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
1494 if (padd->section == NULL)
1495 {
1496 bfd_nonfatal_message (NULL, obfd, NULL,
1497 _("can't create section `%s'"),
1498 padd->name);
1499 return FALSE;
1500 }
1501 }
1502
1503 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1504 {
1505 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1506 return FALSE;
1507 }
1508
1509 if (pset != NULL)
1510 {
1511 if (pset->change_vma != CHANGE_IGNORE)
1512 if (! bfd_set_section_vma (obfd, padd->section,
1513 pset->vma_val))
1514 {
1515 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1516 return FALSE;
1517 }
1518
1519 if (pset->change_lma != CHANGE_IGNORE)
1520 {
1521 padd->section->lma = pset->lma_val;
1522
1523 if (! bfd_set_section_alignment
1524 (obfd, padd->section,
1525 bfd_section_alignment (obfd, padd->section)))
1526 {
1527 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1528 return FALSE;
1529 }
1530 }
1531 }
1532 }
1533 }
1534
1535 if (gnu_debuglink_filename != NULL)
1536 {
1537 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1538 (obfd, gnu_debuglink_filename);
1539
1540 if (gnu_debuglink_section == NULL)
1541 {
1542 bfd_nonfatal_message (NULL, obfd, NULL,
1543 _("cannot create debug link section `%s'"),
1544 gnu_debuglink_filename);
1545 return FALSE;
1546 }
1547
1548 /* Special processing for PE format files. We
1549 have no way to distinguish PE from COFF here. */
1550 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1551 {
1552 bfd_vma debuglink_vma;
1553 asection * highest_section;
1554 asection * sec;
1555
1556 /* The PE spec requires that all sections be adjacent and sorted
1557 in ascending order of VMA. It also specifies that debug
1558 sections should be last. This is despite the fact that debug
1559 sections are not loaded into memory and so in theory have no
1560 use for a VMA.
1561
1562 This means that the debuglink section must be given a non-zero
1563 VMA which makes it contiguous with other debug sections. So
1564 walk the current section list, find the section with the
1565 highest VMA and start the debuglink section after that one. */
1566 for (sec = obfd->sections, highest_section = NULL;
1567 sec != NULL;
1568 sec = sec->next)
1569 if (sec->vma > 0
1570 && (highest_section == NULL
1571 || sec->vma > highest_section->vma))
1572 highest_section = sec;
1573
1574 if (highest_section)
1575 debuglink_vma = BFD_ALIGN (highest_section->vma
1576 + highest_section->size,
1577 /* FIXME: We ought to be using
1578 COFF_PAGE_SIZE here or maybe
1579 bfd_get_section_alignment() (if it
1580 was set) but since this is for PE
1581 and we know the required alignment
1582 it is easier just to hard code it. */
1583 0x1000);
1584 else
1585 /* Umm, not sure what to do in this case. */
1586 debuglink_vma = 0x1000;
1587
1588 bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
1589 }
1590 }
1591
1592 if (bfd_count_sections (obfd) != 0
1593 && (gap_fill_set || pad_to_set))
1594 {
1595 asection **set;
1596 unsigned int c, i;
1597
1598 /* We must fill in gaps between the sections and/or we must pad
1599 the last section to a specified address. We do this by
1600 grabbing a list of the sections, sorting them by VMA, and
1601 increasing the section sizes as required to fill the gaps.
1602 We write out the gap contents below. */
1603
1604 c = bfd_count_sections (obfd);
1605 osections = xmalloc (c * sizeof (asection *));
1606 set = osections;
1607 bfd_map_over_sections (obfd, get_sections, &set);
1608
1609 qsort (osections, c, sizeof (asection *), compare_section_lma);
1610
1611 gaps = xmalloc (c * sizeof (bfd_size_type));
1612 memset (gaps, 0, c * sizeof (bfd_size_type));
1613
1614 if (gap_fill_set)
1615 {
1616 for (i = 0; i < c - 1; i++)
1617 {
1618 flagword flags;
1619 bfd_size_type size;
1620 bfd_vma gap_start, gap_stop;
1621
1622 flags = bfd_get_section_flags (obfd, osections[i]);
1623 if ((flags & SEC_HAS_CONTENTS) == 0
1624 || (flags & SEC_LOAD) == 0)
1625 continue;
1626
1627 size = bfd_section_size (obfd, osections[i]);
1628 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1629 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1630 if (gap_start < gap_stop)
1631 {
1632 if (! bfd_set_section_size (obfd, osections[i],
1633 size + (gap_stop - gap_start)))
1634 {
1635 bfd_nonfatal_message (NULL, obfd, osections[i],
1636 _("Can't fill gap after section"));
1637 status = 1;
1638 break;
1639 }
1640 gaps[i] = gap_stop - gap_start;
1641 if (max_gap < gap_stop - gap_start)
1642 max_gap = gap_stop - gap_start;
1643 }
1644 }
1645 }
1646
1647 if (pad_to_set)
1648 {
1649 bfd_vma lma;
1650 bfd_size_type size;
1651
1652 lma = bfd_section_lma (obfd, osections[c - 1]);
1653 size = bfd_section_size (obfd, osections[c - 1]);
1654 if (lma + size < pad_to)
1655 {
1656 if (! bfd_set_section_size (obfd, osections[c - 1],
1657 pad_to - lma))
1658 {
1659 bfd_nonfatal_message (NULL, obfd, osections[c - 1],
1660 _("can't add padding"));
1661 status = 1;
1662 }
1663 else
1664 {
1665 gaps[c - 1] = pad_to - (lma + size);
1666 if (max_gap < pad_to - (lma + size))
1667 max_gap = pad_to - (lma + size);
1668 }
1669 }
1670 }
1671 }
1672
1673 /* Symbol filtering must happen after the output sections
1674 have been created, but before their contents are set. */
1675 dhandle = NULL;
1676 if (convert_debugging)
1677 dhandle = read_debugging_info (ibfd, isympp, symcount);
1678
1679 if (strip_symbols == STRIP_DEBUG
1680 || strip_symbols == STRIP_ALL
1681 || strip_symbols == STRIP_UNNEEDED
1682 || strip_symbols == STRIP_NONDEBUG
1683 || discard_locals != LOCALS_UNDEF
1684 || localize_hidden
1685 || htab_elements (strip_specific_htab) != 0
1686 || htab_elements (keep_specific_htab) != 0
1687 || htab_elements (localize_specific_htab) != 0
1688 || htab_elements (globalize_specific_htab) != 0
1689 || htab_elements (keepglobal_specific_htab) != 0
1690 || htab_elements (weaken_specific_htab) != 0
1691 || prefix_symbols_string
1692 || sections_removed
1693 || sections_copied
1694 || convert_debugging
1695 || change_leading_char
1696 || remove_leading_char
1697 || redefine_sym_list
1698 || weaken)
1699 {
1700 /* Mark symbols used in output relocations so that they
1701 are kept, even if they are local labels or static symbols.
1702
1703 Note we iterate over the input sections examining their
1704 relocations since the relocations for the output sections
1705 haven't been set yet. mark_symbols_used_in_relocations will
1706 ignore input sections which have no corresponding output
1707 section. */
1708 if (strip_symbols != STRIP_ALL)
1709 bfd_map_over_sections (ibfd,
1710 mark_symbols_used_in_relocations,
1711 isympp);
1712 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1713 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1714 }
1715
1716 if (convert_debugging && dhandle != NULL)
1717 {
1718 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1719 {
1720 status = 1;
1721 return FALSE;
1722 }
1723 }
1724
1725 bfd_set_symtab (obfd, osympp, symcount);
1726
1727 /* This has to happen after the symbol table has been set. */
1728 bfd_map_over_sections (ibfd, copy_section, obfd);
1729
1730 if (add_sections != NULL)
1731 {
1732 struct section_add *padd;
1733
1734 for (padd = add_sections; padd != NULL; padd = padd->next)
1735 {
1736 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1737 0, padd->size))
1738 {
1739 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1740 return FALSE;
1741 }
1742 }
1743 }
1744
1745 if (gnu_debuglink_filename != NULL)
1746 {
1747 if (! bfd_fill_in_gnu_debuglink_section
1748 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1749 {
1750 bfd_nonfatal_message (NULL, obfd, NULL,
1751 _("cannot fill debug link section `%s'"),
1752 gnu_debuglink_filename);
1753 return FALSE;
1754 }
1755 }
1756
1757 if (gap_fill_set || pad_to_set)
1758 {
1759 bfd_byte *buf;
1760 int c, i;
1761
1762 /* Fill in the gaps. */
1763 if (max_gap > 8192)
1764 max_gap = 8192;
1765 buf = xmalloc (max_gap);
1766 memset (buf, gap_fill, max_gap);
1767
1768 c = bfd_count_sections (obfd);
1769 for (i = 0; i < c; i++)
1770 {
1771 if (gaps[i] != 0)
1772 {
1773 bfd_size_type left;
1774 file_ptr off;
1775
1776 left = gaps[i];
1777 off = bfd_section_size (obfd, osections[i]) - left;
1778
1779 while (left > 0)
1780 {
1781 bfd_size_type now;
1782
1783 if (left > 8192)
1784 now = 8192;
1785 else
1786 now = left;
1787
1788 if (! bfd_set_section_contents (obfd, osections[i], buf,
1789 off, now))
1790 {
1791 bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
1792 return FALSE;
1793 }
1794
1795 left -= now;
1796 off += now;
1797 }
1798 }
1799 }
1800 }
1801
1802 /* Do not copy backend data if --extract-symbol is passed; anything
1803 that needs to look at the section contents will fail. */
1804 if (extract_symbol)
1805 return TRUE;
1806
1807 /* Allow the BFD backend to copy any private data it understands
1808 from the input BFD to the output BFD. This is done last to
1809 permit the routine to look at the filtered symbol table, which is
1810 important for the ECOFF code at least. */
1811 if (! bfd_copy_private_bfd_data (ibfd, obfd))
1812 {
1813 bfd_nonfatal_message (NULL, obfd, NULL,
1814 _("error copying private BFD data"));
1815 return FALSE;
1816 }
1817
1818 /* Switch to the alternate machine code. We have to do this at the
1819 very end, because we only initialize the header when we create
1820 the first section. */
1821 if (use_alt_mach_code != 0)
1822 {
1823 if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
1824 {
1825 non_fatal (_("this target does not support %lu alternative machine codes"),
1826 use_alt_mach_code);
1827 if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1828 {
1829 non_fatal (_("treating that number as an absolute e_machine value instead"));
1830 elf_elfheader (obfd)->e_machine = use_alt_mach_code;
1831 }
1832 else
1833 non_fatal (_("ignoring the alternative value"));
1834 }
1835 }
1836
1837 return TRUE;
1838 }
1839
1840 /* Read each archive element in turn from IBFD, copy the
1841 contents to temp file, and keep the temp file handle.
1842 If 'force_output_target' is TRUE then make sure that
1843 all elements in the new archive are of the type
1844 'output_target'. */
1845
1846 static void
1847 copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
1848 bfd_boolean force_output_target)
1849 {
1850 struct name_list
1851 {
1852 struct name_list *next;
1853 const char *name;
1854 bfd *obfd;
1855 } *list, *l;
1856 bfd **ptr = &obfd->archive_head;
1857 bfd *this_element;
1858 char * dir;
1859
1860 /* Make a temp directory to hold the contents. */
1861 dir = make_tempdir (bfd_get_filename (obfd));
1862 if (dir == NULL)
1863 fatal (_("cannot create tempdir for archive copying (error: %s)"),
1864 strerror (errno));
1865
1866 obfd->has_armap = ibfd->has_armap;
1867 obfd->is_thin_archive = ibfd->is_thin_archive;
1868
1869 list = NULL;
1870
1871 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1872
1873 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1874 RETURN_NONFATAL (obfd);
1875
1876 while (!status && this_element != NULL)
1877 {
1878 char *output_name;
1879 bfd *output_bfd;
1880 bfd *last_element;
1881 struct stat buf;
1882 int stat_status = 0;
1883 bfd_boolean delete = TRUE;
1884
1885 /* Create an output file for this member. */
1886 output_name = concat (dir, "/",
1887 bfd_get_filename (this_element), (char *) 0);
1888
1889 /* If the file already exists, make another temp dir. */
1890 if (stat (output_name, &buf) >= 0)
1891 {
1892 output_name = make_tempdir (output_name);
1893 if (output_name == NULL)
1894 fatal (_("cannot create tempdir for archive copying (error: %s)"),
1895 strerror (errno));
1896
1897 l = xmalloc (sizeof (struct name_list));
1898 l->name = output_name;
1899 l->next = list;
1900 l->obfd = NULL;
1901 list = l;
1902 output_name = concat (output_name, "/",
1903 bfd_get_filename (this_element), (char *) 0);
1904 }
1905
1906 if (preserve_dates)
1907 {
1908 stat_status = bfd_stat_arch_elt (this_element, &buf);
1909
1910 if (stat_status != 0)
1911 non_fatal (_("internal stat error on %s"),
1912 bfd_get_filename (this_element));
1913 }
1914
1915 l = xmalloc (sizeof (struct name_list));
1916 l->name = output_name;
1917 l->next = list;
1918 l->obfd = NULL;
1919 list = l;
1920
1921 if (bfd_check_format (this_element, bfd_object))
1922 {
1923 /* PR binutils/3110: Cope with archives
1924 containing multiple target types. */
1925 if (force_output_target)
1926 output_bfd = bfd_openw (output_name, output_target);
1927 else
1928 output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
1929
1930 if (output_bfd == NULL)
1931 {
1932 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
1933 status = 1;
1934 return;
1935 }
1936
1937 delete = ! copy_object (this_element, output_bfd);
1938
1939 if (! delete
1940 || bfd_get_arch (this_element) != bfd_arch_unknown)
1941 {
1942 if (!bfd_close (output_bfd))
1943 {
1944 bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
1945 /* Error in new object file. Don't change archive. */
1946 status = 1;
1947 }
1948 }
1949 else
1950 goto copy_unknown_element;
1951 }
1952 else
1953 {
1954 bfd_nonfatal_message (bfd_get_archive_filename (this_element),
1955 NULL, NULL,
1956 _("Unable to recognise the format of file"));
1957
1958 output_bfd = bfd_openw (output_name, output_target);
1959 copy_unknown_element:
1960 delete = !copy_unknown_object (this_element, output_bfd);
1961 if (!bfd_close_all_done (output_bfd))
1962 {
1963 bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
1964 /* Error in new object file. Don't change archive. */
1965 status = 1;
1966 }
1967 }
1968
1969 if (delete)
1970 {
1971 unlink (output_name);
1972 status = 1;
1973 }
1974 else
1975 {
1976 if (preserve_dates && stat_status == 0)
1977 set_times (output_name, &buf);
1978
1979 /* Open the newly output file and attach to our list. */
1980 output_bfd = bfd_openr (output_name, output_target);
1981
1982 l->obfd = output_bfd;
1983
1984 *ptr = output_bfd;
1985 ptr = &output_bfd->archive_next;
1986
1987 last_element = this_element;
1988
1989 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1990
1991 bfd_close (last_element);
1992 }
1993 }
1994 *ptr = NULL;
1995
1996 if (!bfd_close (obfd))
1997 RETURN_NONFATAL (obfd);
1998
1999 if (!bfd_close (ibfd))
2000 RETURN_NONFATAL (obfd);
2001
2002 /* Delete all the files that we opened. */
2003 for (l = list; l != NULL; l = l->next)
2004 {
2005 if (l->obfd == NULL)
2006 rmdir (l->name);
2007 else
2008 {
2009 bfd_close (l->obfd);
2010 unlink (l->name);
2011 }
2012 }
2013 rmdir (dir);
2014 }
2015
2016 /* The top-level control. */
2017
2018 static void
2019 copy_file (const char *input_filename, const char *output_filename,
2020 const char *input_target, const char *output_target)
2021 {
2022 bfd *ibfd;
2023 char **obj_matching;
2024 char **core_matching;
2025
2026 if (get_file_size (input_filename) < 1)
2027 {
2028 status = 1;
2029 return;
2030 }
2031
2032 /* To allow us to do "strip *" without dying on the first
2033 non-object file, failures are nonfatal. */
2034 ibfd = bfd_openr (input_filename, input_target);
2035 if (ibfd == NULL)
2036 {
2037 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2038 status = 1;
2039 return;
2040 }
2041
2042 if (bfd_check_format (ibfd, bfd_archive))
2043 {
2044 bfd_boolean force_output_target;
2045 bfd *obfd;
2046
2047 /* bfd_get_target does not return the correct value until
2048 bfd_check_format succeeds. */
2049 if (output_target == NULL)
2050 {
2051 output_target = bfd_get_target (ibfd);
2052 force_output_target = FALSE;
2053 }
2054 else
2055 force_output_target = TRUE;
2056
2057 obfd = bfd_openw (output_filename, output_target);
2058 if (obfd == NULL)
2059 {
2060 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2061 status = 1;
2062 return;
2063 }
2064
2065 copy_archive (ibfd, obfd, output_target, force_output_target);
2066 }
2067 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
2068 {
2069 bfd *obfd;
2070 do_copy:
2071
2072 /* bfd_get_target does not return the correct value until
2073 bfd_check_format succeeds. */
2074 if (output_target == NULL)
2075 output_target = bfd_get_target (ibfd);
2076
2077 obfd = bfd_openw (output_filename, output_target);
2078 if (obfd == NULL)
2079 {
2080 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2081 status = 1;
2082 return;
2083 }
2084
2085 if (! copy_object (ibfd, obfd))
2086 status = 1;
2087
2088 if (!bfd_close (obfd))
2089 RETURN_NONFATAL (obfd);
2090
2091 if (!bfd_close (ibfd))
2092 RETURN_NONFATAL (ibfd);
2093 }
2094 else
2095 {
2096 bfd_error_type obj_error = bfd_get_error ();
2097 bfd_error_type core_error;
2098
2099 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
2100 {
2101 /* This probably can't happen.. */
2102 if (obj_error == bfd_error_file_ambiguously_recognized)
2103 free (obj_matching);
2104 goto do_copy;
2105 }
2106
2107 core_error = bfd_get_error ();
2108 /* Report the object error in preference to the core error. */
2109 if (obj_error != core_error)
2110 bfd_set_error (obj_error);
2111
2112 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2113
2114 if (obj_error == bfd_error_file_ambiguously_recognized)
2115 {
2116 list_matching_formats (obj_matching);
2117 free (obj_matching);
2118 }
2119 if (core_error == bfd_error_file_ambiguously_recognized)
2120 {
2121 list_matching_formats (core_matching);
2122 free (core_matching);
2123 }
2124
2125 status = 1;
2126 }
2127 }
2128
2129 /* Add a name to the section renaming list. */
2130
2131 static void
2132 add_section_rename (const char * old_name, const char * new_name,
2133 flagword flags)
2134 {
2135 section_rename * rename;
2136
2137 /* Check for conflicts first. */
2138 for (rename = section_rename_list; rename != NULL; rename = rename->next)
2139 if (strcmp (rename->old_name, old_name) == 0)
2140 {
2141 /* Silently ignore duplicate definitions. */
2142 if (strcmp (rename->new_name, new_name) == 0
2143 && rename->flags == flags)
2144 return;
2145
2146 fatal (_("Multiple renames of section %s"), old_name);
2147 }
2148
2149 rename = xmalloc (sizeof (* rename));
2150
2151 rename->old_name = old_name;
2152 rename->new_name = new_name;
2153 rename->flags = flags;
2154 rename->next = section_rename_list;
2155
2156 section_rename_list = rename;
2157 }
2158
2159 /* Check the section rename list for a new name of the input section
2160 ISECTION. Return the new name if one is found.
2161 Also set RETURNED_FLAGS to the flags to be used for this section. */
2162
2163 static const char *
2164 find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
2165 flagword * returned_flags)
2166 {
2167 const char * old_name = bfd_section_name (ibfd, isection);
2168 section_rename * rename;
2169
2170 /* Default to using the flags of the input section. */
2171 * returned_flags = bfd_get_section_flags (ibfd, isection);
2172
2173 for (rename = section_rename_list; rename != NULL; rename = rename->next)
2174 if (strcmp (rename->old_name, old_name) == 0)
2175 {
2176 if (rename->flags != (flagword) -1)
2177 * returned_flags = rename->flags;
2178
2179 return rename->new_name;
2180 }
2181
2182 return old_name;
2183 }
2184
2185 /* Once each of the sections is copied, we may still need to do some
2186 finalization work for private section headers. Do that here. */
2187
2188 static void
2189 setup_bfd_headers (bfd *ibfd, bfd *obfd)
2190 {
2191 /* Allow the BFD backend to copy any private data it understands
2192 from the input section to the output section. */
2193 if (! bfd_copy_private_header_data (ibfd, obfd))
2194 {
2195 status = 1;
2196 bfd_nonfatal_message (NULL, ibfd, NULL,
2197 _("error in private h eader data"));
2198 return;
2199 }
2200
2201 /* All went well. */
2202 return;
2203 }
2204
2205 /* Create a section in OBFD with the same
2206 name and attributes as ISECTION in IBFD. */
2207
2208 static void
2209 setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2210 {
2211 bfd *obfd = obfdarg;
2212 struct section_list *p;
2213 sec_ptr osection;
2214 bfd_size_type size;
2215 bfd_vma vma;
2216 bfd_vma lma;
2217 flagword flags;
2218 const char *err;
2219 const char * name;
2220 char *prefix = NULL;
2221 bfd_boolean make_nobits;
2222
2223 if (is_strip_section (ibfd, isection))
2224 return;
2225
2226 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
2227 if (p != NULL)
2228 p->used = TRUE;
2229
2230 /* Get the, possibly new, name of the output section. */
2231 name = find_section_rename (ibfd, isection, & flags);
2232
2233 /* Prefix sections. */
2234 if ((prefix_alloc_sections_string)
2235 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
2236 prefix = prefix_alloc_sections_string;
2237 else if (prefix_sections_string)
2238 prefix = prefix_sections_string;
2239
2240 if (prefix)
2241 {
2242 char *n;
2243
2244 n = xmalloc (strlen (prefix) + strlen (name) + 1);
2245 strcpy (n, prefix);
2246 strcat (n, name);
2247 name = n;
2248 }
2249
2250 make_nobits = FALSE;
2251 if (p != NULL && p->set_flags)
2252 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
2253 else if (strip_symbols == STRIP_NONDEBUG
2254 && (flags & SEC_ALLOC) != 0
2255 && (ibfd->xvec->flavour != bfd_target_elf_flavour
2256 || elf_section_type (isection) != SHT_NOTE))
2257 {
2258 flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2259 if (obfd->xvec->flavour == bfd_target_elf_flavour)
2260 {
2261 make_nobits = TRUE;
2262
2263 /* Twiddle the input section flags so that it seems to
2264 elf.c:copy_private_bfd_data that section flags have not
2265 changed between input and output sections. This hack
2266 prevents wholesale rewriting of the program headers. */
2267 isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2268 }
2269 }
2270
2271 osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
2272
2273 if (osection == NULL)
2274 {
2275 err = _("failed to create output section");
2276 goto loser;
2277 }
2278
2279 if (make_nobits)
2280 elf_section_type (osection) = SHT_NOBITS;
2281
2282 size = bfd_section_size (ibfd, isection);
2283 if (copy_byte >= 0)
2284 size = (size + interleave - 1) / interleave;
2285 else if (extract_symbol)
2286 size = 0;
2287 if (! bfd_set_section_size (obfd, osection, size))
2288 {
2289 err = _("failed to set size");
2290 goto loser;
2291 }
2292
2293 vma = bfd_section_vma (ibfd, isection);
2294 if (p != NULL && p->change_vma == CHANGE_MODIFY)
2295 vma += p->vma_val;
2296 else if (p != NULL && p->change_vma == CHANGE_SET)
2297 vma = p->vma_val;
2298 else
2299 vma += change_section_address;
2300
2301 if (! bfd_set_section_vma (obfd, osection, extract_symbol ? 0 : vma))
2302 {
2303 err = _("failed to set vma");
2304 goto loser;
2305 }
2306
2307 lma = isection->lma;
2308 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2309 {
2310 if (p->change_lma == CHANGE_MODIFY)
2311 lma += p->lma_val;
2312 else if (p->change_lma == CHANGE_SET)
2313 lma = p->lma_val;
2314 else
2315 abort ();
2316 }
2317 else
2318 lma += change_section_address;
2319
2320 osection->lma = extract_symbol ? 0 : lma;
2321
2322 /* FIXME: This is probably not enough. If we change the LMA we
2323 may have to recompute the header for the file as well. */
2324 if (!bfd_set_section_alignment (obfd,
2325 osection,
2326 bfd_section_alignment (ibfd, isection)))
2327 {
2328 err = _("failed to set alignment");
2329 goto loser;
2330 }
2331
2332 /* Copy merge entity size. */
2333 osection->entsize = isection->entsize;
2334
2335 /* This used to be mangle_section; we do here to avoid using
2336 bfd_get_section_by_name since some formats allow multiple
2337 sections with the same name. */
2338 isection->output_section = osection;
2339 isection->output_offset = extract_symbol ? vma : 0;
2340
2341 /* Do not copy backend data if --extract-symbol is passed; anything
2342 that needs to look at the section contents will fail. */
2343 if (extract_symbol)
2344 return;
2345
2346 /* Allow the BFD backend to copy any private data it understands
2347 from the input section to the output section. */
2348 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
2349 {
2350 err = _("failed to copy private data");
2351 goto loser;
2352 }
2353 else if ((isection->flags & SEC_GROUP) != 0)
2354 {
2355 asymbol *gsym = group_signature (isection);
2356
2357 if (gsym != NULL)
2358 gsym->flags |= BSF_KEEP;
2359 }
2360
2361 /* All went well. */
2362 return;
2363
2364 loser:
2365 status = 1;
2366 bfd_nonfatal_message (NULL, obfd, osection, err);
2367 }
2368
2369 /* Copy the data of input section ISECTION of IBFD
2370 to an output section with the same name in OBFD.
2371 If stripping then don't copy any relocation info. */
2372
2373 static void
2374 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2375 {
2376 bfd *obfd = obfdarg;
2377 struct section_list *p;
2378 arelent **relpp;
2379 long relcount;
2380 sec_ptr osection;
2381 bfd_size_type size;
2382 long relsize;
2383 flagword flags;
2384
2385 /* If we have already failed earlier on,
2386 do not keep on generating complaints now. */
2387 if (status != 0)
2388 return;
2389
2390 if (is_strip_section (ibfd, isection))
2391 return;
2392
2393 flags = bfd_get_section_flags (ibfd, isection);
2394 if ((flags & SEC_GROUP) != 0)
2395 return;
2396
2397 osection = isection->output_section;
2398 size = bfd_get_section_size (isection);
2399
2400 if (size == 0 || osection == 0)
2401 return;
2402
2403 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2404
2405 /* Core files do not need to be relocated. */
2406 if (bfd_get_format (obfd) == bfd_core)
2407 relsize = 0;
2408 else
2409 {
2410 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2411
2412 if (relsize < 0)
2413 {
2414 /* Do not complain if the target does not support relocations. */
2415 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2416 relsize = 0;
2417 else
2418 {
2419 status = 1;
2420 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2421 return;
2422 }
2423 }
2424 }
2425
2426 if (relsize == 0)
2427 bfd_set_reloc (obfd, osection, NULL, 0);
2428 else
2429 {
2430 relpp = xmalloc (relsize);
2431 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2432 if (relcount < 0)
2433 {
2434 status = 1;
2435 bfd_nonfatal_message (NULL, ibfd, isection,
2436 _("relocation count is negative"));
2437 return;
2438 }
2439
2440 if (strip_symbols == STRIP_ALL)
2441 {
2442 /* Remove relocations which are not in
2443 keep_strip_specific_list. */
2444 arelent **temp_relpp;
2445 long temp_relcount = 0;
2446 long i;
2447
2448 temp_relpp = xmalloc (relsize);
2449 for (i = 0; i < relcount; i++)
2450 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
2451 keep_specific_htab))
2452 temp_relpp [temp_relcount++] = relpp [i];
2453 relcount = temp_relcount;
2454 free (relpp);
2455 relpp = temp_relpp;
2456 }
2457
2458 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
2459 if (relcount == 0)
2460 free (relpp);
2461 }
2462
2463 if (extract_symbol)
2464 return;
2465
2466 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
2467 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
2468 {
2469 void *memhunk = xmalloc (size);
2470
2471 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2472 {
2473 status = 1;
2474 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2475 return;
2476 }
2477
2478 if (reverse_bytes)
2479 {
2480 /* We don't handle leftover bytes (too many possible behaviors,
2481 and we don't know what the user wants). The section length
2482 must be a multiple of the number of bytes to swap. */
2483 if ((size % reverse_bytes) == 0)
2484 {
2485 unsigned long i, j;
2486 bfd_byte b;
2487
2488 for (i = 0; i < size; i += reverse_bytes)
2489 for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2490 {
2491 bfd_byte *m = (bfd_byte *) memhunk;
2492
2493 b = m[i + j];
2494 m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2495 m[(i + reverse_bytes) - (j + 1)] = b;
2496 }
2497 }
2498 else
2499 /* User must pad the section up in order to do this. */
2500 fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2501 bfd_section_name (ibfd, isection), reverse_bytes);
2502 }
2503
2504 if (copy_byte >= 0)
2505 {
2506 /* Keep only every `copy_byte'th byte in MEMHUNK. */
2507 char *from = (char *) memhunk + copy_byte;
2508 char *to = memhunk;
2509 char *end = (char *) memhunk + size;
2510
2511 for (; from < end; from += interleave)
2512 *to++ = *from;
2513
2514 size = (size + interleave - 1 - copy_byte) / interleave;
2515 osection->lma /= interleave;
2516 }
2517
2518 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2519 {
2520 status = 1;
2521 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2522 return;
2523 }
2524 free (memhunk);
2525 }
2526 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2527 {
2528 void *memhunk = xmalloc (size);
2529
2530 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2531 flag--they can just remove the section entirely and add it
2532 back again. However, we do permit them to turn on the
2533 SEC_HAS_CONTENTS flag, and take it to mean that the section
2534 contents should be zeroed out. */
2535
2536 memset (memhunk, 0, size);
2537 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2538 {
2539 status = 1;
2540 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2541 return;
2542 }
2543 free (memhunk);
2544 }
2545 }
2546
2547 /* Get all the sections. This is used when --gap-fill or --pad-to is
2548 used. */
2549
2550 static void
2551 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2552 {
2553 asection ***secppp = secppparg;
2554
2555 **secppp = osection;
2556 ++(*secppp);
2557 }
2558
2559 /* Sort sections by VMA. This is called via qsort, and is used when
2560 --gap-fill or --pad-to is used. We force non loadable or empty
2561 sections to the front, where they are easier to ignore. */
2562
2563 static int
2564 compare_section_lma (const void *arg1, const void *arg2)
2565 {
2566 const asection *const *sec1 = arg1;
2567 const asection *const *sec2 = arg2;
2568 flagword flags1, flags2;
2569
2570 /* Sort non loadable sections to the front. */
2571 flags1 = (*sec1)->flags;
2572 flags2 = (*sec2)->flags;
2573 if ((flags1 & SEC_HAS_CONTENTS) == 0
2574 || (flags1 & SEC_LOAD) == 0)
2575 {
2576 if ((flags2 & SEC_HAS_CONTENTS) != 0
2577 && (flags2 & SEC_LOAD) != 0)
2578 return -1;
2579 }
2580 else
2581 {
2582 if ((flags2 & SEC_HAS_CONTENTS) == 0
2583 || (flags2 & SEC_LOAD) == 0)
2584 return 1;
2585 }
2586
2587 /* Sort sections by LMA. */
2588 if ((*sec1)->lma > (*sec2)->lma)
2589 return 1;
2590 else if ((*sec1)->lma < (*sec2)->lma)
2591 return -1;
2592
2593 /* Sort sections with the same LMA by size. */
2594 if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
2595 return 1;
2596 else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
2597 return -1;
2598
2599 return 0;
2600 }
2601
2602 /* Mark all the symbols which will be used in output relocations with
2603 the BSF_KEEP flag so that those symbols will not be stripped.
2604
2605 Ignore relocations which will not appear in the output file. */
2606
2607 static void
2608 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2609 {
2610 asymbol **symbols = symbolsarg;
2611 long relsize;
2612 arelent **relpp;
2613 long relcount, i;
2614
2615 /* Ignore an input section with no corresponding output section. */
2616 if (isection->output_section == NULL)
2617 return;
2618
2619 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2620 if (relsize < 0)
2621 {
2622 /* Do not complain if the target does not support relocations. */
2623 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2624 return;
2625 bfd_fatal (bfd_get_filename (ibfd));
2626 }
2627
2628 if (relsize == 0)
2629 return;
2630
2631 relpp = xmalloc (relsize);
2632 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2633 if (relcount < 0)
2634 bfd_fatal (bfd_get_filename (ibfd));
2635
2636 /* Examine each symbol used in a relocation. If it's not one of the
2637 special bfd section symbols, then mark it with BSF_KEEP. */
2638 for (i = 0; i < relcount; i++)
2639 {
2640 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2641 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2642 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2643 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2644 }
2645
2646 if (relpp != NULL)
2647 free (relpp);
2648 }
2649
2650 /* Write out debugging information. */
2651
2652 static bfd_boolean
2653 write_debugging_info (bfd *obfd, void *dhandle,
2654 long *symcountp ATTRIBUTE_UNUSED,
2655 asymbol ***symppp ATTRIBUTE_UNUSED)
2656 {
2657 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2658 return write_ieee_debugging_info (obfd, dhandle);
2659
2660 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2661 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2662 {
2663 bfd_byte *syms, *strings;
2664 bfd_size_type symsize, stringsize;
2665 asection *stabsec, *stabstrsec;
2666 flagword flags;
2667
2668 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2669 &symsize, &strings,
2670 &stringsize))
2671 return FALSE;
2672
2673 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2674 stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2675 stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
2676 if (stabsec == NULL
2677 || stabstrsec == NULL
2678 || ! bfd_set_section_size (obfd, stabsec, symsize)
2679 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2680 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2681 || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
2682 {
2683 bfd_nonfatal_message (NULL, obfd, NULL,
2684 _("can't create debugging section"));
2685 return FALSE;
2686 }
2687
2688 /* We can get away with setting the section contents now because
2689 the next thing the caller is going to do is copy over the
2690 real sections. We may someday have to split the contents
2691 setting out of this function. */
2692 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2693 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2694 stringsize))
2695 {
2696 bfd_nonfatal_message (NULL, obfd, NULL,
2697 _("can't set debugging section contents"));
2698 return FALSE;
2699 }
2700
2701 return TRUE;
2702 }
2703
2704 bfd_nonfatal_message (NULL, obfd, NULL,
2705 _("don't know how to write debugging information for %s"),
2706 bfd_get_target (obfd));
2707 return FALSE;
2708 }
2709
2710 static int
2711 strip_main (int argc, char *argv[])
2712 {
2713 char *input_target = NULL;
2714 char *output_target = NULL;
2715 bfd_boolean show_version = FALSE;
2716 bfd_boolean formats_info = FALSE;
2717 int c;
2718 int i;
2719 struct section_list *p;
2720 char *output_file = NULL;
2721
2722 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2723 strip_options, (int *) 0)) != EOF)
2724 {
2725 switch (c)
2726 {
2727 case 'I':
2728 input_target = optarg;
2729 break;
2730 case 'O':
2731 output_target = optarg;
2732 break;
2733 case 'F':
2734 input_target = output_target = optarg;
2735 break;
2736 case 'R':
2737 p = find_section_list (optarg, TRUE);
2738 p->remove = TRUE;
2739 sections_removed = TRUE;
2740 break;
2741 case 's':
2742 strip_symbols = STRIP_ALL;
2743 break;
2744 case 'S':
2745 case 'g':
2746 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2747 strip_symbols = STRIP_DEBUG;
2748 break;
2749 case OPTION_STRIP_UNNEEDED:
2750 strip_symbols = STRIP_UNNEEDED;
2751 break;
2752 case 'K':
2753 add_specific_symbol (optarg, keep_specific_htab);
2754 break;
2755 case 'N':
2756 add_specific_symbol (optarg, strip_specific_htab);
2757 break;
2758 case 'o':
2759 output_file = optarg;
2760 break;
2761 case 'p':
2762 preserve_dates = TRUE;
2763 break;
2764 case 'x':
2765 discard_locals = LOCALS_ALL;
2766 break;
2767 case 'X':
2768 discard_locals = LOCALS_START_L;
2769 break;
2770 case 'v':
2771 verbose = TRUE;
2772 break;
2773 case 'V':
2774 show_version = TRUE;
2775 break;
2776 case OPTION_FORMATS_INFO:
2777 formats_info = TRUE;
2778 break;
2779 case OPTION_ONLY_KEEP_DEBUG:
2780 strip_symbols = STRIP_NONDEBUG;
2781 break;
2782 case OPTION_KEEP_FILE_SYMBOLS:
2783 keep_file_symbols = 1;
2784 break;
2785 case 0:
2786 /* We've been given a long option. */
2787 break;
2788 case 'w':
2789 wildcard = TRUE;
2790 break;
2791 case 'H':
2792 case 'h':
2793 strip_usage (stdout, 0);
2794 default:
2795 strip_usage (stderr, 1);
2796 }
2797 }
2798
2799 if (formats_info)
2800 {
2801 display_info ();
2802 return 0;
2803 }
2804
2805 if (show_version)
2806 print_version ("strip");
2807
2808 /* Default is to strip all symbols. */
2809 if (strip_symbols == STRIP_UNDEF
2810 && discard_locals == LOCALS_UNDEF
2811 && htab_elements (strip_specific_htab) == 0)
2812 strip_symbols = STRIP_ALL;
2813
2814 if (output_target == NULL)
2815 output_target = input_target;
2816
2817 i = optind;
2818 if (i == argc
2819 || (output_file != NULL && (i + 1) < argc))
2820 strip_usage (stderr, 1);
2821
2822 for (; i < argc; i++)
2823 {
2824 int hold_status = status;
2825 struct stat statbuf;
2826 char *tmpname;
2827
2828 if (get_file_size (argv[i]) < 1)
2829 {
2830 status = 1;
2831 continue;
2832 }
2833
2834 if (preserve_dates)
2835 /* No need to check the return value of stat().
2836 It has already been checked in get_file_size(). */
2837 stat (argv[i], &statbuf);
2838
2839 if (output_file == NULL || strcmp (argv[i], output_file) == 0)
2840 tmpname = make_tempname (argv[i]);
2841 else
2842 tmpname = output_file;
2843
2844 if (tmpname == NULL)
2845 {
2846 bfd_nonfatal_message (argv[i], NULL, NULL,
2847 _("could not create temporary file to hold stripped copy"));
2848 status = 1;
2849 continue;
2850 }
2851
2852 status = 0;
2853 copy_file (argv[i], tmpname, input_target, output_target);
2854 if (status == 0)
2855 {
2856 if (preserve_dates)
2857 set_times (tmpname, &statbuf);
2858 if (output_file != tmpname)
2859 smart_rename (tmpname, output_file ? output_file : argv[i],
2860 preserve_dates);
2861 status = hold_status;
2862 }
2863 else
2864 unlink_if_ordinary (tmpname);
2865 if (output_file != tmpname)
2866 free (tmpname);
2867 }
2868
2869 return status;
2870 }
2871
2872 static int
2873 copy_main (int argc, char *argv[])
2874 {
2875 char * binary_architecture = NULL;
2876 char *input_filename = NULL;
2877 char *output_filename = NULL;
2878 char *tmpname;
2879 char *input_target = NULL;
2880 char *output_target = NULL;
2881 bfd_boolean show_version = FALSE;
2882 bfd_boolean change_warn = TRUE;
2883 bfd_boolean formats_info = FALSE;
2884 int c;
2885 struct section_list *p;
2886 struct stat statbuf;
2887
2888 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2889 copy_options, (int *) 0)) != EOF)
2890 {
2891 switch (c)
2892 {
2893 case 'b':
2894 copy_byte = atoi (optarg);
2895 if (copy_byte < 0)
2896 fatal (_("byte number must be non-negative"));
2897 break;
2898
2899 case 'B':
2900 binary_architecture = optarg;
2901 break;
2902
2903 case 'i':
2904 interleave = atoi (optarg);
2905 if (interleave < 1)
2906 fatal (_("interleave must be positive"));
2907 break;
2908
2909 case 'I':
2910 case 's': /* "source" - 'I' is preferred */
2911 input_target = optarg;
2912 break;
2913
2914 case 'O':
2915 case 'd': /* "destination" - 'O' is preferred */
2916 output_target = optarg;
2917 break;
2918
2919 case 'F':
2920 input_target = output_target = optarg;
2921 break;
2922
2923 case 'j':
2924 p = find_section_list (optarg, TRUE);
2925 if (p->remove)
2926 fatal (_("%s both copied and removed"), optarg);
2927 p->copy = TRUE;
2928 sections_copied = TRUE;
2929 break;
2930
2931 case 'R':
2932 p = find_section_list (optarg, TRUE);
2933 if (p->copy)
2934 fatal (_("%s both copied and removed"), optarg);
2935 p->remove = TRUE;
2936 sections_removed = TRUE;
2937 break;
2938
2939 case 'S':
2940 strip_symbols = STRIP_ALL;
2941 break;
2942
2943 case 'g':
2944 strip_symbols = STRIP_DEBUG;
2945 break;
2946
2947 case OPTION_STRIP_UNNEEDED:
2948 strip_symbols = STRIP_UNNEEDED;
2949 break;
2950
2951 case OPTION_ONLY_KEEP_DEBUG:
2952 strip_symbols = STRIP_NONDEBUG;
2953 break;
2954
2955 case OPTION_KEEP_FILE_SYMBOLS:
2956 keep_file_symbols = 1;
2957 break;
2958
2959 case OPTION_ADD_GNU_DEBUGLINK:
2960 gnu_debuglink_filename = optarg;
2961 break;
2962
2963 case 'K':
2964 add_specific_symbol (optarg, keep_specific_htab);
2965 break;
2966
2967 case 'N':
2968 add_specific_symbol (optarg, strip_specific_htab);
2969 break;
2970
2971 case OPTION_STRIP_UNNEEDED_SYMBOL:
2972 add_specific_symbol (optarg, strip_unneeded_htab);
2973 break;
2974
2975 case 'L':
2976 add_specific_symbol (optarg, localize_specific_htab);
2977 break;
2978
2979 case OPTION_GLOBALIZE_SYMBOL:
2980 add_specific_symbol (optarg, globalize_specific_htab);
2981 break;
2982
2983 case 'G':
2984 add_specific_symbol (optarg, keepglobal_specific_htab);
2985 break;
2986
2987 case 'W':
2988 add_specific_symbol (optarg, weaken_specific_htab);
2989 break;
2990
2991 case 'p':
2992 preserve_dates = TRUE;
2993 break;
2994
2995 case 'w':
2996 wildcard = TRUE;
2997 break;
2998
2999 case 'x':
3000 discard_locals = LOCALS_ALL;
3001 break;
3002
3003 case 'X':
3004 discard_locals = LOCALS_START_L;
3005 break;
3006
3007 case 'v':
3008 verbose = TRUE;
3009 break;
3010
3011 case 'V':
3012 show_version = TRUE;
3013 break;
3014
3015 case OPTION_FORMATS_INFO:
3016 formats_info = TRUE;
3017 break;
3018
3019 case OPTION_WEAKEN:
3020 weaken = TRUE;
3021 break;
3022
3023 case OPTION_ADD_SECTION:
3024 {
3025 const char *s;
3026 off_t size;
3027 struct section_add *pa;
3028 int len;
3029 char *name;
3030 FILE *f;
3031
3032 s = strchr (optarg, '=');
3033
3034 if (s == NULL)
3035 fatal (_("bad format for %s"), "--add-section");
3036
3037 size = get_file_size (s + 1);
3038 if (size < 1)
3039 {
3040 status = 1;
3041 break;
3042 }
3043
3044 pa = xmalloc (sizeof (struct section_add));
3045
3046 len = s - optarg;
3047 name = xmalloc (len + 1);
3048 strncpy (name, optarg, len);
3049 name[len] = '\0';
3050 pa->name = name;
3051
3052 pa->filename = s + 1;
3053 pa->size = size;
3054 pa->contents = xmalloc (size);
3055
3056 f = fopen (pa->filename, FOPEN_RB);
3057
3058 if (f == NULL)
3059 fatal (_("cannot open: %s: %s"),
3060 pa->filename, strerror (errno));
3061
3062 if (fread (pa->contents, 1, pa->size, f) == 0
3063 || ferror (f))
3064 fatal (_("%s: fread failed"), pa->filename);
3065
3066 fclose (f);
3067
3068 pa->next = add_sections;
3069 add_sections = pa;
3070 }
3071 break;
3072
3073 case OPTION_CHANGE_START:
3074 change_start = parse_vma (optarg, "--change-start");
3075 break;
3076
3077 case OPTION_CHANGE_SECTION_ADDRESS:
3078 case OPTION_CHANGE_SECTION_LMA:
3079 case OPTION_CHANGE_SECTION_VMA:
3080 {
3081 const char *s;
3082 int len;
3083 char *name;
3084 char *option = NULL;
3085 bfd_vma val;
3086 enum change_action what = CHANGE_IGNORE;
3087
3088 switch (c)
3089 {
3090 case OPTION_CHANGE_SECTION_ADDRESS:
3091 option = "--change-section-address";
3092 break;
3093 case OPTION_CHANGE_SECTION_LMA:
3094 option = "--change-section-lma";
3095 break;
3096 case OPTION_CHANGE_SECTION_VMA:
3097 option = "--change-section-vma";
3098 break;
3099 }
3100
3101 s = strchr (optarg, '=');
3102 if (s == NULL)
3103 {
3104 s = strchr (optarg, '+');
3105 if (s == NULL)
3106 {
3107 s = strchr (optarg, '-');
3108 if (s == NULL)
3109 fatal (_("bad format for %s"), option);
3110 }
3111 }
3112
3113 len = s - optarg;
3114 name = xmalloc (len + 1);
3115 strncpy (name, optarg, len);
3116 name[len] = '\0';
3117
3118 p = find_section_list (name, TRUE);
3119
3120 val = parse_vma (s + 1, option);
3121
3122 switch (*s)
3123 {
3124 case '=': what = CHANGE_SET; break;
3125 case '-': val = - val; /* Drop through. */
3126 case '+': what = CHANGE_MODIFY; break;
3127 }
3128
3129 switch (c)
3130 {
3131 case OPTION_CHANGE_SECTION_ADDRESS:
3132 p->change_vma = what;
3133 p->vma_val = val;
3134 /* Drop through. */
3135
3136 case OPTION_CHANGE_SECTION_LMA:
3137 p->change_lma = what;
3138 p->lma_val = val;
3139 break;
3140
3141 case OPTION_CHANGE_SECTION_VMA:
3142 p->change_vma = what;
3143 p->vma_val = val;
3144 break;
3145 }
3146 }
3147 break;
3148
3149 case OPTION_CHANGE_ADDRESSES:
3150 change_section_address = parse_vma (optarg, "--change-addresses");
3151 change_start = change_section_address;
3152 break;
3153
3154 case OPTION_CHANGE_WARNINGS:
3155 change_warn = TRUE;
3156 break;
3157
3158 case OPTION_CHANGE_LEADING_CHAR:
3159 change_leading_char = TRUE;
3160 break;
3161
3162 case OPTION_DEBUGGING:
3163 convert_debugging = TRUE;
3164 break;
3165
3166 case OPTION_GAP_FILL:
3167 {
3168 bfd_vma gap_fill_vma;
3169
3170 gap_fill_vma = parse_vma (optarg, "--gap-fill");
3171 gap_fill = (bfd_byte) gap_fill_vma;
3172 if ((bfd_vma) gap_fill != gap_fill_vma)
3173 {
3174 char buff[20];
3175
3176 sprintf_vma (buff, gap_fill_vma);
3177
3178 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3179 buff, gap_fill);
3180 }
3181 gap_fill_set = TRUE;
3182 }
3183 break;
3184
3185 case OPTION_NO_CHANGE_WARNINGS:
3186 change_warn = FALSE;
3187 break;
3188
3189 case OPTION_PAD_TO:
3190 pad_to = parse_vma (optarg, "--pad-to");
3191 pad_to_set = TRUE;
3192 break;
3193
3194 case OPTION_REMOVE_LEADING_CHAR:
3195 remove_leading_char = TRUE;
3196 break;
3197
3198 case OPTION_REDEFINE_SYM:
3199 {
3200 /* Push this redefinition onto redefine_symbol_list. */
3201
3202 int len;
3203 const char *s;
3204 const char *nextarg;
3205 char *source, *target;
3206
3207 s = strchr (optarg, '=');
3208 if (s == NULL)
3209 fatal (_("bad format for %s"), "--redefine-sym");
3210
3211 len = s - optarg;
3212 source = xmalloc (len + 1);
3213 strncpy (source, optarg, len);
3214 source[len] = '\0';
3215
3216 nextarg = s + 1;
3217 len = strlen (nextarg);
3218 target = xmalloc (len + 1);
3219 strcpy (target, nextarg);
3220
3221 redefine_list_append ("--redefine-sym", source, target);
3222
3223 free (source);
3224 free (target);
3225 }
3226 break;
3227
3228 case OPTION_REDEFINE_SYMS:
3229 add_redefine_syms_file (optarg);
3230 break;
3231
3232 case OPTION_SET_SECTION_FLAGS:
3233 {
3234 const char *s;
3235 int len;
3236 char *name;
3237
3238 s = strchr (optarg, '=');
3239 if (s == NULL)
3240 fatal (_("bad format for %s"), "--set-section-flags");
3241
3242 len = s - optarg;
3243 name = xmalloc (len + 1);
3244 strncpy (name, optarg, len);
3245 name[len] = '\0';
3246
3247 p = find_section_list (name, TRUE);
3248
3249 p->set_flags = TRUE;
3250 p->flags = parse_flags (s + 1);
3251 }
3252 break;
3253
3254 case OPTION_RENAME_SECTION:
3255 {
3256 flagword flags;
3257 const char *eq, *fl;
3258 char *old_name;
3259 char *new_name;
3260 unsigned int len;
3261
3262 eq = strchr (optarg, '=');
3263 if (eq == NULL)
3264 fatal (_("bad format for %s"), "--rename-section");
3265
3266 len = eq - optarg;
3267 if (len == 0)
3268 fatal (_("bad format for %s"), "--rename-section");
3269
3270 old_name = xmalloc (len + 1);
3271 strncpy (old_name, optarg, len);
3272 old_name[len] = 0;
3273
3274 eq++;
3275 fl = strchr (eq, ',');
3276 if (fl)
3277 {
3278 flags = parse_flags (fl + 1);
3279 len = fl - eq;
3280 }
3281 else
3282 {
3283 flags = -1;
3284 len = strlen (eq);
3285 }
3286
3287 if (len == 0)
3288 fatal (_("bad format for %s"), "--rename-section");
3289
3290 new_name = xmalloc (len + 1);
3291 strncpy (new_name, eq, len);
3292 new_name[len] = 0;
3293
3294 add_section_rename (old_name, new_name, flags);
3295 }
3296 break;
3297
3298 case OPTION_SET_START:
3299 set_start = parse_vma (optarg, "--set-start");
3300 set_start_set = TRUE;
3301 break;
3302
3303 case OPTION_SREC_LEN:
3304 Chunk = parse_vma (optarg, "--srec-len");
3305 break;
3306
3307 case OPTION_SREC_FORCES3:
3308 S3Forced = TRUE;
3309 break;
3310
3311 case OPTION_STRIP_SYMBOLS:
3312 add_specific_symbols (optarg, strip_specific_htab);
3313 break;
3314
3315 case OPTION_STRIP_UNNEEDED_SYMBOLS:
3316 add_specific_symbols (optarg, strip_unneeded_htab);
3317 break;
3318
3319 case OPTION_KEEP_SYMBOLS:
3320 add_specific_symbols (optarg, keep_specific_htab);
3321 break;
3322
3323 case OPTION_LOCALIZE_HIDDEN:
3324 localize_hidden = TRUE;
3325 break;
3326
3327 case OPTION_LOCALIZE_SYMBOLS:
3328 add_specific_symbols (optarg, localize_specific_htab);
3329 break;
3330
3331 case OPTION_GLOBALIZE_SYMBOLS:
3332 add_specific_symbols (optarg, globalize_specific_htab);
3333 break;
3334
3335 case OPTION_KEEPGLOBAL_SYMBOLS:
3336 add_specific_symbols (optarg, keepglobal_specific_htab);
3337 break;
3338
3339 case OPTION_WEAKEN_SYMBOLS:
3340 add_specific_symbols (optarg, weaken_specific_htab);
3341 break;
3342
3343 case OPTION_ALT_MACH_CODE:
3344 use_alt_mach_code = strtoul (optarg, NULL, 0);
3345 if (use_alt_mach_code == 0)
3346 fatal (_("unable to parse alternative machine code"));
3347 break;
3348
3349 case OPTION_PREFIX_SYMBOLS:
3350 prefix_symbols_string = optarg;
3351 break;
3352
3353 case OPTION_PREFIX_SECTIONS:
3354 prefix_sections_string = optarg;
3355 break;
3356
3357 case OPTION_PREFIX_ALLOC_SECTIONS:
3358 prefix_alloc_sections_string = optarg;
3359 break;
3360
3361 case OPTION_READONLY_TEXT:
3362 bfd_flags_to_set |= WP_TEXT;
3363 bfd_flags_to_clear &= ~WP_TEXT;
3364 break;
3365
3366 case OPTION_WRITABLE_TEXT:
3367 bfd_flags_to_clear |= WP_TEXT;
3368 bfd_flags_to_set &= ~WP_TEXT;
3369 break;
3370
3371 case OPTION_PURE:
3372 bfd_flags_to_set |= D_PAGED;
3373 bfd_flags_to_clear &= ~D_PAGED;
3374 break;
3375
3376 case OPTION_IMPURE:
3377 bfd_flags_to_clear |= D_PAGED;
3378 bfd_flags_to_set &= ~D_PAGED;
3379 break;
3380
3381 case OPTION_EXTRACT_SYMBOL:
3382 extract_symbol = TRUE;
3383 break;
3384
3385 case OPTION_REVERSE_BYTES:
3386 {
3387 int prev = reverse_bytes;
3388
3389 reverse_bytes = atoi (optarg);
3390 if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3391 fatal (_("number of bytes to reverse must be positive and even"));
3392
3393 if (prev && prev != reverse_bytes)
3394 non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3395 prev);
3396 break;
3397 }
3398
3399 case 0:
3400 /* We've been given a long option. */
3401 break;
3402
3403 case 'H':
3404 case 'h':
3405 copy_usage (stdout, 0);
3406
3407 default:
3408 copy_usage (stderr, 1);
3409 }
3410 }
3411
3412 if (formats_info)
3413 {
3414 display_info ();
3415 return 0;
3416 }
3417
3418 if (show_version)
3419 print_version ("objcopy");
3420
3421 if (copy_byte >= interleave)
3422 fatal (_("byte number must be less than interleave"));
3423
3424 if (optind == argc || optind + 2 < argc)
3425 copy_usage (stderr, 1);
3426
3427 input_filename = argv[optind];
3428 if (optind + 1 < argc)
3429 output_filename = argv[optind + 1];
3430
3431 /* Default is to strip no symbols. */
3432 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3433 strip_symbols = STRIP_NONE;
3434
3435 if (output_target == NULL)
3436 output_target = input_target;
3437
3438 if (binary_architecture != NULL)
3439 {
3440 if (input_target && strcmp (input_target, "binary") == 0)
3441 {
3442 const bfd_arch_info_type * temp_arch_info;
3443
3444 temp_arch_info = bfd_scan_arch (binary_architecture);
3445
3446 if (temp_arch_info != NULL)
3447 {
3448 bfd_external_binary_architecture = temp_arch_info->arch;
3449 bfd_external_machine = temp_arch_info->mach;
3450 }
3451 else
3452 fatal (_("architecture %s unknown"), binary_architecture);
3453 }
3454 else
3455 {
3456 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
3457 non_fatal (_(" Argument %s ignored"), binary_architecture);
3458 }
3459 }
3460
3461 if (preserve_dates)
3462 if (stat (input_filename, & statbuf) < 0)
3463 fatal (_("warning: could not locate '%s'. System error message: %s"),
3464 input_filename, strerror (errno));
3465
3466 /* If there is no destination file, or the source and destination files
3467 are the same, then create a temp and rename the result into the input. */
3468 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
3469 tmpname = make_tempname (input_filename);
3470 else
3471 tmpname = output_filename;
3472
3473 if (tmpname == NULL)
3474 fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3475 input_filename, strerror (errno));
3476
3477 copy_file (input_filename, tmpname, input_target, output_target);
3478 if (status == 0)
3479 {
3480 if (preserve_dates)
3481 set_times (tmpname, &statbuf);
3482 if (tmpname != output_filename)
3483 smart_rename (tmpname, input_filename, preserve_dates);
3484 }
3485 else
3486 unlink_if_ordinary (tmpname);
3487
3488 if (change_warn)
3489 {
3490 for (p = change_sections; p != NULL; p = p->next)
3491 {
3492 if (! p->used)
3493 {
3494 if (p->change_vma != CHANGE_IGNORE)
3495 {
3496 char buff [20];
3497
3498 sprintf_vma (buff, p->vma_val);
3499
3500 /* xgettext:c-format */
3501 non_fatal (_("%s %s%c0x%s never used"),
3502 "--change-section-vma",
3503 p->name,
3504 p->change_vma == CHANGE_SET ? '=' : '+',
3505 buff);
3506 }
3507
3508 if (p->change_lma != CHANGE_IGNORE)
3509 {
3510 char buff [20];
3511
3512 sprintf_vma (buff, p->lma_val);
3513
3514 /* xgettext:c-format */
3515 non_fatal (_("%s %s%c0x%s never used"),
3516 "--change-section-lma",
3517 p->name,
3518 p->change_lma == CHANGE_SET ? '=' : '+',
3519 buff);
3520 }
3521 }
3522 }
3523 }
3524
3525 return 0;
3526 }
3527
3528 int
3529 main (int argc, char *argv[])
3530 {
3531 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3532 setlocale (LC_MESSAGES, "");
3533 #endif
3534 #if defined (HAVE_SETLOCALE)
3535 setlocale (LC_CTYPE, "");
3536 #endif
3537 bindtextdomain (PACKAGE, LOCALEDIR);
3538 textdomain (PACKAGE);
3539
3540 program_name = argv[0];
3541 xmalloc_set_program_name (program_name);
3542
3543 START_PROGRESS (program_name, 0);
3544
3545 expandargv (&argc, &argv);
3546
3547 strip_symbols = STRIP_UNDEF;
3548 discard_locals = LOCALS_UNDEF;
3549
3550 bfd_init ();
3551 set_default_bfd_target ();
3552
3553 if (is_strip < 0)
3554 {
3555 int i = strlen (program_name);
3556 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
3557 /* Drop the .exe suffix, if any. */
3558 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3559 {
3560 i -= 4;
3561 program_name[i] = '\0';
3562 }
3563 #endif
3564 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
3565 }
3566
3567 create_symbol_htabs ();
3568
3569 if (is_strip)
3570 strip_main (argc, argv);
3571 else
3572 copy_main (argc, argv);
3573
3574 END_PROGRESS (program_name);
3575
3576 return status;
3577 }
This page took 0.158529 seconds and 5 git commands to generate.