Update generated configure scripts.
[binutils.git] / binutils / objcopy.c
blobcae66fc87fbaae7674281cf476216939521052d5
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, 2001
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;
768 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
769 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
770 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
772 fatal (_("Unable to change endianness of input file(s)"));
773 return;
776 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
777 RETURN_NONFATAL (bfd_get_filename (obfd));
779 if (verbose)
780 printf (_("copy from %s(%s) to %s(%s)\n"),
781 bfd_get_filename (ibfd), bfd_get_target (ibfd),
782 bfd_get_filename (obfd), bfd_get_target (obfd));
784 if (set_start_set)
785 start = set_start;
786 else
787 start = bfd_get_start_address (ibfd);
788 start += change_start;
790 if (!bfd_set_start_address (obfd, start)
791 || !bfd_set_file_flags (obfd,
792 (bfd_get_file_flags (ibfd)
793 & bfd_applicable_file_flags (obfd))))
794 RETURN_NONFATAL (bfd_get_filename (ibfd));
796 /* Copy architecture of input file to output file */
797 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
798 bfd_get_mach (ibfd)))
799 non_fatal (_("Warning: Output file cannot represent architecture %s"),
800 bfd_printable_arch_mach (bfd_get_arch (ibfd),
801 bfd_get_mach (ibfd)));
803 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
804 RETURN_NONFATAL (bfd_get_filename (ibfd));
806 if (isympp)
807 free (isympp);
809 if (osympp != isympp)
810 free (osympp);
812 /* BFD mandates that all output sections be created and sizes set before
813 any output is done. Thus, we traverse all sections multiple times. */
814 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
816 if (add_sections != NULL)
818 struct section_add *padd;
819 struct section_list *pset;
821 for (padd = add_sections; padd != NULL; padd = padd->next)
823 padd->section = bfd_make_section (obfd, padd->name);
824 if (padd->section == NULL)
826 non_fatal (_("can't create section `%s': %s"),
827 padd->name, bfd_errmsg (bfd_get_error ()));
828 status = 1;
829 return;
831 else
833 flagword flags;
835 if (! bfd_set_section_size (obfd, padd->section, padd->size))
836 RETURN_NONFATAL (bfd_get_filename (obfd));
838 pset = find_section_list (padd->name, false);
839 if (pset != NULL)
840 pset->used = true;
842 if (pset != NULL && pset->set_flags)
843 flags = pset->flags | SEC_HAS_CONTENTS;
844 else
845 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
847 if (! bfd_set_section_flags (obfd, padd->section, flags))
848 RETURN_NONFATAL (bfd_get_filename (obfd));
850 if (pset != NULL)
852 if (pset->change_vma != CHANGE_IGNORE)
853 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
854 RETURN_NONFATAL (bfd_get_filename (obfd));
856 if (pset->change_lma != CHANGE_IGNORE)
858 padd->section->lma = pset->lma_val;
860 if (! bfd_set_section_alignment
861 (obfd, padd->section,
862 bfd_section_alignment (obfd, padd->section)))
863 RETURN_NONFATAL (bfd_get_filename (obfd));
870 if (gap_fill_set || pad_to_set)
872 asection **set;
873 unsigned int c, i;
875 /* We must fill in gaps between the sections and/or we must pad
876 the last section to a specified address. We do this by
877 grabbing a list of the sections, sorting them by VMA, and
878 increasing the section sizes as required to fill the gaps.
879 We write out the gap contents below. */
881 c = bfd_count_sections (obfd);
882 osections = (asection **) xmalloc (c * sizeof (asection *));
883 set = osections;
884 bfd_map_over_sections (obfd, get_sections, (void *) &set);
886 qsort (osections, c, sizeof (asection *), compare_section_lma);
888 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
889 memset (gaps, 0, c * sizeof (bfd_size_type));
891 if (gap_fill_set)
893 for (i = 0; i < c - 1; i++)
895 flagword flags;
896 bfd_size_type size;
897 bfd_vma gap_start, gap_stop;
899 flags = bfd_get_section_flags (obfd, osections[i]);
900 if ((flags & SEC_HAS_CONTENTS) == 0
901 || (flags & SEC_LOAD) == 0)
902 continue;
904 size = bfd_section_size (obfd, osections[i]);
905 gap_start = bfd_section_lma (obfd, osections[i]) + size;
906 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
907 if (gap_start < gap_stop)
909 if (! bfd_set_section_size (obfd, osections[i],
910 size + (gap_stop - gap_start)))
912 non_fatal (_("Can't fill gap after %s: %s"),
913 bfd_get_section_name (obfd, osections[i]),
914 bfd_errmsg (bfd_get_error ()));
915 status = 1;
916 break;
918 gaps[i] = gap_stop - gap_start;
919 if (max_gap < gap_stop - gap_start)
920 max_gap = gap_stop - gap_start;
925 if (pad_to_set)
927 bfd_vma lma;
928 bfd_size_type size;
930 lma = bfd_section_lma (obfd, osections[c - 1]);
931 size = bfd_section_size (obfd, osections[c - 1]);
932 if (lma + size < pad_to)
934 if (! bfd_set_section_size (obfd, osections[c - 1],
935 pad_to - lma))
937 non_fatal (_("Can't add padding to %s: %s"),
938 bfd_get_section_name (obfd, osections[c - 1]),
939 bfd_errmsg (bfd_get_error ()));
940 status = 1;
942 else
944 gaps[c - 1] = pad_to - (lma + size);
945 if (max_gap < pad_to - (lma + size))
946 max_gap = pad_to - (lma + size);
952 /* Symbol filtering must happen after the output sections have
953 been created, but before their contents are set. */
954 dhandle = NULL;
955 symsize = bfd_get_symtab_upper_bound (ibfd);
956 if (symsize < 0)
957 RETURN_NONFATAL (bfd_get_filename (ibfd));
959 osympp = isympp = (asymbol **) xmalloc (symsize);
960 symcount = bfd_canonicalize_symtab (ibfd, isympp);
961 if (symcount < 0)
962 RETURN_NONFATAL (bfd_get_filename (ibfd));
964 if (convert_debugging)
965 dhandle = read_debugging_info (ibfd, isympp, symcount);
967 if (strip_symbols == STRIP_DEBUG
968 || strip_symbols == STRIP_ALL
969 || strip_symbols == STRIP_UNNEEDED
970 || discard_locals != LOCALS_UNDEF
971 || strip_specific_list != NULL
972 || keep_specific_list != NULL
973 || localize_specific_list != NULL
974 || weaken_specific_list != NULL
975 || sections_removed
976 || sections_copied
977 || convert_debugging
978 || change_leading_char
979 || remove_leading_char
980 || redefine_sym_list
981 || weaken)
983 /* Mark symbols used in output relocations so that they
984 are kept, even if they are local labels or static symbols.
986 Note we iterate over the input sections examining their
987 relocations since the relocations for the output sections
988 haven't been set yet. mark_symbols_used_in_relocations will
989 ignore input sections which have no corresponding output
990 section. */
991 if (strip_symbols != STRIP_ALL)
992 bfd_map_over_sections (ibfd,
993 mark_symbols_used_in_relocations,
994 (PTR)isympp);
995 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
996 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
999 if (convert_debugging && dhandle != NULL)
1001 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1003 status = 1;
1004 return;
1008 bfd_set_symtab (obfd, osympp, symcount);
1010 /* This has to happen after the symbol table has been set. */
1011 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1013 if (add_sections != NULL)
1015 struct section_add *padd;
1017 for (padd = add_sections; padd != NULL; padd = padd->next)
1019 if (! bfd_set_section_contents (obfd, padd->section,
1020 (PTR) padd->contents,
1021 (file_ptr) 0,
1022 (bfd_size_type) padd->size))
1023 RETURN_NONFATAL (bfd_get_filename (obfd));
1027 if (gap_fill_set || pad_to_set)
1029 bfd_byte *buf;
1030 int c, i;
1032 /* Fill in the gaps. */
1034 if (max_gap > 8192)
1035 max_gap = 8192;
1036 buf = (bfd_byte *) xmalloc (max_gap);
1037 memset (buf, gap_fill, (size_t) max_gap);
1039 c = bfd_count_sections (obfd);
1040 for (i = 0; i < c; i++)
1042 if (gaps[i] != 0)
1044 bfd_size_type left;
1045 file_ptr off;
1047 left = gaps[i];
1048 off = bfd_section_size (obfd, osections[i]) - left;
1049 while (left > 0)
1051 bfd_size_type now;
1053 if (left > 8192)
1054 now = 8192;
1055 else
1056 now = left;
1058 if (! bfd_set_section_contents (obfd, osections[i], buf,
1059 off, now))
1060 RETURN_NONFATAL (bfd_get_filename (obfd));
1062 left -= now;
1063 off += now;
1069 /* Allow the BFD backend to copy any private data it understands
1070 from the input BFD to the output BFD. This is done last to
1071 permit the routine to look at the filtered symbol table, which is
1072 important for the ECOFF code at least. */
1073 if (!bfd_copy_private_bfd_data (ibfd, obfd))
1075 non_fatal (_("%s: error copying private BFD data: %s"),
1076 bfd_get_filename (obfd),
1077 bfd_errmsg (bfd_get_error ()));
1078 status = 1;
1079 return;
1083 /* Read each archive element in turn from IBFD, copy the
1084 contents to temp file, and keep the temp file handle. */
1086 static void
1087 copy_archive (ibfd, obfd, output_target)
1088 bfd *ibfd;
1089 bfd *obfd;
1090 const char *output_target;
1092 struct name_list
1094 struct name_list *next;
1095 char *name;
1096 bfd *obfd;
1097 } *list, *l;
1098 bfd **ptr = &obfd->archive_head;
1099 bfd *this_element;
1100 char *dir = make_tempname (bfd_get_filename (obfd));
1102 /* Make a temp directory to hold the contents. */
1103 #if defined (_WIN32) && !defined (__CYGWIN32__)
1104 if (mkdir (dir) != 0)
1105 #else
1106 if (mkdir (dir, 0700) != 0)
1107 #endif
1109 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1110 dir, strerror (errno));
1112 obfd->has_armap = ibfd->has_armap;
1114 list = NULL;
1116 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1117 while (!status && this_element != (bfd *) NULL)
1119 /* Create an output file for this member. */
1120 char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1121 (char *) NULL);
1122 bfd *output_bfd = bfd_openw (output_name, output_target);
1123 bfd *last_element;
1124 struct stat buf;
1125 int stat_status = 0;
1127 if (preserve_dates)
1129 stat_status = bfd_stat_arch_elt (this_element, &buf);
1130 if (stat_status != 0)
1131 non_fatal (_("internal stat error on %s"),
1132 bfd_get_filename (this_element));
1135 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1136 l->name = output_name;
1137 l->next = list;
1138 list = l;
1140 if (output_bfd == (bfd *) NULL)
1141 RETURN_NONFATAL (output_name);
1143 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1144 RETURN_NONFATAL (bfd_get_filename (obfd));
1146 if (bfd_check_format (this_element, bfd_object) == true)
1147 copy_object (this_element, output_bfd);
1149 if (!bfd_close (output_bfd))
1151 bfd_nonfatal (bfd_get_filename (output_bfd));
1152 /* Error in new object file. Don't change archive. */
1153 status = 1;
1156 if (preserve_dates && stat_status == 0)
1157 set_times (output_name, &buf);
1159 /* Open the newly output file and attach to our list. */
1160 output_bfd = bfd_openr (output_name, output_target);
1162 l->obfd = output_bfd;
1164 *ptr = output_bfd;
1165 ptr = &output_bfd->next;
1167 last_element = this_element;
1169 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1171 bfd_close (last_element);
1173 *ptr = (bfd *) NULL;
1175 if (!bfd_close (obfd))
1176 RETURN_NONFATAL (bfd_get_filename (obfd));
1178 if (!bfd_close (ibfd))
1179 RETURN_NONFATAL (bfd_get_filename (ibfd));
1181 /* Delete all the files that we opened. */
1182 for (l = list; l != NULL; l = l->next)
1184 bfd_close (l->obfd);
1185 unlink (l->name);
1187 rmdir (dir);
1190 /* The top-level control. */
1192 static void
1193 copy_file (input_filename, output_filename, input_target, output_target)
1194 const char *input_filename;
1195 const char *output_filename;
1196 const char *input_target;
1197 const char *output_target;
1199 bfd *ibfd;
1200 char **matching;
1202 /* To allow us to do "strip *" without dying on the first
1203 non-object file, failures are nonfatal. */
1205 ibfd = bfd_openr (input_filename, input_target);
1206 if (ibfd == NULL)
1207 RETURN_NONFATAL (input_filename);
1209 if (bfd_check_format (ibfd, bfd_archive))
1211 bfd *obfd;
1213 /* bfd_get_target does not return the correct value until
1214 bfd_check_format succeeds. */
1215 if (output_target == NULL)
1216 output_target = bfd_get_target (ibfd);
1218 obfd = bfd_openw (output_filename, output_target);
1219 if (obfd == NULL)
1220 RETURN_NONFATAL (output_filename);
1222 copy_archive (ibfd, obfd, output_target);
1224 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1226 bfd *obfd;
1228 /* bfd_get_target does not return the correct value until
1229 bfd_check_format succeeds. */
1230 if (output_target == NULL)
1231 output_target = bfd_get_target (ibfd);
1233 obfd = bfd_openw (output_filename, output_target);
1234 if (obfd == NULL)
1235 RETURN_NONFATAL (output_filename);
1237 copy_object (ibfd, obfd);
1239 if (!bfd_close (obfd))
1240 RETURN_NONFATAL (output_filename);
1242 if (!bfd_close (ibfd))
1243 RETURN_NONFATAL (input_filename);
1245 else
1247 bfd_nonfatal (input_filename);
1249 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1251 list_matching_formats (matching);
1252 free (matching);
1255 status = 1;
1259 /* Create a section in OBFD with the same name and attributes
1260 as ISECTION in IBFD. */
1262 static void
1263 setup_section (ibfd, isection, obfdarg)
1264 bfd *ibfd;
1265 sec_ptr isection;
1266 PTR obfdarg;
1268 bfd *obfd = (bfd *) obfdarg;
1269 struct section_list *p;
1270 sec_ptr osection;
1271 bfd_size_type size;
1272 bfd_vma vma;
1273 bfd_vma lma;
1274 flagword flags;
1275 const char *err;
1277 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1278 && (strip_symbols == STRIP_DEBUG
1279 || strip_symbols == STRIP_UNNEEDED
1280 || strip_symbols == STRIP_ALL
1281 || discard_locals == LOCALS_ALL
1282 || convert_debugging))
1283 return;
1285 p = find_section_list (bfd_section_name (ibfd, isection), false);
1286 if (p != NULL)
1287 p->used = true;
1289 if (sections_removed && p != NULL && p->remove)
1290 return;
1291 if (sections_copied && (p == NULL || ! p->copy))
1292 return;
1294 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1296 if (osection == NULL)
1298 err = _("making");
1299 goto loser;
1302 size = bfd_section_size (ibfd, isection);
1303 if (copy_byte >= 0)
1304 size = (size + interleave - 1) / interleave;
1305 if (! bfd_set_section_size (obfd, osection, size))
1307 err = _("size");
1308 goto loser;
1311 vma = bfd_section_vma (ibfd, isection);
1312 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1313 vma += p->vma_val;
1314 else if (p != NULL && p->change_vma == CHANGE_SET)
1315 vma = p->vma_val;
1316 else
1317 vma += change_section_address;
1319 if (! bfd_set_section_vma (obfd, osection, vma))
1321 err = _("vma");
1322 goto loser;
1325 lma = isection->lma;
1326 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1328 if (p->change_lma == CHANGE_MODIFY)
1329 lma += p->lma_val;
1330 else if (p->change_lma == CHANGE_SET)
1331 lma = p->lma_val;
1332 else
1333 abort ();
1335 else
1336 lma += change_section_address;
1338 osection->lma = lma;
1340 /* FIXME: This is probably not enough. If we change the LMA we
1341 may have to recompute the header for the file as well. */
1342 if (bfd_set_section_alignment (obfd,
1343 osection,
1344 bfd_section_alignment (ibfd, isection))
1345 == false)
1347 err = _("alignment");
1348 goto loser;
1351 flags = bfd_get_section_flags (ibfd, isection);
1352 if (p != NULL && p->set_flags)
1353 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1354 if (!bfd_set_section_flags (obfd, osection, flags))
1356 err = _("flags");
1357 goto loser;
1360 /* This used to be mangle_section; we do here to avoid using
1361 bfd_get_section_by_name since some formats allow multiple
1362 sections with the same name. */
1363 isection->output_section = osection;
1364 isection->output_offset = 0;
1366 /* Allow the BFD backend to copy any private data it understands
1367 from the input section to the output section. */
1368 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1370 err = _("private data");
1371 goto loser;
1374 /* All went well */
1375 return;
1377 loser:
1378 non_fatal (_("%s: section `%s': error in %s: %s"),
1379 bfd_get_filename (ibfd),
1380 bfd_section_name (ibfd, isection),
1381 err, bfd_errmsg (bfd_get_error ()));
1382 status = 1;
1385 /* Copy the data of input section ISECTION of IBFD
1386 to an output section with the same name in OBFD.
1387 If stripping then don't copy any relocation info. */
1389 static void
1390 copy_section (ibfd, isection, obfdarg)
1391 bfd *ibfd;
1392 sec_ptr isection;
1393 PTR obfdarg;
1395 bfd *obfd = (bfd *) obfdarg;
1396 struct section_list *p;
1397 arelent **relpp;
1398 long relcount;
1399 sec_ptr osection;
1400 bfd_size_type size;
1401 long relsize;
1403 /* If we have already failed earlier on, do not keep on generating
1404 complaints now. */
1405 if (status != 0)
1406 return;
1408 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1409 && (strip_symbols == STRIP_DEBUG
1410 || strip_symbols == STRIP_UNNEEDED
1411 || strip_symbols == STRIP_ALL
1412 || discard_locals == LOCALS_ALL
1413 || convert_debugging))
1415 return;
1418 p = find_section_list (bfd_section_name (ibfd, isection), false);
1420 if (sections_removed && p != NULL && p->remove)
1421 return;
1422 if (sections_copied && (p == NULL || ! p->copy))
1423 return;
1425 osection = isection->output_section;
1426 size = bfd_get_section_size_before_reloc (isection);
1428 if (size == 0 || osection == 0)
1429 return;
1432 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1433 if (relsize < 0)
1434 RETURN_NONFATAL (bfd_get_filename (ibfd));
1436 if (relsize == 0)
1437 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1438 else
1440 relpp = (arelent **) xmalloc (relsize);
1441 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1442 if (relcount < 0)
1443 RETURN_NONFATAL (bfd_get_filename (ibfd));
1445 if (strip_symbols == STRIP_ALL)
1447 /* Remove relocations which are not in
1448 keep_strip_specific_list. */
1449 arelent **temp_relpp;
1450 long temp_relcount = 0;
1451 long i;
1453 temp_relpp = (arelent **) xmalloc (relsize);
1454 for (i = 0; i < relcount; i++)
1455 if (is_specified_symbol
1456 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
1457 keep_specific_list))
1458 temp_relpp [temp_relcount++] = relpp [i];
1459 relcount = temp_relcount;
1460 free (relpp);
1461 relpp = temp_relpp;
1463 bfd_set_reloc (obfd, osection,
1464 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1467 isection->_cooked_size = isection->_raw_size;
1468 isection->reloc_done = true;
1470 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1472 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1474 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1475 size))
1476 RETURN_NONFATAL (bfd_get_filename (ibfd));
1478 if (copy_byte >= 0)
1479 filter_bytes (memhunk, &size);
1481 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1482 size))
1483 RETURN_NONFATAL (bfd_get_filename (obfd));
1485 free (memhunk);
1487 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1489 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1491 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1492 flag--they can just remove the section entirely and add it
1493 back again. However, we do permit them to turn on the
1494 SEC_HAS_CONTENTS flag, and take it to mean that the section
1495 contents should be zeroed out. */
1497 memset (memhunk, 0, size);
1498 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1499 size))
1500 RETURN_NONFATAL (bfd_get_filename (obfd));
1501 free (memhunk);
1505 /* Get all the sections. This is used when --gap-fill or --pad-to is
1506 used. */
1508 static void
1509 get_sections (obfd, osection, secppparg)
1510 bfd *obfd ATTRIBUTE_UNUSED;
1511 asection *osection;
1512 PTR secppparg;
1514 asection ***secppp = (asection ***) secppparg;
1516 **secppp = osection;
1517 ++(*secppp);
1520 /* Sort sections by VMA. This is called via qsort, and is used when
1521 --gap-fill or --pad-to is used. We force non loadable or empty
1522 sections to the front, where they are easier to ignore. */
1524 static int
1525 compare_section_lma (arg1, arg2)
1526 const PTR arg1;
1527 const PTR arg2;
1529 const asection **sec1 = (const asection **) arg1;
1530 const asection **sec2 = (const asection **) arg2;
1531 flagword flags1, flags2;
1533 /* Sort non loadable sections to the front. */
1534 flags1 = (*sec1)->flags;
1535 flags2 = (*sec2)->flags;
1536 if ((flags1 & SEC_HAS_CONTENTS) == 0
1537 || (flags1 & SEC_LOAD) == 0)
1539 if ((flags2 & SEC_HAS_CONTENTS) != 0
1540 && (flags2 & SEC_LOAD) != 0)
1541 return -1;
1543 else
1545 if ((flags2 & SEC_HAS_CONTENTS) == 0
1546 || (flags2 & SEC_LOAD) == 0)
1547 return 1;
1550 /* Sort sections by LMA. */
1551 if ((*sec1)->lma > (*sec2)->lma)
1552 return 1;
1553 else if ((*sec1)->lma < (*sec2)->lma)
1554 return -1;
1556 /* Sort sections with the same LMA by size. */
1557 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1558 return 1;
1559 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1560 return -1;
1562 return 0;
1565 /* Mark all the symbols which will be used in output relocations with
1566 the BSF_KEEP flag so that those symbols will not be stripped.
1568 Ignore relocations which will not appear in the output file. */
1570 static void
1571 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1572 bfd *ibfd;
1573 sec_ptr isection;
1574 PTR symbolsarg;
1576 asymbol **symbols = (asymbol **) symbolsarg;
1577 long relsize;
1578 arelent **relpp;
1579 long relcount, i;
1581 /* Ignore an input section with no corresponding output section. */
1582 if (isection->output_section == NULL)
1583 return;
1585 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1586 if (relsize < 0)
1587 bfd_fatal (bfd_get_filename (ibfd));
1589 if (relsize == 0)
1590 return;
1592 relpp = (arelent **) xmalloc (relsize);
1593 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1594 if (relcount < 0)
1595 bfd_fatal (bfd_get_filename (ibfd));
1597 /* Examine each symbol used in a relocation. If it's not one of the
1598 special bfd section symbols, then mark it with BSF_KEEP. */
1599 for (i = 0; i < relcount; i++)
1601 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1602 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1603 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1604 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1607 if (relpp != NULL)
1608 free (relpp);
1611 /* Write out debugging information. */
1613 static boolean
1614 write_debugging_info (obfd, dhandle, symcountp, symppp)
1615 bfd *obfd;
1616 PTR dhandle;
1617 long *symcountp ATTRIBUTE_UNUSED;
1618 asymbol ***symppp ATTRIBUTE_UNUSED;
1620 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1621 return write_ieee_debugging_info (obfd, dhandle);
1623 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1624 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1626 bfd_byte *syms, *strings;
1627 bfd_size_type symsize, stringsize;
1628 asection *stabsec, *stabstrsec;
1630 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1631 &symsize, &strings,
1632 &stringsize))
1633 return false;
1635 stabsec = bfd_make_section (obfd, ".stab");
1636 stabstrsec = bfd_make_section (obfd, ".stabstr");
1637 if (stabsec == NULL
1638 || stabstrsec == NULL
1639 || ! bfd_set_section_size (obfd, stabsec, symsize)
1640 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1641 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1642 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1643 || ! bfd_set_section_flags (obfd, stabsec,
1644 (SEC_HAS_CONTENTS
1645 | SEC_READONLY
1646 | SEC_DEBUGGING))
1647 || ! bfd_set_section_flags (obfd, stabstrsec,
1648 (SEC_HAS_CONTENTS
1649 | SEC_READONLY
1650 | SEC_DEBUGGING)))
1652 non_fatal (_("%s: can't create debugging section: %s"),
1653 bfd_get_filename (obfd),
1654 bfd_errmsg (bfd_get_error ()));
1655 return false;
1658 /* We can get away with setting the section contents now because
1659 the next thing the caller is going to do is copy over the
1660 real sections. We may someday have to split the contents
1661 setting out of this function. */
1662 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1663 symsize)
1664 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1665 (file_ptr) 0, stringsize))
1667 non_fatal (_("%s: can't set debugging section contents: %s"),
1668 bfd_get_filename (obfd),
1669 bfd_errmsg (bfd_get_error ()));
1670 return false;
1673 return true;
1676 non_fatal (_("%s: don't know how to write debugging information for %s"),
1677 bfd_get_filename (obfd), bfd_get_target (obfd));
1678 return false;
1681 static int
1682 strip_main (argc, argv)
1683 int argc;
1684 char *argv[];
1686 char *input_target = NULL, *output_target = NULL;
1687 boolean show_version = false;
1688 int c, i;
1689 struct section_list *p;
1690 char *output_file = NULL;
1692 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1693 strip_options, (int *) 0)) != EOF)
1695 switch (c)
1697 case 'I':
1698 input_target = optarg;
1699 break;
1700 case 'O':
1701 output_target = optarg;
1702 break;
1703 case 'F':
1704 input_target = output_target = optarg;
1705 break;
1706 case 'R':
1707 p = find_section_list (optarg, true);
1708 p->remove = true;
1709 sections_removed = true;
1710 break;
1711 case 's':
1712 strip_symbols = STRIP_ALL;
1713 break;
1714 case 'S':
1715 case 'g':
1716 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1717 strip_symbols = STRIP_DEBUG;
1718 break;
1719 case OPTION_STRIP_UNNEEDED:
1720 strip_symbols = STRIP_UNNEEDED;
1721 break;
1722 case 'K':
1723 add_specific_symbol (optarg, &keep_specific_list);
1724 break;
1725 case 'N':
1726 add_specific_symbol (optarg, &strip_specific_list);
1727 break;
1728 case 'o':
1729 output_file = optarg;
1730 break;
1731 case 'p':
1732 preserve_dates = true;
1733 break;
1734 case 'x':
1735 discard_locals = LOCALS_ALL;
1736 break;
1737 case 'X':
1738 discard_locals = LOCALS_START_L;
1739 break;
1740 case 'v':
1741 verbose = true;
1742 break;
1743 case 'V':
1744 show_version = true;
1745 break;
1746 case 0:
1747 break; /* we've been given a long option */
1748 case 'h':
1749 strip_usage (stdout, 0);
1750 default:
1751 strip_usage (stderr, 1);
1755 if (show_version)
1756 print_version ("strip");
1758 /* Default is to strip all symbols. */
1759 if (strip_symbols == STRIP_UNDEF
1760 && discard_locals == LOCALS_UNDEF
1761 && strip_specific_list == NULL)
1762 strip_symbols = STRIP_ALL;
1764 if (output_target == (char *) NULL)
1765 output_target = input_target;
1767 i = optind;
1768 if (i == argc
1769 || (output_file != NULL && (i + 1) < argc))
1770 strip_usage (stderr, 1);
1772 for (; i < argc; i++)
1774 int hold_status = status;
1775 struct stat statbuf;
1776 char *tmpname;
1778 if (preserve_dates)
1780 if (stat (argv[i], &statbuf) < 0)
1782 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1783 continue;
1787 if (output_file != NULL)
1788 tmpname = output_file;
1789 else
1790 tmpname = make_tempname (argv[i]);
1791 status = 0;
1793 copy_file (argv[i], tmpname, input_target, output_target);
1794 if (status == 0)
1796 if (preserve_dates)
1797 set_times (tmpname, &statbuf);
1798 if (output_file == NULL)
1799 smart_rename (tmpname, argv[i], preserve_dates);
1800 status = hold_status;
1802 else
1803 unlink (tmpname);
1804 if (output_file == NULL)
1805 free (tmpname);
1808 return 0;
1811 static int
1812 copy_main (argc, argv)
1813 int argc;
1814 char *argv[];
1816 char *input_filename = NULL, *output_filename = NULL;
1817 char *input_target = NULL, *output_target = NULL;
1818 boolean show_version = false;
1819 boolean change_warn = true;
1820 int c;
1821 struct section_list *p;
1822 struct stat statbuf;
1824 while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
1825 copy_options, (int *) 0)) != EOF)
1827 switch (c)
1829 case 'b':
1830 copy_byte = atoi (optarg);
1831 if (copy_byte < 0)
1832 fatal (_("byte number must be non-negative"));
1833 break;
1835 case 'i':
1836 interleave = atoi (optarg);
1837 if (interleave < 1)
1838 fatal (_("interleave must be positive"));
1839 break;
1841 case 'I':
1842 case 's': /* "source" - 'I' is preferred */
1843 input_target = optarg;
1844 break;
1846 case 'O':
1847 case 'd': /* "destination" - 'O' is preferred */
1848 output_target = optarg;
1849 break;
1851 case 'F':
1852 input_target = output_target = optarg;
1853 break;
1855 case 'j':
1856 p = find_section_list (optarg, true);
1857 if (p->remove)
1858 fatal (_("%s both copied and removed"), optarg);
1859 p->copy = true;
1860 sections_copied = true;
1861 break;
1863 case 'R':
1864 p = find_section_list (optarg, true);
1865 if (p->copy)
1866 fatal (_("%s both copied and removed"), optarg);
1867 p->remove = true;
1868 sections_removed = true;
1869 break;
1871 case 'S':
1872 strip_symbols = STRIP_ALL;
1873 break;
1875 case 'g':
1876 strip_symbols = STRIP_DEBUG;
1877 break;
1879 case OPTION_STRIP_UNNEEDED:
1880 strip_symbols = STRIP_UNNEEDED;
1881 break;
1883 case 'K':
1884 add_specific_symbol (optarg, &keep_specific_list);
1885 break;
1887 case 'N':
1888 add_specific_symbol (optarg, &strip_specific_list);
1889 break;
1891 case 'L':
1892 add_specific_symbol (optarg, &localize_specific_list);
1893 break;
1895 case 'W':
1896 add_specific_symbol (optarg, &weaken_specific_list);
1897 break;
1899 case 'p':
1900 preserve_dates = true;
1901 break;
1903 case 'x':
1904 discard_locals = LOCALS_ALL;
1905 break;
1907 case 'X':
1908 discard_locals = LOCALS_START_L;
1909 break;
1911 case 'v':
1912 verbose = true;
1913 break;
1915 case 'V':
1916 show_version = true;
1917 break;
1919 case OPTION_WEAKEN:
1920 weaken = true;
1921 break;
1923 case OPTION_ADD_SECTION:
1925 const char *s;
1926 struct stat st;
1927 struct section_add *pa;
1928 int len;
1929 char *name;
1930 FILE *f;
1932 s = strchr (optarg, '=');
1934 if (s == NULL)
1935 fatal (_("bad format for %s"), "--add-section");
1937 if (stat (s + 1, & st) < 0)
1938 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
1940 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1942 len = s - optarg;
1943 name = (char *) xmalloc (len + 1);
1944 strncpy (name, optarg, len);
1945 name[len] = '\0';
1946 pa->name = name;
1948 pa->filename = s + 1;
1950 pa->size = st.st_size;
1952 pa->contents = (bfd_byte *) xmalloc (pa->size);
1953 f = fopen (pa->filename, FOPEN_RB);
1955 if (f == NULL)
1956 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
1958 if (fread (pa->contents, 1, pa->size, f) == 0
1959 || ferror (f))
1960 fatal (_("%s: fread failed"), pa->filename);
1962 fclose (f);
1964 pa->next = add_sections;
1965 add_sections = pa;
1967 break;
1969 case OPTION_CHANGE_START:
1970 change_start = parse_vma (optarg, "--change-start");
1971 break;
1973 case OPTION_CHANGE_SECTION_ADDRESS:
1974 case OPTION_CHANGE_SECTION_LMA:
1975 case OPTION_CHANGE_SECTION_VMA:
1977 const char *s;
1978 int len;
1979 char *name;
1980 char *option = NULL;
1981 bfd_vma val;
1982 enum change_action what = CHANGE_IGNORE;
1984 switch (c)
1986 case OPTION_CHANGE_SECTION_ADDRESS:
1987 option = "--change-section-address";
1988 break;
1989 case OPTION_CHANGE_SECTION_LMA:
1990 option = "--change-section-lma";
1991 break;
1992 case OPTION_CHANGE_SECTION_VMA:
1993 option = "--change-section-vma";
1994 break;
1997 s = strchr (optarg, '=');
1998 if (s == NULL)
2000 s = strchr (optarg, '+');
2001 if (s == NULL)
2003 s = strchr (optarg, '-');
2004 if (s == NULL)
2005 fatal (_("bad format for %s"), option);
2009 len = s - optarg;
2010 name = (char *) xmalloc (len + 1);
2011 strncpy (name, optarg, len);
2012 name[len] = '\0';
2014 p = find_section_list (name, true);
2016 val = parse_vma (s + 1, option);
2018 switch (*s)
2020 case '=': what = CHANGE_SET; break;
2021 case '-': val = - val; /* Drop through. */
2022 case '+': what = CHANGE_MODIFY; break;
2025 switch (c)
2027 case OPTION_CHANGE_SECTION_ADDRESS:
2028 p->change_vma = what;
2029 p->vma_val = val;
2030 /* Drop through. */
2032 case OPTION_CHANGE_SECTION_LMA:
2033 p->change_lma = what;
2034 p->lma_val = val;
2035 break;
2037 case OPTION_CHANGE_SECTION_VMA:
2038 p->change_vma = what;
2039 p->vma_val = val;
2040 break;
2043 break;
2045 case OPTION_CHANGE_ADDRESSES:
2046 change_section_address = parse_vma (optarg, "--change-addresses");
2047 change_start = change_section_address;
2048 break;
2050 case OPTION_CHANGE_WARNINGS:
2051 change_warn = true;
2052 break;
2054 case OPTION_CHANGE_LEADING_CHAR:
2055 change_leading_char = true;
2056 break;
2058 case OPTION_DEBUGGING:
2059 convert_debugging = true;
2060 break;
2062 case OPTION_GAP_FILL:
2064 bfd_vma gap_fill_vma;
2066 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2067 gap_fill = (bfd_byte) gap_fill_vma;
2068 if ((bfd_vma) gap_fill != gap_fill_vma)
2070 char buff[20];
2072 sprintf_vma (buff, gap_fill_vma);
2074 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2075 buff, gap_fill);
2077 gap_fill_set = true;
2079 break;
2081 case OPTION_NO_CHANGE_WARNINGS:
2082 change_warn = false;
2083 break;
2085 case OPTION_PAD_TO:
2086 pad_to = parse_vma (optarg, "--pad-to");
2087 pad_to_set = true;
2088 break;
2090 case OPTION_REMOVE_LEADING_CHAR:
2091 remove_leading_char = true;
2092 break;
2094 case OPTION_REDEFINE_SYM:
2096 /* Push this redefinition onto redefine_symbol_list. */
2098 int len;
2099 const char *s;
2100 const char *nextarg;
2101 char *source, *target;
2103 s = strchr (optarg, '=');
2104 if (s == NULL)
2106 fatal (_("bad format for %s"), "--redefine-sym");
2109 len = s - optarg;
2110 source = (char *) xmalloc (len + 1);
2111 strncpy (source, optarg, len);
2112 source[len] = '\0';
2114 nextarg = s + 1;
2115 len = strlen (nextarg);
2116 target = (char *) xmalloc (len + 1);
2117 strcpy (target, nextarg);
2119 redefine_list_append (source, target);
2121 free (source);
2122 free (target);
2124 break;
2126 case OPTION_SET_SECTION_FLAGS:
2128 const char *s;
2129 int len;
2130 char *name;
2132 s = strchr (optarg, '=');
2133 if (s == NULL)
2134 fatal (_("bad format for %s"), "--set-section-flags");
2136 len = s - optarg;
2137 name = (char *) xmalloc (len + 1);
2138 strncpy (name, optarg, len);
2139 name[len] = '\0';
2141 p = find_section_list (name, true);
2143 p->set_flags = true;
2144 p->flags = parse_flags (s + 1);
2146 break;
2148 case OPTION_SET_START:
2149 set_start = parse_vma (optarg, "--set-start");
2150 set_start_set = true;
2151 break;
2153 case OPTION_SREC_LEN:
2154 Chunk = parse_vma (optarg, "--srec-len");
2155 break;
2157 case OPTION_SREC_FORCES3:
2158 S3Forced = true;
2159 break;
2161 case 0:
2162 break; /* we've been given a long option */
2164 case 'h':
2165 copy_usage (stdout, 0);
2167 default:
2168 copy_usage (stderr, 1);
2172 if (show_version)
2173 print_version ("objcopy");
2175 if (copy_byte >= interleave)
2176 fatal (_("byte number must be less than interleave"));
2178 if (optind == argc || optind + 2 < argc)
2179 copy_usage (stderr, 1);
2181 input_filename = argv[optind];
2182 if (optind + 1 < argc)
2183 output_filename = argv[optind + 1];
2185 /* Default is to strip no symbols. */
2186 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2187 strip_symbols = STRIP_NONE;
2189 if (output_target == (char *) NULL)
2190 output_target = input_target;
2192 if (preserve_dates)
2194 if (stat (input_filename, &statbuf) < 0)
2195 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2198 /* If there is no destination file then create a temp and rename
2199 the result into the input. */
2201 if (output_filename == (char *) NULL)
2203 char *tmpname = make_tempname (input_filename);
2205 copy_file (input_filename, tmpname, input_target, output_target);
2206 if (status == 0)
2208 if (preserve_dates)
2209 set_times (tmpname, &statbuf);
2210 smart_rename (tmpname, input_filename, preserve_dates);
2212 else
2213 unlink (tmpname);
2215 else
2217 copy_file (input_filename, output_filename, input_target, output_target);
2218 if (status == 0 && preserve_dates)
2219 set_times (output_filename, &statbuf);
2222 if (change_warn)
2224 for (p = change_sections; p != NULL; p = p->next)
2226 if (! p->used)
2228 if (p->change_vma != CHANGE_IGNORE)
2230 char buff [20];
2232 sprintf_vma (buff, p->vma_val);
2234 /* xgettext:c-format */
2235 non_fatal (_("%s %s%c0x%s never used"),
2236 "--change-section-vma",
2237 p->name,
2238 p->change_vma == CHANGE_SET ? '=' : '+',
2239 buff);
2242 if (p->change_lma != CHANGE_IGNORE)
2244 char buff [20];
2246 sprintf_vma (buff, p->lma_val);
2248 /* xgettext:c-format */
2249 non_fatal (_("%s %s%c0x%s never used"),
2250 "--change-section-lma",
2251 p->name,
2252 p->change_lma == CHANGE_SET ? '=' : '+',
2253 buff);
2259 return 0;
2263 main (argc, argv)
2264 int argc;
2265 char *argv[];
2267 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2268 setlocale (LC_MESSAGES, "");
2269 #endif
2270 bindtextdomain (PACKAGE, LOCALEDIR);
2271 textdomain (PACKAGE);
2273 program_name = argv[0];
2274 xmalloc_set_program_name (program_name);
2276 START_PROGRESS (program_name, 0);
2278 strip_symbols = STRIP_UNDEF;
2279 discard_locals = LOCALS_UNDEF;
2281 bfd_init ();
2282 set_default_bfd_target ();
2284 if (is_strip < 0)
2286 int i = strlen (program_name);
2287 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2288 /* Drop the .exe suffix, if any. */
2289 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2291 i -= 4;
2292 program_name[i] = '\0';
2294 #endif
2295 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2298 if (is_strip)
2299 strip_main (argc, argv);
2300 else
2301 copy_main (argc, argv);
2303 END_PROGRESS (program_name);
2305 return status;