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,
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
27 #include "libiberty.h"
29 #include "filenames.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
43 /* A list to support redefine_sym. */
48 struct redefine_node
*next
;
51 typedef struct section_rename
53 const char * old_name
;
54 const char * new_name
;
56 struct section_rename
* next
;
60 /* List of sections to be renamed. */
61 static section_rename
* section_rename_list
;
63 static void copy_usage
PARAMS ((FILE *, int));
64 static void strip_usage
PARAMS ((FILE *, int));
65 static flagword parse_flags
PARAMS ((const char *));
66 static struct section_list
*find_section_list
PARAMS ((const char *, boolean
));
67 static void setup_section
PARAMS ((bfd
*, asection
*, PTR
));
68 static void copy_section
PARAMS ((bfd
*, asection
*, PTR
));
69 static void get_sections
PARAMS ((bfd
*, asection
*, PTR
));
70 static int compare_section_lma
PARAMS ((const PTR
, const PTR
));
71 static void add_specific_symbol
PARAMS ((const char *, struct symlist
**));
72 static void add_specific_symbols
PARAMS ((const char *, struct symlist
**));
73 static boolean is_specified_symbol
PARAMS ((const char *, struct symlist
*));
74 static boolean is_strip_section
PARAMS ((bfd
*, asection
*));
75 static unsigned int filter_symbols
76 PARAMS ((bfd
*, bfd
*, asymbol
**, asymbol
**, long));
77 static void mark_symbols_used_in_relocations
PARAMS ((bfd
*, asection
*, PTR
));
78 static void filter_bytes
PARAMS ((char *, bfd_size_type
*));
79 static boolean write_debugging_info
PARAMS ((bfd
*, PTR
, long *, asymbol
***));
80 static void copy_object
PARAMS ((bfd
*, bfd
*));
81 static void copy_archive
PARAMS ((bfd
*, bfd
*, const char *));
83 PARAMS ((const char *, const char *, const char *, const char *));
84 static int strip_main
PARAMS ((int, char **));
85 static int copy_main
PARAMS ((int, char **));
86 static const char *lookup_sym_redefinition
PARAMS((const char *));
87 static void redefine_list_append
PARAMS ((const char *, const char *));
88 static const char * find_section_rename
PARAMS ((bfd
*, sec_ptr
, flagword
*));
89 static void add_section_rename
PARAMS ((const char *, const char *, flagword
));
91 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
93 static asymbol
**isympp
= NULL
; /* Input symbols */
94 static asymbol
**osympp
= NULL
; /* Output symbols that survive stripping */
96 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
97 static int copy_byte
= -1;
98 static int interleave
= 4;
100 static boolean verbose
; /* Print file and target names. */
101 static boolean preserve_dates
; /* Preserve input file timestamp. */
102 static int status
= 0; /* Exit status. */
107 STRIP_NONE
, /* don't strip */
108 STRIP_DEBUG
, /* strip all debugger symbols */
109 STRIP_UNNEEDED
, /* strip unnecessary symbols */
110 STRIP_ALL
/* strip all symbols */
113 /* Which symbols to remove. */
114 static enum strip_action strip_symbols
;
119 LOCALS_START_L
, /* discard locals starting with L */
120 LOCALS_ALL
/* discard all locals */
123 /* Which local symbols to remove. Overrides STRIP_ALL. */
124 static enum locals_action discard_locals
;
126 /* What kind of change to perform. */
134 /* Structure used to hold lists of sections and actions to take. */
137 struct section_list
* next
; /* Next section to change. */
138 const char * name
; /* Section name. */
139 boolean used
; /* Whether this entry was used. */
140 boolean remove
; /* Whether to remove this section. */
141 boolean copy
; /* Whether to copy this section. */
142 enum change_action change_vma
;/* Whether to change or set VMA. */
143 bfd_vma vma_val
; /* Amount to change by or set to. */
144 enum change_action change_lma
;/* Whether to change or set LMA. */
145 bfd_vma lma_val
; /* Amount to change by or set to. */
146 boolean set_flags
; /* Whether to set the section flags. */
147 flagword flags
; /* What to set the section flags to. */
150 static struct section_list
*change_sections
;
152 /* True if some sections are to be removed. */
153 static boolean sections_removed
;
155 /* True if only some sections are to be copied. */
156 static boolean sections_copied
;
158 /* Changes to the start address. */
159 static bfd_vma change_start
= 0;
160 static boolean set_start_set
= false;
161 static bfd_vma set_start
;
163 /* Changes to section addresses. */
164 static bfd_vma change_section_address
= 0;
166 /* Filling gaps between sections. */
167 static boolean gap_fill_set
= false;
168 static bfd_byte gap_fill
= 0;
170 /* Pad to a given address. */
171 static boolean pad_to_set
= false;
172 static bfd_vma pad_to
;
174 /* Use alternate machine code? */
175 static int use_alt_mach_code
= 0;
177 /* List of sections to add. */
180 /* Next section to add. */
181 struct section_add
*next
;
182 /* Name of section to add. */
184 /* Name of file holding section contents. */
185 const char *filename
;
188 /* Contents of file. */
190 /* BFD section, after it has been added. */
194 /* List of sections to add to the output BFD. */
195 static struct section_add
*add_sections
;
197 /* Whether to convert debugging information. */
198 static boolean convert_debugging
= false;
200 /* Whether to change the leading character in symbol names. */
201 static boolean change_leading_char
= false;
203 /* Whether to remove the leading character from global symbol names. */
204 static boolean remove_leading_char
= false;
206 /* List of symbols to strip, keep, localize, keep-global, weaken,
208 static struct symlist
*strip_specific_list
= NULL
;
209 static struct symlist
*keep_specific_list
= NULL
;
210 static struct symlist
*localize_specific_list
= NULL
;
211 static struct symlist
*keepglobal_specific_list
= NULL
;
212 static struct symlist
*weaken_specific_list
= NULL
;
213 static struct redefine_node
*redefine_sym_list
= NULL
;
215 /* If this is true, we weaken global symbols (set BSF_WEAK). */
216 static boolean weaken
= false;
218 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
220 #define OPTION_ADD_SECTION 150
221 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
222 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
223 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
224 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
225 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
226 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
227 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
228 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
229 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
230 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
231 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
232 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
233 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
234 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
235 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
236 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
237 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
238 #define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
239 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
240 #define OPTION_STRIP_SYMBOLS (OPTION_SREC_FORCES3 + 1)
241 #define OPTION_KEEP_SYMBOLS (OPTION_STRIP_SYMBOLS + 1)
242 #define OPTION_LOCALIZE_SYMBOLS (OPTION_KEEP_SYMBOLS + 1)
243 #define OPTION_KEEPGLOBAL_SYMBOLS (OPTION_LOCALIZE_SYMBOLS + 1)
244 #define OPTION_WEAKEN_SYMBOLS (OPTION_KEEPGLOBAL_SYMBOLS + 1)
245 #define OPTION_RENAME_SECTION (OPTION_WEAKEN_SYMBOLS + 1)
246 #define OPTION_ALT_MACH_CODE (OPTION_RENAME_SECTION + 1)
248 /* Options to handle if running as "strip". */
250 static struct option strip_options
[] =
252 {"discard-all", no_argument
, 0, 'x'},
253 {"discard-locals", no_argument
, 0, 'X'},
254 {"format", required_argument
, 0, 'F'}, /* Obsolete */
255 {"help", no_argument
, 0, 'h'},
256 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
257 {"input-target", required_argument
, 0, 'I'},
258 {"keep-symbol", required_argument
, 0, 'K'},
259 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
260 {"output-target", required_argument
, 0, 'O'},
261 {"output-file", required_argument
, 0, 'o'},
262 {"preserve-dates", no_argument
, 0, 'p'},
263 {"remove-section", required_argument
, 0, 'R'},
264 {"strip-all", no_argument
, 0, 's'},
265 {"strip-debug", no_argument
, 0, 'S'},
266 {"strip-unneeded", no_argument
, 0, OPTION_STRIP_UNNEEDED
},
267 {"strip-symbol", required_argument
, 0, 'N'},
268 {"target", required_argument
, 0, 'F'},
269 {"verbose", no_argument
, 0, 'v'},
270 {"version", no_argument
, 0, 'V'},
271 {0, no_argument
, 0, 0}
274 /* Options to handle if running as "objcopy". */
276 static struct option copy_options
[] =
278 {"add-section", required_argument
, 0, OPTION_ADD_SECTION
},
279 {"adjust-start", required_argument
, 0, OPTION_CHANGE_START
},
280 {"adjust-vma", required_argument
, 0, OPTION_CHANGE_ADDRESSES
},
281 {"adjust-section-vma", required_argument
, 0, OPTION_CHANGE_SECTION_ADDRESS
},
282 {"adjust-warnings", no_argument
, 0, OPTION_CHANGE_WARNINGS
},
283 {"binary-architecture", required_argument
, 0, 'B'},
284 {"byte", required_argument
, 0, 'b'},
285 {"change-addresses", required_argument
, 0, OPTION_CHANGE_ADDRESSES
},
286 {"change-leading-char", no_argument
, 0, OPTION_CHANGE_LEADING_CHAR
},
287 {"change-section-address", required_argument
, 0, OPTION_CHANGE_SECTION_ADDRESS
},
288 {"change-section-lma", required_argument
, 0, OPTION_CHANGE_SECTION_LMA
},
289 {"change-section-vma", required_argument
, 0, OPTION_CHANGE_SECTION_VMA
},
290 {"change-start", required_argument
, 0, OPTION_CHANGE_START
},
291 {"change-warnings", no_argument
, 0, OPTION_CHANGE_WARNINGS
},
292 {"debugging", no_argument
, 0, OPTION_DEBUGGING
},
293 {"discard-all", no_argument
, 0, 'x'},
294 {"discard-locals", no_argument
, 0, 'X'},
295 {"only-section", required_argument
, 0, 'j'},
296 {"format", required_argument
, 0, 'F'}, /* Obsolete */
297 {"gap-fill", required_argument
, 0, OPTION_GAP_FILL
},
298 {"help", no_argument
, 0, 'h'},
299 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
300 {"input-target", required_argument
, 0, 'I'},
301 {"interleave", required_argument
, 0, 'i'},
302 {"keep-symbol", required_argument
, 0, 'K'},
303 {"no-adjust-warnings", no_argument
, 0, OPTION_NO_CHANGE_WARNINGS
},
304 {"no-change-warnings", no_argument
, 0, OPTION_NO_CHANGE_WARNINGS
},
305 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
306 {"output-target", required_argument
, 0, 'O'},
307 {"pad-to", required_argument
, 0, OPTION_PAD_TO
},
308 {"preserve-dates", no_argument
, 0, 'p'},
309 {"localize-symbol", required_argument
, 0, 'L'},
310 {"keep-global-symbol", required_argument
, 0, 'G'},
311 {"remove-leading-char", no_argument
, 0, OPTION_REMOVE_LEADING_CHAR
},
312 {"remove-section", required_argument
, 0, 'R'},
313 {"rename-section", required_argument
, 0, OPTION_RENAME_SECTION
},
314 {"set-section-flags", required_argument
, 0, OPTION_SET_SECTION_FLAGS
},
315 {"set-start", required_argument
, 0, OPTION_SET_START
},
316 {"strip-all", no_argument
, 0, 'S'},
317 {"strip-debug", no_argument
, 0, 'g'},
318 {"strip-unneeded", no_argument
, 0, OPTION_STRIP_UNNEEDED
},
319 {"strip-symbol", required_argument
, 0, 'N'},
320 {"target", required_argument
, 0, 'F'},
321 {"verbose", no_argument
, 0, 'v'},
322 {"version", no_argument
, 0, 'V'},
323 {"weaken", no_argument
, 0, OPTION_WEAKEN
},
324 {"weaken-symbol", required_argument
, 0, 'W'},
325 {"redefine-sym", required_argument
, 0, OPTION_REDEFINE_SYM
},
326 {"srec-len", required_argument
, 0, OPTION_SREC_LEN
},
327 {"srec-forceS3", no_argument
, 0, OPTION_SREC_FORCES3
},
328 {"keep-symbols", required_argument
, 0, OPTION_KEEP_SYMBOLS
},
329 {"strip-symbols", required_argument
, 0, OPTION_STRIP_SYMBOLS
},
330 {"keep-global-symbols", required_argument
, 0, OPTION_KEEPGLOBAL_SYMBOLS
},
331 {"localize-symbols", required_argument
, 0, OPTION_LOCALIZE_SYMBOLS
},
332 {"weaken-symbols", required_argument
, 0, OPTION_WEAKEN_SYMBOLS
},
333 {"alt-machine-code", required_argument
, 0, OPTION_ALT_MACH_CODE
},
334 {0, no_argument
, 0, 0}
338 extern char *program_name
;
340 /* This flag distinguishes between strip and objcopy:
341 1 means this is 'strip'; 0 means this is 'objcopy'.
342 -1 means if we should use argv[0] to decide. */
345 /* The maximum length of an S record. This variable is declared in srec.c
346 and can be modified by the --srec-len parameter. */
347 extern unsigned int Chunk
;
349 /* Restrict the generation of Srecords to type S3 only.
350 This variable is declare in bfd/srec.c and can be toggled
351 on by the --srec-forceS3 command line switch. */
352 extern boolean S3Forced
;
354 /* Defined in bfd/binary.c. Used to set architecture of input binary files. */
355 extern enum bfd_architecture bfd_external_binary_architecture
;
359 copy_usage (stream
, exit_status
)
363 fprintf (stream
, _("Usage: %s <switches> in-file [out-file]\n"), program_name
);
364 fprintf (stream
, _(" The switches are:\n"));
365 fprintf (stream
, _("\
366 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
367 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
368 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
369 -F --target <bfdname> Set both input and output format to <bfdname>\n\
370 --debugging Convert debugging information, if possible\n\
371 -p --preserve-dates Copy modified/access timestamps to the output\n\
372 -j --only-section <name> Only copy section <name> into the output\n\
373 -R --remove-section <name> Remove section <name> from the output\n\
374 -S --strip-all Remove all symbol and relocation information\n\
375 -g --strip-debug Remove all debugging symbols\n\
376 --strip-unneeded Remove all symbols not needed by relocations\n\
377 -N --strip-symbol <name> Do not copy symbol <name>\n\
378 -K --keep-symbol <name> Only copy symbol <name>\n\
379 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
380 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
381 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
382 --weaken Force all global symbols to be marked as weak\n\
383 -x --discard-all Remove all non-global symbols\n\
384 -X --discard-locals Remove any compiler-generated symbols\n\
385 -i --interleave <number> Only copy one out of every <number> bytes\n\
386 -b --byte <num> Select byte <num> in every interleaved block\n\
387 --gap-fill <val> Fill gaps between sections with <val>\n\
388 --pad-to <addr> Pad the last section up to address <addr>\n\
389 --set-start <addr> Set the start address to <addr>\n\
390 {--change-start|--adjust-start} <incr>\n\
391 Add <incr> to the start address\n\
392 {--change-addresses|--adjust-vma} <incr>\n\
393 Add <incr> to LMA, VMA and start addresses\n\
394 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
395 Change LMA and VMA of section <name> by <val>\n\
396 --change-section-lma <name>{=|+|-}<val>\n\
397 Change the LMA of section <name> by <val>\n\
398 --change-section-vma <name>{=|+|-}<val>\n\
399 Change the VMA of section <name> by <val>\n\
400 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
401 Warn if a named section does not exist\n\
402 --set-section-flags <name>=<flags>\n\
403 Set section <name>'s properties to <flags>\n\
404 --add-section <name>=<file> Add section <name> found in <file> to output\n\
405 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
406 --change-leading-char Force output format's leading character style\n\
407 --remove-leading-char Remove leading character from global symbols\n\
408 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
409 --srec-len <number> Restrict the length of generated Srecords\n\
410 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
411 --strip-symbols <file> -N for all symbols listed in <file>\n\
412 --keep-symbols <file> -K for all symbols listed in <file>\n\
413 --localize-symbols <file> -L for all symbols listed in <file>\n\
414 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
415 --weaken-symbols <file> -W for all symbols listed in <file>\n\
416 --alt-machine-code <index> Use alternate machine code for output\n\
417 -v --verbose List all object files modified\n\
418 -V --version Display this program's version number\n\
419 -h --help Display this output\n\
421 list_supported_targets (program_name
, stream
);
422 if (exit_status
== 0)
423 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
428 strip_usage (stream
, exit_status
)
432 fprintf (stream
, _("Usage: %s <switches> in-file(s)\n"), program_name
);
433 fprintf (stream
, _(" The switches are:\n"));
434 fprintf (stream
, _("\
435 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
436 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
437 -F --target <bfdname> Set both input and output format to <bfdname>\n\
438 -p --preserve-dates Copy modified/access timestamps to the output\n\
439 -R --remove-section <name> Remove section <name> from the output\n\
440 -s --strip-all Remove all symbol and relocation information\n\
441 -g -S --strip-debug Remove all debugging symbols\n\
442 --strip-unneeded Remove all symbols not needed by relocations\n\
443 -N --strip-symbol <name> Do not copy symbol <name>\n\
444 -K --keep-symbol <name> Only copy symbol <name>\n\
445 -x --discard-all Remove all non-global symbols\n\
446 -X --discard-locals Remove any compiler-generated symbols\n\
447 -v --verbose List all object files modified\n\
448 -V --version Display this program's version number\n\
449 -h --help Display this output\n\
450 -o <file> Place stripped output into <file>\n\
453 list_supported_targets (program_name
, stream
);
454 if (exit_status
== 0)
455 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
459 /* Parse section flags into a flagword, with a fatal error if the
460 string can't be parsed. */
474 snext
= strchr (s
, ',');
484 #define PARSE_FLAG(fname,fval) \
485 else if (strncasecmp (fname, s, len) == 0) ret |= fval
486 PARSE_FLAG ("alloc", SEC_ALLOC
);
487 PARSE_FLAG ("load", SEC_LOAD
);
488 PARSE_FLAG ("noload", SEC_NEVER_LOAD
);
489 PARSE_FLAG ("readonly", SEC_READONLY
);
490 PARSE_FLAG ("debug", SEC_DEBUGGING
);
491 PARSE_FLAG ("code", SEC_CODE
);
492 PARSE_FLAG ("data", SEC_DATA
);
493 PARSE_FLAG ("rom", SEC_ROM
);
494 PARSE_FLAG ("share", SEC_SHARED
);
495 PARSE_FLAG ("contents", SEC_HAS_CONTENTS
);
501 copy
= xmalloc (len
+ 1);
502 strncpy (copy
, s
, len
);
504 non_fatal (_("unrecognized section flag `%s'"), copy
);
505 fatal (_("supported flags: %s"),
506 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
516 /* Find and optionally add an entry in the change_sections list. */
518 static struct section_list
*
519 find_section_list (name
, add
)
523 register struct section_list
*p
;
525 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
526 if (strcmp (p
->name
, name
) == 0)
532 p
= (struct section_list
*) xmalloc (sizeof (struct section_list
));
537 p
->change_vma
= CHANGE_IGNORE
;
538 p
->change_lma
= CHANGE_IGNORE
;
541 p
->set_flags
= false;
544 p
->next
= change_sections
;
550 /* Add a symbol to strip_specific_list. */
553 add_specific_symbol (name
, list
)
555 struct symlist
**list
;
557 struct symlist
*tmp_list
;
559 tmp_list
= (struct symlist
*) xmalloc (sizeof (struct symlist
));
560 tmp_list
->name
= name
;
561 tmp_list
->next
= *list
;
565 /* Add symbols listed in `filename' to strip_specific_list. */
567 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
568 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
571 add_specific_symbols (filename
, list
)
572 const char *filename
;
573 struct symlist
**list
;
579 unsigned int line_count
;
581 if (stat (filename
, & st
) < 0)
582 fatal (_("cannot stat: %s: %s"), filename
, strerror (errno
));
586 buffer
= (char *) xmalloc (st
.st_size
+ 2);
587 f
= fopen (filename
, FOPEN_RT
);
589 fatal (_("cannot open: %s: %s"), filename
, strerror (errno
));
591 if (fread (buffer
, 1, st
.st_size
, f
) == 0 || ferror (f
))
592 fatal (_("%s: fread failed"), filename
);
595 buffer
[st
.st_size
] = '\n';
596 buffer
[st
.st_size
+ 1] = '\0';
600 for (line
= buffer
; * line
!= '\0'; line
++)
605 int finished
= false;
607 for (eol
= line
;; eol
++)
613 /* Cope with \n\r. */
621 /* Cope with \r\n. */
632 /* Line comment, Terminate the line here, in case a
633 name is present and then allow the rest of the
634 loop to find the real end of the line. */
646 /* A name may now exist somewhere between 'line' and 'eol'.
647 Strip off leading whitespace and trailing whitespace,
648 then add it to the list. */
649 for (name
= line
; IS_WHITESPACE (* name
); name
++)
651 for (name_end
= name
;
652 (! IS_WHITESPACE (* name_end
))
653 && (! IS_LINE_TERMINATOR (* name_end
));
657 if (! IS_LINE_TERMINATOR (* name_end
))
661 for (extra
= name_end
+ 1; IS_WHITESPACE (* extra
); extra
++)
664 if (! IS_LINE_TERMINATOR (* extra
))
665 non_fatal (_("Ignoring rubbish found on line %d of %s"),
666 line_count
, filename
);
672 add_specific_symbol (name
, list
);
674 /* Advance line pointer to end of line. The 'eol ++' in the for
675 loop above will then advance us to the start of the next line. */
681 /* See whether a symbol should be stripped or kept based on
682 strip_specific_list and keep_symbols. */
685 is_specified_symbol (name
, list
)
687 struct symlist
*list
;
689 struct symlist
*tmp_list
;
691 for (tmp_list
= list
; tmp_list
; tmp_list
= tmp_list
->next
)
692 if (strcmp (name
, tmp_list
->name
) == 0)
698 /* See if a section is being removed. */
701 is_strip_section (abfd
, sec
)
702 bfd
*abfd ATTRIBUTE_UNUSED
;
705 struct section_list
*p
;
707 if ((bfd_get_section_flags (abfd
, sec
) & SEC_DEBUGGING
) != 0
708 && (strip_symbols
== STRIP_DEBUG
709 || strip_symbols
== STRIP_UNNEEDED
710 || strip_symbols
== STRIP_ALL
711 || discard_locals
== LOCALS_ALL
712 || convert_debugging
))
715 if (! sections_removed
&& ! sections_copied
)
718 p
= find_section_list (bfd_get_section_name (abfd
, sec
), false);
719 if (sections_removed
&& p
!= NULL
&& p
->remove
)
721 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
726 /* Choose which symbol entries to copy; put the result in OSYMS.
727 We don't copy in place, because that confuses the relocs.
728 Return the number of symbols to print. */
731 filter_symbols (abfd
, obfd
, osyms
, isyms
, symcount
)
734 asymbol
**osyms
, **isyms
;
737 register asymbol
**from
= isyms
, **to
= osyms
;
738 long src_count
= 0, dst_count
= 0;
739 int relocatable
= (abfd
->flags
& (HAS_RELOC
| EXEC_P
| DYNAMIC
))
742 for (; src_count
< symcount
; src_count
++)
744 asymbol
*sym
= from
[src_count
];
745 flagword flags
= sym
->flags
;
746 const char *name
= bfd_asymbol_name (sym
);
750 if (redefine_sym_list
)
752 const char *old_name
, *new_name
;
754 old_name
= bfd_asymbol_name (sym
);
755 new_name
= lookup_sym_redefinition (old_name
);
756 name
= bfd_asymbol_name (sym
) = new_name
;
759 if (change_leading_char
760 && (bfd_get_symbol_leading_char (abfd
)
761 != bfd_get_symbol_leading_char (obfd
))
762 && (bfd_get_symbol_leading_char (abfd
) == '\0'
763 || (name
[0] == bfd_get_symbol_leading_char (abfd
))))
765 if (bfd_get_symbol_leading_char (obfd
) == '\0')
766 name
= bfd_asymbol_name (sym
) = name
+ 1;
771 n
= xmalloc (strlen (name
) + 2);
772 n
[0] = bfd_get_symbol_leading_char (obfd
);
773 if (bfd_get_symbol_leading_char (abfd
) == '\0')
774 strcpy (n
+ 1, name
);
776 strcpy (n
+ 1, name
+ 1);
777 name
= bfd_asymbol_name (sym
) = n
;
781 undefined
= bfd_is_und_section (bfd_get_section (sym
));
783 if (remove_leading_char
784 && ((flags
& BSF_GLOBAL
) != 0
785 || (flags
& BSF_WEAK
) != 0
787 || bfd_is_com_section (bfd_get_section (sym
)))
788 && name
[0] == bfd_get_symbol_leading_char (abfd
))
789 name
= bfd_asymbol_name (sym
) = name
+ 1;
791 if (strip_symbols
== STRIP_ALL
)
793 else if ((flags
& BSF_KEEP
) != 0 /* Used in relocation. */
794 || ((flags
& BSF_SECTION_SYM
) != 0
795 && ((*bfd_get_section (sym
)->symbol_ptr_ptr
)->flags
798 else if (relocatable
/* Relocatable file. */
799 && (flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0)
801 else if (bfd_decode_symclass (sym
) == 'I')
802 /* Global symbols in $idata sections need to be retained
803 even if relocatable is false. External users of the
804 library containing the $idata section may reference these
807 else if ((flags
& BSF_GLOBAL
) != 0 /* Global symbol. */
808 || (flags
& BSF_WEAK
) != 0
810 || bfd_is_com_section (bfd_get_section (sym
)))
811 keep
= strip_symbols
!= STRIP_UNNEEDED
;
812 else if ((flags
& BSF_DEBUGGING
) != 0) /* Debugging symbol. */
813 keep
= (strip_symbols
!= STRIP_DEBUG
814 && strip_symbols
!= STRIP_UNNEEDED
815 && ! convert_debugging
);
816 else if (bfd_get_section (sym
)->comdat
)
817 /* COMDAT sections store special information in local
818 symbols, so we cannot risk stripping any of them. */
820 else /* Local symbol. */
821 keep
= (strip_symbols
!= STRIP_UNNEEDED
822 && (discard_locals
!= LOCALS_ALL
823 && (discard_locals
!= LOCALS_START_L
824 || ! bfd_is_local_label (abfd
, sym
))));
826 if (keep
&& is_specified_symbol (name
, strip_specific_list
))
828 if (!keep
&& is_specified_symbol (name
, keep_specific_list
))
830 if (keep
&& is_strip_section (abfd
, bfd_get_section (sym
)))
833 if (keep
&& (flags
& BSF_GLOBAL
) != 0
834 && (weaken
|| is_specified_symbol (name
, weaken_specific_list
)))
836 sym
->flags
&=~ BSF_GLOBAL
;
837 sym
->flags
|= BSF_WEAK
;
839 if (keep
&& !undefined
&& (flags
& (BSF_GLOBAL
| BSF_WEAK
))
840 && (is_specified_symbol (name
, localize_specific_list
)
841 || (keepglobal_specific_list
!= NULL
842 && ! is_specified_symbol (name
, keepglobal_specific_list
))))
844 sym
->flags
&= ~(BSF_GLOBAL
| BSF_WEAK
);
845 sym
->flags
|= BSF_LOCAL
;
849 to
[dst_count
++] = sym
;
852 to
[dst_count
] = NULL
;
857 /* Find the redefined name of symbol SOURCE. */
860 lookup_sym_redefinition (source
)
863 struct redefine_node
*list
;
865 for (list
= redefine_sym_list
; list
!= NULL
; list
= list
->next
)
866 if (strcmp (source
, list
->source
) == 0)
872 /* Add a node to a symbol redefine list. */
875 redefine_list_append (source
, target
)
879 struct redefine_node
**p
;
880 struct redefine_node
*list
;
881 struct redefine_node
*new_node
;
883 for (p
= &redefine_sym_list
; (list
= *p
) != NULL
; p
= &list
->next
)
885 if (strcmp (source
, list
->source
) == 0)
886 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
890 if (strcmp (target
, list
->target
) == 0)
891 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
896 new_node
= (struct redefine_node
*) xmalloc (sizeof (struct redefine_node
));
898 new_node
->source
= strdup (source
);
899 new_node
->target
= strdup (target
);
900 new_node
->next
= NULL
;
905 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
909 filter_bytes (memhunk
, size
)
913 char *from
= memhunk
+ copy_byte
, *to
= memhunk
, *end
= memhunk
+ *size
;
915 for (; from
< end
; from
+= interleave
)
918 if (*size
% interleave
> (bfd_size_type
) copy_byte
)
919 *size
= (*size
/ interleave
) + 1;
924 /* Copy object file IBFD onto OBFD. */
927 copy_object (ibfd
, obfd
)
933 asection
**osections
= NULL
;
934 bfd_size_type
*gaps
= NULL
;
935 bfd_size_type max_gap
= 0;
939 if (ibfd
->xvec
->byteorder
!= obfd
->xvec
->byteorder
940 && ibfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
941 && obfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
943 fatal (_("Unable to change endianness of input file(s)"));
947 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
948 RETURN_NONFATAL (bfd_get_filename (obfd
));
951 printf (_("copy from %s(%s) to %s(%s)\n"),
952 bfd_get_filename (ibfd
), bfd_get_target (ibfd
),
953 bfd_get_filename (obfd
), bfd_get_target (obfd
));
958 start
= bfd_get_start_address (ibfd
);
959 start
+= change_start
;
961 if (!bfd_set_start_address (obfd
, start
)
962 || !bfd_set_file_flags (obfd
,
963 (bfd_get_file_flags (ibfd
)
964 & bfd_applicable_file_flags (obfd
))))
965 RETURN_NONFATAL (bfd_get_filename (ibfd
));
967 /* Copy architecture of input file to output file. */
968 if (!bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
969 bfd_get_mach (ibfd
)))
970 non_fatal (_("Warning: Output file cannot represent architecture %s"),
971 bfd_printable_arch_mach (bfd_get_arch (ibfd
),
972 bfd_get_mach (ibfd
)));
974 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
975 RETURN_NONFATAL (bfd_get_filename (ibfd
));
980 if (osympp
!= isympp
)
983 /* BFD mandates that all output sections be created and sizes set before
984 any output is done. Thus, we traverse all sections multiple times. */
985 bfd_map_over_sections (ibfd
, setup_section
, (void *) obfd
);
987 if (add_sections
!= NULL
)
989 struct section_add
*padd
;
990 struct section_list
*pset
;
992 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
994 padd
->section
= bfd_make_section (obfd
, padd
->name
);
995 if (padd
->section
== NULL
)
997 non_fatal (_("can't create section `%s': %s"),
998 padd
->name
, bfd_errmsg (bfd_get_error ()));
1006 if (! bfd_set_section_size (obfd
, padd
->section
, padd
->size
))
1007 RETURN_NONFATAL (bfd_get_filename (obfd
));
1009 pset
= find_section_list (padd
->name
, false);
1013 if (pset
!= NULL
&& pset
->set_flags
)
1014 flags
= pset
->flags
| SEC_HAS_CONTENTS
;
1016 flags
= SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_DATA
;
1018 if (! bfd_set_section_flags (obfd
, padd
->section
, flags
))
1019 RETURN_NONFATAL (bfd_get_filename (obfd
));
1023 if (pset
->change_vma
!= CHANGE_IGNORE
)
1024 if (! bfd_set_section_vma (obfd
, padd
->section
, pset
->vma_val
))
1025 RETURN_NONFATAL (bfd_get_filename (obfd
));
1027 if (pset
->change_lma
!= CHANGE_IGNORE
)
1029 padd
->section
->lma
= pset
->lma_val
;
1031 if (! bfd_set_section_alignment
1032 (obfd
, padd
->section
,
1033 bfd_section_alignment (obfd
, padd
->section
)))
1034 RETURN_NONFATAL (bfd_get_filename (obfd
));
1041 if (gap_fill_set
|| pad_to_set
)
1046 /* We must fill in gaps between the sections and/or we must pad
1047 the last section to a specified address. We do this by
1048 grabbing a list of the sections, sorting them by VMA, and
1049 increasing the section sizes as required to fill the gaps.
1050 We write out the gap contents below. */
1052 c
= bfd_count_sections (obfd
);
1053 osections
= (asection
**) xmalloc (c
* sizeof (asection
*));
1055 bfd_map_over_sections (obfd
, get_sections
, (void *) &set
);
1057 qsort (osections
, c
, sizeof (asection
*), compare_section_lma
);
1059 gaps
= (bfd_size_type
*) xmalloc (c
* sizeof (bfd_size_type
));
1060 memset (gaps
, 0, c
* sizeof (bfd_size_type
));
1064 for (i
= 0; i
< c
- 1; i
++)
1068 bfd_vma gap_start
, gap_stop
;
1070 flags
= bfd_get_section_flags (obfd
, osections
[i
]);
1071 if ((flags
& SEC_HAS_CONTENTS
) == 0
1072 || (flags
& SEC_LOAD
) == 0)
1075 size
= bfd_section_size (obfd
, osections
[i
]);
1076 gap_start
= bfd_section_lma (obfd
, osections
[i
]) + size
;
1077 gap_stop
= bfd_section_lma (obfd
, osections
[i
+ 1]);
1078 if (gap_start
< gap_stop
)
1080 if (! bfd_set_section_size (obfd
, osections
[i
],
1081 size
+ (gap_stop
- gap_start
)))
1083 non_fatal (_("Can't fill gap after %s: %s"),
1084 bfd_get_section_name (obfd
, osections
[i
]),
1085 bfd_errmsg (bfd_get_error ()));
1089 gaps
[i
] = gap_stop
- gap_start
;
1090 if (max_gap
< gap_stop
- gap_start
)
1091 max_gap
= gap_stop
- gap_start
;
1101 lma
= bfd_section_lma (obfd
, osections
[c
- 1]);
1102 size
= bfd_section_size (obfd
, osections
[c
- 1]);
1103 if (lma
+ size
< pad_to
)
1105 if (! bfd_set_section_size (obfd
, osections
[c
- 1],
1108 non_fatal (_("Can't add padding to %s: %s"),
1109 bfd_get_section_name (obfd
, osections
[c
- 1]),
1110 bfd_errmsg (bfd_get_error ()));
1115 gaps
[c
- 1] = pad_to
- (lma
+ size
);
1116 if (max_gap
< pad_to
- (lma
+ size
))
1117 max_gap
= pad_to
- (lma
+ size
);
1123 /* Symbol filtering must happen after the output sections
1124 have been created, but before their contents are set. */
1126 symsize
= bfd_get_symtab_upper_bound (ibfd
);
1128 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1130 osympp
= isympp
= (asymbol
**) xmalloc (symsize
);
1131 symcount
= bfd_canonicalize_symtab (ibfd
, isympp
);
1133 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1135 if (convert_debugging
)
1136 dhandle
= read_debugging_info (ibfd
, isympp
, symcount
);
1138 if (strip_symbols
== STRIP_DEBUG
1139 || strip_symbols
== STRIP_ALL
1140 || strip_symbols
== STRIP_UNNEEDED
1141 || discard_locals
!= LOCALS_UNDEF
1142 || strip_specific_list
!= NULL
1143 || keep_specific_list
!= NULL
1144 || localize_specific_list
!= NULL
1145 || keepglobal_specific_list
!= NULL
1146 || weaken_specific_list
!= NULL
1149 || convert_debugging
1150 || change_leading_char
1151 || remove_leading_char
1152 || redefine_sym_list
1155 /* Mark symbols used in output relocations so that they
1156 are kept, even if they are local labels or static symbols.
1158 Note we iterate over the input sections examining their
1159 relocations since the relocations for the output sections
1160 haven't been set yet. mark_symbols_used_in_relocations will
1161 ignore input sections which have no corresponding output
1163 if (strip_symbols
!= STRIP_ALL
)
1164 bfd_map_over_sections (ibfd
,
1165 mark_symbols_used_in_relocations
,
1167 osympp
= (asymbol
**) xmalloc ((symcount
+ 1) * sizeof (asymbol
*));
1168 symcount
= filter_symbols (ibfd
, obfd
, osympp
, isympp
, symcount
);
1171 if (convert_debugging
&& dhandle
!= NULL
)
1173 if (! write_debugging_info (obfd
, dhandle
, &symcount
, &osympp
))
1180 bfd_set_symtab (obfd
, osympp
, symcount
);
1182 /* This has to happen after the symbol table has been set. */
1183 bfd_map_over_sections (ibfd
, copy_section
, (void *) obfd
);
1185 if (add_sections
!= NULL
)
1187 struct section_add
*padd
;
1189 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1191 if (! bfd_set_section_contents (obfd
, padd
->section
,
1192 (PTR
) padd
->contents
,
1194 (bfd_size_type
) padd
->size
))
1195 RETURN_NONFATAL (bfd_get_filename (obfd
));
1199 if (gap_fill_set
|| pad_to_set
)
1204 /* Fill in the gaps. */
1207 buf
= (bfd_byte
*) xmalloc (max_gap
);
1208 memset (buf
, gap_fill
, (size_t) max_gap
);
1210 c
= bfd_count_sections (obfd
);
1211 for (i
= 0; i
< c
; i
++)
1219 off
= bfd_section_size (obfd
, osections
[i
]) - left
;
1230 if (! bfd_set_section_contents (obfd
, osections
[i
], buf
,
1232 RETURN_NONFATAL (bfd_get_filename (obfd
));
1241 /* Allow the BFD backend to copy any private data it understands
1242 from the input BFD to the output BFD. This is done last to
1243 permit the routine to look at the filtered symbol table, which is
1244 important for the ECOFF code at least. */
1245 if (! bfd_copy_private_bfd_data (ibfd
, obfd
))
1247 non_fatal (_("%s: error copying private BFD data: %s"),
1248 bfd_get_filename (obfd
),
1249 bfd_errmsg (bfd_get_error ()));
1254 /* Switch to the alternate machine code. We have to do this at the
1255 very end, because we only initialize the header when we create
1256 the first section. */
1257 if (use_alt_mach_code
!= 0)
1259 if (!bfd_alt_mach_code (obfd
, use_alt_mach_code
))
1260 non_fatal (_("unknown alternate machine code, ignored"));
1264 /* Read each archive element in turn from IBFD, copy the
1265 contents to temp file, and keep the temp file handle. */
1268 copy_archive (ibfd
, obfd
, output_target
)
1271 const char *output_target
;
1275 struct name_list
*next
;
1279 bfd
**ptr
= &obfd
->archive_head
;
1281 char *dir
= make_tempname (bfd_get_filename (obfd
));
1283 /* Make a temp directory to hold the contents. */
1284 #if defined (_WIN32) && !defined (__CYGWIN32__)
1285 if (mkdir (dir
) != 0)
1287 if (mkdir (dir
, 0700) != 0)
1290 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1291 dir
, strerror (errno
));
1293 obfd
->has_armap
= ibfd
->has_armap
;
1297 this_element
= bfd_openr_next_archived_file (ibfd
, NULL
);
1299 while (!status
&& this_element
!= (bfd
*) NULL
)
1301 /* Create an output file for this member. */
1302 char *output_name
= concat (dir
, "/", bfd_get_filename (this_element
),
1304 bfd
*output_bfd
= bfd_openw (output_name
, output_target
);
1307 int stat_status
= 0;
1311 stat_status
= bfd_stat_arch_elt (this_element
, &buf
);
1313 if (stat_status
!= 0)
1314 non_fatal (_("internal stat error on %s"),
1315 bfd_get_filename (this_element
));
1318 l
= (struct name_list
*) xmalloc (sizeof (struct name_list
));
1319 l
->name
= output_name
;
1323 if (output_bfd
== (bfd
*) NULL
)
1324 RETURN_NONFATAL (output_name
);
1326 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1327 RETURN_NONFATAL (bfd_get_filename (obfd
));
1329 if (bfd_check_format (this_element
, bfd_object
) == true)
1330 copy_object (this_element
, output_bfd
);
1332 if (!bfd_close (output_bfd
))
1334 bfd_nonfatal (bfd_get_filename (output_bfd
));
1335 /* Error in new object file. Don't change archive. */
1339 if (preserve_dates
&& stat_status
== 0)
1340 set_times (output_name
, &buf
);
1342 /* Open the newly output file and attach to our list. */
1343 output_bfd
= bfd_openr (output_name
, output_target
);
1345 l
->obfd
= output_bfd
;
1348 ptr
= &output_bfd
->next
;
1350 last_element
= this_element
;
1352 this_element
= bfd_openr_next_archived_file (ibfd
, last_element
);
1354 bfd_close (last_element
);
1356 *ptr
= (bfd
*) NULL
;
1358 if (!bfd_close (obfd
))
1359 RETURN_NONFATAL (bfd_get_filename (obfd
));
1361 if (!bfd_close (ibfd
))
1362 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1364 /* Delete all the files that we opened. */
1365 for (l
= list
; l
!= NULL
; l
= l
->next
)
1367 bfd_close (l
->obfd
);
1373 /* The top-level control. */
1376 copy_file (input_filename
, output_filename
, input_target
, output_target
)
1377 const char *input_filename
;
1378 const char *output_filename
;
1379 const char *input_target
;
1380 const char *output_target
;
1385 /* To allow us to do "strip *" without dying on the first
1386 non-object file, failures are nonfatal. */
1387 ibfd
= bfd_openr (input_filename
, input_target
);
1389 RETURN_NONFATAL (input_filename
);
1391 if (bfd_check_format (ibfd
, bfd_archive
))
1395 /* bfd_get_target does not return the correct value until
1396 bfd_check_format succeeds. */
1397 if (output_target
== NULL
)
1398 output_target
= bfd_get_target (ibfd
);
1400 obfd
= bfd_openw (output_filename
, output_target
);
1402 RETURN_NONFATAL (output_filename
);
1404 copy_archive (ibfd
, obfd
, output_target
);
1406 else if (bfd_check_format_matches (ibfd
, bfd_object
, &matching
))
1410 /* bfd_get_target does not return the correct value until
1411 bfd_check_format succeeds. */
1412 if (output_target
== NULL
)
1413 output_target
= bfd_get_target (ibfd
);
1415 obfd
= bfd_openw (output_filename
, output_target
);
1417 RETURN_NONFATAL (output_filename
);
1419 copy_object (ibfd
, obfd
);
1421 if (!bfd_close (obfd
))
1422 RETURN_NONFATAL (output_filename
);
1424 if (!bfd_close (ibfd
))
1425 RETURN_NONFATAL (input_filename
);
1429 bfd_nonfatal (input_filename
);
1431 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
1433 list_matching_formats (matching
);
1441 /* Add a name to the section renaming list. */
1444 add_section_rename (old_name
, new_name
, flags
)
1445 const char * old_name
;
1446 const char * new_name
;
1449 section_rename
* rename
;
1451 /* Check for conflicts first. */
1452 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1453 if (strcmp (rename
->old_name
, old_name
) == 0)
1455 /* Silently ignore duplicate definitions. */
1456 if (strcmp (rename
->new_name
, new_name
) == 0
1457 && rename
->flags
== flags
)
1460 fatal (_("Multiple renames of section %s"), old_name
);
1463 rename
= (section_rename
*) xmalloc (sizeof (* rename
));
1465 rename
->old_name
= old_name
;
1466 rename
->new_name
= new_name
;
1467 rename
->flags
= flags
;
1468 rename
->next
= section_rename_list
;
1470 section_rename_list
= rename
;
1473 /* Check the section rename list for a new name of the input section
1474 ISECTION. Return the new name if one is found.
1475 Also set RETURNED_FLAGS to the flags to be used for this section. */
1478 find_section_rename (ibfd
, isection
, returned_flags
)
1479 bfd
* ibfd ATTRIBUTE_UNUSED
;
1481 flagword
* returned_flags
;
1483 const char * old_name
= bfd_section_name (ibfd
, isection
);
1484 section_rename
* rename
;
1486 /* Default to using the flags of the input section. */
1487 * returned_flags
= bfd_get_section_flags (ibfd
, isection
);
1489 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1490 if (strcmp (rename
->old_name
, old_name
) == 0)
1492 if (rename
->flags
!= (flagword
) -1)
1493 * returned_flags
= rename
->flags
;
1495 return rename
->new_name
;
1501 /* Create a section in OBFD with the same
1502 name and attributes as ISECTION in IBFD. */
1505 setup_section (ibfd
, isection
, obfdarg
)
1510 bfd
*obfd
= (bfd
*) obfdarg
;
1511 struct section_list
*p
;
1520 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
1521 && (strip_symbols
== STRIP_DEBUG
1522 || strip_symbols
== STRIP_UNNEEDED
1523 || strip_symbols
== STRIP_ALL
1524 || discard_locals
== LOCALS_ALL
1525 || convert_debugging
))
1528 p
= find_section_list (bfd_section_name (ibfd
, isection
), false);
1532 if (sections_removed
&& p
!= NULL
&& p
->remove
)
1534 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
1537 /* Get the, possibly new, name of the output section. */
1538 name
= find_section_rename (ibfd
, isection
, & flags
);
1540 osection
= bfd_make_section_anyway (obfd
, name
);
1542 if (osection
== NULL
)
1548 size
= bfd_section_size (ibfd
, isection
);
1550 size
= (size
+ interleave
- 1) / interleave
;
1551 if (! bfd_set_section_size (obfd
, osection
, size
))
1557 vma
= bfd_section_vma (ibfd
, isection
);
1558 if (p
!= NULL
&& p
->change_vma
== CHANGE_MODIFY
)
1560 else if (p
!= NULL
&& p
->change_vma
== CHANGE_SET
)
1563 vma
+= change_section_address
;
1565 if (! bfd_set_section_vma (obfd
, osection
, vma
))
1571 lma
= isection
->lma
;
1572 if ((p
!= NULL
) && p
->change_lma
!= CHANGE_IGNORE
)
1574 if (p
->change_lma
== CHANGE_MODIFY
)
1576 else if (p
->change_lma
== CHANGE_SET
)
1582 lma
+= change_section_address
;
1584 osection
->lma
= lma
;
1586 /* FIXME: This is probably not enough. If we change the LMA we
1587 may have to recompute the header for the file as well. */
1588 if (bfd_set_section_alignment (obfd
,
1590 bfd_section_alignment (ibfd
, isection
))
1593 err
= _("alignment");
1597 if (p
!= NULL
&& p
->set_flags
)
1598 flags
= p
->flags
| (flags
& (SEC_HAS_CONTENTS
| SEC_RELOC
));
1599 if (!bfd_set_section_flags (obfd
, osection
, flags
))
1605 /* Copy merge entity size. */
1606 osection
->entsize
= isection
->entsize
;
1608 /* This used to be mangle_section; we do here to avoid using
1609 bfd_get_section_by_name since some formats allow multiple
1610 sections with the same name. */
1611 isection
->output_section
= osection
;
1612 isection
->output_offset
= 0;
1614 /* Allow the BFD backend to copy any private data it understands
1615 from the input section to the output section. */
1616 if (!bfd_copy_private_section_data (ibfd
, isection
, obfd
, osection
))
1618 err
= _("private data");
1622 /* All went well. */
1626 non_fatal (_("%s: section `%s': error in %s: %s"),
1627 bfd_get_filename (ibfd
),
1628 bfd_section_name (ibfd
, isection
),
1629 err
, bfd_errmsg (bfd_get_error ()));
1633 /* Copy the data of input section ISECTION of IBFD
1634 to an output section with the same name in OBFD.
1635 If stripping then don't copy any relocation info. */
1638 copy_section (ibfd
, isection
, obfdarg
)
1643 bfd
*obfd
= (bfd
*) obfdarg
;
1644 struct section_list
*p
;
1651 /* If we have already failed earlier on,
1652 do not keep on generating complaints now. */
1656 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
1657 && (strip_symbols
== STRIP_DEBUG
1658 || strip_symbols
== STRIP_UNNEEDED
1659 || strip_symbols
== STRIP_ALL
1660 || discard_locals
== LOCALS_ALL
1661 || convert_debugging
))
1664 p
= find_section_list (bfd_section_name (ibfd
, isection
), false);
1666 if (sections_removed
&& p
!= NULL
&& p
->remove
)
1668 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
1671 osection
= isection
->output_section
;
1672 size
= bfd_get_section_size_before_reloc (isection
);
1674 if (size
== 0 || osection
== 0)
1677 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1679 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1682 bfd_set_reloc (obfd
, osection
, (arelent
**) NULL
, 0);
1685 relpp
= (arelent
**) xmalloc (relsize
);
1686 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
1688 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1690 if (strip_symbols
== STRIP_ALL
)
1692 /* Remove relocations which are not in
1693 keep_strip_specific_list. */
1694 arelent
**temp_relpp
;
1695 long temp_relcount
= 0;
1698 temp_relpp
= (arelent
**) xmalloc (relsize
);
1699 for (i
= 0; i
< relcount
; i
++)
1700 if (is_specified_symbol
1701 (bfd_asymbol_name (*relpp
[i
]->sym_ptr_ptr
),
1702 keep_specific_list
))
1703 temp_relpp
[temp_relcount
++] = relpp
[i
];
1704 relcount
= temp_relcount
;
1709 bfd_set_reloc (obfd
, osection
,
1710 (relcount
== 0 ? (arelent
**) NULL
: relpp
), relcount
);
1713 isection
->_cooked_size
= isection
->_raw_size
;
1714 isection
->reloc_done
= true;
1716 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
)
1718 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
1720 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, (file_ptr
) 0,
1722 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1725 filter_bytes (memhunk
, &size
);
1727 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
1729 RETURN_NONFATAL (bfd_get_filename (obfd
));
1733 else if (p
!= NULL
&& p
->set_flags
&& (p
->flags
& SEC_HAS_CONTENTS
) != 0)
1735 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
1737 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1738 flag--they can just remove the section entirely and add it
1739 back again. However, we do permit them to turn on the
1740 SEC_HAS_CONTENTS flag, and take it to mean that the section
1741 contents should be zeroed out. */
1743 memset (memhunk
, 0, size
);
1744 if (! bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
1746 RETURN_NONFATAL (bfd_get_filename (obfd
));
1751 /* Get all the sections. This is used when --gap-fill or --pad-to is
1755 get_sections (obfd
, osection
, secppparg
)
1756 bfd
*obfd ATTRIBUTE_UNUSED
;
1760 asection
***secppp
= (asection
***) secppparg
;
1762 **secppp
= osection
;
1766 /* Sort sections by VMA. This is called via qsort, and is used when
1767 --gap-fill or --pad-to is used. We force non loadable or empty
1768 sections to the front, where they are easier to ignore. */
1771 compare_section_lma (arg1
, arg2
)
1775 const asection
**sec1
= (const asection
**) arg1
;
1776 const asection
**sec2
= (const asection
**) arg2
;
1777 flagword flags1
, flags2
;
1779 /* Sort non loadable sections to the front. */
1780 flags1
= (*sec1
)->flags
;
1781 flags2
= (*sec2
)->flags
;
1782 if ((flags1
& SEC_HAS_CONTENTS
) == 0
1783 || (flags1
& SEC_LOAD
) == 0)
1785 if ((flags2
& SEC_HAS_CONTENTS
) != 0
1786 && (flags2
& SEC_LOAD
) != 0)
1791 if ((flags2
& SEC_HAS_CONTENTS
) == 0
1792 || (flags2
& SEC_LOAD
) == 0)
1796 /* Sort sections by LMA. */
1797 if ((*sec1
)->lma
> (*sec2
)->lma
)
1799 else if ((*sec1
)->lma
< (*sec2
)->lma
)
1802 /* Sort sections with the same LMA by size. */
1803 if ((*sec1
)->_raw_size
> (*sec2
)->_raw_size
)
1805 else if ((*sec1
)->_raw_size
< (*sec2
)->_raw_size
)
1811 /* Mark all the symbols which will be used in output relocations with
1812 the BSF_KEEP flag so that those symbols will not be stripped.
1814 Ignore relocations which will not appear in the output file. */
1817 mark_symbols_used_in_relocations (ibfd
, isection
, symbolsarg
)
1822 asymbol
**symbols
= (asymbol
**) symbolsarg
;
1827 /* Ignore an input section with no corresponding output section. */
1828 if (isection
->output_section
== NULL
)
1831 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1833 bfd_fatal (bfd_get_filename (ibfd
));
1838 relpp
= (arelent
**) xmalloc (relsize
);
1839 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, symbols
);
1841 bfd_fatal (bfd_get_filename (ibfd
));
1843 /* Examine each symbol used in a relocation. If it's not one of the
1844 special bfd section symbols, then mark it with BSF_KEEP. */
1845 for (i
= 0; i
< relcount
; i
++)
1847 if (*relpp
[i
]->sym_ptr_ptr
!= bfd_com_section_ptr
->symbol
1848 && *relpp
[i
]->sym_ptr_ptr
!= bfd_abs_section_ptr
->symbol
1849 && *relpp
[i
]->sym_ptr_ptr
!= bfd_und_section_ptr
->symbol
)
1850 (*relpp
[i
]->sym_ptr_ptr
)->flags
|= BSF_KEEP
;
1857 /* Write out debugging information. */
1860 write_debugging_info (obfd
, dhandle
, symcountp
, symppp
)
1863 long *symcountp ATTRIBUTE_UNUSED
;
1864 asymbol
***symppp ATTRIBUTE_UNUSED
;
1866 if (bfd_get_flavour (obfd
) == bfd_target_ieee_flavour
)
1867 return write_ieee_debugging_info (obfd
, dhandle
);
1869 if (bfd_get_flavour (obfd
) == bfd_target_coff_flavour
1870 || bfd_get_flavour (obfd
) == bfd_target_elf_flavour
)
1872 bfd_byte
*syms
, *strings
;
1873 bfd_size_type symsize
, stringsize
;
1874 asection
*stabsec
, *stabstrsec
;
1876 if (! write_stabs_in_sections_debugging_info (obfd
, dhandle
, &syms
,
1881 stabsec
= bfd_make_section (obfd
, ".stab");
1882 stabstrsec
= bfd_make_section (obfd
, ".stabstr");
1884 || stabstrsec
== NULL
1885 || ! bfd_set_section_size (obfd
, stabsec
, symsize
)
1886 || ! bfd_set_section_size (obfd
, stabstrsec
, stringsize
)
1887 || ! bfd_set_section_alignment (obfd
, stabsec
, 2)
1888 || ! bfd_set_section_alignment (obfd
, stabstrsec
, 0)
1889 || ! bfd_set_section_flags (obfd
, stabsec
,
1893 || ! bfd_set_section_flags (obfd
, stabstrsec
,
1898 non_fatal (_("%s: can't create debugging section: %s"),
1899 bfd_get_filename (obfd
),
1900 bfd_errmsg (bfd_get_error ()));
1904 /* We can get away with setting the section contents now because
1905 the next thing the caller is going to do is copy over the
1906 real sections. We may someday have to split the contents
1907 setting out of this function. */
1908 if (! bfd_set_section_contents (obfd
, stabsec
, syms
, (file_ptr
) 0,
1910 || ! bfd_set_section_contents (obfd
, stabstrsec
, strings
,
1911 (file_ptr
) 0, stringsize
))
1913 non_fatal (_("%s: can't set debugging section contents: %s"),
1914 bfd_get_filename (obfd
),
1915 bfd_errmsg (bfd_get_error ()));
1922 non_fatal (_("%s: don't know how to write debugging information for %s"),
1923 bfd_get_filename (obfd
), bfd_get_target (obfd
));
1928 strip_main (argc
, argv
)
1932 char *input_target
= NULL
, *output_target
= NULL
;
1933 boolean show_version
= false;
1935 struct section_list
*p
;
1936 char *output_file
= NULL
;
1938 while ((c
= getopt_long (argc
, argv
, "I:O:F:K:N:R:o:sSpdgxXVv",
1939 strip_options
, (int *) 0)) != EOF
)
1944 input_target
= optarg
;
1947 output_target
= optarg
;
1950 input_target
= output_target
= optarg
;
1953 p
= find_section_list (optarg
, true);
1955 sections_removed
= true;
1958 strip_symbols
= STRIP_ALL
;
1962 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1963 strip_symbols
= STRIP_DEBUG
;
1965 case OPTION_STRIP_UNNEEDED
:
1966 strip_symbols
= STRIP_UNNEEDED
;
1969 add_specific_symbol (optarg
, &keep_specific_list
);
1972 add_specific_symbol (optarg
, &strip_specific_list
);
1975 output_file
= optarg
;
1978 preserve_dates
= true;
1981 discard_locals
= LOCALS_ALL
;
1984 discard_locals
= LOCALS_START_L
;
1990 show_version
= true;
1993 /* We've been given a long option. */
1996 strip_usage (stdout
, 0);
1998 strip_usage (stderr
, 1);
2003 print_version ("strip");
2005 /* Default is to strip all symbols. */
2006 if (strip_symbols
== STRIP_UNDEF
2007 && discard_locals
== LOCALS_UNDEF
2008 && strip_specific_list
== NULL
)
2009 strip_symbols
= STRIP_ALL
;
2011 if (output_target
== (char *) NULL
)
2012 output_target
= input_target
;
2016 || (output_file
!= NULL
&& (i
+ 1) < argc
))
2017 strip_usage (stderr
, 1);
2019 for (; i
< argc
; i
++)
2021 int hold_status
= status
;
2022 struct stat statbuf
;
2027 if (stat (argv
[i
], &statbuf
) < 0)
2029 non_fatal (_("%s: cannot stat: %s"), argv
[i
], strerror (errno
));
2034 if (output_file
!= NULL
)
2035 tmpname
= output_file
;
2037 tmpname
= make_tempname (argv
[i
]);
2040 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
2044 set_times (tmpname
, &statbuf
);
2045 if (output_file
== NULL
)
2046 smart_rename (tmpname
, argv
[i
], preserve_dates
);
2047 status
= hold_status
;
2051 if (output_file
== NULL
)
2059 copy_main (argc
, argv
)
2063 char * binary_architecture
= NULL
;
2064 char *input_filename
= NULL
, *output_filename
= NULL
;
2065 char *input_target
= NULL
, *output_target
= NULL
;
2066 boolean show_version
= false;
2067 boolean change_warn
= true;
2069 struct section_list
*p
;
2070 struct stat statbuf
;
2072 while ((c
= getopt_long (argc
, argv
, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
2073 copy_options
, (int *) 0)) != EOF
)
2078 copy_byte
= atoi (optarg
);
2080 fatal (_("byte number must be non-negative"));
2084 binary_architecture
= optarg
;
2088 interleave
= atoi (optarg
);
2090 fatal (_("interleave must be positive"));
2094 case 's': /* "source" - 'I' is preferred */
2095 input_target
= optarg
;
2099 case 'd': /* "destination" - 'O' is preferred */
2100 output_target
= optarg
;
2104 input_target
= output_target
= optarg
;
2108 p
= find_section_list (optarg
, true);
2110 fatal (_("%s both copied and removed"), optarg
);
2112 sections_copied
= true;
2116 p
= find_section_list (optarg
, true);
2118 fatal (_("%s both copied and removed"), optarg
);
2120 sections_removed
= true;
2124 strip_symbols
= STRIP_ALL
;
2128 strip_symbols
= STRIP_DEBUG
;
2131 case OPTION_STRIP_UNNEEDED
:
2132 strip_symbols
= STRIP_UNNEEDED
;
2136 add_specific_symbol (optarg
, &keep_specific_list
);
2140 add_specific_symbol (optarg
, &strip_specific_list
);
2144 add_specific_symbol (optarg
, &localize_specific_list
);
2148 add_specific_symbol (optarg
, &keepglobal_specific_list
);
2152 add_specific_symbol (optarg
, &weaken_specific_list
);
2156 preserve_dates
= true;
2160 discard_locals
= LOCALS_ALL
;
2164 discard_locals
= LOCALS_START_L
;
2172 show_version
= true;
2179 case OPTION_ADD_SECTION
:
2183 struct section_add
*pa
;
2188 s
= strchr (optarg
, '=');
2191 fatal (_("bad format for %s"), "--add-section");
2193 if (stat (s
+ 1, & st
) < 0)
2194 fatal (_("cannot stat: %s: %s"), s
+ 1, strerror (errno
));
2196 pa
= (struct section_add
*) xmalloc (sizeof (struct section_add
));
2199 name
= (char *) xmalloc (len
+ 1);
2200 strncpy (name
, optarg
, len
);
2204 pa
->filename
= s
+ 1;
2206 pa
->size
= st
.st_size
;
2208 pa
->contents
= (bfd_byte
*) xmalloc (pa
->size
);
2209 f
= fopen (pa
->filename
, FOPEN_RB
);
2212 fatal (_("cannot open: %s: %s"), pa
->filename
, strerror (errno
));
2214 if (fread (pa
->contents
, 1, pa
->size
, f
) == 0
2216 fatal (_("%s: fread failed"), pa
->filename
);
2220 pa
->next
= add_sections
;
2225 case OPTION_CHANGE_START
:
2226 change_start
= parse_vma (optarg
, "--change-start");
2229 case OPTION_CHANGE_SECTION_ADDRESS
:
2230 case OPTION_CHANGE_SECTION_LMA
:
2231 case OPTION_CHANGE_SECTION_VMA
:
2236 char *option
= NULL
;
2238 enum change_action what
= CHANGE_IGNORE
;
2242 case OPTION_CHANGE_SECTION_ADDRESS
:
2243 option
= "--change-section-address";
2245 case OPTION_CHANGE_SECTION_LMA
:
2246 option
= "--change-section-lma";
2248 case OPTION_CHANGE_SECTION_VMA
:
2249 option
= "--change-section-vma";
2253 s
= strchr (optarg
, '=');
2256 s
= strchr (optarg
, '+');
2259 s
= strchr (optarg
, '-');
2261 fatal (_("bad format for %s"), option
);
2266 name
= (char *) xmalloc (len
+ 1);
2267 strncpy (name
, optarg
, len
);
2270 p
= find_section_list (name
, true);
2272 val
= parse_vma (s
+ 1, option
);
2276 case '=': what
= CHANGE_SET
; break;
2277 case '-': val
= - val
; /* Drop through. */
2278 case '+': what
= CHANGE_MODIFY
; break;
2283 case OPTION_CHANGE_SECTION_ADDRESS
:
2284 p
->change_vma
= what
;
2288 case OPTION_CHANGE_SECTION_LMA
:
2289 p
->change_lma
= what
;
2293 case OPTION_CHANGE_SECTION_VMA
:
2294 p
->change_vma
= what
;
2301 case OPTION_CHANGE_ADDRESSES
:
2302 change_section_address
= parse_vma (optarg
, "--change-addresses");
2303 change_start
= change_section_address
;
2306 case OPTION_CHANGE_WARNINGS
:
2310 case OPTION_CHANGE_LEADING_CHAR
:
2311 change_leading_char
= true;
2314 case OPTION_DEBUGGING
:
2315 convert_debugging
= true;
2318 case OPTION_GAP_FILL
:
2320 bfd_vma gap_fill_vma
;
2322 gap_fill_vma
= parse_vma (optarg
, "--gap-fill");
2323 gap_fill
= (bfd_byte
) gap_fill_vma
;
2324 if ((bfd_vma
) gap_fill
!= gap_fill_vma
)
2328 sprintf_vma (buff
, gap_fill_vma
);
2330 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2333 gap_fill_set
= true;
2337 case OPTION_NO_CHANGE_WARNINGS
:
2338 change_warn
= false;
2342 pad_to
= parse_vma (optarg
, "--pad-to");
2346 case OPTION_REMOVE_LEADING_CHAR
:
2347 remove_leading_char
= true;
2350 case OPTION_REDEFINE_SYM
:
2352 /* Push this redefinition onto redefine_symbol_list. */
2356 const char *nextarg
;
2357 char *source
, *target
;
2359 s
= strchr (optarg
, '=');
2361 fatal (_("bad format for %s"), "--redefine-sym");
2364 source
= (char *) xmalloc (len
+ 1);
2365 strncpy (source
, optarg
, len
);
2369 len
= strlen (nextarg
);
2370 target
= (char *) xmalloc (len
+ 1);
2371 strcpy (target
, nextarg
);
2373 redefine_list_append (source
, target
);
2380 case OPTION_SET_SECTION_FLAGS
:
2386 s
= strchr (optarg
, '=');
2388 fatal (_("bad format for %s"), "--set-section-flags");
2391 name
= (char *) xmalloc (len
+ 1);
2392 strncpy (name
, optarg
, len
);
2395 p
= find_section_list (name
, true);
2397 p
->set_flags
= true;
2398 p
->flags
= parse_flags (s
+ 1);
2402 case OPTION_RENAME_SECTION
:
2405 const char *eq
, *fl
;
2410 eq
= strchr (optarg
, '=');
2412 fatal (_("bad format for %s"), "--rename-section");
2416 fatal (_("bad format for %s"), "--rename-section");
2418 old_name
= (char *) xmalloc (len
+ 1);
2419 strncpy (old_name
, optarg
, len
);
2423 fl
= strchr (eq
, ',');
2426 flags
= parse_flags (fl
+ 1);
2436 fatal (_("bad format for %s"), "--rename-section");
2438 new_name
= (char *) xmalloc (len
+ 1);
2439 strncpy (new_name
, eq
, len
);
2442 add_section_rename (old_name
, new_name
, flags
);
2446 case OPTION_SET_START
:
2447 set_start
= parse_vma (optarg
, "--set-start");
2448 set_start_set
= true;
2451 case OPTION_SREC_LEN
:
2452 Chunk
= parse_vma (optarg
, "--srec-len");
2455 case OPTION_SREC_FORCES3
:
2459 case OPTION_STRIP_SYMBOLS
:
2460 add_specific_symbols (optarg
, &strip_specific_list
);
2463 case OPTION_KEEP_SYMBOLS
:
2464 add_specific_symbols (optarg
, &keep_specific_list
);
2467 case OPTION_LOCALIZE_SYMBOLS
:
2468 add_specific_symbols (optarg
, &localize_specific_list
);
2471 case OPTION_KEEPGLOBAL_SYMBOLS
:
2472 add_specific_symbols (optarg
, &keepglobal_specific_list
);
2475 case OPTION_WEAKEN_SYMBOLS
:
2476 add_specific_symbols (optarg
, &weaken_specific_list
);
2479 case OPTION_ALT_MACH_CODE
:
2480 use_alt_mach_code
= atoi (optarg
);
2481 if (use_alt_mach_code
<= 0)
2482 fatal (_("alternate machine code index must be positive"));
2486 break; /* we've been given a long option */
2489 copy_usage (stdout
, 0);
2492 copy_usage (stderr
, 1);
2497 print_version ("objcopy");
2499 if (copy_byte
>= interleave
)
2500 fatal (_("byte number must be less than interleave"));
2502 if (optind
== argc
|| optind
+ 2 < argc
)
2503 copy_usage (stderr
, 1);
2505 input_filename
= argv
[optind
];
2506 if (optind
+ 1 < argc
)
2507 output_filename
= argv
[optind
+ 1];
2509 /* Default is to strip no symbols. */
2510 if (strip_symbols
== STRIP_UNDEF
&& discard_locals
== LOCALS_UNDEF
)
2511 strip_symbols
= STRIP_NONE
;
2513 if (output_target
== (char *) NULL
)
2514 output_target
= input_target
;
2516 if (binary_architecture
!= (char *) NULL
)
2518 if (input_target
&& strcmp (input_target
, "binary") == 0)
2520 const bfd_arch_info_type
* temp_arch_info
;
2522 temp_arch_info
= bfd_scan_arch (binary_architecture
);
2524 if (temp_arch_info
!= NULL
)
2525 bfd_external_binary_architecture
= temp_arch_info
->arch
;
2527 fatal (_("architecture %s unknown"), binary_architecture
);
2531 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2532 non_fatal (_(" Argument %s ignored"), binary_architecture
);
2537 if (stat (input_filename
, & statbuf
) < 0)
2538 fatal (_("Cannot stat: %s: %s"), input_filename
, strerror (errno
));
2540 /* If there is no destination file then create a temp and rename
2541 the result into the input. */
2543 if (output_filename
== (char *) NULL
)
2545 char *tmpname
= make_tempname (input_filename
);
2547 copy_file (input_filename
, tmpname
, input_target
, output_target
);
2551 set_times (tmpname
, &statbuf
);
2552 smart_rename (tmpname
, input_filename
, preserve_dates
);
2559 copy_file (input_filename
, output_filename
, input_target
, output_target
);
2561 if (status
== 0 && preserve_dates
)
2562 set_times (output_filename
, &statbuf
);
2567 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
2571 if (p
->change_vma
!= CHANGE_IGNORE
)
2575 sprintf_vma (buff
, p
->vma_val
);
2577 /* xgettext:c-format */
2578 non_fatal (_("%s %s%c0x%s never used"),
2579 "--change-section-vma",
2581 p
->change_vma
== CHANGE_SET
? '=' : '+',
2585 if (p
->change_lma
!= CHANGE_IGNORE
)
2589 sprintf_vma (buff
, p
->lma_val
);
2591 /* xgettext:c-format */
2592 non_fatal (_("%s %s%c0x%s never used"),
2593 "--change-section-lma",
2595 p
->change_lma
== CHANGE_SET
? '=' : '+',
2605 int main
PARAMS ((int, char **));
2612 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2613 setlocale (LC_MESSAGES
, "");
2615 #if defined (HAVE_SETLOCALE)
2616 setlocale (LC_CTYPE
, "");
2618 bindtextdomain (PACKAGE
, LOCALEDIR
);
2619 textdomain (PACKAGE
);
2621 program_name
= argv
[0];
2622 xmalloc_set_program_name (program_name
);
2624 START_PROGRESS (program_name
, 0);
2626 strip_symbols
= STRIP_UNDEF
;
2627 discard_locals
= LOCALS_UNDEF
;
2630 set_default_bfd_target ();
2634 int i
= strlen (program_name
);
2635 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2636 /* Drop the .exe suffix, if any. */
2637 if (i
> 4 && FILENAME_CMP (program_name
+ i
- 4, ".exe") == 0)
2640 program_name
[i
] = '\0';
2643 is_strip
= (i
>= 5 && FILENAME_CMP (program_name
+ i
- 5, "strip") == 0);
2647 strip_main (argc
, argv
);
2649 copy_main (argc
, argv
);
2651 END_PROGRESS (program_name
);