2000-12-12 H.J. Lu <hjl@gnu.org>
[binutils.git] / binutils / objcopy.c
blob21f579366dd6b390c5820ec0108064c1a7b42d6b
1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "bfd.h"
23 #include "progress.h"
24 #include "bucomm.h"
25 #include "getopt.h"
26 #include "libiberty.h"
27 #include "budbg.h"
28 #include "filenames.h"
29 #include <sys/stat.h>
31 /* A list of symbols to explicitly strip out, or to keep. A linked
32 list is good enough for a small number from the command line, but
33 this will slow things down a lot if many symbols are being
34 deleted. */
36 struct symlist
38 const char *name;
39 struct symlist *next;
42 /* A list to support redefine_sym. */
43 struct redefine_node
45 char *source;
46 char *target;
47 struct redefine_node *next;
50 static void copy_usage PARAMS ((FILE *, int));
51 static void strip_usage PARAMS ((FILE *, int));
52 static flagword parse_flags PARAMS ((const char *));
53 static struct section_list *find_section_list PARAMS ((const char *, boolean));
54 static void setup_section PARAMS ((bfd *, asection *, PTR));
55 static void copy_section PARAMS ((bfd *, asection *, PTR));
56 static void get_sections PARAMS ((bfd *, asection *, PTR));
57 static int compare_section_lma PARAMS ((const PTR, const PTR));
58 static void add_specific_symbol PARAMS ((const char *, struct symlist **));
59 static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
60 static boolean is_strip_section PARAMS ((bfd *, asection *));
61 static unsigned int filter_symbols
62 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
63 static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
64 static void filter_bytes PARAMS ((char *, bfd_size_type *));
65 static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
66 static void copy_object PARAMS ((bfd *, bfd *));
67 static void copy_archive PARAMS ((bfd *, bfd *, const char *));
68 static void copy_file
69 PARAMS ((const char *, const char *, const char *, const char *));
70 static int strip_main PARAMS ((int, char **));
71 static int copy_main PARAMS ((int, char **));
72 static const char *lookup_sym_redefinition PARAMS((const char *));
73 static void redefine_list_append PARAMS ((const char *, const char *));
75 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
77 static asymbol **isympp = NULL; /* Input symbols */
78 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
80 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
81 static int copy_byte = -1;
82 static int interleave = 4;
84 static boolean verbose; /* Print file and target names. */
85 static boolean preserve_dates; /* Preserve input file timestamp. */
86 static int status = 0; /* Exit status. */
88 enum strip_action
90 STRIP_UNDEF,
91 STRIP_NONE, /* don't strip */
92 STRIP_DEBUG, /* strip all debugger symbols */
93 STRIP_UNNEEDED, /* strip unnecessary symbols */
94 STRIP_ALL /* strip all symbols */
97 /* Which symbols to remove. */
98 static enum strip_action strip_symbols;
100 enum locals_action
102 LOCALS_UNDEF,
103 LOCALS_START_L, /* discard locals starting with L */
104 LOCALS_ALL /* discard all locals */
107 /* Which local symbols to remove. Overrides STRIP_ALL. */
108 static enum locals_action discard_locals;
110 /* What kind of change to perform. */
111 enum change_action
113 CHANGE_IGNORE,
114 CHANGE_MODIFY,
115 CHANGE_SET
118 /* Structure used to hold lists of sections and actions to take. */
119 struct section_list
121 struct section_list * next; /* Next section to change. */
122 const char * name; /* Section name. */
123 boolean used; /* Whether this entry was used. */
124 boolean remove; /* Whether to remove this section. */
125 boolean copy; /* Whether to copy this section. */
126 enum change_action change_vma;/* Whether to change or set VMA. */
127 bfd_vma vma_val; /* Amount to change by or set to. */
128 enum change_action change_lma;/* Whether to change or set LMA. */
129 bfd_vma lma_val; /* Amount to change by or set to. */
130 boolean set_flags; /* Whether to set the section flags. */
131 flagword flags; /* What to set the section flags to. */
134 static struct section_list *change_sections;
135 static boolean sections_removed;
136 static boolean sections_copied;
138 /* Changes to the start address. */
139 static bfd_vma change_start = 0;
140 static boolean set_start_set = false;
141 static bfd_vma set_start;
143 /* Changes to section addresses. */
144 static bfd_vma change_section_address = 0;
146 /* Filling gaps between sections. */
147 static boolean gap_fill_set = false;
148 static bfd_byte gap_fill = 0;
150 /* Pad to a given address. */
151 static boolean pad_to_set = false;
152 static bfd_vma pad_to;
154 /* List of sections to add. */
156 struct section_add
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;
172 static struct section_add *add_sections;
174 /* Whether to convert debugging information. */
176 static boolean convert_debugging = false;
178 /* Whether to change the leading character in symbol names. */
180 static boolean change_leading_char = false;
182 /* Whether to remove the leading character from global symbol names. */
184 static boolean remove_leading_char = false;
186 /* List of symbols to strip, keep, localize, weaken, or redefine. */
188 static struct symlist *strip_specific_list = NULL;
189 static struct symlist *keep_specific_list = NULL;
190 static struct symlist *localize_specific_list = NULL;
191 static struct symlist *weaken_specific_list = NULL;
192 static struct redefine_node *redefine_sym_list = NULL;
194 /* If this is true, we weaken global symbols (set BSF_WEAK). */
196 static boolean weaken = false;
198 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
200 #define OPTION_ADD_SECTION 150
201 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
202 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
203 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
204 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
205 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
206 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
207 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
208 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
209 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
210 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
211 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
212 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
213 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
214 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
215 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
216 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
217 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
218 #define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
219 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
221 /* Options to handle if running as "strip". */
223 static struct option strip_options[] =
225 {"discard-all", no_argument, 0, 'x'},
226 {"discard-locals", no_argument, 0, 'X'},
227 {"format", required_argument, 0, 'F'}, /* Obsolete */
228 {"help", no_argument, 0, 'h'},
229 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
230 {"input-target", required_argument, 0, 'I'},
231 {"keep-symbol", required_argument, 0, 'K'},
232 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
233 {"output-target", required_argument, 0, 'O'},
234 {"preserve-dates", no_argument, 0, 'p'},
235 {"remove-section", required_argument, 0, 'R'},
236 {"strip-all", no_argument, 0, 's'},
237 {"strip-debug", no_argument, 0, 'S'},
238 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
239 {"strip-symbol", required_argument, 0, 'N'},
240 {"target", required_argument, 0, 'F'},
241 {"verbose", no_argument, 0, 'v'},
242 {"version", no_argument, 0, 'V'},
243 {0, no_argument, 0, 0}
246 /* Options to handle if running as "objcopy". */
248 static struct option copy_options[] =
250 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
251 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
252 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
253 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
254 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
255 {"byte", required_argument, 0, 'b'},
256 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
257 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
258 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
259 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
260 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
261 {"change-start", required_argument, 0, OPTION_CHANGE_START},
262 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
263 {"debugging", no_argument, 0, OPTION_DEBUGGING},
264 {"discard-all", no_argument, 0, 'x'},
265 {"discard-locals", no_argument, 0, 'X'},
266 {"only-section", required_argument, 0, 'j'},
267 {"format", required_argument, 0, 'F'}, /* Obsolete */
268 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
269 {"help", no_argument, 0, 'h'},
270 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
271 {"input-target", required_argument, 0, 'I'},
272 {"interleave", required_argument, 0, 'i'},
273 {"keep-symbol", required_argument, 0, 'K'},
274 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
275 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
276 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
277 {"output-target", required_argument, 0, 'O'},
278 {"pad-to", required_argument, 0, OPTION_PAD_TO},
279 {"preserve-dates", no_argument, 0, 'p'},
280 {"localize-symbol", required_argument, 0, 'L'},
281 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
282 {"remove-section", required_argument, 0, 'R'},
283 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
284 {"set-start", required_argument, 0, OPTION_SET_START},
285 {"strip-all", no_argument, 0, 'S'},
286 {"strip-debug", no_argument, 0, 'g'},
287 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
288 {"strip-symbol", required_argument, 0, 'N'},
289 {"target", required_argument, 0, 'F'},
290 {"verbose", no_argument, 0, 'v'},
291 {"version", no_argument, 0, 'V'},
292 {"weaken", no_argument, 0, OPTION_WEAKEN},
293 {"weaken-symbol", required_argument, 0, 'W'},
294 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
295 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
296 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
297 {0, no_argument, 0, 0}
300 /* IMPORTS */
301 extern char *program_name;
303 /* This flag distinguishes between strip and objcopy:
304 1 means this is 'strip'; 0 means this is 'objcopy'.
305 -1 means if we should use argv[0] to decide. */
306 extern int is_strip;
308 /* The maximum length of an S record. This variable is declared in srec.c
309 and can be modified by the --srec-len parameter. */
310 extern unsigned int Chunk;
312 /* Restrict the generation of Srecords to type S3 only.
313 This variable is declare in bfd/srec.c and can be toggled
314 on by the --srec-forceS3 command line switch. */
315 extern boolean S3Forced;
317 static void
318 copy_usage (stream, exit_status)
319 FILE *stream;
320 int exit_status;
322 fprintf (stream, _("Usage: %s <switches> in-file [out-file]\n"), program_name);
323 fprintf (stream, _(" The switches are:\n"));
324 fprintf (stream, _("\
325 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
326 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
327 -F --target <bfdname> Set both input and output format to <bfdname>\n\
328 --debugging Convert debugging information, if possible\n\
329 -p --preserve-dates Copy modified/access timestamps to the output\n\
330 -j --only-section <name> Only copy section <name> into the output\n\
331 -R --remove-section <name> Remove section <name> from the output\n\
332 -S --strip-all Remove all symbol and relocation information\n\
333 -g --strip-debug Remove all debugging symbols\n\
334 --strip-unneeded Remove all symbols not needed by relocations\n\
335 -N --strip-symbol <name> Do not copy symbol <name>\n\
336 -K --keep-symbol <name> Only copy symbol <name>\n\
337 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
338 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
339 --weaken Force all global symbols to be marked as weak\n\
340 -x --discard-all Remove all non-global symbols\n\
341 -X --discard-locals Remove any compiler-generated symbols\n\
342 -i --interleave <number> Only copy one out of every <number> bytes\n\
343 -b --byte <num> Select byte <num> in every interleaved block\n\
344 --gap-fill <val> Fill gaps between sections with <val>\n\
345 --pad-to <addr> Pad the last section up to address <addr>\n\
346 --set-start <addr> Set the start address to <addr>\n\
347 {--change-start|--adjust-start} <incr>\n\
348 Add <incr> to the start address\n\
349 {--change-addresses|--adjust-vma} <incr>\n\
350 Add <incr> to LMA, VMA and start addresses\n\
351 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
352 Change LMA and VMA of section <name> by <val>\n\
353 --change-section-lma <name>{=|+|-}<val>\n\
354 Change the LMA of section <name> by <val>\n\
355 --change-section-vma <name>{=|+|-}<val>\n\
356 Change the VMA of section <name> by <val>\n\
357 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
358 Warn if a named section does not exist\n\
359 --set-section-flags <name>=<flags>\n\
360 Set section <name>'s properties to <flags>\n\
361 --add-section <name>=<file> Add section <name> found in <file> to output\n\
362 --change-leading-char Force output format's leading character style\n\
363 --remove-leading-char Remove leading character from global symbols\n\
364 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
365 --srec-len <number> Restrict the length of generated Srecords\n\
366 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
367 -v --verbose List all object files modified\n\
368 -V --version Display this program's version number\n\
369 -h --help Display this output\n\
370 "));
371 list_supported_targets (program_name, stream);
372 if (exit_status == 0)
373 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
374 exit (exit_status);
377 static void
378 strip_usage (stream, exit_status)
379 FILE *stream;
380 int exit_status;
382 fprintf (stream, _("Usage: %s <switches> in-file(s)\n"), program_name);
383 fprintf (stream, _(" The switches are:\n"));
384 fprintf (stream, _("\
385 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
386 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
387 -F --target <bfdname> Set both input and output format to <bfdname>\n\
388 -p --preserve-dates Copy modified/access timestamps to the output\n\
389 -R --remove-section <name> Remove section <name> from the output\n\
390 -s --strip-all Remove all symbol and relocation information\n\
391 -g -S --strip-debug Remove all debugging symbols\n\
392 --strip-unneeded Remove all symbols not needed by relocations\n\
393 -N --strip-symbol <name> Do not copy symbol <name>\n\
394 -K --keep-symbol <name> Only copy symbol <name>\n\
395 -x --discard-all Remove all non-global symbols\n\
396 -X --discard-locals Remove any compiler-generated symbols\n\
397 -v --verbose List all object files modified\n\
398 -V --version Display this program's version number\n\
399 -h --help Display this output\n\
400 -o <file> Place stripped output into <file>\n\
401 "));
403 list_supported_targets (program_name, stream);
404 if (exit_status == 0)
405 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
406 exit (exit_status);
409 /* Parse section flags into a flagword, with a fatal error if the
410 string can't be parsed. */
412 static flagword
413 parse_flags (s)
414 const char *s;
416 flagword ret;
417 const char *snext;
418 int len;
420 ret = SEC_NO_FLAGS;
424 snext = strchr (s, ',');
425 if (snext == NULL)
426 len = strlen (s);
427 else
429 len = snext - s;
430 ++snext;
433 if (0) ;
434 #define PARSE_FLAG(fname,fval) \
435 else if (strncasecmp (fname, s, len) == 0) ret |= fval
436 PARSE_FLAG ("alloc", SEC_ALLOC);
437 PARSE_FLAG ("load", SEC_LOAD);
438 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
439 PARSE_FLAG ("readonly", SEC_READONLY);
440 PARSE_FLAG ("debug", SEC_DEBUGGING);
441 PARSE_FLAG ("code", SEC_CODE);
442 PARSE_FLAG ("data", SEC_DATA);
443 PARSE_FLAG ("rom", SEC_ROM);
444 PARSE_FLAG ("share", SEC_SHARED);
445 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
446 #undef PARSE_FLAG
447 else
449 char *copy;
451 copy = xmalloc (len + 1);
452 strncpy (copy, s, len);
453 copy[len] = '\0';
454 non_fatal (_("unrecognized section flag `%s'"), copy);
455 fatal (_("supported flags: %s"),
456 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
459 s = snext;
461 while (s != NULL);
463 return ret;
466 /* Find and optionally add an entry in the change_sections list. */
468 static struct section_list *
469 find_section_list (name, add)
470 const char *name;
471 boolean add;
473 register struct section_list *p;
475 for (p = change_sections; p != NULL; p = p->next)
476 if (strcmp (p->name, name) == 0)
477 return p;
479 if (! add)
480 return NULL;
482 p = (struct section_list *) xmalloc (sizeof (struct section_list));
483 p->name = name;
484 p->used = false;
485 p->remove = false;
486 p->copy = false;
487 p->change_vma = CHANGE_IGNORE;
488 p->change_lma = CHANGE_IGNORE;
489 p->vma_val = 0;
490 p->lma_val = 0;
491 p->set_flags = false;
492 p->flags = 0;
494 p->next = change_sections;
495 change_sections = p;
497 return p;
500 /* Add a symbol to strip_specific_list. */
502 static void
503 add_specific_symbol (name, list)
504 const char *name;
505 struct symlist **list;
507 struct symlist *tmp_list;
509 tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
510 tmp_list->name = name;
511 tmp_list->next = *list;
512 *list = tmp_list;
515 /* See whether a symbol should be stripped or kept based on
516 strip_specific_list and keep_symbols. */
518 static boolean
519 is_specified_symbol (name, list)
520 const char *name;
521 struct symlist *list;
523 struct symlist *tmp_list;
525 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
527 if (strcmp (name, tmp_list->name) == 0)
528 return true;
530 return false;
533 /* See if a section is being removed. */
535 static boolean
536 is_strip_section (abfd, sec)
537 bfd *abfd ATTRIBUTE_UNUSED;
538 asection *sec;
540 struct section_list *p;
542 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
543 && (strip_symbols == STRIP_DEBUG
544 || strip_symbols == STRIP_UNNEEDED
545 || strip_symbols == STRIP_ALL
546 || discard_locals == LOCALS_ALL
547 || convert_debugging))
548 return true;
550 if (! sections_removed && ! sections_copied)
551 return false;
553 p = find_section_list (bfd_get_section_name (abfd, sec), false);
554 if (sections_removed && p != NULL && p->remove)
555 return true;
556 if (sections_copied && (p == NULL || ! p->copy))
557 return true;
558 return false;
561 /* Choose which symbol entries to copy; put the result in OSYMS.
562 We don't copy in place, because that confuses the relocs.
563 Return the number of symbols to print. */
565 static unsigned int
566 filter_symbols (abfd, obfd, osyms, isyms, symcount)
567 bfd *abfd;
568 bfd *obfd;
569 asymbol **osyms, **isyms;
570 long symcount;
572 register asymbol **from = isyms, **to = osyms;
573 long src_count = 0, dst_count = 0;
574 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
575 == HAS_RELOC;
577 for (; src_count < symcount; src_count++)
579 asymbol *sym = from[src_count];
580 flagword flags = sym->flags;
581 const char *name = bfd_asymbol_name (sym);
582 int keep;
584 if (redefine_sym_list)
586 const char *old_name, *new_name;
588 old_name = bfd_asymbol_name (sym);
589 new_name = lookup_sym_redefinition (old_name);
590 name = bfd_asymbol_name (sym) = new_name;
593 if (change_leading_char
594 && (bfd_get_symbol_leading_char (abfd)
595 != bfd_get_symbol_leading_char (obfd))
596 && (bfd_get_symbol_leading_char (abfd) == '\0'
597 || (name[0] == bfd_get_symbol_leading_char (abfd))))
599 if (bfd_get_symbol_leading_char (obfd) == '\0')
600 name = bfd_asymbol_name (sym) = name + 1;
601 else
603 char *n;
605 n = xmalloc (strlen (name) + 2);
606 n[0] = bfd_get_symbol_leading_char (obfd);
607 if (bfd_get_symbol_leading_char (abfd) == '\0')
608 strcpy (n + 1, name);
609 else
610 strcpy (n + 1, name + 1);
611 name = bfd_asymbol_name (sym) = n;
615 if (remove_leading_char
616 && ((flags & BSF_GLOBAL) != 0
617 || (flags & BSF_WEAK) != 0
618 || bfd_is_und_section (bfd_get_section (sym))
619 || bfd_is_com_section (bfd_get_section (sym)))
620 && name[0] == bfd_get_symbol_leading_char (abfd))
621 name = bfd_asymbol_name (sym) = name + 1;
623 if (strip_symbols == STRIP_ALL)
624 keep = 0;
625 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
626 || ((flags & BSF_SECTION_SYM) != 0
627 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
628 & BSF_KEEP) != 0))
629 keep = 1;
630 else if (relocatable /* Relocatable file. */
631 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
632 keep = 1;
633 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
634 || (flags & BSF_WEAK) != 0
635 || bfd_is_und_section (bfd_get_section (sym))
636 || bfd_is_com_section (bfd_get_section (sym)))
637 keep = strip_symbols != STRIP_UNNEEDED;
638 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
639 keep = (strip_symbols != STRIP_DEBUG
640 && strip_symbols != STRIP_UNNEEDED
641 && ! convert_debugging);
642 else /* Local symbol. */
643 keep = (strip_symbols != STRIP_UNNEEDED
644 && (discard_locals != LOCALS_ALL
645 && (discard_locals != LOCALS_START_L
646 || ! bfd_is_local_label (abfd, sym))));
648 if (keep && is_specified_symbol (name, strip_specific_list))
649 keep = 0;
650 if (!keep && is_specified_symbol (name, keep_specific_list))
651 keep = 1;
652 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
653 keep = 0;
655 if (keep && (flags & BSF_GLOBAL) != 0
656 && (weaken || is_specified_symbol (name, weaken_specific_list)))
658 sym->flags &=~ BSF_GLOBAL;
659 sym->flags |= BSF_WEAK;
661 if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
662 && is_specified_symbol (name, localize_specific_list))
664 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
665 sym->flags |= BSF_LOCAL;
668 if (keep)
669 to[dst_count++] = sym;
672 to[dst_count] = NULL;
674 return dst_count;
677 static const char *
678 lookup_sym_redefinition (source)
679 const char *source;
681 const char *result;
682 struct redefine_node *list;
684 result = source;
686 for (list = redefine_sym_list; list != NULL; list = list->next)
688 if (strcmp (source, list->source) == 0)
690 result = list->target;
691 break;
694 return result;
697 /* Add a node to a symbol redefine list */
699 static void
700 redefine_list_append (source, target)
701 const char *source;
702 const char *target;
704 struct redefine_node **p;
705 struct redefine_node *list;
706 struct redefine_node *new_node;
708 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
710 if (strcmp (source, list->source) == 0)
712 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
713 "--redefine-sym",
714 source);
717 if (strcmp (target, list->target) == 0)
719 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
720 "--redefine-sym",
721 target);
725 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
727 new_node->source = strdup (source);
728 new_node->target = strdup (target);
729 new_node->next = NULL;
731 *p = new_node;
735 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
736 Adjust *SIZE. */
738 static void
739 filter_bytes (memhunk, size)
740 char *memhunk;
741 bfd_size_type *size;
743 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
745 for (; from < end; from += interleave)
746 *to++ = *from;
747 if (*size % interleave > (bfd_size_type) copy_byte)
748 *size = (*size / interleave) + 1;
749 else
750 *size /= interleave;
753 /* Copy object file IBFD onto OBFD. */
755 static void
756 copy_object (ibfd, obfd)
757 bfd *ibfd;
758 bfd *obfd;
760 bfd_vma start;
761 long symcount;
762 asection **osections = NULL;
763 bfd_size_type *gaps = NULL;
764 bfd_size_type max_gap = 0;
765 long symsize;
766 PTR dhandle;
769 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
770 RETURN_NONFATAL (bfd_get_filename (obfd));
772 if (verbose)
773 printf (_("copy from %s(%s) to %s(%s)\n"),
774 bfd_get_filename (ibfd), bfd_get_target (ibfd),
775 bfd_get_filename (obfd), bfd_get_target (obfd));
777 if (set_start_set)
778 start = set_start;
779 else
780 start = bfd_get_start_address (ibfd);
781 start += change_start;
783 if (!bfd_set_start_address (obfd, start)
784 || !bfd_set_file_flags (obfd,
785 (bfd_get_file_flags (ibfd)
786 & bfd_applicable_file_flags (obfd))))
787 RETURN_NONFATAL (bfd_get_filename (ibfd));
789 /* Copy architecture of input file to output file */
790 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
791 bfd_get_mach (ibfd)))
792 non_fatal (_("Warning: Output file cannot represent architecture %s"),
793 bfd_printable_arch_mach (bfd_get_arch (ibfd),
794 bfd_get_mach (ibfd)));
796 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
797 RETURN_NONFATAL (bfd_get_filename (ibfd));
799 if (isympp)
800 free (isympp);
802 if (osympp != isympp)
803 free (osympp);
805 /* BFD mandates that all output sections be created and sizes set before
806 any output is done. Thus, we traverse all sections multiple times. */
807 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
809 if (add_sections != NULL)
811 struct section_add *padd;
812 struct section_list *pset;
814 for (padd = add_sections; padd != NULL; padd = padd->next)
816 padd->section = bfd_make_section (obfd, padd->name);
817 if (padd->section == NULL)
819 non_fatal (_("can't create section `%s': %s"),
820 padd->name, bfd_errmsg (bfd_get_error ()));
821 status = 1;
822 return;
824 else
826 flagword flags;
828 if (! bfd_set_section_size (obfd, padd->section, padd->size))
829 RETURN_NONFATAL (bfd_get_filename (obfd));
831 pset = find_section_list (padd->name, false);
832 if (pset != NULL)
833 pset->used = true;
835 if (pset != NULL && pset->set_flags)
836 flags = pset->flags | SEC_HAS_CONTENTS;
837 else
838 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
840 if (! bfd_set_section_flags (obfd, padd->section, flags))
841 RETURN_NONFATAL (bfd_get_filename (obfd));
843 if (pset != NULL)
845 if (pset->change_vma != CHANGE_IGNORE)
846 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
847 RETURN_NONFATAL (bfd_get_filename (obfd));
849 if (pset->change_lma != CHANGE_IGNORE)
851 padd->section->lma = pset->lma_val;
853 if (! bfd_set_section_alignment
854 (obfd, padd->section,
855 bfd_section_alignment (obfd, padd->section)))
856 RETURN_NONFATAL (bfd_get_filename (obfd));
863 if (gap_fill_set || pad_to_set)
865 asection **set;
866 unsigned int c, i;
868 /* We must fill in gaps between the sections and/or we must pad
869 the last section to a specified address. We do this by
870 grabbing a list of the sections, sorting them by VMA, and
871 increasing the section sizes as required to fill the gaps.
872 We write out the gap contents below. */
874 c = bfd_count_sections (obfd);
875 osections = (asection **) xmalloc (c * sizeof (asection *));
876 set = osections;
877 bfd_map_over_sections (obfd, get_sections, (void *) &set);
879 qsort (osections, c, sizeof (asection *), compare_section_lma);
881 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
882 memset (gaps, 0, c * sizeof (bfd_size_type));
884 if (gap_fill_set)
886 for (i = 0; i < c - 1; i++)
888 flagword flags;
889 bfd_size_type size;
890 bfd_vma gap_start, gap_stop;
892 flags = bfd_get_section_flags (obfd, osections[i]);
893 if ((flags & SEC_HAS_CONTENTS) == 0
894 || (flags & SEC_LOAD) == 0)
895 continue;
897 size = bfd_section_size (obfd, osections[i]);
898 gap_start = bfd_section_lma (obfd, osections[i]) + size;
899 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
900 if (gap_start < gap_stop)
902 if (! bfd_set_section_size (obfd, osections[i],
903 size + (gap_stop - gap_start)))
905 non_fatal (_("Can't fill gap after %s: %s"),
906 bfd_get_section_name (obfd, osections[i]),
907 bfd_errmsg (bfd_get_error ()));
908 status = 1;
909 break;
911 gaps[i] = gap_stop - gap_start;
912 if (max_gap < gap_stop - gap_start)
913 max_gap = gap_stop - gap_start;
918 if (pad_to_set)
920 bfd_vma lma;
921 bfd_size_type size;
923 lma = bfd_section_lma (obfd, osections[c - 1]);
924 size = bfd_section_size (obfd, osections[c - 1]);
925 if (lma + size < pad_to)
927 if (! bfd_set_section_size (obfd, osections[c - 1],
928 pad_to - lma))
930 non_fatal (_("Can't add padding to %s: %s"),
931 bfd_get_section_name (obfd, osections[c - 1]),
932 bfd_errmsg (bfd_get_error ()));
933 status = 1;
935 else
937 gaps[c - 1] = pad_to - (lma + size);
938 if (max_gap < pad_to - (lma + size))
939 max_gap = pad_to - (lma + size);
945 /* Symbol filtering must happen after the output sections have
946 been created, but before their contents are set. */
947 dhandle = NULL;
948 symsize = bfd_get_symtab_upper_bound (ibfd);
949 if (symsize < 0)
950 RETURN_NONFATAL (bfd_get_filename (ibfd));
952 osympp = isympp = (asymbol **) xmalloc (symsize);
953 symcount = bfd_canonicalize_symtab (ibfd, isympp);
954 if (symcount < 0)
955 RETURN_NONFATAL (bfd_get_filename (ibfd));
957 if (convert_debugging)
958 dhandle = read_debugging_info (ibfd, isympp, symcount);
960 if (strip_symbols == STRIP_DEBUG
961 || strip_symbols == STRIP_ALL
962 || strip_symbols == STRIP_UNNEEDED
963 || discard_locals != LOCALS_UNDEF
964 || strip_specific_list != NULL
965 || keep_specific_list != NULL
966 || localize_specific_list != NULL
967 || weaken_specific_list != NULL
968 || sections_removed
969 || sections_copied
970 || convert_debugging
971 || change_leading_char
972 || remove_leading_char
973 || redefine_sym_list
974 || weaken)
976 /* Mark symbols used in output relocations so that they
977 are kept, even if they are local labels or static symbols.
979 Note we iterate over the input sections examining their
980 relocations since the relocations for the output sections
981 haven't been set yet. mark_symbols_used_in_relocations will
982 ignore input sections which have no corresponding output
983 section. */
984 if (strip_symbols != STRIP_ALL)
985 bfd_map_over_sections (ibfd,
986 mark_symbols_used_in_relocations,
987 (PTR)isympp);
988 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
989 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
992 if (convert_debugging && dhandle != NULL)
994 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
996 status = 1;
997 return;
1001 bfd_set_symtab (obfd, osympp, symcount);
1003 /* This has to happen after the symbol table has been set. */
1004 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1006 if (add_sections != NULL)
1008 struct section_add *padd;
1010 for (padd = add_sections; padd != NULL; padd = padd->next)
1012 if (! bfd_set_section_contents (obfd, padd->section,
1013 (PTR) padd->contents,
1014 (file_ptr) 0,
1015 (bfd_size_type) padd->size))
1016 RETURN_NONFATAL (bfd_get_filename (obfd));
1020 if (gap_fill_set || pad_to_set)
1022 bfd_byte *buf;
1023 int c, i;
1025 /* Fill in the gaps. */
1027 if (max_gap > 8192)
1028 max_gap = 8192;
1029 buf = (bfd_byte *) xmalloc (max_gap);
1030 memset (buf, gap_fill, (size_t) max_gap);
1032 c = bfd_count_sections (obfd);
1033 for (i = 0; i < c; i++)
1035 if (gaps[i] != 0)
1037 bfd_size_type left;
1038 file_ptr off;
1040 left = gaps[i];
1041 off = bfd_section_size (obfd, osections[i]) - left;
1042 while (left > 0)
1044 bfd_size_type now;
1046 if (left > 8192)
1047 now = 8192;
1048 else
1049 now = left;
1051 if (! bfd_set_section_contents (obfd, osections[i], buf,
1052 off, now))
1053 RETURN_NONFATAL (bfd_get_filename (obfd));
1055 left -= now;
1056 off += now;
1062 /* Allow the BFD backend to copy any private data it understands
1063 from the input BFD to the output BFD. This is done last to
1064 permit the routine to look at the filtered symbol table, which is
1065 important for the ECOFF code at least. */
1066 if (!bfd_copy_private_bfd_data (ibfd, obfd))
1068 non_fatal (_("%s: error copying private BFD data: %s"),
1069 bfd_get_filename (obfd),
1070 bfd_errmsg (bfd_get_error ()));
1071 status = 1;
1072 return;
1076 /* Read each archive element in turn from IBFD, copy the
1077 contents to temp file, and keep the temp file handle. */
1079 static void
1080 copy_archive (ibfd, obfd, output_target)
1081 bfd *ibfd;
1082 bfd *obfd;
1083 const char *output_target;
1085 struct name_list
1087 struct name_list *next;
1088 char *name;
1089 bfd *obfd;
1090 } *list, *l;
1091 bfd **ptr = &obfd->archive_head;
1092 bfd *this_element;
1093 char *dir = make_tempname (bfd_get_filename (obfd));
1095 /* Make a temp directory to hold the contents. */
1096 #if defined (_WIN32) && !defined (__CYGWIN32__)
1097 if (mkdir (dir) != 0)
1098 #else
1099 if (mkdir (dir, 0700) != 0)
1100 #endif
1102 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1103 dir, strerror (errno));
1105 obfd->has_armap = ibfd->has_armap;
1107 list = NULL;
1109 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1110 while (!status && this_element != (bfd *) NULL)
1112 /* Create an output file for this member. */
1113 char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1114 (char *) NULL);
1115 bfd *output_bfd = bfd_openw (output_name, output_target);
1116 bfd *last_element;
1117 struct stat buf;
1118 int stat_status = 0;
1120 if (preserve_dates)
1122 stat_status = bfd_stat_arch_elt (this_element, &buf);
1123 if (stat_status != 0)
1124 non_fatal (_("internal stat error on %s"),
1125 bfd_get_filename (this_element));
1128 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1129 l->name = output_name;
1130 l->next = list;
1131 list = l;
1133 if (output_bfd == (bfd *) NULL)
1134 RETURN_NONFATAL (output_name);
1136 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1137 RETURN_NONFATAL (bfd_get_filename (obfd));
1139 if (bfd_check_format (this_element, bfd_object) == true)
1140 copy_object (this_element, output_bfd);
1142 if (!bfd_close (output_bfd))
1144 bfd_nonfatal (bfd_get_filename (output_bfd));
1145 /* Error in new object file. Don't change archive. */
1146 status = 1;
1149 if (preserve_dates && stat_status == 0)
1150 set_times (output_name, &buf);
1152 /* Open the newly output file and attach to our list. */
1153 output_bfd = bfd_openr (output_name, output_target);
1155 l->obfd = output_bfd;
1157 *ptr = output_bfd;
1158 ptr = &output_bfd->next;
1160 last_element = this_element;
1162 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1164 bfd_close (last_element);
1166 *ptr = (bfd *) NULL;
1168 if (!bfd_close (obfd))
1169 RETURN_NONFATAL (bfd_get_filename (obfd));
1171 if (!bfd_close (ibfd))
1172 RETURN_NONFATAL (bfd_get_filename (ibfd));
1174 /* Delete all the files that we opened. */
1175 for (l = list; l != NULL; l = l->next)
1177 bfd_close (l->obfd);
1178 unlink (l->name);
1180 rmdir (dir);
1183 /* The top-level control. */
1185 static void
1186 copy_file (input_filename, output_filename, input_target, output_target)
1187 const char *input_filename;
1188 const char *output_filename;
1189 const char *input_target;
1190 const char *output_target;
1192 bfd *ibfd;
1193 char **matching;
1195 /* To allow us to do "strip *" without dying on the first
1196 non-object file, failures are nonfatal. */
1198 ibfd = bfd_openr (input_filename, input_target);
1199 if (ibfd == NULL)
1200 RETURN_NONFATAL (input_filename);
1202 if (bfd_check_format (ibfd, bfd_archive))
1204 bfd *obfd;
1206 /* bfd_get_target does not return the correct value until
1207 bfd_check_format succeeds. */
1208 if (output_target == NULL)
1209 output_target = bfd_get_target (ibfd);
1211 obfd = bfd_openw (output_filename, output_target);
1212 if (obfd == NULL)
1213 RETURN_NONFATAL (output_filename);
1215 copy_archive (ibfd, obfd, output_target);
1217 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1219 bfd *obfd;
1221 /* bfd_get_target does not return the correct value until
1222 bfd_check_format succeeds. */
1223 if (output_target == NULL)
1224 output_target = bfd_get_target (ibfd);
1226 obfd = bfd_openw (output_filename, output_target);
1227 if (obfd == NULL)
1228 RETURN_NONFATAL (output_filename);
1230 copy_object (ibfd, obfd);
1232 if (!bfd_close (obfd))
1233 RETURN_NONFATAL (output_filename);
1235 if (!bfd_close (ibfd))
1236 RETURN_NONFATAL (input_filename);
1238 else
1240 bfd_nonfatal (input_filename);
1242 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1244 list_matching_formats (matching);
1245 free (matching);
1248 status = 1;
1252 /* Create a section in OBFD with the same name and attributes
1253 as ISECTION in IBFD. */
1255 static void
1256 setup_section (ibfd, isection, obfdarg)
1257 bfd *ibfd;
1258 sec_ptr isection;
1259 PTR obfdarg;
1261 bfd *obfd = (bfd *) obfdarg;
1262 struct section_list *p;
1263 sec_ptr osection;
1264 bfd_size_type size;
1265 bfd_vma vma;
1266 bfd_vma lma;
1267 flagword flags;
1268 const char *err;
1270 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1271 && (strip_symbols == STRIP_DEBUG
1272 || strip_symbols == STRIP_UNNEEDED
1273 || strip_symbols == STRIP_ALL
1274 || discard_locals == LOCALS_ALL
1275 || convert_debugging))
1276 return;
1278 p = find_section_list (bfd_section_name (ibfd, isection), false);
1279 if (p != NULL)
1280 p->used = true;
1282 if (sections_removed && p != NULL && p->remove)
1283 return;
1284 if (sections_copied && (p == NULL || ! p->copy))
1285 return;
1287 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1289 if (osection == NULL)
1291 err = _("making");
1292 goto loser;
1295 size = bfd_section_size (ibfd, isection);
1296 if (copy_byte >= 0)
1297 size = (size + interleave - 1) / interleave;
1298 if (! bfd_set_section_size (obfd, osection, size))
1300 err = _("size");
1301 goto loser;
1304 vma = bfd_section_vma (ibfd, isection);
1305 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1306 vma += p->vma_val;
1307 else if (p != NULL && p->change_vma == CHANGE_SET)
1308 vma = p->vma_val;
1309 else
1310 vma += change_section_address;
1312 if (! bfd_set_section_vma (obfd, osection, vma))
1314 err = _("vma");
1315 goto loser;
1318 lma = isection->lma;
1319 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1321 if (p->change_lma == CHANGE_MODIFY)
1322 lma += p->lma_val;
1323 else if (p->change_lma == CHANGE_SET)
1324 lma = p->lma_val;
1325 else
1326 abort ();
1328 else
1329 lma += change_section_address;
1331 osection->lma = lma;
1333 /* FIXME: This is probably not enough. If we change the LMA we
1334 may have to recompute the header for the file as well. */
1335 if (bfd_set_section_alignment (obfd,
1336 osection,
1337 bfd_section_alignment (ibfd, isection))
1338 == false)
1340 err = _("alignment");
1341 goto loser;
1344 flags = bfd_get_section_flags (ibfd, isection);
1345 if (p != NULL && p->set_flags)
1346 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1347 if (!bfd_set_section_flags (obfd, osection, flags))
1349 err = _("flags");
1350 goto loser;
1353 /* This used to be mangle_section; we do here to avoid using
1354 bfd_get_section_by_name since some formats allow multiple
1355 sections with the same name. */
1356 isection->output_section = osection;
1357 isection->output_offset = 0;
1359 /* Allow the BFD backend to copy any private data it understands
1360 from the input section to the output section. */
1361 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1363 err = _("private data");
1364 goto loser;
1367 /* All went well */
1368 return;
1370 loser:
1371 non_fatal (_("%s: section `%s': error in %s: %s"),
1372 bfd_get_filename (ibfd),
1373 bfd_section_name (ibfd, isection),
1374 err, bfd_errmsg (bfd_get_error ()));
1375 status = 1;
1378 /* Copy the data of input section ISECTION of IBFD
1379 to an output section with the same name in OBFD.
1380 If stripping then don't copy any relocation info. */
1382 static void
1383 copy_section (ibfd, isection, obfdarg)
1384 bfd *ibfd;
1385 sec_ptr isection;
1386 PTR obfdarg;
1388 bfd *obfd = (bfd *) obfdarg;
1389 struct section_list *p;
1390 arelent **relpp;
1391 long relcount;
1392 sec_ptr osection;
1393 bfd_size_type size;
1394 long relsize;
1396 /* If we have already failed earlier on, do not keep on generating
1397 complaints now. */
1398 if (status != 0)
1399 return;
1401 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1402 && (strip_symbols == STRIP_DEBUG
1403 || strip_symbols == STRIP_UNNEEDED
1404 || strip_symbols == STRIP_ALL
1405 || discard_locals == LOCALS_ALL
1406 || convert_debugging))
1408 return;
1411 p = find_section_list (bfd_section_name (ibfd, isection), false);
1413 if (sections_removed && p != NULL && p->remove)
1414 return;
1415 if (sections_copied && (p == NULL || ! p->copy))
1416 return;
1418 osection = isection->output_section;
1419 size = bfd_get_section_size_before_reloc (isection);
1421 if (size == 0 || osection == 0)
1422 return;
1425 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1426 if (relsize < 0)
1427 RETURN_NONFATAL (bfd_get_filename (ibfd));
1429 if (relsize == 0)
1430 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1431 else
1433 relpp = (arelent **) xmalloc (relsize);
1434 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1435 if (relcount < 0)
1436 RETURN_NONFATAL (bfd_get_filename (ibfd));
1438 if (strip_symbols == STRIP_ALL)
1440 /* Remove relocations which are not in
1441 keep_strip_specific_list. */
1442 arelent **temp_relpp;
1443 long temp_relcount = 0;
1444 long i;
1446 temp_relpp = (arelent **) xmalloc (relsize);
1447 for (i = 0; i < relcount; i++)
1448 if (is_specified_symbol
1449 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
1450 keep_specific_list))
1451 temp_relpp [temp_relcount++] = relpp [i];
1452 relcount = temp_relcount;
1453 free (relpp);
1454 relpp = temp_relpp;
1456 bfd_set_reloc (obfd, osection,
1457 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1460 isection->_cooked_size = isection->_raw_size;
1461 isection->reloc_done = true;
1463 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1465 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1467 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1468 size))
1469 RETURN_NONFATAL (bfd_get_filename (ibfd));
1471 if (copy_byte >= 0)
1472 filter_bytes (memhunk, &size);
1474 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1475 size))
1476 RETURN_NONFATAL (bfd_get_filename (obfd));
1478 free (memhunk);
1480 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1482 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1484 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1485 flag--they can just remove the section entirely and add it
1486 back again. However, we do permit them to turn on the
1487 SEC_HAS_CONTENTS flag, and take it to mean that the section
1488 contents should be zeroed out. */
1490 memset (memhunk, 0, size);
1491 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1492 size))
1493 RETURN_NONFATAL (bfd_get_filename (obfd));
1494 free (memhunk);
1498 /* Get all the sections. This is used when --gap-fill or --pad-to is
1499 used. */
1501 static void
1502 get_sections (obfd, osection, secppparg)
1503 bfd *obfd ATTRIBUTE_UNUSED;
1504 asection *osection;
1505 PTR secppparg;
1507 asection ***secppp = (asection ***) secppparg;
1509 **secppp = osection;
1510 ++(*secppp);
1513 /* Sort sections by VMA. This is called via qsort, and is used when
1514 --gap-fill or --pad-to is used. We force non loadable or empty
1515 sections to the front, where they are easier to ignore. */
1517 static int
1518 compare_section_lma (arg1, arg2)
1519 const PTR arg1;
1520 const PTR arg2;
1522 const asection **sec1 = (const asection **) arg1;
1523 const asection **sec2 = (const asection **) arg2;
1524 flagword flags1, flags2;
1526 /* Sort non loadable sections to the front. */
1527 flags1 = (*sec1)->flags;
1528 flags2 = (*sec2)->flags;
1529 if ((flags1 & SEC_HAS_CONTENTS) == 0
1530 || (flags1 & SEC_LOAD) == 0)
1532 if ((flags2 & SEC_HAS_CONTENTS) != 0
1533 && (flags2 & SEC_LOAD) != 0)
1534 return -1;
1536 else
1538 if ((flags2 & SEC_HAS_CONTENTS) == 0
1539 || (flags2 & SEC_LOAD) == 0)
1540 return 1;
1543 /* Sort sections by LMA. */
1544 if ((*sec1)->lma > (*sec2)->lma)
1545 return 1;
1546 else if ((*sec1)->lma < (*sec2)->lma)
1547 return -1;
1549 /* Sort sections with the same LMA by size. */
1550 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1551 return 1;
1552 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1553 return -1;
1555 return 0;
1558 /* Mark all the symbols which will be used in output relocations with
1559 the BSF_KEEP flag so that those symbols will not be stripped.
1561 Ignore relocations which will not appear in the output file. */
1563 static void
1564 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1565 bfd *ibfd;
1566 sec_ptr isection;
1567 PTR symbolsarg;
1569 asymbol **symbols = (asymbol **) symbolsarg;
1570 long relsize;
1571 arelent **relpp;
1572 long relcount, i;
1574 /* Ignore an input section with no corresponding output section. */
1575 if (isection->output_section == NULL)
1576 return;
1578 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1579 if (relsize < 0)
1580 bfd_fatal (bfd_get_filename (ibfd));
1582 if (relsize == 0)
1583 return;
1585 relpp = (arelent **) xmalloc (relsize);
1586 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1587 if (relcount < 0)
1588 bfd_fatal (bfd_get_filename (ibfd));
1590 /* Examine each symbol used in a relocation. If it's not one of the
1591 special bfd section symbols, then mark it with BSF_KEEP. */
1592 for (i = 0; i < relcount; i++)
1594 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1595 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1596 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1597 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1600 if (relpp != NULL)
1601 free (relpp);
1604 /* Write out debugging information. */
1606 static boolean
1607 write_debugging_info (obfd, dhandle, symcountp, symppp)
1608 bfd *obfd;
1609 PTR dhandle;
1610 long *symcountp ATTRIBUTE_UNUSED;
1611 asymbol ***symppp ATTRIBUTE_UNUSED;
1613 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1614 return write_ieee_debugging_info (obfd, dhandle);
1616 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1617 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1619 bfd_byte *syms, *strings;
1620 bfd_size_type symsize, stringsize;
1621 asection *stabsec, *stabstrsec;
1623 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1624 &symsize, &strings,
1625 &stringsize))
1626 return false;
1628 stabsec = bfd_make_section (obfd, ".stab");
1629 stabstrsec = bfd_make_section (obfd, ".stabstr");
1630 if (stabsec == NULL
1631 || stabstrsec == NULL
1632 || ! bfd_set_section_size (obfd, stabsec, symsize)
1633 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1634 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1635 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1636 || ! bfd_set_section_flags (obfd, stabsec,
1637 (SEC_HAS_CONTENTS
1638 | SEC_READONLY
1639 | SEC_DEBUGGING))
1640 || ! bfd_set_section_flags (obfd, stabstrsec,
1641 (SEC_HAS_CONTENTS
1642 | SEC_READONLY
1643 | SEC_DEBUGGING)))
1645 non_fatal (_("%s: can't create debugging section: %s"),
1646 bfd_get_filename (obfd),
1647 bfd_errmsg (bfd_get_error ()));
1648 return false;
1651 /* We can get away with setting the section contents now because
1652 the next thing the caller is going to do is copy over the
1653 real sections. We may someday have to split the contents
1654 setting out of this function. */
1655 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1656 symsize)
1657 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1658 (file_ptr) 0, stringsize))
1660 non_fatal (_("%s: can't set debugging section contents: %s"),
1661 bfd_get_filename (obfd),
1662 bfd_errmsg (bfd_get_error ()));
1663 return false;
1666 return true;
1669 non_fatal (_("%s: don't know how to write debugging information for %s"),
1670 bfd_get_filename (obfd), bfd_get_target (obfd));
1671 return false;
1674 static int
1675 strip_main (argc, argv)
1676 int argc;
1677 char *argv[];
1679 char *input_target = NULL, *output_target = NULL;
1680 boolean show_version = false;
1681 int c, i;
1682 struct section_list *p;
1683 char *output_file = NULL;
1685 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1686 strip_options, (int *) 0)) != EOF)
1688 switch (c)
1690 case 'I':
1691 input_target = optarg;
1692 break;
1693 case 'O':
1694 output_target = optarg;
1695 break;
1696 case 'F':
1697 input_target = output_target = optarg;
1698 break;
1699 case 'R':
1700 p = find_section_list (optarg, true);
1701 p->remove = true;
1702 sections_removed = true;
1703 break;
1704 case 's':
1705 strip_symbols = STRIP_ALL;
1706 break;
1707 case 'S':
1708 case 'g':
1709 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1710 strip_symbols = STRIP_DEBUG;
1711 break;
1712 case OPTION_STRIP_UNNEEDED:
1713 strip_symbols = STRIP_UNNEEDED;
1714 break;
1715 case 'K':
1716 add_specific_symbol (optarg, &keep_specific_list);
1717 break;
1718 case 'N':
1719 add_specific_symbol (optarg, &strip_specific_list);
1720 break;
1721 case 'o':
1722 output_file = optarg;
1723 break;
1724 case 'p':
1725 preserve_dates = true;
1726 break;
1727 case 'x':
1728 discard_locals = LOCALS_ALL;
1729 break;
1730 case 'X':
1731 discard_locals = LOCALS_START_L;
1732 break;
1733 case 'v':
1734 verbose = true;
1735 break;
1736 case 'V':
1737 show_version = true;
1738 break;
1739 case 0:
1740 break; /* we've been given a long option */
1741 case 'h':
1742 strip_usage (stdout, 0);
1743 default:
1744 strip_usage (stderr, 1);
1748 if (show_version)
1749 print_version ("strip");
1751 /* Default is to strip all symbols. */
1752 if (strip_symbols == STRIP_UNDEF
1753 && discard_locals == LOCALS_UNDEF
1754 && strip_specific_list == NULL)
1755 strip_symbols = STRIP_ALL;
1757 if (output_target == (char *) NULL)
1758 output_target = input_target;
1760 i = optind;
1761 if (i == argc
1762 || (output_file != NULL && (i + 1) < argc))
1763 strip_usage (stderr, 1);
1765 for (; i < argc; i++)
1767 int hold_status = status;
1768 struct stat statbuf;
1769 char *tmpname;
1771 if (preserve_dates)
1773 if (stat (argv[i], &statbuf) < 0)
1775 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1776 continue;
1780 if (output_file != NULL)
1781 tmpname = output_file;
1782 else
1783 tmpname = make_tempname (argv[i]);
1784 status = 0;
1786 copy_file (argv[i], tmpname, input_target, output_target);
1787 if (status == 0)
1789 if (preserve_dates)
1790 set_times (tmpname, &statbuf);
1791 if (output_file == NULL)
1792 smart_rename (tmpname, argv[i], preserve_dates);
1793 status = hold_status;
1795 else
1796 unlink (tmpname);
1797 if (output_file == NULL)
1798 free (tmpname);
1801 return 0;
1804 static int
1805 copy_main (argc, argv)
1806 int argc;
1807 char *argv[];
1809 char *input_filename = NULL, *output_filename = NULL;
1810 char *input_target = NULL, *output_target = NULL;
1811 boolean show_version = false;
1812 boolean change_warn = true;
1813 int c;
1814 struct section_list *p;
1815 struct stat statbuf;
1817 while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
1818 copy_options, (int *) 0)) != EOF)
1820 switch (c)
1822 case 'b':
1823 copy_byte = atoi (optarg);
1824 if (copy_byte < 0)
1825 fatal (_("byte number must be non-negative"));
1826 break;
1828 case 'i':
1829 interleave = atoi (optarg);
1830 if (interleave < 1)
1831 fatal (_("interleave must be positive"));
1832 break;
1834 case 'I':
1835 case 's': /* "source" - 'I' is preferred */
1836 input_target = optarg;
1837 break;
1839 case 'O':
1840 case 'd': /* "destination" - 'O' is preferred */
1841 output_target = optarg;
1842 break;
1844 case 'F':
1845 input_target = output_target = optarg;
1846 break;
1848 case 'j':
1849 p = find_section_list (optarg, true);
1850 if (p->remove)
1851 fatal (_("%s both copied and removed"), optarg);
1852 p->copy = true;
1853 sections_copied = true;
1854 break;
1856 case 'R':
1857 p = find_section_list (optarg, true);
1858 if (p->copy)
1859 fatal (_("%s both copied and removed"), optarg);
1860 p->remove = true;
1861 sections_removed = true;
1862 break;
1864 case 'S':
1865 strip_symbols = STRIP_ALL;
1866 break;
1868 case 'g':
1869 strip_symbols = STRIP_DEBUG;
1870 break;
1872 case OPTION_STRIP_UNNEEDED:
1873 strip_symbols = STRIP_UNNEEDED;
1874 break;
1876 case 'K':
1877 add_specific_symbol (optarg, &keep_specific_list);
1878 break;
1880 case 'N':
1881 add_specific_symbol (optarg, &strip_specific_list);
1882 break;
1884 case 'L':
1885 add_specific_symbol (optarg, &localize_specific_list);
1886 break;
1888 case 'W':
1889 add_specific_symbol (optarg, &weaken_specific_list);
1890 break;
1892 case 'p':
1893 preserve_dates = true;
1894 break;
1896 case 'x':
1897 discard_locals = LOCALS_ALL;
1898 break;
1900 case 'X':
1901 discard_locals = LOCALS_START_L;
1902 break;
1904 case 'v':
1905 verbose = true;
1906 break;
1908 case 'V':
1909 show_version = true;
1910 break;
1912 case OPTION_WEAKEN:
1913 weaken = true;
1914 break;
1916 case OPTION_ADD_SECTION:
1918 const char *s;
1919 struct stat st;
1920 struct section_add *pa;
1921 int len;
1922 char *name;
1923 FILE *f;
1925 s = strchr (optarg, '=');
1927 if (s == NULL)
1928 fatal (_("bad format for %s"), "--add-section");
1930 if (stat (s + 1, & st) < 0)
1931 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
1933 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1935 len = s - optarg;
1936 name = (char *) xmalloc (len + 1);
1937 strncpy (name, optarg, len);
1938 name[len] = '\0';
1939 pa->name = name;
1941 pa->filename = s + 1;
1943 pa->size = st.st_size;
1945 pa->contents = (bfd_byte *) xmalloc (pa->size);
1946 f = fopen (pa->filename, FOPEN_RB);
1948 if (f == NULL)
1949 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
1951 if (fread (pa->contents, 1, pa->size, f) == 0
1952 || ferror (f))
1953 fatal (_("%s: fread failed"), pa->filename);
1955 fclose (f);
1957 pa->next = add_sections;
1958 add_sections = pa;
1960 break;
1962 case OPTION_CHANGE_START:
1963 change_start = parse_vma (optarg, "--change-start");
1964 break;
1966 case OPTION_CHANGE_SECTION_ADDRESS:
1967 case OPTION_CHANGE_SECTION_LMA:
1968 case OPTION_CHANGE_SECTION_VMA:
1970 const char *s;
1971 int len;
1972 char *name;
1973 char *option = NULL;
1974 bfd_vma val;
1975 enum change_action what = CHANGE_IGNORE;
1977 switch (c)
1979 case OPTION_CHANGE_SECTION_ADDRESS:
1980 option = "--change-section-address";
1981 break;
1982 case OPTION_CHANGE_SECTION_LMA:
1983 option = "--change-section-lma";
1984 break;
1985 case OPTION_CHANGE_SECTION_VMA:
1986 option = "--change-section-vma";
1987 break;
1990 s = strchr (optarg, '=');
1991 if (s == NULL)
1993 s = strchr (optarg, '+');
1994 if (s == NULL)
1996 s = strchr (optarg, '-');
1997 if (s == NULL)
1998 fatal (_("bad format for %s"), option);
2002 len = s - optarg;
2003 name = (char *) xmalloc (len + 1);
2004 strncpy (name, optarg, len);
2005 name[len] = '\0';
2007 p = find_section_list (name, true);
2009 val = parse_vma (s + 1, option);
2011 switch (*s)
2013 case '=': what = CHANGE_SET; break;
2014 case '-': val = - val; /* Drop through. */
2015 case '+': what = CHANGE_MODIFY; break;
2018 switch (c)
2020 case OPTION_CHANGE_SECTION_ADDRESS:
2021 p->change_vma = what;
2022 p->vma_val = val;
2023 /* Drop through. */
2025 case OPTION_CHANGE_SECTION_LMA:
2026 p->change_lma = what;
2027 p->lma_val = val;
2028 break;
2030 case OPTION_CHANGE_SECTION_VMA:
2031 p->change_vma = what;
2032 p->vma_val = val;
2033 break;
2036 break;
2038 case OPTION_CHANGE_ADDRESSES:
2039 change_section_address = parse_vma (optarg, "--change-addresses");
2040 change_start = change_section_address;
2041 break;
2043 case OPTION_CHANGE_WARNINGS:
2044 change_warn = true;
2045 break;
2047 case OPTION_CHANGE_LEADING_CHAR:
2048 change_leading_char = true;
2049 break;
2051 case OPTION_DEBUGGING:
2052 convert_debugging = true;
2053 break;
2055 case OPTION_GAP_FILL:
2057 bfd_vma gap_fill_vma;
2059 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2060 gap_fill = (bfd_byte) gap_fill_vma;
2061 if ((bfd_vma) gap_fill != gap_fill_vma)
2063 char buff[20];
2065 sprintf_vma (buff, gap_fill_vma);
2067 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2068 buff, gap_fill);
2070 gap_fill_set = true;
2072 break;
2074 case OPTION_NO_CHANGE_WARNINGS:
2075 change_warn = false;
2076 break;
2078 case OPTION_PAD_TO:
2079 pad_to = parse_vma (optarg, "--pad-to");
2080 pad_to_set = true;
2081 break;
2083 case OPTION_REMOVE_LEADING_CHAR:
2084 remove_leading_char = true;
2085 break;
2087 case OPTION_REDEFINE_SYM:
2089 /* Push this redefinition onto redefine_symbol_list. */
2091 int len;
2092 const char *s;
2093 const char *nextarg;
2094 char *source, *target;
2096 s = strchr (optarg, '=');
2097 if (s == NULL)
2099 fatal (_("bad format for %s"), "--redefine-sym");
2102 len = s - optarg;
2103 source = (char *) xmalloc (len + 1);
2104 strncpy (source, optarg, len);
2105 source[len] = '\0';
2107 nextarg = s + 1;
2108 len = strlen (nextarg);
2109 target = (char *) xmalloc (len + 1);
2110 strcpy (target, nextarg);
2112 redefine_list_append (source, target);
2114 free (source);
2115 free (target);
2117 break;
2119 case OPTION_SET_SECTION_FLAGS:
2121 const char *s;
2122 int len;
2123 char *name;
2125 s = strchr (optarg, '=');
2126 if (s == NULL)
2127 fatal (_("bad format for %s"), "--set-section-flags");
2129 len = s - optarg;
2130 name = (char *) xmalloc (len + 1);
2131 strncpy (name, optarg, len);
2132 name[len] = '\0';
2134 p = find_section_list (name, true);
2136 p->set_flags = true;
2137 p->flags = parse_flags (s + 1);
2139 break;
2141 case OPTION_SET_START:
2142 set_start = parse_vma (optarg, "--set-start");
2143 set_start_set = true;
2144 break;
2146 case OPTION_SREC_LEN:
2147 Chunk = parse_vma (optarg, "--srec-len");
2148 break;
2150 case OPTION_SREC_FORCES3:
2151 S3Forced = true;
2152 break;
2154 case 0:
2155 break; /* we've been given a long option */
2157 case 'h':
2158 copy_usage (stdout, 0);
2160 default:
2161 copy_usage (stderr, 1);
2165 if (show_version)
2166 print_version ("objcopy");
2168 if (copy_byte >= interleave)
2169 fatal (_("byte number must be less than interleave"));
2171 if (optind == argc || optind + 2 < argc)
2172 copy_usage (stderr, 1);
2174 input_filename = argv[optind];
2175 if (optind + 1 < argc)
2176 output_filename = argv[optind + 1];
2178 /* Default is to strip no symbols. */
2179 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2180 strip_symbols = STRIP_NONE;
2182 if (output_target == (char *) NULL)
2183 output_target = input_target;
2185 if (preserve_dates)
2187 if (stat (input_filename, &statbuf) < 0)
2188 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2191 /* If there is no destination file then create a temp and rename
2192 the result into the input. */
2194 if (output_filename == (char *) NULL)
2196 char *tmpname = make_tempname (input_filename);
2198 copy_file (input_filename, tmpname, input_target, output_target);
2199 if (status == 0)
2201 if (preserve_dates)
2202 set_times (tmpname, &statbuf);
2203 smart_rename (tmpname, input_filename, preserve_dates);
2205 else
2206 unlink (tmpname);
2208 else
2210 copy_file (input_filename, output_filename, input_target, output_target);
2211 if (status == 0 && preserve_dates)
2212 set_times (output_filename, &statbuf);
2215 if (change_warn)
2217 for (p = change_sections; p != NULL; p = p->next)
2219 if (! p->used)
2221 if (p->change_vma != CHANGE_IGNORE)
2223 char buff [20];
2225 sprintf_vma (buff, p->vma_val);
2227 /* xgettext:c-format */
2228 non_fatal (_("%s %s%c0x%s never used"),
2229 "--change-section-vma",
2230 p->name,
2231 p->change_vma == CHANGE_SET ? '=' : '+',
2232 buff);
2235 if (p->change_lma != CHANGE_IGNORE)
2237 char buff [20];
2239 sprintf_vma (buff, p->lma_val);
2241 /* xgettext:c-format */
2242 non_fatal (_("%s %s%c0x%s never used"),
2243 "--change-section-lma",
2244 p->name,
2245 p->change_lma == CHANGE_SET ? '=' : '+',
2246 buff);
2252 return 0;
2256 main (argc, argv)
2257 int argc;
2258 char *argv[];
2260 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2261 setlocale (LC_MESSAGES, "");
2262 #endif
2263 bindtextdomain (PACKAGE, LOCALEDIR);
2264 textdomain (PACKAGE);
2266 program_name = argv[0];
2267 xmalloc_set_program_name (program_name);
2269 START_PROGRESS (program_name, 0);
2271 strip_symbols = STRIP_UNDEF;
2272 discard_locals = LOCALS_UNDEF;
2274 bfd_init ();
2275 set_default_bfd_target ();
2277 if (is_strip < 0)
2279 int i = strlen (program_name);
2280 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2281 /* Drop the .exe suffix, if any. */
2282 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2284 i -= 4;
2285 program_name[i] = '\0';
2287 #endif
2288 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2291 if (is_strip)
2292 strip_main (argc, argv);
2293 else
2294 copy_main (argc, argv);
2296 END_PROGRESS (program_name);
2298 return status;