ac60cb1e40ac256dbdf85353076149ba39031965
[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
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 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
1088 Adjust *SIZE. */
1089
1090 static void
1091 filter_bytes (char *memhunk, bfd_size_type *size)
1092 {
1093 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
1094
1095 for (; from < end; from += interleave)
1096 *to++ = *from;
1097
1098 if (*size % interleave > (bfd_size_type) copy_byte)
1099 *size = (*size / interleave) + 1;
1100 else
1101 *size /= interleave;
1102 }
1103
1104 /* Copy object file IBFD onto OBFD. */
1105
1106 static void
1107 copy_object (bfd *ibfd, bfd *obfd)
1108 {
1109 bfd_vma start;
1110 long symcount;
1111 asection **osections = NULL;
1112 asection *gnu_debuglink_section = NULL;
1113 bfd_size_type *gaps = NULL;
1114 bfd_size_type max_gap = 0;
1115 long symsize;
1116 void *dhandle;
1117 enum bfd_architecture iarch;
1118 unsigned int imach;
1119
1120 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1121 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1122 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1123 {
1124 fatal (_("Unable to change endianness of input file(s)"));
1125 return;
1126 }
1127
1128 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1129 RETURN_NONFATAL (bfd_get_filename (obfd));
1130
1131 if (verbose)
1132 printf (_("copy from %s(%s) to %s(%s)\n"),
1133 bfd_get_filename (ibfd), bfd_get_target (ibfd),
1134 bfd_get_filename (obfd), bfd_get_target (obfd));
1135
1136 if (set_start_set)
1137 start = set_start;
1138 else
1139 start = bfd_get_start_address (ibfd);
1140 start += change_start;
1141
1142 /* Neither the start address nor the flags
1143 need to be set for a core file. */
1144 if (bfd_get_format (obfd) != bfd_core)
1145 {
1146 flagword flags;
1147
1148 flags = bfd_get_file_flags (ibfd);
1149 flags |= bfd_flags_to_set;
1150 flags &= ~bfd_flags_to_clear;
1151 flags &= bfd_applicable_file_flags (obfd);
1152
1153 if (!bfd_set_start_address (obfd, start)
1154 || !bfd_set_file_flags (obfd, flags))
1155 RETURN_NONFATAL (bfd_get_filename (ibfd));
1156 }
1157
1158 /* Copy architecture of input file to output file. */
1159 iarch = bfd_get_arch (ibfd);
1160 imach = bfd_get_mach (ibfd);
1161 if (!bfd_set_arch_mach (obfd, iarch, imach)
1162 && (ibfd->target_defaulted
1163 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1164 {
1165 if (bfd_get_arch (ibfd) == bfd_arch_unknown)
1166 fatal (_("Unable to recognise the format of the input file %s"),
1167 bfd_get_filename (ibfd));
1168 else
1169 {
1170 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1171 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1172 bfd_get_mach (ibfd)));
1173 status = 1;
1174 return;
1175 }
1176 }
1177
1178 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1179 RETURN_NONFATAL (bfd_get_filename (ibfd));
1180
1181 if (isympp)
1182 free (isympp);
1183
1184 if (osympp != isympp)
1185 free (osympp);
1186
1187 /* BFD mandates that all output sections be created and sizes set before
1188 any output is done. Thus, we traverse all sections multiple times. */
1189 bfd_map_over_sections (ibfd, setup_section, obfd);
1190
1191 if (add_sections != NULL)
1192 {
1193 struct section_add *padd;
1194 struct section_list *pset;
1195
1196 for (padd = add_sections; padd != NULL; padd = padd->next)
1197 {
1198 flagword flags;
1199
1200 padd->section = bfd_make_section (obfd, padd->name);
1201 if (padd->section == NULL)
1202 {
1203 non_fatal (_("can't create section `%s': %s"),
1204 padd->name, bfd_errmsg (bfd_get_error ()));
1205 status = 1;
1206 return;
1207 }
1208
1209 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1210 RETURN_NONFATAL (bfd_get_filename (obfd));
1211
1212 pset = find_section_list (padd->name, FALSE);
1213 if (pset != NULL)
1214 pset->used = TRUE;
1215
1216 if (pset != NULL && pset->set_flags)
1217 flags = pset->flags | SEC_HAS_CONTENTS;
1218 else
1219 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1220
1221 if (! bfd_set_section_flags (obfd, padd->section, flags))
1222 RETURN_NONFATAL (bfd_get_filename (obfd));
1223
1224 if (pset != NULL)
1225 {
1226 if (pset->change_vma != CHANGE_IGNORE)
1227 if (! bfd_set_section_vma (obfd, padd->section,
1228 pset->vma_val))
1229 RETURN_NONFATAL (bfd_get_filename (obfd));
1230
1231 if (pset->change_lma != CHANGE_IGNORE)
1232 {
1233 padd->section->lma = pset->lma_val;
1234
1235 if (! bfd_set_section_alignment
1236 (obfd, padd->section,
1237 bfd_section_alignment (obfd, padd->section)))
1238 RETURN_NONFATAL (bfd_get_filename (obfd));
1239 }
1240 }
1241 }
1242 }
1243
1244 if (gnu_debuglink_filename != NULL)
1245 {
1246 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1247 (obfd, gnu_debuglink_filename);
1248
1249 if (gnu_debuglink_section == NULL)
1250 RETURN_NONFATAL (gnu_debuglink_filename);
1251 }
1252
1253 if (gap_fill_set || pad_to_set)
1254 {
1255 asection **set;
1256 unsigned int c, i;
1257
1258 /* We must fill in gaps between the sections and/or we must pad
1259 the last section to a specified address. We do this by
1260 grabbing a list of the sections, sorting them by VMA, and
1261 increasing the section sizes as required to fill the gaps.
1262 We write out the gap contents below. */
1263
1264 c = bfd_count_sections (obfd);
1265 osections = xmalloc (c * sizeof (asection *));
1266 set = osections;
1267 bfd_map_over_sections (obfd, get_sections, &set);
1268
1269 qsort (osections, c, sizeof (asection *), compare_section_lma);
1270
1271 gaps = xmalloc (c * sizeof (bfd_size_type));
1272 memset (gaps, 0, c * sizeof (bfd_size_type));
1273
1274 if (gap_fill_set)
1275 {
1276 for (i = 0; i < c - 1; i++)
1277 {
1278 flagword flags;
1279 bfd_size_type size;
1280 bfd_vma gap_start, gap_stop;
1281
1282 flags = bfd_get_section_flags (obfd, osections[i]);
1283 if ((flags & SEC_HAS_CONTENTS) == 0
1284 || (flags & SEC_LOAD) == 0)
1285 continue;
1286
1287 size = bfd_section_size (obfd, osections[i]);
1288 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1289 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1290 if (gap_start < gap_stop)
1291 {
1292 if (! bfd_set_section_size (obfd, osections[i],
1293 size + (gap_stop - gap_start)))
1294 {
1295 non_fatal (_("Can't fill gap after %s: %s"),
1296 bfd_get_section_name (obfd, osections[i]),
1297 bfd_errmsg (bfd_get_error ()));
1298 status = 1;
1299 break;
1300 }
1301 gaps[i] = gap_stop - gap_start;
1302 if (max_gap < gap_stop - gap_start)
1303 max_gap = gap_stop - gap_start;
1304 }
1305 }
1306 }
1307
1308 if (pad_to_set)
1309 {
1310 bfd_vma lma;
1311 bfd_size_type size;
1312
1313 lma = bfd_section_lma (obfd, osections[c - 1]);
1314 size = bfd_section_size (obfd, osections[c - 1]);
1315 if (lma + size < pad_to)
1316 {
1317 if (! bfd_set_section_size (obfd, osections[c - 1],
1318 pad_to - lma))
1319 {
1320 non_fatal (_("Can't add padding to %s: %s"),
1321 bfd_get_section_name (obfd, osections[c - 1]),
1322 bfd_errmsg (bfd_get_error ()));
1323 status = 1;
1324 }
1325 else
1326 {
1327 gaps[c - 1] = pad_to - (lma + size);
1328 if (max_gap < pad_to - (lma + size))
1329 max_gap = pad_to - (lma + size);
1330 }
1331 }
1332 }
1333 }
1334
1335 /* Symbol filtering must happen after the output sections
1336 have been created, but before their contents are set. */
1337 dhandle = NULL;
1338 symsize = bfd_get_symtab_upper_bound (ibfd);
1339 if (symsize < 0)
1340 RETURN_NONFATAL (bfd_get_filename (ibfd));
1341
1342 osympp = isympp = xmalloc (symsize);
1343 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1344 if (symcount < 0)
1345 RETURN_NONFATAL (bfd_get_filename (ibfd));
1346
1347 if (convert_debugging)
1348 dhandle = read_debugging_info (ibfd, isympp, symcount);
1349
1350 if (strip_symbols == STRIP_DEBUG
1351 || strip_symbols == STRIP_ALL
1352 || strip_symbols == STRIP_UNNEEDED
1353 || strip_symbols == STRIP_NONDEBUG
1354 || discard_locals != LOCALS_UNDEF
1355 || strip_specific_list != NULL
1356 || keep_specific_list != NULL
1357 || localize_specific_list != NULL
1358 || keepglobal_specific_list != NULL
1359 || weaken_specific_list != NULL
1360 || prefix_symbols_string
1361 || sections_removed
1362 || sections_copied
1363 || convert_debugging
1364 || change_leading_char
1365 || remove_leading_char
1366 || redefine_sym_list
1367 || weaken)
1368 {
1369 /* Mark symbols used in output relocations so that they
1370 are kept, even if they are local labels or static symbols.
1371
1372 Note we iterate over the input sections examining their
1373 relocations since the relocations for the output sections
1374 haven't been set yet. mark_symbols_used_in_relocations will
1375 ignore input sections which have no corresponding output
1376 section. */
1377 if (strip_symbols != STRIP_ALL)
1378 bfd_map_over_sections (ibfd,
1379 mark_symbols_used_in_relocations,
1380 isympp);
1381 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1382 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1383 }
1384
1385 if (convert_debugging && dhandle != NULL)
1386 {
1387 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1388 {
1389 status = 1;
1390 return;
1391 }
1392 }
1393
1394 bfd_set_symtab (obfd, osympp, symcount);
1395
1396 /* This has to happen after the symbol table has been set. */
1397 bfd_map_over_sections (ibfd, copy_section, obfd);
1398
1399 if (add_sections != NULL)
1400 {
1401 struct section_add *padd;
1402
1403 for (padd = add_sections; padd != NULL; padd = padd->next)
1404 {
1405 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1406 0, padd->size))
1407 RETURN_NONFATAL (bfd_get_filename (obfd));
1408 }
1409 }
1410
1411 if (gnu_debuglink_filename != NULL)
1412 {
1413 if (! bfd_fill_in_gnu_debuglink_section
1414 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1415 RETURN_NONFATAL (gnu_debuglink_filename);
1416 }
1417
1418 if (gap_fill_set || pad_to_set)
1419 {
1420 bfd_byte *buf;
1421 int c, i;
1422
1423 /* Fill in the gaps. */
1424 if (max_gap > 8192)
1425 max_gap = 8192;
1426 buf = xmalloc (max_gap);
1427 memset (buf, gap_fill, max_gap);
1428
1429 c = bfd_count_sections (obfd);
1430 for (i = 0; i < c; i++)
1431 {
1432 if (gaps[i] != 0)
1433 {
1434 bfd_size_type left;
1435 file_ptr off;
1436
1437 left = gaps[i];
1438 off = bfd_section_size (obfd, osections[i]) - left;
1439
1440 while (left > 0)
1441 {
1442 bfd_size_type now;
1443
1444 if (left > 8192)
1445 now = 8192;
1446 else
1447 now = left;
1448
1449 if (! bfd_set_section_contents (obfd, osections[i], buf,
1450 off, now))
1451 RETURN_NONFATAL (bfd_get_filename (obfd));
1452
1453 left -= now;
1454 off += now;
1455 }
1456 }
1457 }
1458 }
1459
1460 /* Allow the BFD backend to copy any private data it understands
1461 from the input BFD to the output BFD. This is done last to
1462 permit the routine to look at the filtered symbol table, which is
1463 important for the ECOFF code at least. */
1464 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1465 && strip_symbols == STRIP_NONDEBUG)
1466 /* Do not copy the private data when creating an ELF format
1467 debug info file. We do not want the program headers. */
1468 ;
1469 else if (! bfd_copy_private_bfd_data (ibfd, obfd))
1470 {
1471 non_fatal (_("%s: error copying private BFD data: %s"),
1472 bfd_get_filename (obfd),
1473 bfd_errmsg (bfd_get_error ()));
1474 status = 1;
1475 return;
1476 }
1477
1478 /* Switch to the alternate machine code. We have to do this at the
1479 very end, because we only initialize the header when we create
1480 the first section. */
1481 if (use_alt_mach_code != 0)
1482 {
1483 if (!bfd_alt_mach_code (obfd, use_alt_mach_code))
1484 non_fatal (_("unknown alternate machine code, ignored"));
1485 }
1486 }
1487
1488 #undef MKDIR
1489 #if defined (_WIN32) && !defined (__CYGWIN32__)
1490 #define MKDIR(DIR, MODE) mkdir (DIR)
1491 #else
1492 #define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1493 #endif
1494
1495 /* Read each archive element in turn from IBFD, copy the
1496 contents to temp file, and keep the temp file handle. */
1497
1498 static void
1499 copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
1500 {
1501 struct name_list
1502 {
1503 struct name_list *next;
1504 const char *name;
1505 bfd *obfd;
1506 } *list, *l;
1507 bfd **ptr = &obfd->archive_head;
1508 bfd *this_element;
1509 char *dir = make_tempname (bfd_get_filename (obfd));
1510
1511 /* Make a temp directory to hold the contents. */
1512 if (MKDIR (dir, 0700) != 0)
1513 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1514 dir, strerror (errno));
1515
1516 obfd->has_armap = ibfd->has_armap;
1517
1518 list = NULL;
1519
1520 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1521
1522 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1523 RETURN_NONFATAL (bfd_get_filename (obfd));
1524
1525 while (!status && this_element != NULL)
1526 {
1527 char *output_name;
1528 bfd *output_bfd;
1529 bfd *last_element;
1530 struct stat buf;
1531 int stat_status = 0;
1532
1533 /* Create an output file for this member. */
1534 output_name = concat (dir, "/",
1535 bfd_get_filename (this_element), (char *) 0);
1536
1537 /* If the file already exists, make another temp dir. */
1538 if (stat (output_name, &buf) >= 0)
1539 {
1540 output_name = make_tempname (output_name);
1541 if (MKDIR (output_name, 0700) != 0)
1542 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1543 output_name, strerror (errno));
1544
1545 l = xmalloc (sizeof (struct name_list));
1546 l->name = output_name;
1547 l->next = list;
1548 l->obfd = NULL;
1549 list = l;
1550 output_name = concat (output_name, "/",
1551 bfd_get_filename (this_element), (char *) 0);
1552 }
1553
1554 output_bfd = bfd_openw (output_name, output_target);
1555 if (preserve_dates)
1556 {
1557 stat_status = bfd_stat_arch_elt (this_element, &buf);
1558
1559 if (stat_status != 0)
1560 non_fatal (_("internal stat error on %s"),
1561 bfd_get_filename (this_element));
1562 }
1563
1564 l = xmalloc (sizeof (struct name_list));
1565 l->name = output_name;
1566 l->next = list;
1567 list = l;
1568
1569 if (output_bfd == NULL)
1570 RETURN_NONFATAL (output_name);
1571
1572 if (bfd_check_format (this_element, bfd_object))
1573 copy_object (this_element, output_bfd);
1574
1575 if (!bfd_close (output_bfd))
1576 {
1577 bfd_nonfatal (bfd_get_filename (output_bfd));
1578 /* Error in new object file. Don't change archive. */
1579 status = 1;
1580 }
1581
1582 if (preserve_dates && stat_status == 0)
1583 set_times (output_name, &buf);
1584
1585 /* Open the newly output file and attach to our list. */
1586 output_bfd = bfd_openr (output_name, output_target);
1587
1588 l->obfd = output_bfd;
1589
1590 *ptr = output_bfd;
1591 ptr = &output_bfd->next;
1592
1593 last_element = this_element;
1594
1595 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1596
1597 bfd_close (last_element);
1598 }
1599 *ptr = NULL;
1600
1601 if (!bfd_close (obfd))
1602 RETURN_NONFATAL (bfd_get_filename (obfd));
1603
1604 if (!bfd_close (ibfd))
1605 RETURN_NONFATAL (bfd_get_filename (ibfd));
1606
1607 /* Delete all the files that we opened. */
1608 for (l = list; l != NULL; l = l->next)
1609 {
1610 if (l->obfd == NULL)
1611 rmdir (l->name);
1612 else
1613 {
1614 bfd_close (l->obfd);
1615 unlink (l->name);
1616 }
1617 }
1618 rmdir (dir);
1619 }
1620
1621 /* The top-level control. */
1622
1623 static void
1624 copy_file (const char *input_filename, const char *output_filename,
1625 const char *input_target, const char *output_target)
1626 {
1627 bfd *ibfd;
1628 char **obj_matching;
1629 char **core_matching;
1630
1631 if (get_file_size (input_filename) < 1)
1632 {
1633 status = 1;
1634 return;
1635 }
1636
1637 /* To allow us to do "strip *" without dying on the first
1638 non-object file, failures are nonfatal. */
1639 ibfd = bfd_openr (input_filename, input_target);
1640 if (ibfd == NULL)
1641 RETURN_NONFATAL (input_filename);
1642
1643 if (bfd_check_format (ibfd, bfd_archive))
1644 {
1645 bfd *obfd;
1646
1647 /* bfd_get_target does not return the correct value until
1648 bfd_check_format succeeds. */
1649 if (output_target == NULL)
1650 output_target = bfd_get_target (ibfd);
1651
1652 obfd = bfd_openw (output_filename, output_target);
1653 if (obfd == NULL)
1654 RETURN_NONFATAL (output_filename);
1655
1656 copy_archive (ibfd, obfd, output_target);
1657 }
1658 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
1659 {
1660 bfd *obfd;
1661 do_copy:
1662 /* bfd_get_target does not return the correct value until
1663 bfd_check_format succeeds. */
1664 if (output_target == NULL)
1665 output_target = bfd_get_target (ibfd);
1666
1667 obfd = bfd_openw (output_filename, output_target);
1668 if (obfd == NULL)
1669 RETURN_NONFATAL (output_filename);
1670
1671 copy_object (ibfd, obfd);
1672
1673 if (!bfd_close (obfd))
1674 RETURN_NONFATAL (output_filename);
1675
1676 if (!bfd_close (ibfd))
1677 RETURN_NONFATAL (input_filename);
1678 }
1679 else
1680 {
1681 bfd_error_type obj_error = bfd_get_error ();
1682 bfd_error_type core_error;
1683
1684 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
1685 {
1686 /* This probably can't happen.. */
1687 if (obj_error == bfd_error_file_ambiguously_recognized)
1688 free (obj_matching);
1689 goto do_copy;
1690 }
1691
1692 core_error = bfd_get_error ();
1693 /* Report the object error in preference to the core error. */
1694 if (obj_error != core_error)
1695 bfd_set_error (obj_error);
1696
1697 bfd_nonfatal (input_filename);
1698
1699 if (obj_error == bfd_error_file_ambiguously_recognized)
1700 {
1701 list_matching_formats (obj_matching);
1702 free (obj_matching);
1703 }
1704 if (core_error == bfd_error_file_ambiguously_recognized)
1705 {
1706 list_matching_formats (core_matching);
1707 free (core_matching);
1708 }
1709
1710 status = 1;
1711 }
1712 }
1713
1714 /* Add a name to the section renaming list. */
1715
1716 static void
1717 add_section_rename (const char * old_name, const char * new_name,
1718 flagword flags)
1719 {
1720 section_rename * rename;
1721
1722 /* Check for conflicts first. */
1723 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1724 if (strcmp (rename->old_name, old_name) == 0)
1725 {
1726 /* Silently ignore duplicate definitions. */
1727 if (strcmp (rename->new_name, new_name) == 0
1728 && rename->flags == flags)
1729 return;
1730
1731 fatal (_("Multiple renames of section %s"), old_name);
1732 }
1733
1734 rename = xmalloc (sizeof (* rename));
1735
1736 rename->old_name = old_name;
1737 rename->new_name = new_name;
1738 rename->flags = flags;
1739 rename->next = section_rename_list;
1740
1741 section_rename_list = rename;
1742 }
1743
1744 /* Check the section rename list for a new name of the input section
1745 ISECTION. Return the new name if one is found.
1746 Also set RETURNED_FLAGS to the flags to be used for this section. */
1747
1748 static const char *
1749 find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
1750 flagword * returned_flags)
1751 {
1752 const char * old_name = bfd_section_name (ibfd, isection);
1753 section_rename * rename;
1754
1755 /* Default to using the flags of the input section. */
1756 * returned_flags = bfd_get_section_flags (ibfd, isection);
1757
1758 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1759 if (strcmp (rename->old_name, old_name) == 0)
1760 {
1761 if (rename->flags != (flagword) -1)
1762 * returned_flags = rename->flags;
1763
1764 return rename->new_name;
1765 }
1766
1767 return old_name;
1768 }
1769
1770 /* Create a section in OBFD with the same
1771 name and attributes as ISECTION in IBFD. */
1772
1773 static void
1774 setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1775 {
1776 bfd *obfd = obfdarg;
1777 struct section_list *p;
1778 sec_ptr osection;
1779 bfd_size_type size;
1780 bfd_vma vma;
1781 bfd_vma lma;
1782 flagword flags;
1783 const char *err;
1784 const char * name;
1785 char *prefix = NULL;
1786
1787 if (is_strip_section (ibfd, isection))
1788 return;
1789
1790 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
1791 if (p != NULL)
1792 p->used = TRUE;
1793
1794 /* Get the, possibly new, name of the output section. */
1795 name = find_section_rename (ibfd, isection, & flags);
1796
1797 /* Prefix sections. */
1798 if ((prefix_alloc_sections_string)
1799 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
1800 prefix = prefix_alloc_sections_string;
1801 else if (prefix_sections_string)
1802 prefix = prefix_sections_string;
1803
1804 if (prefix)
1805 {
1806 char *n;
1807
1808 n = xmalloc (strlen (prefix) + strlen (name) + 1);
1809 strcpy (n, prefix);
1810 strcat (n, name);
1811 name = n;
1812 }
1813
1814 osection = bfd_make_section_anyway (obfd, name);
1815
1816 if (osection == NULL)
1817 {
1818 err = _("making");
1819 goto loser;
1820 }
1821
1822 size = bfd_section_size (ibfd, isection);
1823 if (copy_byte >= 0)
1824 size = (size + interleave - 1) / interleave;
1825 if (! bfd_set_section_size (obfd, osection, size))
1826 {
1827 err = _("size");
1828 goto loser;
1829 }
1830
1831 vma = bfd_section_vma (ibfd, isection);
1832 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1833 vma += p->vma_val;
1834 else if (p != NULL && p->change_vma == CHANGE_SET)
1835 vma = p->vma_val;
1836 else
1837 vma += change_section_address;
1838
1839 if (! bfd_set_section_vma (obfd, osection, vma))
1840 {
1841 err = _("vma");
1842 goto loser;
1843 }
1844
1845 lma = isection->lma;
1846 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1847 {
1848 if (p->change_lma == CHANGE_MODIFY)
1849 lma += p->lma_val;
1850 else if (p->change_lma == CHANGE_SET)
1851 lma = p->lma_val;
1852 else
1853 abort ();
1854 }
1855 else
1856 lma += change_section_address;
1857
1858 osection->lma = lma;
1859
1860 /* FIXME: This is probably not enough. If we change the LMA we
1861 may have to recompute the header for the file as well. */
1862 if (!bfd_set_section_alignment (obfd,
1863 osection,
1864 bfd_section_alignment (ibfd, isection)))
1865 {
1866 err = _("alignment");
1867 goto loser;
1868 }
1869
1870 if (p != NULL && p->set_flags)
1871 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
1872 if (!bfd_set_section_flags (obfd, osection, flags))
1873 {
1874 err = _("flags");
1875 goto loser;
1876 }
1877
1878 /* Copy merge entity size. */
1879 osection->entsize = isection->entsize;
1880
1881 /* This used to be mangle_section; we do here to avoid using
1882 bfd_get_section_by_name since some formats allow multiple
1883 sections with the same name. */
1884 isection->output_section = osection;
1885 isection->output_offset = 0;
1886
1887 /* Allow the BFD backend to copy any private data it understands
1888 from the input section to the output section. */
1889 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1890 && strip_symbols == STRIP_NONDEBUG)
1891 /* Do not copy the private data when creating an ELF format
1892 debug info file. We do not want the program headers. */
1893 ;
1894 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1895 {
1896 err = _("private data");
1897 goto loser;
1898 }
1899
1900 /* All went well. */
1901 return;
1902
1903 loser:
1904 non_fatal (_("%s: section `%s': error in %s: %s"),
1905 bfd_get_filename (ibfd),
1906 bfd_section_name (ibfd, isection),
1907 err, bfd_errmsg (bfd_get_error ()));
1908 status = 1;
1909 }
1910
1911 /* Copy the data of input section ISECTION of IBFD
1912 to an output section with the same name in OBFD.
1913 If stripping then don't copy any relocation info. */
1914
1915 static void
1916 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1917 {
1918 bfd *obfd = obfdarg;
1919 struct section_list *p;
1920 arelent **relpp;
1921 long relcount;
1922 sec_ptr osection;
1923 bfd_size_type size;
1924 long relsize;
1925 flagword flags;
1926
1927 /* If we have already failed earlier on,
1928 do not keep on generating complaints now. */
1929 if (status != 0)
1930 return;
1931
1932 if (is_strip_section (ibfd, isection))
1933 return;
1934
1935 flags = bfd_get_section_flags (ibfd, isection);
1936 if ((flags & SEC_GROUP) != 0)
1937 return;
1938
1939 osection = isection->output_section;
1940 size = bfd_get_section_size_before_reloc (isection);
1941
1942 if (size == 0 || osection == 0)
1943 return;
1944
1945 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
1946
1947 /* Core files do not need to be relocated. */
1948 if (bfd_get_format (obfd) == bfd_core)
1949 relsize = 0;
1950 else
1951 {
1952 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1953
1954 if (relsize < 0)
1955 {
1956 /* Do not complain if the target does not support relocations. */
1957 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
1958 relsize = 0;
1959 else
1960 RETURN_NONFATAL (bfd_get_filename (ibfd));
1961 }
1962 }
1963
1964 if (relsize == 0)
1965 bfd_set_reloc (obfd, osection, NULL, 0);
1966 else
1967 {
1968 relpp = xmalloc (relsize);
1969 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1970 if (relcount < 0)
1971 RETURN_NONFATAL (bfd_get_filename (ibfd));
1972
1973 if (strip_symbols == STRIP_ALL)
1974 {
1975 /* Remove relocations which are not in
1976 keep_strip_specific_list. */
1977 arelent **temp_relpp;
1978 long temp_relcount = 0;
1979 long i;
1980
1981 temp_relpp = xmalloc (relsize);
1982 for (i = 0; i < relcount; i++)
1983 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
1984 keep_specific_list))
1985 temp_relpp [temp_relcount++] = relpp [i];
1986 relcount = temp_relcount;
1987 free (relpp);
1988 relpp = temp_relpp;
1989 }
1990
1991 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
1992 }
1993
1994 isection->_cooked_size = isection->_raw_size;
1995 isection->reloc_done = TRUE;
1996
1997 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
1998 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
1999 {
2000 void *memhunk = xmalloc (size);
2001
2002 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2003 RETURN_NONFATAL (bfd_get_filename (ibfd));
2004
2005 if (copy_byte >= 0)
2006 filter_bytes (memhunk, &size);
2007
2008 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2009 RETURN_NONFATAL (bfd_get_filename (obfd));
2010
2011 free (memhunk);
2012 }
2013 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2014 {
2015 void *memhunk = xmalloc (size);
2016
2017 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2018 flag--they can just remove the section entirely and add it
2019 back again. However, we do permit them to turn on the
2020 SEC_HAS_CONTENTS flag, and take it to mean that the section
2021 contents should be zeroed out. */
2022
2023 memset (memhunk, 0, size);
2024 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2025 RETURN_NONFATAL (bfd_get_filename (obfd));
2026 free (memhunk);
2027 }
2028 }
2029
2030 /* Get all the sections. This is used when --gap-fill or --pad-to is
2031 used. */
2032
2033 static void
2034 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2035 {
2036 asection ***secppp = secppparg;
2037
2038 **secppp = osection;
2039 ++(*secppp);
2040 }
2041
2042 /* Sort sections by VMA. This is called via qsort, and is used when
2043 --gap-fill or --pad-to is used. We force non loadable or empty
2044 sections to the front, where they are easier to ignore. */
2045
2046 static int
2047 compare_section_lma (const void *arg1, const void *arg2)
2048 {
2049 const asection *const *sec1 = arg1;
2050 const asection *const *sec2 = arg2;
2051 flagword flags1, flags2;
2052
2053 /* Sort non loadable sections to the front. */
2054 flags1 = (*sec1)->flags;
2055 flags2 = (*sec2)->flags;
2056 if ((flags1 & SEC_HAS_CONTENTS) == 0
2057 || (flags1 & SEC_LOAD) == 0)
2058 {
2059 if ((flags2 & SEC_HAS_CONTENTS) != 0
2060 && (flags2 & SEC_LOAD) != 0)
2061 return -1;
2062 }
2063 else
2064 {
2065 if ((flags2 & SEC_HAS_CONTENTS) == 0
2066 || (flags2 & SEC_LOAD) == 0)
2067 return 1;
2068 }
2069
2070 /* Sort sections by LMA. */
2071 if ((*sec1)->lma > (*sec2)->lma)
2072 return 1;
2073 else if ((*sec1)->lma < (*sec2)->lma)
2074 return -1;
2075
2076 /* Sort sections with the same LMA by size. */
2077 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
2078 return 1;
2079 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
2080 return -1;
2081
2082 return 0;
2083 }
2084
2085 /* Mark all the symbols which will be used in output relocations with
2086 the BSF_KEEP flag so that those symbols will not be stripped.
2087
2088 Ignore relocations which will not appear in the output file. */
2089
2090 static void
2091 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2092 {
2093 asymbol **symbols = symbolsarg;
2094 long relsize;
2095 arelent **relpp;
2096 long relcount, i;
2097
2098 /* Ignore an input section with no corresponding output section. */
2099 if (isection->output_section == NULL)
2100 return;
2101
2102 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2103 if (relsize < 0)
2104 {
2105 /* Do not complain if the target does not support relocations. */
2106 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2107 return;
2108 bfd_fatal (bfd_get_filename (ibfd));
2109 }
2110
2111 if (relsize == 0)
2112 return;
2113
2114 relpp = xmalloc (relsize);
2115 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2116 if (relcount < 0)
2117 bfd_fatal (bfd_get_filename (ibfd));
2118
2119 /* Examine each symbol used in a relocation. If it's not one of the
2120 special bfd section symbols, then mark it with BSF_KEEP. */
2121 for (i = 0; i < relcount; i++)
2122 {
2123 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2124 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2125 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2126 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2127 }
2128
2129 if (relpp != NULL)
2130 free (relpp);
2131 }
2132
2133 /* Write out debugging information. */
2134
2135 static bfd_boolean
2136 write_debugging_info (bfd *obfd, void *dhandle,
2137 long *symcountp ATTRIBUTE_UNUSED,
2138 asymbol ***symppp ATTRIBUTE_UNUSED)
2139 {
2140 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2141 return write_ieee_debugging_info (obfd, dhandle);
2142
2143 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2144 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2145 {
2146 bfd_byte *syms, *strings;
2147 bfd_size_type symsize, stringsize;
2148 asection *stabsec, *stabstrsec;
2149
2150 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2151 &symsize, &strings,
2152 &stringsize))
2153 return FALSE;
2154
2155 stabsec = bfd_make_section (obfd, ".stab");
2156 stabstrsec = bfd_make_section (obfd, ".stabstr");
2157 if (stabsec == NULL
2158 || stabstrsec == NULL
2159 || ! bfd_set_section_size (obfd, stabsec, symsize)
2160 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2161 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2162 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
2163 || ! bfd_set_section_flags (obfd, stabsec,
2164 (SEC_HAS_CONTENTS
2165 | SEC_READONLY
2166 | SEC_DEBUGGING))
2167 || ! bfd_set_section_flags (obfd, stabstrsec,
2168 (SEC_HAS_CONTENTS
2169 | SEC_READONLY
2170 | SEC_DEBUGGING)))
2171 {
2172 non_fatal (_("%s: can't create debugging section: %s"),
2173 bfd_get_filename (obfd),
2174 bfd_errmsg (bfd_get_error ()));
2175 return FALSE;
2176 }
2177
2178 /* We can get away with setting the section contents now because
2179 the next thing the caller is going to do is copy over the
2180 real sections. We may someday have to split the contents
2181 setting out of this function. */
2182 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2183 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2184 stringsize))
2185 {
2186 non_fatal (_("%s: can't set debugging section contents: %s"),
2187 bfd_get_filename (obfd),
2188 bfd_errmsg (bfd_get_error ()));
2189 return FALSE;
2190 }
2191
2192 return TRUE;
2193 }
2194
2195 non_fatal (_("%s: don't know how to write debugging information for %s"),
2196 bfd_get_filename (obfd), bfd_get_target (obfd));
2197 return FALSE;
2198 }
2199
2200 static int
2201 strip_main (int argc, char *argv[])
2202 {
2203 char *input_target = NULL;
2204 char *output_target = NULL;
2205 bfd_boolean show_version = FALSE;
2206 bfd_boolean formats_info = FALSE;
2207 int c;
2208 int i;
2209 struct section_list *p;
2210 char *output_file = NULL;
2211
2212 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2213 strip_options, (int *) 0)) != EOF)
2214 {
2215 switch (c)
2216 {
2217 case 'I':
2218 input_target = optarg;
2219 break;
2220 case 'O':
2221 output_target = optarg;
2222 break;
2223 case 'F':
2224 input_target = output_target = optarg;
2225 break;
2226 case 'R':
2227 p = find_section_list (optarg, TRUE);
2228 p->remove = TRUE;
2229 sections_removed = TRUE;
2230 break;
2231 case 's':
2232 strip_symbols = STRIP_ALL;
2233 break;
2234 case 'S':
2235 case 'g':
2236 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2237 strip_symbols = STRIP_DEBUG;
2238 break;
2239 case OPTION_STRIP_UNNEEDED:
2240 strip_symbols = STRIP_UNNEEDED;
2241 break;
2242 case 'K':
2243 add_specific_symbol (optarg, &keep_specific_list);
2244 break;
2245 case 'N':
2246 add_specific_symbol (optarg, &strip_specific_list);
2247 break;
2248 case 'o':
2249 output_file = optarg;
2250 break;
2251 case 'p':
2252 preserve_dates = TRUE;
2253 break;
2254 case 'x':
2255 discard_locals = LOCALS_ALL;
2256 break;
2257 case 'X':
2258 discard_locals = LOCALS_START_L;
2259 break;
2260 case 'v':
2261 verbose = TRUE;
2262 break;
2263 case 'V':
2264 show_version = TRUE;
2265 break;
2266 case OPTION_FORMATS_INFO:
2267 formats_info = TRUE;
2268 break;
2269 case OPTION_ONLY_KEEP_DEBUG:
2270 strip_symbols = STRIP_NONDEBUG;
2271 break;
2272 case 0:
2273 /* We've been given a long option. */
2274 break;
2275 case 'w':
2276 wildcard = TRUE;
2277 break;
2278 case 'H':
2279 case 'h':
2280 strip_usage (stdout, 0);
2281 default:
2282 strip_usage (stderr, 1);
2283 }
2284 }
2285
2286 if (formats_info)
2287 {
2288 display_info ();
2289 return 0;
2290 }
2291
2292 if (show_version)
2293 print_version ("strip");
2294
2295 /* Default is to strip all symbols. */
2296 if (strip_symbols == STRIP_UNDEF
2297 && discard_locals == LOCALS_UNDEF
2298 && strip_specific_list == NULL)
2299 strip_symbols = STRIP_ALL;
2300
2301 if (output_target == NULL)
2302 output_target = input_target;
2303
2304 i = optind;
2305 if (i == argc
2306 || (output_file != NULL && (i + 1) < argc))
2307 strip_usage (stderr, 1);
2308
2309 for (; i < argc; i++)
2310 {
2311 int hold_status = status;
2312 struct stat statbuf;
2313 char *tmpname;
2314
2315 if (get_file_size (argv[i]) < 1)
2316 continue;
2317
2318 if (preserve_dates)
2319 /* No need to check the return value of stat().
2320 It has already been checked in get_file_size(). */
2321 stat (argv[i], &statbuf);
2322
2323 if (output_file != NULL)
2324 tmpname = output_file;
2325 else
2326 tmpname = make_tempname (argv[i]);
2327 status = 0;
2328
2329 copy_file (argv[i], tmpname, input_target, output_target);
2330 if (status == 0)
2331 {
2332 if (preserve_dates)
2333 set_times (tmpname, &statbuf);
2334 if (output_file == NULL)
2335 smart_rename (tmpname, argv[i], preserve_dates);
2336 status = hold_status;
2337 }
2338 else
2339 unlink (tmpname);
2340 if (output_file == NULL)
2341 free (tmpname);
2342 }
2343
2344 return 0;
2345 }
2346
2347 static int
2348 copy_main (int argc, char *argv[])
2349 {
2350 char * binary_architecture = NULL;
2351 char *input_filename = NULL;
2352 char *output_filename = NULL;
2353 char *input_target = NULL;
2354 char *output_target = NULL;
2355 bfd_boolean show_version = FALSE;
2356 bfd_boolean change_warn = TRUE;
2357 bfd_boolean formats_info = FALSE;
2358 int c;
2359 struct section_list *p;
2360 struct stat statbuf;
2361
2362 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2363 copy_options, (int *) 0)) != EOF)
2364 {
2365 switch (c)
2366 {
2367 case 'b':
2368 copy_byte = atoi (optarg);
2369 if (copy_byte < 0)
2370 fatal (_("byte number must be non-negative"));
2371 break;
2372
2373 case 'B':
2374 binary_architecture = optarg;
2375 break;
2376
2377 case 'i':
2378 interleave = atoi (optarg);
2379 if (interleave < 1)
2380 fatal (_("interleave must be positive"));
2381 break;
2382
2383 case 'I':
2384 case 's': /* "source" - 'I' is preferred */
2385 input_target = optarg;
2386 break;
2387
2388 case 'O':
2389 case 'd': /* "destination" - 'O' is preferred */
2390 output_target = optarg;
2391 break;
2392
2393 case 'F':
2394 input_target = output_target = optarg;
2395 break;
2396
2397 case 'j':
2398 p = find_section_list (optarg, TRUE);
2399 if (p->remove)
2400 fatal (_("%s both copied and removed"), optarg);
2401 p->copy = TRUE;
2402 sections_copied = TRUE;
2403 break;
2404
2405 case 'R':
2406 p = find_section_list (optarg, TRUE);
2407 if (p->copy)
2408 fatal (_("%s both copied and removed"), optarg);
2409 p->remove = TRUE;
2410 sections_removed = TRUE;
2411 break;
2412
2413 case 'S':
2414 strip_symbols = STRIP_ALL;
2415 break;
2416
2417 case 'g':
2418 strip_symbols = STRIP_DEBUG;
2419 break;
2420
2421 case OPTION_STRIP_UNNEEDED:
2422 strip_symbols = STRIP_UNNEEDED;
2423 break;
2424
2425 case OPTION_ONLY_KEEP_DEBUG:
2426 strip_symbols = STRIP_NONDEBUG;
2427 break;
2428
2429 case OPTION_ADD_GNU_DEBUGLINK:
2430 gnu_debuglink_filename = optarg;
2431 break;
2432
2433 case 'K':
2434 add_specific_symbol (optarg, &keep_specific_list);
2435 break;
2436
2437 case 'N':
2438 add_specific_symbol (optarg, &strip_specific_list);
2439 break;
2440
2441 case 'L':
2442 add_specific_symbol (optarg, &localize_specific_list);
2443 break;
2444
2445 case 'G':
2446 add_specific_symbol (optarg, &keepglobal_specific_list);
2447 break;
2448
2449 case 'W':
2450 add_specific_symbol (optarg, &weaken_specific_list);
2451 break;
2452
2453 case 'p':
2454 preserve_dates = TRUE;
2455 break;
2456
2457 case 'w':
2458 wildcard = TRUE;
2459 break;
2460
2461 case 'x':
2462 discard_locals = LOCALS_ALL;
2463 break;
2464
2465 case 'X':
2466 discard_locals = LOCALS_START_L;
2467 break;
2468
2469 case 'v':
2470 verbose = TRUE;
2471 break;
2472
2473 case 'V':
2474 show_version = TRUE;
2475 break;
2476
2477 case OPTION_FORMATS_INFO:
2478 formats_info = TRUE;
2479 break;
2480
2481 case OPTION_WEAKEN:
2482 weaken = TRUE;
2483 break;
2484
2485 case OPTION_ADD_SECTION:
2486 {
2487 const char *s;
2488 off_t size;
2489 struct section_add *pa;
2490 int len;
2491 char *name;
2492 FILE *f;
2493
2494 s = strchr (optarg, '=');
2495
2496 if (s == NULL)
2497 fatal (_("bad format for %s"), "--add-section");
2498
2499 size = get_file_size (s + 1);
2500 if (size < 1)
2501 break;
2502
2503 pa = xmalloc (sizeof (struct section_add));
2504
2505 len = s - optarg;
2506 name = xmalloc (len + 1);
2507 strncpy (name, optarg, len);
2508 name[len] = '\0';
2509 pa->name = name;
2510
2511 pa->filename = s + 1;
2512 pa->size = size;
2513 pa->contents = xmalloc (size);
2514
2515 f = fopen (pa->filename, FOPEN_RB);
2516
2517 if (f == NULL)
2518 fatal (_("cannot open: %s: %s"),
2519 pa->filename, strerror (errno));
2520
2521 if (fread (pa->contents, 1, pa->size, f) == 0
2522 || ferror (f))
2523 fatal (_("%s: fread failed"), pa->filename);
2524
2525 fclose (f);
2526
2527 pa->next = add_sections;
2528 add_sections = pa;
2529 }
2530 break;
2531
2532 case OPTION_CHANGE_START:
2533 change_start = parse_vma (optarg, "--change-start");
2534 break;
2535
2536 case OPTION_CHANGE_SECTION_ADDRESS:
2537 case OPTION_CHANGE_SECTION_LMA:
2538 case OPTION_CHANGE_SECTION_VMA:
2539 {
2540 const char *s;
2541 int len;
2542 char *name;
2543 char *option = NULL;
2544 bfd_vma val;
2545 enum change_action what = CHANGE_IGNORE;
2546
2547 switch (c)
2548 {
2549 case OPTION_CHANGE_SECTION_ADDRESS:
2550 option = "--change-section-address";
2551 break;
2552 case OPTION_CHANGE_SECTION_LMA:
2553 option = "--change-section-lma";
2554 break;
2555 case OPTION_CHANGE_SECTION_VMA:
2556 option = "--change-section-vma";
2557 break;
2558 }
2559
2560 s = strchr (optarg, '=');
2561 if (s == NULL)
2562 {
2563 s = strchr (optarg, '+');
2564 if (s == NULL)
2565 {
2566 s = strchr (optarg, '-');
2567 if (s == NULL)
2568 fatal (_("bad format for %s"), option);
2569 }
2570 }
2571
2572 len = s - optarg;
2573 name = xmalloc (len + 1);
2574 strncpy (name, optarg, len);
2575 name[len] = '\0';
2576
2577 p = find_section_list (name, TRUE);
2578
2579 val = parse_vma (s + 1, option);
2580
2581 switch (*s)
2582 {
2583 case '=': what = CHANGE_SET; break;
2584 case '-': val = - val; /* Drop through. */
2585 case '+': what = CHANGE_MODIFY; break;
2586 }
2587
2588 switch (c)
2589 {
2590 case OPTION_CHANGE_SECTION_ADDRESS:
2591 p->change_vma = what;
2592 p->vma_val = val;
2593 /* Drop through. */
2594
2595 case OPTION_CHANGE_SECTION_LMA:
2596 p->change_lma = what;
2597 p->lma_val = val;
2598 break;
2599
2600 case OPTION_CHANGE_SECTION_VMA:
2601 p->change_vma = what;
2602 p->vma_val = val;
2603 break;
2604 }
2605 }
2606 break;
2607
2608 case OPTION_CHANGE_ADDRESSES:
2609 change_section_address = parse_vma (optarg, "--change-addresses");
2610 change_start = change_section_address;
2611 break;
2612
2613 case OPTION_CHANGE_WARNINGS:
2614 change_warn = TRUE;
2615 break;
2616
2617 case OPTION_CHANGE_LEADING_CHAR:
2618 change_leading_char = TRUE;
2619 break;
2620
2621 case OPTION_DEBUGGING:
2622 convert_debugging = TRUE;
2623 break;
2624
2625 case OPTION_GAP_FILL:
2626 {
2627 bfd_vma gap_fill_vma;
2628
2629 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2630 gap_fill = (bfd_byte) gap_fill_vma;
2631 if ((bfd_vma) gap_fill != gap_fill_vma)
2632 {
2633 char buff[20];
2634
2635 sprintf_vma (buff, gap_fill_vma);
2636
2637 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2638 buff, gap_fill);
2639 }
2640 gap_fill_set = TRUE;
2641 }
2642 break;
2643
2644 case OPTION_NO_CHANGE_WARNINGS:
2645 change_warn = FALSE;
2646 break;
2647
2648 case OPTION_PAD_TO:
2649 pad_to = parse_vma (optarg, "--pad-to");
2650 pad_to_set = TRUE;
2651 break;
2652
2653 case OPTION_REMOVE_LEADING_CHAR:
2654 remove_leading_char = TRUE;
2655 break;
2656
2657 case OPTION_REDEFINE_SYM:
2658 {
2659 /* Push this redefinition onto redefine_symbol_list. */
2660
2661 int len;
2662 const char *s;
2663 const char *nextarg;
2664 char *source, *target;
2665
2666 s = strchr (optarg, '=');
2667 if (s == NULL)
2668 fatal (_("bad format for %s"), "--redefine-sym");
2669
2670 len = s - optarg;
2671 source = xmalloc (len + 1);
2672 strncpy (source, optarg, len);
2673 source[len] = '\0';
2674
2675 nextarg = s + 1;
2676 len = strlen (nextarg);
2677 target = xmalloc (len + 1);
2678 strcpy (target, nextarg);
2679
2680 redefine_list_append ("--redefine-sym", source, target);
2681
2682 free (source);
2683 free (target);
2684 }
2685 break;
2686
2687 case OPTION_REDEFINE_SYMS:
2688 add_redefine_syms_file (optarg);
2689 break;
2690
2691 case OPTION_SET_SECTION_FLAGS:
2692 {
2693 const char *s;
2694 int len;
2695 char *name;
2696
2697 s = strchr (optarg, '=');
2698 if (s == NULL)
2699 fatal (_("bad format for %s"), "--set-section-flags");
2700
2701 len = s - optarg;
2702 name = xmalloc (len + 1);
2703 strncpy (name, optarg, len);
2704 name[len] = '\0';
2705
2706 p = find_section_list (name, TRUE);
2707
2708 p->set_flags = TRUE;
2709 p->flags = parse_flags (s + 1);
2710 }
2711 break;
2712
2713 case OPTION_RENAME_SECTION:
2714 {
2715 flagword flags;
2716 const char *eq, *fl;
2717 char *old_name;
2718 char *new_name;
2719 unsigned int len;
2720
2721 eq = strchr (optarg, '=');
2722 if (eq == NULL)
2723 fatal (_("bad format for %s"), "--rename-section");
2724
2725 len = eq - optarg;
2726 if (len == 0)
2727 fatal (_("bad format for %s"), "--rename-section");
2728
2729 old_name = xmalloc (len + 1);
2730 strncpy (old_name, optarg, len);
2731 old_name[len] = 0;
2732
2733 eq++;
2734 fl = strchr (eq, ',');
2735 if (fl)
2736 {
2737 flags = parse_flags (fl + 1);
2738 len = fl - eq;
2739 }
2740 else
2741 {
2742 flags = -1;
2743 len = strlen (eq);
2744 }
2745
2746 if (len == 0)
2747 fatal (_("bad format for %s"), "--rename-section");
2748
2749 new_name = xmalloc (len + 1);
2750 strncpy (new_name, eq, len);
2751 new_name[len] = 0;
2752
2753 add_section_rename (old_name, new_name, flags);
2754 }
2755 break;
2756
2757 case OPTION_SET_START:
2758 set_start = parse_vma (optarg, "--set-start");
2759 set_start_set = TRUE;
2760 break;
2761
2762 case OPTION_SREC_LEN:
2763 Chunk = parse_vma (optarg, "--srec-len");
2764 break;
2765
2766 case OPTION_SREC_FORCES3:
2767 S3Forced = TRUE;
2768 break;
2769
2770 case OPTION_STRIP_SYMBOLS:
2771 add_specific_symbols (optarg, &strip_specific_list);
2772 break;
2773
2774 case OPTION_KEEP_SYMBOLS:
2775 add_specific_symbols (optarg, &keep_specific_list);
2776 break;
2777
2778 case OPTION_LOCALIZE_SYMBOLS:
2779 add_specific_symbols (optarg, &localize_specific_list);
2780 break;
2781
2782 case OPTION_KEEPGLOBAL_SYMBOLS:
2783 add_specific_symbols (optarg, &keepglobal_specific_list);
2784 break;
2785
2786 case OPTION_WEAKEN_SYMBOLS:
2787 add_specific_symbols (optarg, &weaken_specific_list);
2788 break;
2789
2790 case OPTION_ALT_MACH_CODE:
2791 use_alt_mach_code = atoi (optarg);
2792 if (use_alt_mach_code <= 0)
2793 fatal (_("alternate machine code index must be positive"));
2794 break;
2795
2796 case OPTION_PREFIX_SYMBOLS:
2797 prefix_symbols_string = optarg;
2798 break;
2799
2800 case OPTION_PREFIX_SECTIONS:
2801 prefix_sections_string = optarg;
2802 break;
2803
2804 case OPTION_PREFIX_ALLOC_SECTIONS:
2805 prefix_alloc_sections_string = optarg;
2806 break;
2807
2808 case OPTION_READONLY_TEXT:
2809 bfd_flags_to_set |= WP_TEXT;
2810 bfd_flags_to_clear &= ~WP_TEXT;
2811 break;
2812
2813 case OPTION_WRITABLE_TEXT:
2814 bfd_flags_to_clear |= WP_TEXT;
2815 bfd_flags_to_set &= ~WP_TEXT;
2816 break;
2817
2818 case OPTION_PURE:
2819 bfd_flags_to_set |= D_PAGED;
2820 bfd_flags_to_clear &= ~D_PAGED;
2821 break;
2822
2823 case OPTION_IMPURE:
2824 bfd_flags_to_clear |= D_PAGED;
2825 bfd_flags_to_set &= ~D_PAGED;
2826 break;
2827
2828 case 0:
2829 /* We've been given a long option. */
2830 break;
2831
2832 case 'H':
2833 case 'h':
2834 copy_usage (stdout, 0);
2835
2836 default:
2837 copy_usage (stderr, 1);
2838 }
2839 }
2840
2841 if (formats_info)
2842 {
2843 display_info ();
2844 return 0;
2845 }
2846
2847 if (show_version)
2848 print_version ("objcopy");
2849
2850 if (copy_byte >= interleave)
2851 fatal (_("byte number must be less than interleave"));
2852
2853 if (optind == argc || optind + 2 < argc)
2854 copy_usage (stderr, 1);
2855
2856 input_filename = argv[optind];
2857 if (optind + 1 < argc)
2858 output_filename = argv[optind + 1];
2859
2860 /* Default is to strip no symbols. */
2861 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2862 strip_symbols = STRIP_NONE;
2863
2864 if (output_target == NULL)
2865 output_target = input_target;
2866
2867 if (binary_architecture != NULL)
2868 {
2869 if (input_target && strcmp (input_target, "binary") == 0)
2870 {
2871 const bfd_arch_info_type * temp_arch_info;
2872
2873 temp_arch_info = bfd_scan_arch (binary_architecture);
2874
2875 if (temp_arch_info != NULL)
2876 {
2877 bfd_external_binary_architecture = temp_arch_info->arch;
2878 bfd_external_machine = temp_arch_info->mach;
2879 }
2880 else
2881 fatal (_("architecture %s unknown"), binary_architecture);
2882 }
2883 else
2884 {
2885 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2886 non_fatal (_(" Argument %s ignored"), binary_architecture);
2887 }
2888 }
2889
2890 if (preserve_dates)
2891 if (stat (input_filename, & statbuf) < 0)
2892 fatal (_("warning: could not locate '%s'. System error message: %s"),
2893 input_filename, strerror (errno));
2894
2895 /* If there is no destination file, or the source and destination files
2896 are the same, then create a temp and rename the result into the input. */
2897 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
2898 {
2899 char *tmpname = make_tempname (input_filename);
2900
2901 copy_file (input_filename, tmpname, input_target, output_target);
2902 if (status == 0)
2903 {
2904 if (preserve_dates)
2905 set_times (tmpname, &statbuf);
2906 smart_rename (tmpname, input_filename, preserve_dates);
2907 }
2908 else
2909 unlink (tmpname);
2910 }
2911 else
2912 {
2913 copy_file (input_filename, output_filename, input_target, output_target);
2914
2915 if (status == 0 && preserve_dates)
2916 set_times (output_filename, &statbuf);
2917 }
2918
2919 if (change_warn)
2920 {
2921 for (p = change_sections; p != NULL; p = p->next)
2922 {
2923 if (! p->used)
2924 {
2925 if (p->change_vma != CHANGE_IGNORE)
2926 {
2927 char buff [20];
2928
2929 sprintf_vma (buff, p->vma_val);
2930
2931 /* xgettext:c-format */
2932 non_fatal (_("%s %s%c0x%s never used"),
2933 "--change-section-vma",
2934 p->name,
2935 p->change_vma == CHANGE_SET ? '=' : '+',
2936 buff);
2937 }
2938
2939 if (p->change_lma != CHANGE_IGNORE)
2940 {
2941 char buff [20];
2942
2943 sprintf_vma (buff, p->lma_val);
2944
2945 /* xgettext:c-format */
2946 non_fatal (_("%s %s%c0x%s never used"),
2947 "--change-section-lma",
2948 p->name,
2949 p->change_lma == CHANGE_SET ? '=' : '+',
2950 buff);
2951 }
2952 }
2953 }
2954 }
2955
2956 return 0;
2957 }
2958
2959 int
2960 main (int argc, char *argv[])
2961 {
2962 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2963 setlocale (LC_MESSAGES, "");
2964 #endif
2965 #if defined (HAVE_SETLOCALE)
2966 setlocale (LC_CTYPE, "");
2967 #endif
2968 bindtextdomain (PACKAGE, LOCALEDIR);
2969 textdomain (PACKAGE);
2970
2971 program_name = argv[0];
2972 xmalloc_set_program_name (program_name);
2973
2974 START_PROGRESS (program_name, 0);
2975
2976 strip_symbols = STRIP_UNDEF;
2977 discard_locals = LOCALS_UNDEF;
2978
2979 bfd_init ();
2980 set_default_bfd_target ();
2981
2982 if (is_strip < 0)
2983 {
2984 int i = strlen (program_name);
2985 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2986 /* Drop the .exe suffix, if any. */
2987 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2988 {
2989 i -= 4;
2990 program_name[i] = '\0';
2991 }
2992 #endif
2993 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2994 }
2995
2996 if (is_strip)
2997 strip_main (argc, argv);
2998 else
2999 copy_main (argc, argv);
3000
3001 END_PROGRESS (program_name);
3002
3003 return status;
3004 }