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