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