Convert to C90
[binutils.git] / binutils / objcopy.c
blob9b87a8a7c754eb1356d8daad820528a568b4e863
1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include "bfd.h"
24 #include "progress.h"
25 #include "bucomm.h"
26 #include "getopt.h"
27 #include "libiberty.h"
28 #include "budbg.h"
29 #include "filenames.h"
30 #include <sys/stat.h>
32 /* A list of symbols to explicitly strip out, or to keep. A linked
33 list is good enough for a small number from the command line, but
34 this will slow things down a lot if many symbols are being
35 deleted. */
37 struct symlist
39 const char *name;
40 struct symlist *next;
43 /* A list to support redefine_sym. */
44 struct redefine_node
46 char *source;
47 char *target;
48 struct redefine_node *next;
51 typedef struct section_rename
53 const char * old_name;
54 const char * new_name;
55 flagword flags;
56 struct section_rename * next;
58 section_rename;
60 /* List of sections to be renamed. */
61 static section_rename * section_rename_list;
63 static void copy_usage
64 PARAMS ((FILE *, int));
65 static void strip_usage
66 PARAMS ((FILE *, int));
67 static flagword parse_flags
68 PARAMS ((const char *));
69 static struct section_list *find_section_list
70 PARAMS ((const char *, bfd_boolean));
71 static void setup_section
72 PARAMS ((bfd *, asection *, PTR));
73 static void copy_section
74 PARAMS ((bfd *, asection *, PTR));
75 static void get_sections
76 PARAMS ((bfd *, asection *, PTR));
77 static int compare_section_lma
78 PARAMS ((const PTR, const PTR));
79 static void add_specific_symbol
80 PARAMS ((const char *, struct symlist **));
81 static void add_specific_symbols
82 PARAMS ((const char *, struct symlist **));
83 static bfd_boolean is_specified_symbol
84 PARAMS ((const char *, struct symlist *));
85 static bfd_boolean is_strip_section
86 PARAMS ((bfd *, asection *));
87 static unsigned int filter_symbols
88 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
89 static void mark_symbols_used_in_relocations
90 PARAMS ((bfd *, asection *, PTR));
91 static void filter_bytes
92 PARAMS ((char *, bfd_size_type *));
93 static bfd_boolean write_debugging_info
94 PARAMS ((bfd *, PTR, long *, asymbol ***));
95 static void copy_object
96 PARAMS ((bfd *, bfd *));
97 static void copy_archive
98 PARAMS ((bfd *, bfd *, const char *));
99 static void copy_file
100 PARAMS ((const char *, const char *, const char *, const char *));
101 static int strip_main
102 PARAMS ((int, char **));
103 static int copy_main
104 PARAMS ((int, char **));
105 static const char *lookup_sym_redefinition
106 PARAMS((const char *));
107 static void redefine_list_append
108 PARAMS ((const char *, const char *, const char *));
109 static const char * find_section_rename
110 PARAMS ((bfd *, sec_ptr, flagword *));
111 static void add_section_rename
112 PARAMS ((const char *, const char *, flagword));
113 static void add_redefine_syms_file
114 PARAMS ((const char *));
116 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
118 static asymbol **isympp = NULL; /* Input symbols */
119 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
121 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
122 static int copy_byte = -1;
123 static int interleave = 4;
125 static bfd_boolean verbose; /* Print file and target names. */
126 static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
127 static int status = 0; /* Exit status. */
129 enum strip_action
131 STRIP_UNDEF,
132 STRIP_NONE, /* don't strip */
133 STRIP_DEBUG, /* strip all debugger symbols */
134 STRIP_UNNEEDED, /* strip unnecessary symbols */
135 STRIP_NONDEBUG, /* Strip everything but debug info. */
136 STRIP_ALL /* strip all symbols */
139 /* Which symbols to remove. */
140 static enum strip_action strip_symbols;
142 enum locals_action
144 LOCALS_UNDEF,
145 LOCALS_START_L, /* discard locals starting with L */
146 LOCALS_ALL /* discard all locals */
149 /* Which local symbols to remove. Overrides STRIP_ALL. */
150 static enum locals_action discard_locals;
152 /* What kind of change to perform. */
153 enum change_action
155 CHANGE_IGNORE,
156 CHANGE_MODIFY,
157 CHANGE_SET
160 /* Structure used to hold lists of sections and actions to take. */
161 struct section_list
163 struct section_list * next; /* Next section to change. */
164 const char * name; /* Section name. */
165 bfd_boolean used; /* Whether this entry was used. */
166 bfd_boolean remove; /* Whether to remove this section. */
167 bfd_boolean copy; /* Whether to copy this section. */
168 enum change_action change_vma;/* Whether to change or set VMA. */
169 bfd_vma vma_val; /* Amount to change by or set to. */
170 enum change_action change_lma;/* Whether to change or set LMA. */
171 bfd_vma lma_val; /* Amount to change by or set to. */
172 bfd_boolean set_flags; /* Whether to set the section flags. */
173 flagword flags; /* What to set the section flags to. */
176 static struct section_list *change_sections;
178 /* TRUE if some sections are to be removed. */
179 static bfd_boolean sections_removed;
181 /* TRUE if only some sections are to be copied. */
182 static bfd_boolean sections_copied;
184 /* Changes to the start address. */
185 static bfd_vma change_start = 0;
186 static bfd_boolean set_start_set = FALSE;
187 static bfd_vma set_start;
189 /* Changes to section addresses. */
190 static bfd_vma change_section_address = 0;
192 /* Filling gaps between sections. */
193 static bfd_boolean gap_fill_set = FALSE;
194 static bfd_byte gap_fill = 0;
196 /* Pad to a given address. */
197 static bfd_boolean pad_to_set = FALSE;
198 static bfd_vma pad_to;
200 /* Use alternate machine code? */
201 static int use_alt_mach_code = 0;
203 /* List of sections to add. */
204 struct section_add
206 /* Next section to add. */
207 struct section_add *next;
208 /* Name of section to add. */
209 const char *name;
210 /* Name of file holding section contents. */
211 const char *filename;
212 /* Size of file. */
213 size_t size;
214 /* Contents of file. */
215 bfd_byte *contents;
216 /* BFD section, after it has been added. */
217 asection *section;
220 /* List of sections to add to the output BFD. */
221 static struct section_add *add_sections;
223 /* If non-NULL the argument to --add-gnu-debuglink.
224 This should be the filename to store in the .gnu_debuglink section. */
225 static const char * gnu_debuglink_filename = NULL;
227 /* Whether to convert debugging information. */
228 static bfd_boolean convert_debugging = FALSE;
230 /* Whether to change the leading character in symbol names. */
231 static bfd_boolean change_leading_char = FALSE;
233 /* Whether to remove the leading character from global symbol names. */
234 static bfd_boolean remove_leading_char = FALSE;
236 /* List of symbols to strip, keep, localize, keep-global, weaken,
237 or redefine. */
238 static struct symlist *strip_specific_list = NULL;
239 static struct symlist *keep_specific_list = NULL;
240 static struct symlist *localize_specific_list = NULL;
241 static struct symlist *keepglobal_specific_list = NULL;
242 static struct symlist *weaken_specific_list = NULL;
243 static struct redefine_node *redefine_sym_list = NULL;
245 /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
246 static bfd_boolean weaken = FALSE;
248 /* Prefix symbols/sections. */
249 static char *prefix_symbols_string = 0;
250 static char *prefix_sections_string = 0;
251 static char *prefix_alloc_sections_string = 0;
253 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
255 #define OPTION_ADD_SECTION 150
256 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
257 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
258 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
259 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
260 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
261 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
262 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
263 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
264 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
265 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
266 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
267 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
268 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
269 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
270 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
271 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
272 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
273 #define OPTION_REDEFINE_SYMS (OPTION_REDEFINE_SYM + 1)
274 #define OPTION_SREC_LEN (OPTION_REDEFINE_SYMS + 1)
275 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
276 #define OPTION_STRIP_SYMBOLS (OPTION_SREC_FORCES3 + 1)
277 #define OPTION_KEEP_SYMBOLS (OPTION_STRIP_SYMBOLS + 1)
278 #define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1)
279 #define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1)
280 #define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)
281 #define OPTION_RENAME_SECTION (OPTION_WEAKEN_SYMBOLS + 1)
282 #define OPTION_ALT_MACH_CODE (OPTION_RENAME_SECTION + 1)
283 #define OPTION_PREFIX_SYMBOLS (OPTION_ALT_MACH_CODE + 1)
284 #define OPTION_PREFIX_SECTIONS (OPTION_PREFIX_SYMBOLS + 1)
285 #define OPTION_PREFIX_ALLOC_SECTIONS (OPTION_PREFIX_SECTIONS + 1)
286 #define OPTION_FORMATS_INFO (OPTION_PREFIX_ALLOC_SECTIONS + 1)
287 #define OPTION_ADD_GNU_DEBUGLINK (OPTION_FORMATS_INFO + 1)
288 #define OPTION_ONLY_KEEP_DEBUG (OPTION_ADD_GNU_DEBUGLINK + 1)
290 /* Options to handle if running as "strip". */
292 static struct option strip_options[] =
294 {"discard-all", no_argument, 0, 'x'},
295 {"discard-locals", no_argument, 0, 'X'},
296 {"format", required_argument, 0, 'F'}, /* Obsolete */
297 {"help", no_argument, 0, 'h'},
298 {"info", no_argument, 0, OPTION_FORMATS_INFO},
299 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
300 {"input-target", required_argument, 0, 'I'},
301 {"keep-symbol", required_argument, 0, 'K'},
302 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
303 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
304 {"output-target", required_argument, 0, 'O'},
305 {"output-file", required_argument, 0, 'o'},
306 {"preserve-dates", no_argument, 0, 'p'},
307 {"remove-section", required_argument, 0, 'R'},
308 {"strip-all", no_argument, 0, 's'},
309 {"strip-debug", no_argument, 0, 'S'},
310 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
311 {"strip-symbol", required_argument, 0, 'N'},
312 {"target", required_argument, 0, 'F'},
313 {"verbose", no_argument, 0, 'v'},
314 {"version", no_argument, 0, 'V'},
315 {0, no_argument, 0, 0}
318 /* Options to handle if running as "objcopy". */
320 static struct option copy_options[] =
322 {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
323 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
324 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
325 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
326 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
327 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
328 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
329 {"binary-architecture", required_argument, 0, 'B'},
330 {"byte", required_argument, 0, 'b'},
331 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
332 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
333 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
334 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
335 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
336 {"change-start", required_argument, 0, OPTION_CHANGE_START},
337 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
338 {"debugging", no_argument, 0, OPTION_DEBUGGING},
339 {"discard-all", no_argument, 0, 'x'},
340 {"discard-locals", no_argument, 0, 'X'},
341 {"format", required_argument, 0, 'F'}, /* Obsolete */
342 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
343 {"help", no_argument, 0, 'h'},
344 {"info", no_argument, 0, OPTION_FORMATS_INFO},
345 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
346 {"input-target", required_argument, 0, 'I'},
347 {"interleave", required_argument, 0, 'i'},
348 {"keep-global-symbol", required_argument, 0, 'G'},
349 {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
350 {"keep-symbol", required_argument, 0, 'K'},
351 {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
352 {"localize-symbol", required_argument, 0, 'L'},
353 {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
354 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
355 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
356 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
357 {"only-section", required_argument, 0, 'j'},
358 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
359 {"output-target", required_argument, 0, 'O'},
360 {"pad-to", required_argument, 0, OPTION_PAD_TO},
361 {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
362 {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
363 {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
364 {"preserve-dates", no_argument, 0, 'p'},
365 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
366 {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
367 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
368 {"remove-section", required_argument, 0, 'R'},
369 {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
370 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
371 {"set-start", required_argument, 0, OPTION_SET_START},
372 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
373 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
374 {"strip-all", no_argument, 0, 'S'},
375 {"strip-debug", no_argument, 0, 'g'},
376 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
377 {"strip-symbol", required_argument, 0, 'N'},
378 {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
379 {"target", required_argument, 0, 'F'},
380 {"verbose", no_argument, 0, 'v'},
381 {"version", no_argument, 0, 'V'},
382 {"weaken", no_argument, 0, OPTION_WEAKEN},
383 {"weaken-symbol", required_argument, 0, 'W'},
384 {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
385 {0, no_argument, 0, 0}
388 /* IMPORTS */
389 extern char *program_name;
391 /* This flag distinguishes between strip and objcopy:
392 1 means this is 'strip'; 0 means this is 'objcopy'.
393 -1 means if we should use argv[0] to decide. */
394 extern int is_strip;
396 /* The maximum length of an S record. This variable is declared in srec.c
397 and can be modified by the --srec-len parameter. */
398 extern unsigned int Chunk;
400 /* Restrict the generation of Srecords to type S3 only.
401 This variable is declare in bfd/srec.c and can be toggled
402 on by the --srec-forceS3 command line switch. */
403 extern bfd_boolean S3Forced;
405 /* Defined in bfd/binary.c. Used to set architecture of input binary files. */
406 extern enum bfd_architecture bfd_external_binary_architecture;
409 static void
410 copy_usage (stream, exit_status)
411 FILE *stream;
412 int exit_status;
414 fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
415 fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
416 fprintf (stream, _(" The options are:\n"));
417 fprintf (stream, _("\
418 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
419 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
420 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
421 -F --target <bfdname> Set both input and output format to <bfdname>\n\
422 --debugging Convert debugging information, if possible\n\
423 -p --preserve-dates Copy modified/access timestamps to the output\n\
424 -j --only-section <name> Only copy section <name> into the output\n\
425 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
426 -R --remove-section <name> Remove section <name> from the output\n\
427 -S --strip-all Remove all symbol and relocation information\n\
428 -g --strip-debug Remove all debugging symbols & sections\n\
429 --strip-unneeded Remove all symbols not needed by relocations\n\
430 -N --strip-symbol <name> Do not copy symbol <name>\n\
431 -K --keep-symbol <name> Only copy symbol <name>\n\
432 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
433 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
434 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
435 --weaken Force all global symbols to be marked as weak\n\
436 -x --discard-all Remove all non-global symbols\n\
437 -X --discard-locals Remove any compiler-generated symbols\n\
438 -i --interleave <number> Only copy one out of every <number> bytes\n\
439 -b --byte <num> Select byte <num> in every interleaved block\n\
440 --gap-fill <val> Fill gaps between sections with <val>\n\
441 --pad-to <addr> Pad the last section up to address <addr>\n\
442 --set-start <addr> Set the start address to <addr>\n\
443 {--change-start|--adjust-start} <incr>\n\
444 Add <incr> to the start address\n\
445 {--change-addresses|--adjust-vma} <incr>\n\
446 Add <incr> to LMA, VMA and start addresses\n\
447 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
448 Change LMA and VMA of section <name> by <val>\n\
449 --change-section-lma <name>{=|+|-}<val>\n\
450 Change the LMA of section <name> by <val>\n\
451 --change-section-vma <name>{=|+|-}<val>\n\
452 Change the VMA of section <name> by <val>\n\
453 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
454 Warn if a named section does not exist\n\
455 --set-section-flags <name>=<flags>\n\
456 Set section <name>'s properties to <flags>\n\
457 --add-section <name>=<file> Add section <name> found in <file> to output\n\
458 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
459 --change-leading-char Force output format's leading character style\n\
460 --remove-leading-char Remove leading character from global symbols\n\
461 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
462 --redefine-syms <file> --redefine-sym for all symbol pairs \n\
463 listed in <file>\n\
464 --srec-len <number> Restrict the length of generated Srecords\n\
465 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
466 --strip-symbols <file> -N for all symbols listed in <file>\n\
467 --keep-symbols <file> -K for all symbols listed in <file>\n\
468 --localize-symbols <file> -L for all symbols listed in <file>\n\
469 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
470 --weaken-symbols <file> -W for all symbols listed in <file>\n\
471 --alt-machine-code <index> Use alternate machine code for output\n\
472 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\
473 --prefix-sections <prefix> Add <prefix> to start of every section name\n\
474 --prefix-alloc-sections <prefix>\n\
475 Add <prefix> to start of every allocatable\n\
476 section name\n\
477 -v --verbose List all object files modified\n\
478 -V --version Display this program's version number\n\
479 -h --help Display this output\n\
480 --info List object formats & architectures supported\n\
481 "));
482 list_supported_targets (program_name, stream);
483 if (exit_status == 0)
484 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
485 exit (exit_status);
488 static void
489 strip_usage (stream, exit_status)
490 FILE *stream;
491 int exit_status;
493 fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
494 fprintf (stream, _(" Removes symbols and sections from files\n"));
495 fprintf (stream, _(" The options are:\n"));
496 fprintf (stream, _("\
497 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\
498 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\
499 -F --target=<bfdname> Set both input and output format to <bfdname>\n\
500 -p --preserve-dates Copy modified/access timestamps to the output\n\
501 -R --remove-section=<name> Remove section <name> from the output\n\
502 -s --strip-all Remove all symbol and relocation information\n\
503 -g -S -d --strip-debug Remove all debugging symbols & sections\n\
504 --strip-unneeded Remove all symbols not needed by relocations\n\
505 -N --strip-symbol=<name> Do not copy symbol <name>\n\
506 -K --keep-symbol=<name> Only copy symbol <name>\n\
507 -x --discard-all Remove all non-global symbols\n\
508 -X --discard-locals Remove any compiler-generated symbols\n\
509 -v --verbose List all object files modified\n\
510 -V --version Display this program's version number\n\
511 -h --help Display this output\n\
512 --info List object formats & architectures supported\n\
513 -o <file> Place stripped output into <file>\n\
514 "));
516 list_supported_targets (program_name, stream);
517 if (exit_status == 0)
518 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
519 exit (exit_status);
522 /* Parse section flags into a flagword, with a fatal error if the
523 string can't be parsed. */
525 static flagword
526 parse_flags (s)
527 const char *s;
529 flagword ret;
530 const char *snext;
531 int len;
533 ret = SEC_NO_FLAGS;
537 snext = strchr (s, ',');
538 if (snext == NULL)
539 len = strlen (s);
540 else
542 len = snext - s;
543 ++snext;
546 if (0) ;
547 #define PARSE_FLAG(fname,fval) \
548 else if (strncasecmp (fname, s, len) == 0) ret |= fval
549 PARSE_FLAG ("alloc", SEC_ALLOC);
550 PARSE_FLAG ("load", SEC_LOAD);
551 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
552 PARSE_FLAG ("readonly", SEC_READONLY);
553 PARSE_FLAG ("debug", SEC_DEBUGGING);
554 PARSE_FLAG ("code", SEC_CODE);
555 PARSE_FLAG ("data", SEC_DATA);
556 PARSE_FLAG ("rom", SEC_ROM);
557 PARSE_FLAG ("share", SEC_SHARED);
558 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
559 #undef PARSE_FLAG
560 else
562 char *copy;
564 copy = xmalloc (len + 1);
565 strncpy (copy, s, len);
566 copy[len] = '\0';
567 non_fatal (_("unrecognized section flag `%s'"), copy);
568 fatal (_("supported flags: %s"),
569 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
572 s = snext;
574 while (s != NULL);
576 return ret;
579 /* Find and optionally add an entry in the change_sections list. */
581 static struct section_list *
582 find_section_list (name, add)
583 const char *name;
584 bfd_boolean add;
586 register struct section_list *p;
588 for (p = change_sections; p != NULL; p = p->next)
589 if (strcmp (p->name, name) == 0)
590 return p;
592 if (! add)
593 return NULL;
595 p = (struct section_list *) xmalloc (sizeof (struct section_list));
596 p->name = name;
597 p->used = FALSE;
598 p->remove = FALSE;
599 p->copy = FALSE;
600 p->change_vma = CHANGE_IGNORE;
601 p->change_lma = CHANGE_IGNORE;
602 p->vma_val = 0;
603 p->lma_val = 0;
604 p->set_flags = FALSE;
605 p->flags = 0;
607 p->next = change_sections;
608 change_sections = p;
610 return p;
613 /* Add a symbol to strip_specific_list. */
615 static void
616 add_specific_symbol (name, list)
617 const char *name;
618 struct symlist **list;
620 struct symlist *tmp_list;
622 tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
623 tmp_list->name = name;
624 tmp_list->next = *list;
625 *list = tmp_list;
628 /* Add symbols listed in `filename' to strip_specific_list. */
630 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
631 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
633 static void
634 add_specific_symbols (filename, list)
635 const char *filename;
636 struct symlist **list;
638 struct stat st;
639 FILE * f;
640 char * line;
641 char * buffer;
642 unsigned int line_count;
644 if (stat (filename, & st) < 0)
645 fatal (_("cannot stat: %s: %s"), filename, strerror (errno));
646 if (st.st_size == 0)
647 return;
649 buffer = (char *) xmalloc (st.st_size + 2);
650 f = fopen (filename, FOPEN_RT);
651 if (f == NULL)
652 fatal (_("cannot open: %s: %s"), filename, strerror (errno));
654 if (fread (buffer, 1, st.st_size, f) == 0 || ferror (f))
655 fatal (_("%s: fread failed"), filename);
657 fclose (f);
658 buffer [st.st_size] = '\n';
659 buffer [st.st_size + 1] = '\0';
661 line_count = 1;
663 for (line = buffer; * line != '\0'; line ++)
665 char * eol;
666 char * name;
667 char * name_end;
668 int finished = FALSE;
670 for (eol = line;; eol ++)
672 switch (* eol)
674 case '\n':
675 * eol = '\0';
676 /* Cope with \n\r. */
677 if (eol[1] == '\r')
678 ++ eol;
679 finished = TRUE;
680 break;
682 case '\r':
683 * eol = '\0';
684 /* Cope with \r\n. */
685 if (eol[1] == '\n')
686 ++ eol;
687 finished = TRUE;
688 break;
690 case 0:
691 finished = TRUE;
692 break;
694 case '#':
695 /* Line comment, Terminate the line here, in case a
696 name is present and then allow the rest of the
697 loop to find the real end of the line. */
698 * eol = '\0';
699 break;
701 default:
702 break;
705 if (finished)
706 break;
709 /* A name may now exist somewhere between 'line' and 'eol'.
710 Strip off leading whitespace and trailing whitespace,
711 then add it to the list. */
712 for (name = line; IS_WHITESPACE (* name); name ++)
714 for (name_end = name;
715 (! IS_WHITESPACE (* name_end))
716 && (! IS_LINE_TERMINATOR (* name_end));
717 name_end ++)
720 if (! IS_LINE_TERMINATOR (* name_end))
722 char * extra;
724 for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
727 if (! IS_LINE_TERMINATOR (* extra))
728 non_fatal (_("Ignoring rubbish found on line %d of %s"),
729 line_count, filename);
732 * name_end = '\0';
734 if (name_end > name)
735 add_specific_symbol (name, list);
737 /* Advance line pointer to end of line. The 'eol ++' in the for
738 loop above will then advance us to the start of the next line. */
739 line = eol;
740 line_count ++;
744 /* See whether a symbol should be stripped or kept based on
745 strip_specific_list and keep_symbols. */
747 static bfd_boolean
748 is_specified_symbol (name, list)
749 const char *name;
750 struct symlist *list;
752 struct symlist *tmp_list;
754 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
755 if (strcmp (name, tmp_list->name) == 0)
756 return TRUE;
758 return FALSE;
761 /* See if a section is being removed. */
763 static bfd_boolean
764 is_strip_section (abfd, sec)
765 bfd *abfd ATTRIBUTE_UNUSED;
766 asection *sec;
768 if (sections_removed || sections_copied)
770 struct section_list *p;
772 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
774 if (sections_removed && p != NULL && p->remove)
775 return TRUE;
776 if (sections_copied && (p == NULL || ! p->copy))
777 return TRUE;
780 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
782 if (strip_symbols == STRIP_DEBUG
783 || strip_symbols == STRIP_UNNEEDED
784 || strip_symbols == STRIP_ALL
785 || discard_locals == LOCALS_ALL
786 || convert_debugging)
787 return TRUE;
789 if (strip_symbols == STRIP_NONDEBUG)
790 return FALSE;
793 return strip_symbols == STRIP_NONDEBUG ? TRUE : FALSE;
796 /* Choose which symbol entries to copy; put the result in OSYMS.
797 We don't copy in place, because that confuses the relocs.
798 Return the number of symbols to print. */
800 static unsigned int
801 filter_symbols (abfd, obfd, osyms, isyms, symcount)
802 bfd *abfd;
803 bfd *obfd;
804 asymbol **osyms, **isyms;
805 long symcount;
807 register asymbol **from = isyms, **to = osyms;
808 long src_count = 0, dst_count = 0;
809 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
810 == HAS_RELOC;
812 for (; src_count < symcount; src_count++)
814 asymbol *sym = from[src_count];
815 flagword flags = sym->flags;
816 char *name = (char *) bfd_asymbol_name (sym);
817 int keep;
818 bfd_boolean undefined;
819 bfd_boolean rem_leading_char;
820 bfd_boolean add_leading_char;
822 undefined = bfd_is_und_section (bfd_get_section (sym));
824 if (redefine_sym_list)
826 char *old_name, *new_name;
828 old_name = (char *) bfd_asymbol_name (sym);
829 new_name = (char *) lookup_sym_redefinition (old_name);
830 bfd_asymbol_name (sym) = new_name;
831 name = new_name;
834 /* Check if we will remove the current leading character. */
835 rem_leading_char =
836 (name[0] == bfd_get_symbol_leading_char (abfd))
837 && (change_leading_char
838 || (remove_leading_char
839 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
840 || undefined
841 || bfd_is_com_section (bfd_get_section (sym)))));
843 /* Check if we will add a new leading character. */
844 add_leading_char =
845 change_leading_char
846 && (bfd_get_symbol_leading_char (obfd) != '\0')
847 && (bfd_get_symbol_leading_char (abfd) == '\0'
848 || (name[0] == bfd_get_symbol_leading_char (abfd)));
850 /* Short circuit for change_leading_char if we can do it in-place. */
851 if (rem_leading_char && add_leading_char && !prefix_symbols_string)
853 name[0] = bfd_get_symbol_leading_char (obfd);
854 bfd_asymbol_name (sym) = name;
855 rem_leading_char = FALSE;
856 add_leading_char = FALSE;
859 /* Remove leading char. */
860 if (rem_leading_char)
861 bfd_asymbol_name (sym) = ++name;
863 /* Add new leading char and/or prefix. */
864 if (add_leading_char || prefix_symbols_string)
866 char *n, *ptr;
868 ptr = n = xmalloc (1 + strlen (prefix_symbols_string) + strlen (name) + 1);
869 if (add_leading_char)
870 *ptr++ = bfd_get_symbol_leading_char (obfd);
872 if (prefix_symbols_string)
874 strcpy (ptr, prefix_symbols_string);
875 ptr += strlen (prefix_symbols_string);
878 strcpy (ptr, name);
879 bfd_asymbol_name (sym) = n;
880 name = n;
883 if (strip_symbols == STRIP_ALL)
884 keep = 0;
885 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
886 || ((flags & BSF_SECTION_SYM) != 0
887 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
888 & BSF_KEEP) != 0))
889 keep = 1;
890 else if (relocatable /* Relocatable file. */
891 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
892 keep = 1;
893 else if (bfd_decode_symclass (sym) == 'I')
894 /* Global symbols in $idata sections need to be retained
895 even if relocatable is FALSE. External users of the
896 library containing the $idata section may reference these
897 symbols. */
898 keep = 1;
899 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
900 || (flags & BSF_WEAK) != 0
901 || undefined
902 || bfd_is_com_section (bfd_get_section (sym)))
903 keep = strip_symbols != STRIP_UNNEEDED;
904 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
905 keep = (strip_symbols != STRIP_DEBUG
906 && strip_symbols != STRIP_UNNEEDED
907 && ! convert_debugging);
908 else if (bfd_get_section (sym)->comdat)
909 /* COMDAT sections store special information in local
910 symbols, so we cannot risk stripping any of them. */
911 keep = 1;
912 else /* Local symbol. */
913 keep = (strip_symbols != STRIP_UNNEEDED
914 && (discard_locals != LOCALS_ALL
915 && (discard_locals != LOCALS_START_L
916 || ! bfd_is_local_label (abfd, sym))));
918 if (keep && is_specified_symbol (name, strip_specific_list))
919 keep = 0;
920 if (!keep && is_specified_symbol (name, keep_specific_list))
921 keep = 1;
922 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
923 keep = 0;
925 if (keep && (flags & BSF_GLOBAL) != 0
926 && (weaken || is_specified_symbol (name, weaken_specific_list)))
928 sym->flags &=~ BSF_GLOBAL;
929 sym->flags |= BSF_WEAK;
931 if (keep && !undefined && (flags & (BSF_GLOBAL | BSF_WEAK))
932 && (is_specified_symbol (name, localize_specific_list)
933 || (keepglobal_specific_list != NULL
934 && ! is_specified_symbol (name, keepglobal_specific_list))))
936 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
937 sym->flags |= BSF_LOCAL;
940 if (keep)
941 to[dst_count++] = sym;
944 to[dst_count] = NULL;
946 return dst_count;
949 /* Find the redefined name of symbol SOURCE. */
951 static const char *
952 lookup_sym_redefinition (source)
953 const char *source;
955 struct redefine_node *list;
957 for (list = redefine_sym_list; list != NULL; list = list->next)
958 if (strcmp (source, list->source) == 0)
959 return list->target;
961 return source;
964 /* Add a node to a symbol redefine list. */
966 static void
967 redefine_list_append (cause, source, target)
968 const char *cause;
969 const char *source;
970 const char *target;
972 struct redefine_node **p;
973 struct redefine_node *list;
974 struct redefine_node *new_node;
976 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
978 if (strcmp (source, list->source) == 0)
979 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
980 cause, source);
982 if (strcmp (target, list->target) == 0)
983 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
984 cause, target);
987 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
989 new_node->source = strdup (source);
990 new_node->target = strdup (target);
991 new_node->next = NULL;
993 *p = new_node;
996 /* Handle the --redefine-syms option. Read lines containing "old new"
997 from the file, and add them to the symbol redefine list. */
999 static void
1000 add_redefine_syms_file (filename)
1001 const char *filename;
1003 FILE *file;
1004 char *buf;
1005 size_t bufsize, len, outsym_off;
1006 int c, lineno;
1008 file = fopen (filename, "r");
1009 if (file == (FILE *) NULL)
1010 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
1011 filename, strerror (errno));
1013 bufsize = 100;
1014 buf = (char *) xmalloc (bufsize);
1016 lineno = 1;
1017 c = getc (file);
1018 len = 0;
1019 outsym_off = 0;
1020 while (c != EOF)
1022 /* Collect the input symbol name. */
1023 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1025 if (c == '#')
1026 goto comment;
1027 buf[len++] = c;
1028 if (len >= bufsize)
1030 bufsize *= 2;
1031 buf = xrealloc (buf, bufsize);
1033 c = getc (file);
1035 buf[len++] = '\0';
1036 if (c == EOF)
1037 break;
1039 /* Eat white space between the symbol names. */
1040 while (IS_WHITESPACE (c))
1041 c = getc (file);
1042 if (c == '#' || IS_LINE_TERMINATOR (c))
1043 goto comment;
1044 if (c == EOF)
1045 break;
1047 /* Collect the output symbol name. */
1048 outsym_off = len;
1049 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1051 if (c == '#')
1052 goto comment;
1053 buf[len++] = c;
1054 if (len >= bufsize)
1056 bufsize *= 2;
1057 buf = xrealloc (buf, bufsize);
1059 c = getc (file);
1061 buf[len++] = '\0';
1062 if (c == EOF)
1063 break;
1065 /* Eat white space at end of line. */
1066 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1067 c = getc (file);
1068 if (c == '#')
1069 goto comment;
1070 /* Handle \r\n. */
1071 if ((c == '\r' && (c = getc (file)) == '\n')
1072 || c == '\n' || c == EOF)
1074 end_of_line:
1075 /* Append the redefinition to the list. */
1076 if (buf[0] != '\0')
1077 redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1079 lineno++;
1080 len = 0;
1081 outsym_off = 0;
1082 if (c == EOF)
1083 break;
1084 c = getc (file);
1085 continue;
1087 else
1088 fatal (_("%s: garbage at end of line %d"), filename, lineno);
1089 comment:
1090 if (len != 0 && (outsym_off == 0 || outsym_off == len))
1091 fatal (_("%s: missing new symbol name at line %d"), filename, lineno);
1092 buf[len++] = '\0';
1094 /* Eat the rest of the line and finish it. */
1095 while (c != '\n' && c != EOF)
1096 c = getc (file);
1097 goto end_of_line;
1100 if (len != 0)
1101 fatal (_("%s: premature end of file at line %d"), filename, lineno);
1103 free (buf);
1106 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
1107 Adjust *SIZE. */
1109 static void
1110 filter_bytes (memhunk, size)
1111 char *memhunk;
1112 bfd_size_type *size;
1114 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
1116 for (; from < end; from += interleave)
1117 *to++ = *from;
1119 if (*size % interleave > (bfd_size_type) copy_byte)
1120 *size = (*size / interleave) + 1;
1121 else
1122 *size /= interleave;
1125 /* Copy object file IBFD onto OBFD. */
1127 static void
1128 copy_object (ibfd, obfd)
1129 bfd *ibfd;
1130 bfd *obfd;
1132 bfd_vma start;
1133 long symcount;
1134 asection **osections = NULL;
1135 asection * gnu_debuglink_section = NULL;
1136 bfd_size_type *gaps = NULL;
1137 bfd_size_type max_gap = 0;
1138 long symsize;
1139 PTR dhandle;
1140 enum bfd_architecture iarch;
1141 unsigned int imach;
1143 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1144 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1145 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1147 fatal (_("Unable to change endianness of input file(s)"));
1148 return;
1151 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1152 RETURN_NONFATAL (bfd_get_filename (obfd));
1154 if (verbose)
1155 printf (_("copy from %s(%s) to %s(%s)\n"),
1156 bfd_get_filename (ibfd), bfd_get_target (ibfd),
1157 bfd_get_filename (obfd), bfd_get_target (obfd));
1159 if (set_start_set)
1160 start = set_start;
1161 else
1162 start = bfd_get_start_address (ibfd);
1163 start += change_start;
1165 /* Neither the start address nor the flags
1166 need to be set for a core file. */
1167 if (bfd_get_format (obfd) != bfd_core)
1169 if (!bfd_set_start_address (obfd, start)
1170 || !bfd_set_file_flags (obfd,
1171 (bfd_get_file_flags (ibfd)
1172 & bfd_applicable_file_flags (obfd))))
1173 RETURN_NONFATAL (bfd_get_filename (ibfd));
1176 /* Copy architecture of input file to output file. */
1177 iarch = bfd_get_arch (ibfd);
1178 imach = bfd_get_mach (ibfd);
1179 if (!bfd_set_arch_mach (obfd, iarch, imach)
1180 && (ibfd->target_defaulted
1181 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1182 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1183 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1184 bfd_get_mach (ibfd)));
1186 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1187 RETURN_NONFATAL (bfd_get_filename (ibfd));
1189 if (isympp)
1190 free (isympp);
1192 if (osympp != isympp)
1193 free (osympp);
1195 /* BFD mandates that all output sections be created and sizes set before
1196 any output is done. Thus, we traverse all sections multiple times. */
1197 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
1199 if (add_sections != NULL)
1201 struct section_add *padd;
1202 struct section_list *pset;
1204 for (padd = add_sections; padd != NULL; padd = padd->next)
1206 flagword flags;
1208 padd->section = bfd_make_section (obfd, padd->name);
1209 if (padd->section == NULL)
1211 non_fatal (_("can't create section `%s': %s"),
1212 padd->name, bfd_errmsg (bfd_get_error ()));
1213 status = 1;
1214 return;
1217 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1218 RETURN_NONFATAL (bfd_get_filename (obfd));
1220 pset = find_section_list (padd->name, FALSE);
1221 if (pset != NULL)
1222 pset->used = TRUE;
1224 if (pset != NULL && pset->set_flags)
1225 flags = pset->flags | SEC_HAS_CONTENTS;
1226 else
1227 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1229 if (! bfd_set_section_flags (obfd, padd->section, flags))
1230 RETURN_NONFATAL (bfd_get_filename (obfd));
1232 if (pset != NULL)
1234 if (pset->change_vma != CHANGE_IGNORE)
1235 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
1236 RETURN_NONFATAL (bfd_get_filename (obfd));
1238 if (pset->change_lma != CHANGE_IGNORE)
1240 padd->section->lma = pset->lma_val;
1242 if (! bfd_set_section_alignment
1243 (obfd, padd->section,
1244 bfd_section_alignment (obfd, padd->section)))
1245 RETURN_NONFATAL (bfd_get_filename (obfd));
1251 if (gnu_debuglink_filename != NULL)
1253 gnu_debuglink_section = bfd_create_gnu_debuglink_section (obfd, gnu_debuglink_filename);
1255 if (gnu_debuglink_section == NULL)
1257 fprintf (stderr, "UGG\n");
1258 RETURN_NONFATAL (gnu_debuglink_filename);
1262 if (gap_fill_set || pad_to_set)
1264 asection **set;
1265 unsigned int c, i;
1267 /* We must fill in gaps between the sections and/or we must pad
1268 the last section to a specified address. We do this by
1269 grabbing a list of the sections, sorting them by VMA, and
1270 increasing the section sizes as required to fill the gaps.
1271 We write out the gap contents below. */
1273 c = bfd_count_sections (obfd);
1274 osections = (asection **) xmalloc (c * sizeof (asection *));
1275 set = osections;
1276 bfd_map_over_sections (obfd, get_sections, (void *) &set);
1278 qsort (osections, c, sizeof (asection *), compare_section_lma);
1280 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
1281 memset (gaps, 0, c * sizeof (bfd_size_type));
1283 if (gap_fill_set)
1285 for (i = 0; i < c - 1; i++)
1287 flagword flags;
1288 bfd_size_type size;
1289 bfd_vma gap_start, gap_stop;
1291 flags = bfd_get_section_flags (obfd, osections[i]);
1292 if ((flags & SEC_HAS_CONTENTS) == 0
1293 || (flags & SEC_LOAD) == 0)
1294 continue;
1296 size = bfd_section_size (obfd, osections[i]);
1297 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1298 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1299 if (gap_start < gap_stop)
1301 if (! bfd_set_section_size (obfd, osections[i],
1302 size + (gap_stop - gap_start)))
1304 non_fatal (_("Can't fill gap after %s: %s"),
1305 bfd_get_section_name (obfd, osections[i]),
1306 bfd_errmsg (bfd_get_error ()));
1307 status = 1;
1308 break;
1310 gaps[i] = gap_stop - gap_start;
1311 if (max_gap < gap_stop - gap_start)
1312 max_gap = gap_stop - gap_start;
1317 if (pad_to_set)
1319 bfd_vma lma;
1320 bfd_size_type size;
1322 lma = bfd_section_lma (obfd, osections[c - 1]);
1323 size = bfd_section_size (obfd, osections[c - 1]);
1324 if (lma + size < pad_to)
1326 if (! bfd_set_section_size (obfd, osections[c - 1],
1327 pad_to - lma))
1329 non_fatal (_("Can't add padding to %s: %s"),
1330 bfd_get_section_name (obfd, osections[c - 1]),
1331 bfd_errmsg (bfd_get_error ()));
1332 status = 1;
1334 else
1336 gaps[c - 1] = pad_to - (lma + size);
1337 if (max_gap < pad_to - (lma + size))
1338 max_gap = pad_to - (lma + size);
1344 /* Symbol filtering must happen after the output sections
1345 have been created, but before their contents are set. */
1346 dhandle = NULL;
1347 symsize = bfd_get_symtab_upper_bound (ibfd);
1348 if (symsize < 0)
1349 RETURN_NONFATAL (bfd_get_filename (ibfd));
1351 osympp = isympp = (asymbol **) xmalloc (symsize);
1352 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1353 if (symcount < 0)
1354 RETURN_NONFATAL (bfd_get_filename (ibfd));
1356 if (convert_debugging)
1357 dhandle = read_debugging_info (ibfd, isympp, symcount);
1359 if (strip_symbols == STRIP_DEBUG
1360 || strip_symbols == STRIP_ALL
1361 || strip_symbols == STRIP_UNNEEDED
1362 || strip_symbols == STRIP_NONDEBUG
1363 || discard_locals != LOCALS_UNDEF
1364 || strip_specific_list != NULL
1365 || keep_specific_list != NULL
1366 || localize_specific_list != NULL
1367 || keepglobal_specific_list != NULL
1368 || weaken_specific_list != NULL
1369 || prefix_symbols_string
1370 || sections_removed
1371 || sections_copied
1372 || convert_debugging
1373 || change_leading_char
1374 || remove_leading_char
1375 || redefine_sym_list
1376 || weaken)
1378 /* Mark symbols used in output relocations so that they
1379 are kept, even if they are local labels or static symbols.
1381 Note we iterate over the input sections examining their
1382 relocations since the relocations for the output sections
1383 haven't been set yet. mark_symbols_used_in_relocations will
1384 ignore input sections which have no corresponding output
1385 section. */
1386 if (strip_symbols != STRIP_ALL)
1387 bfd_map_over_sections (ibfd,
1388 mark_symbols_used_in_relocations,
1389 (PTR)isympp);
1390 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
1391 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1394 if (convert_debugging && dhandle != NULL)
1396 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1398 status = 1;
1399 return;
1403 bfd_set_symtab (obfd, osympp, symcount);
1405 /* This has to happen after the symbol table has been set. */
1406 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1408 if (add_sections != NULL)
1410 struct section_add *padd;
1412 for (padd = add_sections; padd != NULL; padd = padd->next)
1414 if (! bfd_set_section_contents (obfd, padd->section,
1415 (PTR) padd->contents,
1416 (file_ptr) 0,
1417 (bfd_size_type) padd->size))
1418 RETURN_NONFATAL (bfd_get_filename (obfd));
1422 if (gnu_debuglink_filename != NULL)
1424 if (! bfd_fill_in_gnu_debuglink_section
1425 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1427 fprintf (stderr, "UGG 2\n");
1428 RETURN_NONFATAL (gnu_debuglink_filename);
1432 if (gap_fill_set || pad_to_set)
1434 bfd_byte *buf;
1435 int c, i;
1437 /* Fill in the gaps. */
1438 if (max_gap > 8192)
1439 max_gap = 8192;
1440 buf = (bfd_byte *) xmalloc (max_gap);
1441 memset (buf, gap_fill, (size_t) max_gap);
1443 c = bfd_count_sections (obfd);
1444 for (i = 0; i < c; i++)
1446 if (gaps[i] != 0)
1448 bfd_size_type left;
1449 file_ptr off;
1451 left = gaps[i];
1452 off = bfd_section_size (obfd, osections[i]) - left;
1454 while (left > 0)
1456 bfd_size_type now;
1458 if (left > 8192)
1459 now = 8192;
1460 else
1461 now = left;
1463 if (! bfd_set_section_contents (obfd, osections[i], buf,
1464 off, now))
1465 RETURN_NONFATAL (bfd_get_filename (obfd));
1467 left -= now;
1468 off += now;
1474 /* Allow the BFD backend to copy any private data it understands
1475 from the input BFD to the output BFD. This is done last to
1476 permit the routine to look at the filtered symbol table, which is
1477 important for the ECOFF code at least. */
1478 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1479 && strip_symbols == STRIP_NONDEBUG)
1480 /* Do not copy the private data when creating an ELF format
1481 debug info file. We do not want the program headers. */
1483 else if (! bfd_copy_private_bfd_data (ibfd, obfd))
1485 non_fatal (_("%s: error copying private BFD data: %s"),
1486 bfd_get_filename (obfd),
1487 bfd_errmsg (bfd_get_error ()));
1488 status = 1;
1489 return;
1492 /* Switch to the alternate machine code. We have to do this at the
1493 very end, because we only initialize the header when we create
1494 the first section. */
1495 if (use_alt_mach_code != 0)
1497 if (!bfd_alt_mach_code (obfd, use_alt_mach_code))
1498 non_fatal (_("unknown alternate machine code, ignored"));
1502 #undef MKDIR
1503 #if defined (_WIN32) && !defined (__CYGWIN32__)
1504 #define MKDIR(DIR, MODE) mkdir (DIR)
1505 #else
1506 #define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1507 #endif
1509 /* Read each archive element in turn from IBFD, copy the
1510 contents to temp file, and keep the temp file handle. */
1512 static void
1513 copy_archive (ibfd, obfd, output_target)
1514 bfd *ibfd;
1515 bfd *obfd;
1516 const char *output_target;
1518 struct name_list
1520 struct name_list *next;
1521 const char *name;
1522 bfd *obfd;
1523 } *list, *l;
1524 bfd **ptr = &obfd->archive_head;
1525 bfd *this_element;
1526 char *dir = make_tempname (bfd_get_filename (obfd));
1528 /* Make a temp directory to hold the contents. */
1529 if (MKDIR (dir, 0700) != 0)
1531 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1532 dir, strerror (errno));
1534 obfd->has_armap = ibfd->has_armap;
1536 list = NULL;
1538 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1540 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1541 RETURN_NONFATAL (bfd_get_filename (obfd));
1543 while (!status && this_element != (bfd *) NULL)
1545 char *output_name;
1546 bfd *output_bfd;
1547 bfd *last_element;
1548 struct stat buf;
1549 int stat_status = 0;
1551 /* Create an output file for this member. */
1552 output_name = concat (dir, "/",
1553 bfd_get_filename (this_element), (char *) 0);
1555 /* If the file already exists, make another temp dir. */
1556 if (stat (output_name, &buf) >= 0)
1558 output_name = make_tempname (output_name);
1559 if (MKDIR (output_name, 0700) != 0)
1561 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1562 output_name, strerror (errno));
1564 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1565 l->name = output_name;
1566 l->next = list;
1567 l->obfd = NULL;
1568 list = l;
1569 output_name = concat (output_name, "/",
1570 bfd_get_filename (this_element), (char *) 0);
1573 output_bfd = bfd_openw (output_name, output_target);
1574 if (preserve_dates)
1576 stat_status = bfd_stat_arch_elt (this_element, &buf);
1578 if (stat_status != 0)
1579 non_fatal (_("internal stat error on %s"),
1580 bfd_get_filename (this_element));
1583 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1584 l->name = output_name;
1585 l->next = list;
1586 list = l;
1588 if (output_bfd == (bfd *) NULL)
1589 RETURN_NONFATAL (output_name);
1591 if (bfd_check_format (this_element, bfd_object))
1592 copy_object (this_element, output_bfd);
1594 if (!bfd_close (output_bfd))
1596 bfd_nonfatal (bfd_get_filename (output_bfd));
1597 /* Error in new object file. Don't change archive. */
1598 status = 1;
1601 if (preserve_dates && stat_status == 0)
1602 set_times (output_name, &buf);
1604 /* Open the newly output file and attach to our list. */
1605 output_bfd = bfd_openr (output_name, output_target);
1607 l->obfd = output_bfd;
1609 *ptr = output_bfd;
1610 ptr = &output_bfd->next;
1612 last_element = this_element;
1614 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1616 bfd_close (last_element);
1618 *ptr = (bfd *) NULL;
1620 if (!bfd_close (obfd))
1621 RETURN_NONFATAL (bfd_get_filename (obfd));
1623 if (!bfd_close (ibfd))
1624 RETURN_NONFATAL (bfd_get_filename (ibfd));
1626 /* Delete all the files that we opened. */
1627 for (l = list; l != NULL; l = l->next)
1629 if (l->obfd == NULL)
1630 rmdir (l->name);
1631 else
1633 bfd_close (l->obfd);
1634 unlink (l->name);
1637 rmdir (dir);
1640 /* The top-level control. */
1642 static void
1643 copy_file (input_filename, output_filename, input_target, output_target)
1644 const char *input_filename;
1645 const char *output_filename;
1646 const char *input_target;
1647 const char *output_target;
1649 bfd *ibfd;
1650 char **obj_matching;
1651 char **core_matching;
1653 /* To allow us to do "strip *" without dying on the first
1654 non-object file, failures are nonfatal. */
1655 ibfd = bfd_openr (input_filename, input_target);
1656 if (ibfd == NULL)
1657 RETURN_NONFATAL (input_filename);
1659 if (bfd_check_format (ibfd, bfd_archive))
1661 bfd *obfd;
1663 /* bfd_get_target does not return the correct value until
1664 bfd_check_format succeeds. */
1665 if (output_target == NULL)
1666 output_target = bfd_get_target (ibfd);
1668 obfd = bfd_openw (output_filename, output_target);
1669 if (obfd == NULL)
1670 RETURN_NONFATAL (output_filename);
1672 copy_archive (ibfd, obfd, output_target);
1674 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
1676 bfd *obfd;
1677 do_copy:
1678 /* bfd_get_target does not return the correct value until
1679 bfd_check_format succeeds. */
1680 if (output_target == NULL)
1681 output_target = bfd_get_target (ibfd);
1683 obfd = bfd_openw (output_filename, output_target);
1684 if (obfd == NULL)
1685 RETURN_NONFATAL (output_filename);
1687 copy_object (ibfd, obfd);
1689 if (!bfd_close (obfd))
1690 RETURN_NONFATAL (output_filename);
1692 if (!bfd_close (ibfd))
1693 RETURN_NONFATAL (input_filename);
1695 else
1697 bfd_error_type obj_error = bfd_get_error ();
1698 bfd_error_type core_error;
1700 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
1702 /* This probably can't happen.. */
1703 if (obj_error == bfd_error_file_ambiguously_recognized)
1704 free (obj_matching);
1705 goto do_copy;
1708 core_error = bfd_get_error ();
1709 /* Report the object error in preference to the core error. */
1710 if (obj_error != core_error)
1711 bfd_set_error (obj_error);
1713 bfd_nonfatal (input_filename);
1715 if (obj_error == bfd_error_file_ambiguously_recognized)
1717 list_matching_formats (obj_matching);
1718 free (obj_matching);
1720 if (core_error == bfd_error_file_ambiguously_recognized)
1722 list_matching_formats (core_matching);
1723 free (core_matching);
1726 status = 1;
1730 /* Add a name to the section renaming list. */
1732 static void
1733 add_section_rename (old_name, new_name, flags)
1734 const char * old_name;
1735 const char * new_name;
1736 flagword flags;
1738 section_rename * rename;
1740 /* Check for conflicts first. */
1741 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1742 if (strcmp (rename->old_name, old_name) == 0)
1744 /* Silently ignore duplicate definitions. */
1745 if (strcmp (rename->new_name, new_name) == 0
1746 && rename->flags == flags)
1747 return;
1749 fatal (_("Multiple renames of section %s"), old_name);
1752 rename = (section_rename *) xmalloc (sizeof (* rename));
1754 rename->old_name = old_name;
1755 rename->new_name = new_name;
1756 rename->flags = flags;
1757 rename->next = section_rename_list;
1759 section_rename_list = rename;
1762 /* Check the section rename list for a new name of the input section
1763 ISECTION. Return the new name if one is found.
1764 Also set RETURNED_FLAGS to the flags to be used for this section. */
1766 static const char *
1767 find_section_rename (ibfd, isection, returned_flags)
1768 bfd * ibfd ATTRIBUTE_UNUSED;
1769 sec_ptr isection;
1770 flagword * returned_flags;
1772 const char * old_name = bfd_section_name (ibfd, isection);
1773 section_rename * rename;
1775 /* Default to using the flags of the input section. */
1776 * returned_flags = bfd_get_section_flags (ibfd, isection);
1778 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1779 if (strcmp (rename->old_name, old_name) == 0)
1781 if (rename->flags != (flagword) -1)
1782 * returned_flags = rename->flags;
1784 return rename->new_name;
1787 return old_name;
1790 /* Create a section in OBFD with the same
1791 name and attributes as ISECTION in IBFD. */
1793 static void
1794 setup_section (ibfd, isection, obfdarg)
1795 bfd *ibfd;
1796 sec_ptr isection;
1797 PTR obfdarg;
1799 bfd *obfd = (bfd *) obfdarg;
1800 struct section_list *p;
1801 sec_ptr osection;
1802 bfd_size_type size;
1803 bfd_vma vma;
1804 bfd_vma lma;
1805 flagword flags;
1806 const char *err;
1807 const char * name;
1808 char *prefix = NULL;
1810 if (is_strip_section (ibfd, isection))
1811 return;
1813 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
1814 if (p != NULL)
1815 p->used = TRUE;
1817 /* Get the, possibly new, name of the output section. */
1818 name = find_section_rename (ibfd, isection, & flags);
1820 /* Prefix sections. */
1821 if ((prefix_alloc_sections_string) && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
1822 prefix = prefix_alloc_sections_string;
1823 else if (prefix_sections_string)
1824 prefix = prefix_sections_string;
1826 if (prefix)
1828 char *n;
1830 n = xmalloc (strlen (prefix) + strlen (name) + 1);
1831 strcpy (n, prefix);
1832 strcat (n, name);
1833 name = n;
1836 osection = bfd_make_section_anyway (obfd, name);
1838 if (osection == NULL)
1840 err = _("making");
1841 goto loser;
1844 size = bfd_section_size (ibfd, isection);
1845 if (copy_byte >= 0)
1846 size = (size + interleave - 1) / interleave;
1847 if (! bfd_set_section_size (obfd, osection, size))
1849 err = _("size");
1850 goto loser;
1853 vma = bfd_section_vma (ibfd, isection);
1854 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1855 vma += p->vma_val;
1856 else if (p != NULL && p->change_vma == CHANGE_SET)
1857 vma = p->vma_val;
1858 else
1859 vma += change_section_address;
1861 if (! bfd_set_section_vma (obfd, osection, vma))
1863 err = _("vma");
1864 goto loser;
1867 lma = isection->lma;
1868 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1870 if (p->change_lma == CHANGE_MODIFY)
1871 lma += p->lma_val;
1872 else if (p->change_lma == CHANGE_SET)
1873 lma = p->lma_val;
1874 else
1875 abort ();
1877 else
1878 lma += change_section_address;
1880 osection->lma = lma;
1882 /* FIXME: This is probably not enough. If we change the LMA we
1883 may have to recompute the header for the file as well. */
1884 if (!bfd_set_section_alignment (obfd,
1885 osection,
1886 bfd_section_alignment (ibfd, isection)))
1888 err = _("alignment");
1889 goto loser;
1892 if (p != NULL && p->set_flags)
1893 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
1894 if (!bfd_set_section_flags (obfd, osection, flags))
1896 err = _("flags");
1897 goto loser;
1900 /* Copy merge entity size. */
1901 osection->entsize = isection->entsize;
1903 /* This used to be mangle_section; we do here to avoid using
1904 bfd_get_section_by_name since some formats allow multiple
1905 sections with the same name. */
1906 isection->output_section = osection;
1907 isection->output_offset = 0;
1909 /* Allow the BFD backend to copy any private data it understands
1910 from the input section to the output section. */
1911 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1912 && strip_symbols == STRIP_NONDEBUG)
1913 /* Do not copy the private data when creating an ELF format
1914 debug info file. We do not want the program headers. */
1916 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1918 err = _("private data");
1919 goto loser;
1922 /* All went well. */
1923 return;
1925 loser:
1926 non_fatal (_("%s: section `%s': error in %s: %s"),
1927 bfd_get_filename (ibfd),
1928 bfd_section_name (ibfd, isection),
1929 err, bfd_errmsg (bfd_get_error ()));
1930 status = 1;
1933 /* Copy the data of input section ISECTION of IBFD
1934 to an output section with the same name in OBFD.
1935 If stripping then don't copy any relocation info. */
1937 static void
1938 copy_section (ibfd, isection, obfdarg)
1939 bfd *ibfd;
1940 sec_ptr isection;
1941 PTR obfdarg;
1943 bfd *obfd = (bfd *) obfdarg;
1944 struct section_list *p;
1945 arelent **relpp;
1946 long relcount;
1947 sec_ptr osection;
1948 bfd_size_type size;
1949 long relsize;
1950 flagword flags;
1952 /* If we have already failed earlier on,
1953 do not keep on generating complaints now. */
1954 if (status != 0)
1955 return;
1957 if (is_strip_section (ibfd, isection))
1958 return;
1960 flags = bfd_get_section_flags (ibfd, isection);
1961 if ((flags & SEC_GROUP) != 0)
1962 return;
1964 osection = isection->output_section;
1965 size = bfd_get_section_size_before_reloc (isection);
1967 if (size == 0 || osection == 0)
1968 return;
1970 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
1972 /* Core files do not need to be relocated. */
1973 if (bfd_get_format (obfd) == bfd_core)
1974 relsize = 0;
1975 else
1976 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1978 if (relsize < 0)
1979 RETURN_NONFATAL (bfd_get_filename (ibfd));
1981 if (relsize == 0)
1982 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1983 else
1985 relpp = (arelent **) xmalloc (relsize);
1986 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1987 if (relcount < 0)
1988 RETURN_NONFATAL (bfd_get_filename (ibfd));
1990 if (strip_symbols == STRIP_ALL)
1992 /* Remove relocations which are not in
1993 keep_strip_specific_list. */
1994 arelent **temp_relpp;
1995 long temp_relcount = 0;
1996 long i;
1998 temp_relpp = (arelent **) xmalloc (relsize);
1999 for (i = 0; i < relcount; i++)
2000 if (is_specified_symbol
2001 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
2002 keep_specific_list))
2003 temp_relpp [temp_relcount++] = relpp [i];
2004 relcount = temp_relcount;
2005 free (relpp);
2006 relpp = temp_relpp;
2009 bfd_set_reloc (obfd, osection,
2010 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
2013 isection->_cooked_size = isection->_raw_size;
2014 isection->reloc_done = TRUE;
2016 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
2017 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
2019 PTR memhunk = (PTR) xmalloc ((unsigned) size);
2021 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
2022 size))
2023 RETURN_NONFATAL (bfd_get_filename (ibfd));
2025 if (copy_byte >= 0)
2026 filter_bytes (memhunk, &size);
2028 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
2029 size))
2030 RETURN_NONFATAL (bfd_get_filename (obfd));
2032 free (memhunk);
2034 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2036 PTR memhunk = (PTR) xmalloc ((unsigned) size);
2038 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2039 flag--they can just remove the section entirely and add it
2040 back again. However, we do permit them to turn on the
2041 SEC_HAS_CONTENTS flag, and take it to mean that the section
2042 contents should be zeroed out. */
2044 memset (memhunk, 0, size);
2045 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
2046 size))
2047 RETURN_NONFATAL (bfd_get_filename (obfd));
2048 free (memhunk);
2052 /* Get all the sections. This is used when --gap-fill or --pad-to is
2053 used. */
2055 static void
2056 get_sections (obfd, osection, secppparg)
2057 bfd *obfd ATTRIBUTE_UNUSED;
2058 asection *osection;
2059 PTR secppparg;
2061 asection ***secppp = (asection ***) secppparg;
2063 **secppp = osection;
2064 ++(*secppp);
2067 /* Sort sections by VMA. This is called via qsort, and is used when
2068 --gap-fill or --pad-to is used. We force non loadable or empty
2069 sections to the front, where they are easier to ignore. */
2071 static int
2072 compare_section_lma (arg1, arg2)
2073 const PTR arg1;
2074 const PTR arg2;
2076 const asection **sec1 = (const asection **) arg1;
2077 const asection **sec2 = (const asection **) arg2;
2078 flagword flags1, flags2;
2080 /* Sort non loadable sections to the front. */
2081 flags1 = (*sec1)->flags;
2082 flags2 = (*sec2)->flags;
2083 if ((flags1 & SEC_HAS_CONTENTS) == 0
2084 || (flags1 & SEC_LOAD) == 0)
2086 if ((flags2 & SEC_HAS_CONTENTS) != 0
2087 && (flags2 & SEC_LOAD) != 0)
2088 return -1;
2090 else
2092 if ((flags2 & SEC_HAS_CONTENTS) == 0
2093 || (flags2 & SEC_LOAD) == 0)
2094 return 1;
2097 /* Sort sections by LMA. */
2098 if ((*sec1)->lma > (*sec2)->lma)
2099 return 1;
2100 else if ((*sec1)->lma < (*sec2)->lma)
2101 return -1;
2103 /* Sort sections with the same LMA by size. */
2104 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
2105 return 1;
2106 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
2107 return -1;
2109 return 0;
2112 /* Mark all the symbols which will be used in output relocations with
2113 the BSF_KEEP flag so that those symbols will not be stripped.
2115 Ignore relocations which will not appear in the output file. */
2117 static void
2118 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
2119 bfd *ibfd;
2120 sec_ptr isection;
2121 PTR symbolsarg;
2123 asymbol **symbols = (asymbol **) symbolsarg;
2124 long relsize;
2125 arelent **relpp;
2126 long relcount, i;
2128 /* Ignore an input section with no corresponding output section. */
2129 if (isection->output_section == NULL)
2130 return;
2132 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2133 if (relsize < 0)
2134 bfd_fatal (bfd_get_filename (ibfd));
2136 if (relsize == 0)
2137 return;
2139 relpp = (arelent **) xmalloc (relsize);
2140 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2141 if (relcount < 0)
2142 bfd_fatal (bfd_get_filename (ibfd));
2144 /* Examine each symbol used in a relocation. If it's not one of the
2145 special bfd section symbols, then mark it with BSF_KEEP. */
2146 for (i = 0; i < relcount; i++)
2148 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2149 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2150 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2151 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2154 if (relpp != NULL)
2155 free (relpp);
2158 /* Write out debugging information. */
2160 static bfd_boolean
2161 write_debugging_info (obfd, dhandle, symcountp, symppp)
2162 bfd *obfd;
2163 PTR dhandle;
2164 long *symcountp ATTRIBUTE_UNUSED;
2165 asymbol ***symppp ATTRIBUTE_UNUSED;
2167 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2168 return write_ieee_debugging_info (obfd, dhandle);
2170 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2171 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2173 bfd_byte *syms, *strings;
2174 bfd_size_type symsize, stringsize;
2175 asection *stabsec, *stabstrsec;
2177 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2178 &symsize, &strings,
2179 &stringsize))
2180 return FALSE;
2182 stabsec = bfd_make_section (obfd, ".stab");
2183 stabstrsec = bfd_make_section (obfd, ".stabstr");
2184 if (stabsec == NULL
2185 || stabstrsec == NULL
2186 || ! bfd_set_section_size (obfd, stabsec, symsize)
2187 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2188 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2189 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
2190 || ! bfd_set_section_flags (obfd, stabsec,
2191 (SEC_HAS_CONTENTS
2192 | SEC_READONLY
2193 | SEC_DEBUGGING))
2194 || ! bfd_set_section_flags (obfd, stabstrsec,
2195 (SEC_HAS_CONTENTS
2196 | SEC_READONLY
2197 | SEC_DEBUGGING)))
2199 non_fatal (_("%s: can't create debugging section: %s"),
2200 bfd_get_filename (obfd),
2201 bfd_errmsg (bfd_get_error ()));
2202 return FALSE;
2205 /* We can get away with setting the section contents now because
2206 the next thing the caller is going to do is copy over the
2207 real sections. We may someday have to split the contents
2208 setting out of this function. */
2209 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
2210 symsize)
2211 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
2212 (file_ptr) 0, stringsize))
2214 non_fatal (_("%s: can't set debugging section contents: %s"),
2215 bfd_get_filename (obfd),
2216 bfd_errmsg (bfd_get_error ()));
2217 return FALSE;
2220 return TRUE;
2223 non_fatal (_("%s: don't know how to write debugging information for %s"),
2224 bfd_get_filename (obfd), bfd_get_target (obfd));
2225 return FALSE;
2228 static int
2229 strip_main (argc, argv)
2230 int argc;
2231 char *argv[];
2233 char *input_target = NULL;
2234 char *output_target = NULL;
2235 bfd_boolean show_version = FALSE;
2236 bfd_boolean formats_info = FALSE;
2237 int c;
2238 int i;
2239 struct section_list *p;
2240 char *output_file = NULL;
2242 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVv",
2243 strip_options, (int *) 0)) != EOF)
2245 switch (c)
2247 case 'I':
2248 input_target = optarg;
2249 break;
2250 case 'O':
2251 output_target = optarg;
2252 break;
2253 case 'F':
2254 input_target = output_target = optarg;
2255 break;
2256 case 'R':
2257 p = find_section_list (optarg, TRUE);
2258 p->remove = TRUE;
2259 sections_removed = TRUE;
2260 break;
2261 case 's':
2262 strip_symbols = STRIP_ALL;
2263 break;
2264 case 'S':
2265 case 'g':
2266 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2267 strip_symbols = STRIP_DEBUG;
2268 break;
2269 case OPTION_STRIP_UNNEEDED:
2270 strip_symbols = STRIP_UNNEEDED;
2271 break;
2272 case 'K':
2273 add_specific_symbol (optarg, &keep_specific_list);
2274 break;
2275 case 'N':
2276 add_specific_symbol (optarg, &strip_specific_list);
2277 break;
2278 case 'o':
2279 output_file = optarg;
2280 break;
2281 case 'p':
2282 preserve_dates = TRUE;
2283 break;
2284 case 'x':
2285 discard_locals = LOCALS_ALL;
2286 break;
2287 case 'X':
2288 discard_locals = LOCALS_START_L;
2289 break;
2290 case 'v':
2291 verbose = TRUE;
2292 break;
2293 case 'V':
2294 show_version = TRUE;
2295 break;
2296 case OPTION_FORMATS_INFO:
2297 formats_info = TRUE;
2298 break;
2299 case OPTION_ONLY_KEEP_DEBUG:
2300 strip_symbols = STRIP_NONDEBUG;
2301 break;
2302 case 0:
2303 /* We've been given a long option. */
2304 break;
2305 case 'H':
2306 case 'h':
2307 strip_usage (stdout, 0);
2308 default:
2309 strip_usage (stderr, 1);
2313 if (formats_info)
2315 display_info ();
2316 return 0;
2319 if (show_version)
2320 print_version ("strip");
2322 /* Default is to strip all symbols. */
2323 if (strip_symbols == STRIP_UNDEF
2324 && discard_locals == LOCALS_UNDEF
2325 && strip_specific_list == NULL)
2326 strip_symbols = STRIP_ALL;
2328 if (output_target == (char *) NULL)
2329 output_target = input_target;
2331 i = optind;
2332 if (i == argc
2333 || (output_file != NULL && (i + 1) < argc))
2334 strip_usage (stderr, 1);
2336 for (; i < argc; i++)
2338 int hold_status = status;
2339 struct stat statbuf;
2340 char *tmpname;
2342 if (preserve_dates)
2344 if (stat (argv[i], &statbuf) < 0)
2346 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
2347 continue;
2351 if (output_file != NULL)
2352 tmpname = output_file;
2353 else
2354 tmpname = make_tempname (argv[i]);
2355 status = 0;
2357 copy_file (argv[i], tmpname, input_target, output_target);
2358 if (status == 0)
2360 if (preserve_dates)
2361 set_times (tmpname, &statbuf);
2362 if (output_file == NULL)
2363 smart_rename (tmpname, argv[i], preserve_dates);
2364 status = hold_status;
2366 else
2367 unlink (tmpname);
2368 if (output_file == NULL)
2369 free (tmpname);
2372 return 0;
2375 static int
2376 copy_main (argc, argv)
2377 int argc;
2378 char *argv[];
2380 char * binary_architecture = NULL;
2381 char *input_filename = NULL;
2382 char *output_filename = NULL;
2383 char *input_target = NULL;
2384 char *output_target = NULL;
2385 bfd_boolean show_version = FALSE;
2386 bfd_boolean change_warn = TRUE;
2387 bfd_boolean formats_info = FALSE;
2388 int c;
2389 struct section_list *p;
2390 struct stat statbuf;
2392 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:",
2393 copy_options, (int *) 0)) != EOF)
2395 switch (c)
2397 case 'b':
2398 copy_byte = atoi (optarg);
2399 if (copy_byte < 0)
2400 fatal (_("byte number must be non-negative"));
2401 break;
2403 case 'B':
2404 binary_architecture = optarg;
2405 break;
2407 case 'i':
2408 interleave = atoi (optarg);
2409 if (interleave < 1)
2410 fatal (_("interleave must be positive"));
2411 break;
2413 case 'I':
2414 case 's': /* "source" - 'I' is preferred */
2415 input_target = optarg;
2416 break;
2418 case 'O':
2419 case 'd': /* "destination" - 'O' is preferred */
2420 output_target = optarg;
2421 break;
2423 case 'F':
2424 input_target = output_target = optarg;
2425 break;
2427 case 'j':
2428 p = find_section_list (optarg, TRUE);
2429 if (p->remove)
2430 fatal (_("%s both copied and removed"), optarg);
2431 p->copy = TRUE;
2432 sections_copied = TRUE;
2433 break;
2435 case 'R':
2436 p = find_section_list (optarg, TRUE);
2437 if (p->copy)
2438 fatal (_("%s both copied and removed"), optarg);
2439 p->remove = TRUE;
2440 sections_removed = TRUE;
2441 break;
2443 case 'S':
2444 strip_symbols = STRIP_ALL;
2445 break;
2447 case 'g':
2448 strip_symbols = STRIP_DEBUG;
2449 break;
2451 case OPTION_STRIP_UNNEEDED:
2452 strip_symbols = STRIP_UNNEEDED;
2453 break;
2455 case OPTION_ONLY_KEEP_DEBUG:
2456 strip_symbols = STRIP_NONDEBUG;
2457 break;
2459 case OPTION_ADD_GNU_DEBUGLINK:
2460 gnu_debuglink_filename = optarg;
2461 break;
2463 case 'K':
2464 add_specific_symbol (optarg, &keep_specific_list);
2465 break;
2467 case 'N':
2468 add_specific_symbol (optarg, &strip_specific_list);
2469 break;
2471 case 'L':
2472 add_specific_symbol (optarg, &localize_specific_list);
2473 break;
2475 case 'G':
2476 add_specific_symbol (optarg, &keepglobal_specific_list);
2477 break;
2479 case 'W':
2480 add_specific_symbol (optarg, &weaken_specific_list);
2481 break;
2483 case 'p':
2484 preserve_dates = TRUE;
2485 break;
2487 case 'x':
2488 discard_locals = LOCALS_ALL;
2489 break;
2491 case 'X':
2492 discard_locals = LOCALS_START_L;
2493 break;
2495 case 'v':
2496 verbose = TRUE;
2497 break;
2499 case 'V':
2500 show_version = TRUE;
2501 break;
2503 case OPTION_FORMATS_INFO:
2504 formats_info = TRUE;
2505 break;
2507 case OPTION_WEAKEN:
2508 weaken = TRUE;
2509 break;
2511 case OPTION_ADD_SECTION:
2513 const char *s;
2514 struct stat st;
2515 struct section_add *pa;
2516 int len;
2517 char *name;
2518 FILE *f;
2520 s = strchr (optarg, '=');
2522 if (s == NULL)
2523 fatal (_("bad format for %s"), "--add-section");
2525 if (stat (s + 1, & st) < 0)
2526 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
2528 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
2530 len = s - optarg;
2531 name = (char *) xmalloc (len + 1);
2532 strncpy (name, optarg, len);
2533 name[len] = '\0';
2534 pa->name = name;
2536 pa->filename = s + 1;
2538 pa->size = st.st_size;
2540 pa->contents = (bfd_byte *) xmalloc (pa->size);
2541 f = fopen (pa->filename, FOPEN_RB);
2543 if (f == NULL)
2544 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
2546 if (fread (pa->contents, 1, pa->size, f) == 0
2547 || ferror (f))
2548 fatal (_("%s: fread failed"), pa->filename);
2550 fclose (f);
2552 pa->next = add_sections;
2553 add_sections = pa;
2555 break;
2557 case OPTION_CHANGE_START:
2558 change_start = parse_vma (optarg, "--change-start");
2559 break;
2561 case OPTION_CHANGE_SECTION_ADDRESS:
2562 case OPTION_CHANGE_SECTION_LMA:
2563 case OPTION_CHANGE_SECTION_VMA:
2565 const char *s;
2566 int len;
2567 char *name;
2568 char *option = NULL;
2569 bfd_vma val;
2570 enum change_action what = CHANGE_IGNORE;
2572 switch (c)
2574 case OPTION_CHANGE_SECTION_ADDRESS:
2575 option = "--change-section-address";
2576 break;
2577 case OPTION_CHANGE_SECTION_LMA:
2578 option = "--change-section-lma";
2579 break;
2580 case OPTION_CHANGE_SECTION_VMA:
2581 option = "--change-section-vma";
2582 break;
2585 s = strchr (optarg, '=');
2586 if (s == NULL)
2588 s = strchr (optarg, '+');
2589 if (s == NULL)
2591 s = strchr (optarg, '-');
2592 if (s == NULL)
2593 fatal (_("bad format for %s"), option);
2597 len = s - optarg;
2598 name = (char *) xmalloc (len + 1);
2599 strncpy (name, optarg, len);
2600 name[len] = '\0';
2602 p = find_section_list (name, TRUE);
2604 val = parse_vma (s + 1, option);
2606 switch (*s)
2608 case '=': what = CHANGE_SET; break;
2609 case '-': val = - val; /* Drop through. */
2610 case '+': what = CHANGE_MODIFY; break;
2613 switch (c)
2615 case OPTION_CHANGE_SECTION_ADDRESS:
2616 p->change_vma = what;
2617 p->vma_val = val;
2618 /* Drop through. */
2620 case OPTION_CHANGE_SECTION_LMA:
2621 p->change_lma = what;
2622 p->lma_val = val;
2623 break;
2625 case OPTION_CHANGE_SECTION_VMA:
2626 p->change_vma = what;
2627 p->vma_val = val;
2628 break;
2631 break;
2633 case OPTION_CHANGE_ADDRESSES:
2634 change_section_address = parse_vma (optarg, "--change-addresses");
2635 change_start = change_section_address;
2636 break;
2638 case OPTION_CHANGE_WARNINGS:
2639 change_warn = TRUE;
2640 break;
2642 case OPTION_CHANGE_LEADING_CHAR:
2643 change_leading_char = TRUE;
2644 break;
2646 case OPTION_DEBUGGING:
2647 convert_debugging = TRUE;
2648 break;
2650 case OPTION_GAP_FILL:
2652 bfd_vma gap_fill_vma;
2654 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2655 gap_fill = (bfd_byte) gap_fill_vma;
2656 if ((bfd_vma) gap_fill != gap_fill_vma)
2658 char buff[20];
2660 sprintf_vma (buff, gap_fill_vma);
2662 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2663 buff, gap_fill);
2665 gap_fill_set = TRUE;
2667 break;
2669 case OPTION_NO_CHANGE_WARNINGS:
2670 change_warn = FALSE;
2671 break;
2673 case OPTION_PAD_TO:
2674 pad_to = parse_vma (optarg, "--pad-to");
2675 pad_to_set = TRUE;
2676 break;
2678 case OPTION_REMOVE_LEADING_CHAR:
2679 remove_leading_char = TRUE;
2680 break;
2682 case OPTION_REDEFINE_SYM:
2684 /* Push this redefinition onto redefine_symbol_list. */
2686 int len;
2687 const char *s;
2688 const char *nextarg;
2689 char *source, *target;
2691 s = strchr (optarg, '=');
2692 if (s == NULL)
2693 fatal (_("bad format for %s"), "--redefine-sym");
2695 len = s - optarg;
2696 source = (char *) xmalloc (len + 1);
2697 strncpy (source, optarg, len);
2698 source[len] = '\0';
2700 nextarg = s + 1;
2701 len = strlen (nextarg);
2702 target = (char *) xmalloc (len + 1);
2703 strcpy (target, nextarg);
2705 redefine_list_append ("--redefine-sym", source, target);
2707 free (source);
2708 free (target);
2710 break;
2712 case OPTION_REDEFINE_SYMS:
2713 add_redefine_syms_file (optarg);
2714 break;
2716 case OPTION_SET_SECTION_FLAGS:
2718 const char *s;
2719 int len;
2720 char *name;
2722 s = strchr (optarg, '=');
2723 if (s == NULL)
2724 fatal (_("bad format for %s"), "--set-section-flags");
2726 len = s - optarg;
2727 name = (char *) xmalloc (len + 1);
2728 strncpy (name, optarg, len);
2729 name[len] = '\0';
2731 p = find_section_list (name, TRUE);
2733 p->set_flags = TRUE;
2734 p->flags = parse_flags (s + 1);
2736 break;
2738 case OPTION_RENAME_SECTION:
2740 flagword flags;
2741 const char *eq, *fl;
2742 char *old_name;
2743 char *new_name;
2744 unsigned int len;
2746 eq = strchr (optarg, '=');
2747 if (eq == NULL)
2748 fatal (_("bad format for %s"), "--rename-section");
2750 len = eq - optarg;
2751 if (len == 0)
2752 fatal (_("bad format for %s"), "--rename-section");
2754 old_name = (char *) xmalloc (len + 1);
2755 strncpy (old_name, optarg, len);
2756 old_name[len] = 0;
2758 eq++;
2759 fl = strchr (eq, ',');
2760 if (fl)
2762 flags = parse_flags (fl + 1);
2763 len = fl - eq;
2765 else
2767 flags = -1;
2768 len = strlen (eq);
2771 if (len == 0)
2772 fatal (_("bad format for %s"), "--rename-section");
2774 new_name = (char *) xmalloc (len + 1);
2775 strncpy (new_name, eq, len);
2776 new_name[len] = 0;
2778 add_section_rename (old_name, new_name, flags);
2780 break;
2782 case OPTION_SET_START:
2783 set_start = parse_vma (optarg, "--set-start");
2784 set_start_set = TRUE;
2785 break;
2787 case OPTION_SREC_LEN:
2788 Chunk = parse_vma (optarg, "--srec-len");
2789 break;
2791 case OPTION_SREC_FORCES3:
2792 S3Forced = TRUE;
2793 break;
2795 case OPTION_STRIP_SYMBOLS:
2796 add_specific_symbols (optarg, &strip_specific_list);
2797 break;
2799 case OPTION_KEEP_SYMBOLS:
2800 add_specific_symbols (optarg, &keep_specific_list);
2801 break;
2803 case OPTION_LOCALIZE_SYMBOLS:
2804 add_specific_symbols (optarg, &localize_specific_list);
2805 break;
2807 case OPTION_KEEPGLOBAL_SYMBOLS:
2808 add_specific_symbols (optarg, &keepglobal_specific_list);
2809 break;
2811 case OPTION_WEAKEN_SYMBOLS:
2812 add_specific_symbols (optarg, &weaken_specific_list);
2813 break;
2815 case OPTION_ALT_MACH_CODE:
2816 use_alt_mach_code = atoi (optarg);
2817 if (use_alt_mach_code <= 0)
2818 fatal (_("alternate machine code index must be positive"));
2819 break;
2821 case OPTION_PREFIX_SYMBOLS:
2822 prefix_symbols_string = optarg;
2823 break;
2825 case OPTION_PREFIX_SECTIONS:
2826 prefix_sections_string = optarg;
2827 break;
2829 case OPTION_PREFIX_ALLOC_SECTIONS:
2830 prefix_alloc_sections_string = optarg;
2831 break;
2833 case 0:
2834 /* We've been given a long option. */
2835 break;
2837 case 'H':
2838 case 'h':
2839 copy_usage (stdout, 0);
2841 default:
2842 copy_usage (stderr, 1);
2846 if (formats_info)
2848 display_info ();
2849 return 0;
2852 if (show_version)
2853 print_version ("objcopy");
2855 if (copy_byte >= interleave)
2856 fatal (_("byte number must be less than interleave"));
2858 if (optind == argc || optind + 2 < argc)
2859 copy_usage (stderr, 1);
2861 input_filename = argv[optind];
2862 if (optind + 1 < argc)
2863 output_filename = argv[optind + 1];
2865 /* Default is to strip no symbols. */
2866 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2867 strip_symbols = STRIP_NONE;
2869 if (output_target == (char *) NULL)
2870 output_target = input_target;
2872 if (binary_architecture != (char *) NULL)
2874 if (input_target && strcmp (input_target, "binary") == 0)
2876 const bfd_arch_info_type * temp_arch_info;
2878 temp_arch_info = bfd_scan_arch (binary_architecture);
2880 if (temp_arch_info != NULL)
2881 bfd_external_binary_architecture = temp_arch_info->arch;
2882 else
2883 fatal (_("architecture %s unknown"), binary_architecture);
2885 else
2887 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2888 non_fatal (_(" Argument %s ignored"), binary_architecture);
2892 if (preserve_dates)
2893 if (stat (input_filename, & statbuf) < 0)
2894 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2896 /* If there is no destination file, or the source and destination files
2897 are the same, then create a temp and rename the result into the input. */
2898 if ((output_filename == (char *) NULL) ||
2899 (strcmp (input_filename, output_filename) == 0))
2901 char *tmpname = make_tempname (input_filename);
2903 copy_file (input_filename, tmpname, input_target, output_target);
2904 if (status == 0)
2906 if (preserve_dates)
2907 set_times (tmpname, &statbuf);
2908 smart_rename (tmpname, input_filename, preserve_dates);
2910 else
2911 unlink (tmpname);
2913 else
2915 copy_file (input_filename, output_filename, input_target, output_target);
2917 if (status == 0 && preserve_dates)
2918 set_times (output_filename, &statbuf);
2921 if (change_warn)
2923 for (p = change_sections; p != NULL; p = p->next)
2925 if (! p->used)
2927 if (p->change_vma != CHANGE_IGNORE)
2929 char buff [20];
2931 sprintf_vma (buff, p->vma_val);
2933 /* xgettext:c-format */
2934 non_fatal (_("%s %s%c0x%s never used"),
2935 "--change-section-vma",
2936 p->name,
2937 p->change_vma == CHANGE_SET ? '=' : '+',
2938 buff);
2941 if (p->change_lma != CHANGE_IGNORE)
2943 char buff [20];
2945 sprintf_vma (buff, p->lma_val);
2947 /* xgettext:c-format */
2948 non_fatal (_("%s %s%c0x%s never used"),
2949 "--change-section-lma",
2950 p->name,
2951 p->change_lma == CHANGE_SET ? '=' : '+',
2952 buff);
2958 return 0;
2961 int main PARAMS ((int, char **));
2964 main (argc, argv)
2965 int argc;
2966 char *argv[];
2968 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2969 setlocale (LC_MESSAGES, "");
2970 #endif
2971 #if defined (HAVE_SETLOCALE)
2972 setlocale (LC_CTYPE, "");
2973 #endif
2974 bindtextdomain (PACKAGE, LOCALEDIR);
2975 textdomain (PACKAGE);
2977 program_name = argv[0];
2978 xmalloc_set_program_name (program_name);
2980 START_PROGRESS (program_name, 0);
2982 strip_symbols = STRIP_UNDEF;
2983 discard_locals = LOCALS_UNDEF;
2985 bfd_init ();
2986 set_default_bfd_target ();
2988 if (is_strip < 0)
2990 int i = strlen (program_name);
2991 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2992 /* Drop the .exe suffix, if any. */
2993 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2995 i -= 4;
2996 program_name[i] = '\0';
2998 #endif
2999 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
3002 if (is_strip)
3003 strip_main (argc, argv);
3004 else
3005 copy_main (argc, argv);
3007 END_PROGRESS (program_name);
3009 return status;