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 /* Neither the start address nor the flags
962 need to be set for a core file. */
963 if (bfd_get_format (obfd
) != bfd_core
)
965 if (!bfd_set_start_address (obfd
, start
)
966 || !bfd_set_file_flags (obfd
,
967 (bfd_get_file_flags (ibfd
)
968 & bfd_applicable_file_flags (obfd
))))
969 RETURN_NONFATAL (bfd_get_filename (ibfd
));
972 /* Copy architecture of input file to output file. */
973 if (!bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
974 bfd_get_mach (ibfd
)))
975 non_fatal (_("Warning: Output file cannot represent architecture %s"),
976 bfd_printable_arch_mach (bfd_get_arch (ibfd
),
977 bfd_get_mach (ibfd
)));
979 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
980 RETURN_NONFATAL (bfd_get_filename (ibfd
));
985 if (osympp
!= isympp
)
988 /* BFD mandates that all output sections be created and sizes set before
989 any output is done. Thus, we traverse all sections multiple times. */
990 bfd_map_over_sections (ibfd
, setup_section
, (void *) obfd
);
992 if (add_sections
!= NULL
)
994 struct section_add
*padd
;
995 struct section_list
*pset
;
997 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
999 padd
->section
= bfd_make_section (obfd
, padd
->name
);
1000 if (padd
->section
== NULL
)
1002 non_fatal (_("can't create section `%s': %s"),
1003 padd
->name
, bfd_errmsg (bfd_get_error ()));
1011 if (! bfd_set_section_size (obfd
, padd
->section
, padd
->size
))
1012 RETURN_NONFATAL (bfd_get_filename (obfd
));
1014 pset
= find_section_list (padd
->name
, false);
1018 if (pset
!= NULL
&& pset
->set_flags
)
1019 flags
= pset
->flags
| SEC_HAS_CONTENTS
;
1021 flags
= SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_DATA
;
1023 if (! bfd_set_section_flags (obfd
, padd
->section
, flags
))
1024 RETURN_NONFATAL (bfd_get_filename (obfd
));
1028 if (pset
->change_vma
!= CHANGE_IGNORE
)
1029 if (! bfd_set_section_vma (obfd
, padd
->section
, pset
->vma_val
))
1030 RETURN_NONFATAL (bfd_get_filename (obfd
));
1032 if (pset
->change_lma
!= CHANGE_IGNORE
)
1034 padd
->section
->lma
= pset
->lma_val
;
1036 if (! bfd_set_section_alignment
1037 (obfd
, padd
->section
,
1038 bfd_section_alignment (obfd
, padd
->section
)))
1039 RETURN_NONFATAL (bfd_get_filename (obfd
));
1046 if (gap_fill_set
|| pad_to_set
)
1051 /* We must fill in gaps between the sections and/or we must pad
1052 the last section to a specified address. We do this by
1053 grabbing a list of the sections, sorting them by VMA, and
1054 increasing the section sizes as required to fill the gaps.
1055 We write out the gap contents below. */
1057 c
= bfd_count_sections (obfd
);
1058 osections
= (asection
**) xmalloc (c
* sizeof (asection
*));
1060 bfd_map_over_sections (obfd
, get_sections
, (void *) &set
);
1062 qsort (osections
, c
, sizeof (asection
*), compare_section_lma
);
1064 gaps
= (bfd_size_type
*) xmalloc (c
* sizeof (bfd_size_type
));
1065 memset (gaps
, 0, c
* sizeof (bfd_size_type
));
1069 for (i
= 0; i
< c
- 1; i
++)
1073 bfd_vma gap_start
, gap_stop
;
1075 flags
= bfd_get_section_flags (obfd
, osections
[i
]);
1076 if ((flags
& SEC_HAS_CONTENTS
) == 0
1077 || (flags
& SEC_LOAD
) == 0)
1080 size
= bfd_section_size (obfd
, osections
[i
]);
1081 gap_start
= bfd_section_lma (obfd
, osections
[i
]) + size
;
1082 gap_stop
= bfd_section_lma (obfd
, osections
[i
+ 1]);
1083 if (gap_start
< gap_stop
)
1085 if (! bfd_set_section_size (obfd
, osections
[i
],
1086 size
+ (gap_stop
- gap_start
)))
1088 non_fatal (_("Can't fill gap after %s: %s"),
1089 bfd_get_section_name (obfd
, osections
[i
]),
1090 bfd_errmsg (bfd_get_error ()));
1094 gaps
[i
] = gap_stop
- gap_start
;
1095 if (max_gap
< gap_stop
- gap_start
)
1096 max_gap
= gap_stop
- gap_start
;
1106 lma
= bfd_section_lma (obfd
, osections
[c
- 1]);
1107 size
= bfd_section_size (obfd
, osections
[c
- 1]);
1108 if (lma
+ size
< pad_to
)
1110 if (! bfd_set_section_size (obfd
, osections
[c
- 1],
1113 non_fatal (_("Can't add padding to %s: %s"),
1114 bfd_get_section_name (obfd
, osections
[c
- 1]),
1115 bfd_errmsg (bfd_get_error ()));
1120 gaps
[c
- 1] = pad_to
- (lma
+ size
);
1121 if (max_gap
< pad_to
- (lma
+ size
))
1122 max_gap
= pad_to
- (lma
+ size
);
1128 /* Symbol filtering must happen after the output sections
1129 have been created, but before their contents are set. */
1131 symsize
= bfd_get_symtab_upper_bound (ibfd
);
1133 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1135 osympp
= isympp
= (asymbol
**) xmalloc (symsize
);
1136 symcount
= bfd_canonicalize_symtab (ibfd
, isympp
);
1138 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1140 if (convert_debugging
)
1141 dhandle
= read_debugging_info (ibfd
, isympp
, symcount
);
1143 if (strip_symbols
== STRIP_DEBUG
1144 || strip_symbols
== STRIP_ALL
1145 || strip_symbols
== STRIP_UNNEEDED
1146 || discard_locals
!= LOCALS_UNDEF
1147 || strip_specific_list
!= NULL
1148 || keep_specific_list
!= NULL
1149 || localize_specific_list
!= NULL
1150 || keepglobal_specific_list
!= NULL
1151 || weaken_specific_list
!= NULL
1154 || convert_debugging
1155 || change_leading_char
1156 || remove_leading_char
1157 || redefine_sym_list
1160 /* Mark symbols used in output relocations so that they
1161 are kept, even if they are local labels or static symbols.
1163 Note we iterate over the input sections examining their
1164 relocations since the relocations for the output sections
1165 haven't been set yet. mark_symbols_used_in_relocations will
1166 ignore input sections which have no corresponding output
1168 if (strip_symbols
!= STRIP_ALL
)
1169 bfd_map_over_sections (ibfd
,
1170 mark_symbols_used_in_relocations
,
1172 osympp
= (asymbol
**) xmalloc ((symcount
+ 1) * sizeof (asymbol
*));
1173 symcount
= filter_symbols (ibfd
, obfd
, osympp
, isympp
, symcount
);
1176 if (convert_debugging
&& dhandle
!= NULL
)
1178 if (! write_debugging_info (obfd
, dhandle
, &symcount
, &osympp
))
1185 bfd_set_symtab (obfd
, osympp
, symcount
);
1187 /* This has to happen after the symbol table has been set. */
1188 bfd_map_over_sections (ibfd
, copy_section
, (void *) obfd
);
1190 if (add_sections
!= NULL
)
1192 struct section_add
*padd
;
1194 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1196 if (! bfd_set_section_contents (obfd
, padd
->section
,
1197 (PTR
) padd
->contents
,
1199 (bfd_size_type
) padd
->size
))
1200 RETURN_NONFATAL (bfd_get_filename (obfd
));
1204 if (gap_fill_set
|| pad_to_set
)
1209 /* Fill in the gaps. */
1212 buf
= (bfd_byte
*) xmalloc (max_gap
);
1213 memset (buf
, gap_fill
, (size_t) max_gap
);
1215 c
= bfd_count_sections (obfd
);
1216 for (i
= 0; i
< c
; i
++)
1224 off
= bfd_section_size (obfd
, osections
[i
]) - left
;
1235 if (! bfd_set_section_contents (obfd
, osections
[i
], buf
,
1237 RETURN_NONFATAL (bfd_get_filename (obfd
));
1246 /* Allow the BFD backend to copy any private data it understands
1247 from the input BFD to the output BFD. This is done last to
1248 permit the routine to look at the filtered symbol table, which is
1249 important for the ECOFF code at least. */
1250 if (! bfd_copy_private_bfd_data (ibfd
, obfd
))
1252 non_fatal (_("%s: error copying private BFD data: %s"),
1253 bfd_get_filename (obfd
),
1254 bfd_errmsg (bfd_get_error ()));
1259 /* Switch to the alternate machine code. We have to do this at the
1260 very end, because we only initialize the header when we create
1261 the first section. */
1262 if (use_alt_mach_code
!= 0)
1264 if (!bfd_alt_mach_code (obfd
, use_alt_mach_code
))
1265 non_fatal (_("unknown alternate machine code, ignored"));
1269 /* Read each archive element in turn from IBFD, copy the
1270 contents to temp file, and keep the temp file handle. */
1273 copy_archive (ibfd
, obfd
, output_target
)
1276 const char *output_target
;
1280 struct name_list
*next
;
1284 bfd
**ptr
= &obfd
->archive_head
;
1286 char *dir
= make_tempname (bfd_get_filename (obfd
));
1288 /* Make a temp directory to hold the contents. */
1289 #if defined (_WIN32) && !defined (__CYGWIN32__)
1290 if (mkdir (dir
) != 0)
1292 if (mkdir (dir
, 0700) != 0)
1295 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1296 dir
, strerror (errno
));
1298 obfd
->has_armap
= ibfd
->has_armap
;
1302 this_element
= bfd_openr_next_archived_file (ibfd
, NULL
);
1304 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1305 RETURN_NONFATAL (bfd_get_filename (obfd
));
1307 while (!status
&& this_element
!= (bfd
*) NULL
)
1309 /* Create an output file for this member. */
1310 char *output_name
= concat (dir
, "/", bfd_get_filename (this_element
),
1312 bfd
*output_bfd
= bfd_openw (output_name
, output_target
);
1315 int stat_status
= 0;
1319 stat_status
= bfd_stat_arch_elt (this_element
, &buf
);
1321 if (stat_status
!= 0)
1322 non_fatal (_("internal stat error on %s"),
1323 bfd_get_filename (this_element
));
1326 l
= (struct name_list
*) xmalloc (sizeof (struct name_list
));
1327 l
->name
= output_name
;
1331 if (output_bfd
== (bfd
*) NULL
)
1332 RETURN_NONFATAL (output_name
);
1334 if (bfd_check_format (this_element
, bfd_object
) == true)
1335 copy_object (this_element
, output_bfd
);
1337 if (!bfd_close (output_bfd
))
1339 bfd_nonfatal (bfd_get_filename (output_bfd
));
1340 /* Error in new object file. Don't change archive. */
1344 if (preserve_dates
&& stat_status
== 0)
1345 set_times (output_name
, &buf
);
1347 /* Open the newly output file and attach to our list. */
1348 output_bfd
= bfd_openr (output_name
, output_target
);
1350 l
->obfd
= output_bfd
;
1353 ptr
= &output_bfd
->next
;
1355 last_element
= this_element
;
1357 this_element
= bfd_openr_next_archived_file (ibfd
, last_element
);
1359 bfd_close (last_element
);
1361 *ptr
= (bfd
*) NULL
;
1363 if (!bfd_close (obfd
))
1364 RETURN_NONFATAL (bfd_get_filename (obfd
));
1366 if (!bfd_close (ibfd
))
1367 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1369 /* Delete all the files that we opened. */
1370 for (l
= list
; l
!= NULL
; l
= l
->next
)
1372 bfd_close (l
->obfd
);
1378 /* The top-level control. */
1381 copy_file (input_filename
, output_filename
, input_target
, output_target
)
1382 const char *input_filename
;
1383 const char *output_filename
;
1384 const char *input_target
;
1385 const char *output_target
;
1390 /* To allow us to do "strip *" without dying on the first
1391 non-object file, failures are nonfatal. */
1392 ibfd
= bfd_openr (input_filename
, input_target
);
1394 RETURN_NONFATAL (input_filename
);
1396 if (bfd_check_format (ibfd
, bfd_archive
))
1400 /* bfd_get_target does not return the correct value until
1401 bfd_check_format succeeds. */
1402 if (output_target
== NULL
)
1403 output_target
= bfd_get_target (ibfd
);
1405 obfd
= bfd_openw (output_filename
, output_target
);
1407 RETURN_NONFATAL (output_filename
);
1409 copy_archive (ibfd
, obfd
, output_target
);
1411 else if (bfd_check_format_matches (ibfd
, bfd_object
, &matching
)
1412 || bfd_check_format_matches (ibfd
, bfd_core
, &matching
))
1416 /* bfd_get_target does not return the correct value until
1417 bfd_check_format succeeds. */
1418 if (output_target
== NULL
)
1419 output_target
= bfd_get_target (ibfd
);
1421 obfd
= bfd_openw (output_filename
, output_target
);
1423 RETURN_NONFATAL (output_filename
);
1425 copy_object (ibfd
, obfd
);
1427 if (!bfd_close (obfd
))
1428 RETURN_NONFATAL (output_filename
);
1430 if (!bfd_close (ibfd
))
1431 RETURN_NONFATAL (input_filename
);
1435 bfd_nonfatal (input_filename
);
1437 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
1439 list_matching_formats (matching
);
1447 /* Add a name to the section renaming list. */
1450 add_section_rename (old_name
, new_name
, flags
)
1451 const char * old_name
;
1452 const char * new_name
;
1455 section_rename
* rename
;
1457 /* Check for conflicts first. */
1458 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1459 if (strcmp (rename
->old_name
, old_name
) == 0)
1461 /* Silently ignore duplicate definitions. */
1462 if (strcmp (rename
->new_name
, new_name
) == 0
1463 && rename
->flags
== flags
)
1466 fatal (_("Multiple renames of section %s"), old_name
);
1469 rename
= (section_rename
*) xmalloc (sizeof (* rename
));
1471 rename
->old_name
= old_name
;
1472 rename
->new_name
= new_name
;
1473 rename
->flags
= flags
;
1474 rename
->next
= section_rename_list
;
1476 section_rename_list
= rename
;
1479 /* Check the section rename list for a new name of the input section
1480 ISECTION. Return the new name if one is found.
1481 Also set RETURNED_FLAGS to the flags to be used for this section. */
1484 find_section_rename (ibfd
, isection
, returned_flags
)
1485 bfd
* ibfd ATTRIBUTE_UNUSED
;
1487 flagword
* returned_flags
;
1489 const char * old_name
= bfd_section_name (ibfd
, isection
);
1490 section_rename
* rename
;
1492 /* Default to using the flags of the input section. */
1493 * returned_flags
= bfd_get_section_flags (ibfd
, isection
);
1495 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1496 if (strcmp (rename
->old_name
, old_name
) == 0)
1498 if (rename
->flags
!= (flagword
) -1)
1499 * returned_flags
= rename
->flags
;
1501 return rename
->new_name
;
1507 /* Create a section in OBFD with the same
1508 name and attributes as ISECTION in IBFD. */
1511 setup_section (ibfd
, isection
, obfdarg
)
1516 bfd
*obfd
= (bfd
*) obfdarg
;
1517 struct section_list
*p
;
1526 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
1527 && (strip_symbols
== STRIP_DEBUG
1528 || strip_symbols
== STRIP_UNNEEDED
1529 || strip_symbols
== STRIP_ALL
1530 || discard_locals
== LOCALS_ALL
1531 || convert_debugging
))
1534 p
= find_section_list (bfd_section_name (ibfd
, isection
), false);
1538 if (sections_removed
&& p
!= NULL
&& p
->remove
)
1540 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
1543 /* Get the, possibly new, name of the output section. */
1544 name
= find_section_rename (ibfd
, isection
, & flags
);
1546 osection
= bfd_make_section_anyway (obfd
, name
);
1548 if (osection
== NULL
)
1554 size
= bfd_section_size (ibfd
, isection
);
1556 size
= (size
+ interleave
- 1) / interleave
;
1557 if (! bfd_set_section_size (obfd
, osection
, size
))
1563 vma
= bfd_section_vma (ibfd
, isection
);
1564 if (p
!= NULL
&& p
->change_vma
== CHANGE_MODIFY
)
1566 else if (p
!= NULL
&& p
->change_vma
== CHANGE_SET
)
1569 vma
+= change_section_address
;
1571 if (! bfd_set_section_vma (obfd
, osection
, vma
))
1577 lma
= isection
->lma
;
1578 if ((p
!= NULL
) && p
->change_lma
!= CHANGE_IGNORE
)
1580 if (p
->change_lma
== CHANGE_MODIFY
)
1582 else if (p
->change_lma
== CHANGE_SET
)
1588 lma
+= change_section_address
;
1590 osection
->lma
= lma
;
1592 /* FIXME: This is probably not enough. If we change the LMA we
1593 may have to recompute the header for the file as well. */
1594 if (bfd_set_section_alignment (obfd
,
1596 bfd_section_alignment (ibfd
, isection
))
1599 err
= _("alignment");
1603 if (p
!= NULL
&& p
->set_flags
)
1604 flags
= p
->flags
| (flags
& (SEC_HAS_CONTENTS
| SEC_RELOC
));
1605 if (!bfd_set_section_flags (obfd
, osection
, flags
))
1611 /* Copy merge entity size. */
1612 osection
->entsize
= isection
->entsize
;
1614 /* This used to be mangle_section; we do here to avoid using
1615 bfd_get_section_by_name since some formats allow multiple
1616 sections with the same name. */
1617 isection
->output_section
= osection
;
1618 isection
->output_offset
= 0;
1620 /* Allow the BFD backend to copy any private data it understands
1621 from the input section to the output section. */
1622 if (!bfd_copy_private_section_data (ibfd
, isection
, obfd
, osection
))
1624 err
= _("private data");
1628 /* All went well. */
1632 non_fatal (_("%s: section `%s': error in %s: %s"),
1633 bfd_get_filename (ibfd
),
1634 bfd_section_name (ibfd
, isection
),
1635 err
, bfd_errmsg (bfd_get_error ()));
1639 /* Copy the data of input section ISECTION of IBFD
1640 to an output section with the same name in OBFD.
1641 If stripping then don't copy any relocation info. */
1644 copy_section (ibfd
, isection
, obfdarg
)
1649 bfd
*obfd
= (bfd
*) obfdarg
;
1650 struct section_list
*p
;
1657 /* If we have already failed earlier on,
1658 do not keep on generating complaints now. */
1662 if ((bfd_get_section_flags (ibfd
, isection
) & SEC_DEBUGGING
) != 0
1663 && (strip_symbols
== STRIP_DEBUG
1664 || strip_symbols
== STRIP_UNNEEDED
1665 || strip_symbols
== STRIP_ALL
1666 || discard_locals
== LOCALS_ALL
1667 || convert_debugging
))
1670 p
= find_section_list (bfd_section_name (ibfd
, isection
), false);
1672 if (sections_removed
&& p
!= NULL
&& p
->remove
)
1674 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
1677 osection
= isection
->output_section
;
1678 size
= bfd_get_section_size_before_reloc (isection
);
1680 if (size
== 0 || osection
== 0)
1683 /* Core files do not need to be relocated. */
1684 if (bfd_get_format (obfd
) == bfd_core
)
1687 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1690 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1693 bfd_set_reloc (obfd
, osection
, (arelent
**) NULL
, 0);
1696 relpp
= (arelent
**) xmalloc (relsize
);
1697 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
1699 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1701 if (strip_symbols
== STRIP_ALL
)
1703 /* Remove relocations which are not in
1704 keep_strip_specific_list. */
1705 arelent
**temp_relpp
;
1706 long temp_relcount
= 0;
1709 temp_relpp
= (arelent
**) xmalloc (relsize
);
1710 for (i
= 0; i
< relcount
; i
++)
1711 if (is_specified_symbol
1712 (bfd_asymbol_name (*relpp
[i
]->sym_ptr_ptr
),
1713 keep_specific_list
))
1714 temp_relpp
[temp_relcount
++] = relpp
[i
];
1715 relcount
= temp_relcount
;
1720 bfd_set_reloc (obfd
, osection
,
1721 (relcount
== 0 ? (arelent
**) NULL
: relpp
), relcount
);
1724 isection
->_cooked_size
= isection
->_raw_size
;
1725 isection
->reloc_done
= true;
1727 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
1728 && bfd_get_section_flags (obfd
, osection
) & SEC_HAS_CONTENTS
)
1730 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
1732 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, (file_ptr
) 0,
1734 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1737 filter_bytes (memhunk
, &size
);
1739 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
1741 RETURN_NONFATAL (bfd_get_filename (obfd
));
1745 else if (p
!= NULL
&& p
->set_flags
&& (p
->flags
& SEC_HAS_CONTENTS
) != 0)
1747 PTR memhunk
= (PTR
) xmalloc ((unsigned) size
);
1749 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1750 flag--they can just remove the section entirely and add it
1751 back again. However, we do permit them to turn on the
1752 SEC_HAS_CONTENTS flag, and take it to mean that the section
1753 contents should be zeroed out. */
1755 memset (memhunk
, 0, size
);
1756 if (! bfd_set_section_contents (obfd
, osection
, memhunk
, (file_ptr
) 0,
1758 RETURN_NONFATAL (bfd_get_filename (obfd
));
1763 /* Get all the sections. This is used when --gap-fill or --pad-to is
1767 get_sections (obfd
, osection
, secppparg
)
1768 bfd
*obfd ATTRIBUTE_UNUSED
;
1772 asection
***secppp
= (asection
***) secppparg
;
1774 **secppp
= osection
;
1778 /* Sort sections by VMA. This is called via qsort, and is used when
1779 --gap-fill or --pad-to is used. We force non loadable or empty
1780 sections to the front, where they are easier to ignore. */
1783 compare_section_lma (arg1
, arg2
)
1787 const asection
**sec1
= (const asection
**) arg1
;
1788 const asection
**sec2
= (const asection
**) arg2
;
1789 flagword flags1
, flags2
;
1791 /* Sort non loadable sections to the front. */
1792 flags1
= (*sec1
)->flags
;
1793 flags2
= (*sec2
)->flags
;
1794 if ((flags1
& SEC_HAS_CONTENTS
) == 0
1795 || (flags1
& SEC_LOAD
) == 0)
1797 if ((flags2
& SEC_HAS_CONTENTS
) != 0
1798 && (flags2
& SEC_LOAD
) != 0)
1803 if ((flags2
& SEC_HAS_CONTENTS
) == 0
1804 || (flags2
& SEC_LOAD
) == 0)
1808 /* Sort sections by LMA. */
1809 if ((*sec1
)->lma
> (*sec2
)->lma
)
1811 else if ((*sec1
)->lma
< (*sec2
)->lma
)
1814 /* Sort sections with the same LMA by size. */
1815 if ((*sec1
)->_raw_size
> (*sec2
)->_raw_size
)
1817 else if ((*sec1
)->_raw_size
< (*sec2
)->_raw_size
)
1823 /* Mark all the symbols which will be used in output relocations with
1824 the BSF_KEEP flag so that those symbols will not be stripped.
1826 Ignore relocations which will not appear in the output file. */
1829 mark_symbols_used_in_relocations (ibfd
, isection
, symbolsarg
)
1834 asymbol
**symbols
= (asymbol
**) symbolsarg
;
1839 /* Ignore an input section with no corresponding output section. */
1840 if (isection
->output_section
== NULL
)
1843 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1845 bfd_fatal (bfd_get_filename (ibfd
));
1850 relpp
= (arelent
**) xmalloc (relsize
);
1851 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, symbols
);
1853 bfd_fatal (bfd_get_filename (ibfd
));
1855 /* Examine each symbol used in a relocation. If it's not one of the
1856 special bfd section symbols, then mark it with BSF_KEEP. */
1857 for (i
= 0; i
< relcount
; i
++)
1859 if (*relpp
[i
]->sym_ptr_ptr
!= bfd_com_section_ptr
->symbol
1860 && *relpp
[i
]->sym_ptr_ptr
!= bfd_abs_section_ptr
->symbol
1861 && *relpp
[i
]->sym_ptr_ptr
!= bfd_und_section_ptr
->symbol
)
1862 (*relpp
[i
]->sym_ptr_ptr
)->flags
|= BSF_KEEP
;
1869 /* Write out debugging information. */
1872 write_debugging_info (obfd
, dhandle
, symcountp
, symppp
)
1875 long *symcountp ATTRIBUTE_UNUSED
;
1876 asymbol
***symppp ATTRIBUTE_UNUSED
;
1878 if (bfd_get_flavour (obfd
) == bfd_target_ieee_flavour
)
1879 return write_ieee_debugging_info (obfd
, dhandle
);
1881 if (bfd_get_flavour (obfd
) == bfd_target_coff_flavour
1882 || bfd_get_flavour (obfd
) == bfd_target_elf_flavour
)
1884 bfd_byte
*syms
, *strings
;
1885 bfd_size_type symsize
, stringsize
;
1886 asection
*stabsec
, *stabstrsec
;
1888 if (! write_stabs_in_sections_debugging_info (obfd
, dhandle
, &syms
,
1893 stabsec
= bfd_make_section (obfd
, ".stab");
1894 stabstrsec
= bfd_make_section (obfd
, ".stabstr");
1896 || stabstrsec
== NULL
1897 || ! bfd_set_section_size (obfd
, stabsec
, symsize
)
1898 || ! bfd_set_section_size (obfd
, stabstrsec
, stringsize
)
1899 || ! bfd_set_section_alignment (obfd
, stabsec
, 2)
1900 || ! bfd_set_section_alignment (obfd
, stabstrsec
, 0)
1901 || ! bfd_set_section_flags (obfd
, stabsec
,
1905 || ! bfd_set_section_flags (obfd
, stabstrsec
,
1910 non_fatal (_("%s: can't create debugging section: %s"),
1911 bfd_get_filename (obfd
),
1912 bfd_errmsg (bfd_get_error ()));
1916 /* We can get away with setting the section contents now because
1917 the next thing the caller is going to do is copy over the
1918 real sections. We may someday have to split the contents
1919 setting out of this function. */
1920 if (! bfd_set_section_contents (obfd
, stabsec
, syms
, (file_ptr
) 0,
1922 || ! bfd_set_section_contents (obfd
, stabstrsec
, strings
,
1923 (file_ptr
) 0, stringsize
))
1925 non_fatal (_("%s: can't set debugging section contents: %s"),
1926 bfd_get_filename (obfd
),
1927 bfd_errmsg (bfd_get_error ()));
1934 non_fatal (_("%s: don't know how to write debugging information for %s"),
1935 bfd_get_filename (obfd
), bfd_get_target (obfd
));
1940 strip_main (argc
, argv
)
1944 char *input_target
= NULL
, *output_target
= NULL
;
1945 boolean show_version
= false;
1947 struct section_list
*p
;
1948 char *output_file
= NULL
;
1950 while ((c
= getopt_long (argc
, argv
, "I:O:F:K:N:R:o:sSpdgxXVv",
1951 strip_options
, (int *) 0)) != EOF
)
1956 input_target
= optarg
;
1959 output_target
= optarg
;
1962 input_target
= output_target
= optarg
;
1965 p
= find_section_list (optarg
, true);
1967 sections_removed
= true;
1970 strip_symbols
= STRIP_ALL
;
1974 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1975 strip_symbols
= STRIP_DEBUG
;
1977 case OPTION_STRIP_UNNEEDED
:
1978 strip_symbols
= STRIP_UNNEEDED
;
1981 add_specific_symbol (optarg
, &keep_specific_list
);
1984 add_specific_symbol (optarg
, &strip_specific_list
);
1987 output_file
= optarg
;
1990 preserve_dates
= true;
1993 discard_locals
= LOCALS_ALL
;
1996 discard_locals
= LOCALS_START_L
;
2002 show_version
= true;
2005 /* We've been given a long option. */
2008 strip_usage (stdout
, 0);
2010 strip_usage (stderr
, 1);
2015 print_version ("strip");
2017 /* Default is to strip all symbols. */
2018 if (strip_symbols
== STRIP_UNDEF
2019 && discard_locals
== LOCALS_UNDEF
2020 && strip_specific_list
== NULL
)
2021 strip_symbols
= STRIP_ALL
;
2023 if (output_target
== (char *) NULL
)
2024 output_target
= input_target
;
2028 || (output_file
!= NULL
&& (i
+ 1) < argc
))
2029 strip_usage (stderr
, 1);
2031 for (; i
< argc
; i
++)
2033 int hold_status
= status
;
2034 struct stat statbuf
;
2039 if (stat (argv
[i
], &statbuf
) < 0)
2041 non_fatal (_("%s: cannot stat: %s"), argv
[i
], strerror (errno
));
2046 if (output_file
!= NULL
)
2047 tmpname
= output_file
;
2049 tmpname
= make_tempname (argv
[i
]);
2052 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
2056 set_times (tmpname
, &statbuf
);
2057 if (output_file
== NULL
)
2058 smart_rename (tmpname
, argv
[i
], preserve_dates
);
2059 status
= hold_status
;
2063 if (output_file
== NULL
)
2071 copy_main (argc
, argv
)
2075 char * binary_architecture
= NULL
;
2076 char *input_filename
= NULL
, *output_filename
= NULL
;
2077 char *input_target
= NULL
, *output_target
= NULL
;
2078 boolean show_version
= false;
2079 boolean change_warn
= true;
2081 struct section_list
*p
;
2082 struct stat statbuf
;
2084 while ((c
= getopt_long (argc
, argv
, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
2085 copy_options
, (int *) 0)) != EOF
)
2090 copy_byte
= atoi (optarg
);
2092 fatal (_("byte number must be non-negative"));
2096 binary_architecture
= optarg
;
2100 interleave
= atoi (optarg
);
2102 fatal (_("interleave must be positive"));
2106 case 's': /* "source" - 'I' is preferred */
2107 input_target
= optarg
;
2111 case 'd': /* "destination" - 'O' is preferred */
2112 output_target
= optarg
;
2116 input_target
= output_target
= optarg
;
2120 p
= find_section_list (optarg
, true);
2122 fatal (_("%s both copied and removed"), optarg
);
2124 sections_copied
= true;
2128 p
= find_section_list (optarg
, true);
2130 fatal (_("%s both copied and removed"), optarg
);
2132 sections_removed
= true;
2136 strip_symbols
= STRIP_ALL
;
2140 strip_symbols
= STRIP_DEBUG
;
2143 case OPTION_STRIP_UNNEEDED
:
2144 strip_symbols
= STRIP_UNNEEDED
;
2148 add_specific_symbol (optarg
, &keep_specific_list
);
2152 add_specific_symbol (optarg
, &strip_specific_list
);
2156 add_specific_symbol (optarg
, &localize_specific_list
);
2160 add_specific_symbol (optarg
, &keepglobal_specific_list
);
2164 add_specific_symbol (optarg
, &weaken_specific_list
);
2168 preserve_dates
= true;
2172 discard_locals
= LOCALS_ALL
;
2176 discard_locals
= LOCALS_START_L
;
2184 show_version
= true;
2191 case OPTION_ADD_SECTION
:
2195 struct section_add
*pa
;
2200 s
= strchr (optarg
, '=');
2203 fatal (_("bad format for %s"), "--add-section");
2205 if (stat (s
+ 1, & st
) < 0)
2206 fatal (_("cannot stat: %s: %s"), s
+ 1, strerror (errno
));
2208 pa
= (struct section_add
*) xmalloc (sizeof (struct section_add
));
2211 name
= (char *) xmalloc (len
+ 1);
2212 strncpy (name
, optarg
, len
);
2216 pa
->filename
= s
+ 1;
2218 pa
->size
= st
.st_size
;
2220 pa
->contents
= (bfd_byte
*) xmalloc (pa
->size
);
2221 f
= fopen (pa
->filename
, FOPEN_RB
);
2224 fatal (_("cannot open: %s: %s"), pa
->filename
, strerror (errno
));
2226 if (fread (pa
->contents
, 1, pa
->size
, f
) == 0
2228 fatal (_("%s: fread failed"), pa
->filename
);
2232 pa
->next
= add_sections
;
2237 case OPTION_CHANGE_START
:
2238 change_start
= parse_vma (optarg
, "--change-start");
2241 case OPTION_CHANGE_SECTION_ADDRESS
:
2242 case OPTION_CHANGE_SECTION_LMA
:
2243 case OPTION_CHANGE_SECTION_VMA
:
2248 char *option
= NULL
;
2250 enum change_action what
= CHANGE_IGNORE
;
2254 case OPTION_CHANGE_SECTION_ADDRESS
:
2255 option
= "--change-section-address";
2257 case OPTION_CHANGE_SECTION_LMA
:
2258 option
= "--change-section-lma";
2260 case OPTION_CHANGE_SECTION_VMA
:
2261 option
= "--change-section-vma";
2265 s
= strchr (optarg
, '=');
2268 s
= strchr (optarg
, '+');
2271 s
= strchr (optarg
, '-');
2273 fatal (_("bad format for %s"), option
);
2278 name
= (char *) xmalloc (len
+ 1);
2279 strncpy (name
, optarg
, len
);
2282 p
= find_section_list (name
, true);
2284 val
= parse_vma (s
+ 1, option
);
2288 case '=': what
= CHANGE_SET
; break;
2289 case '-': val
= - val
; /* Drop through. */
2290 case '+': what
= CHANGE_MODIFY
; break;
2295 case OPTION_CHANGE_SECTION_ADDRESS
:
2296 p
->change_vma
= what
;
2300 case OPTION_CHANGE_SECTION_LMA
:
2301 p
->change_lma
= what
;
2305 case OPTION_CHANGE_SECTION_VMA
:
2306 p
->change_vma
= what
;
2313 case OPTION_CHANGE_ADDRESSES
:
2314 change_section_address
= parse_vma (optarg
, "--change-addresses");
2315 change_start
= change_section_address
;
2318 case OPTION_CHANGE_WARNINGS
:
2322 case OPTION_CHANGE_LEADING_CHAR
:
2323 change_leading_char
= true;
2326 case OPTION_DEBUGGING
:
2327 convert_debugging
= true;
2330 case OPTION_GAP_FILL
:
2332 bfd_vma gap_fill_vma
;
2334 gap_fill_vma
= parse_vma (optarg
, "--gap-fill");
2335 gap_fill
= (bfd_byte
) gap_fill_vma
;
2336 if ((bfd_vma
) gap_fill
!= gap_fill_vma
)
2340 sprintf_vma (buff
, gap_fill_vma
);
2342 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2345 gap_fill_set
= true;
2349 case OPTION_NO_CHANGE_WARNINGS
:
2350 change_warn
= false;
2354 pad_to
= parse_vma (optarg
, "--pad-to");
2358 case OPTION_REMOVE_LEADING_CHAR
:
2359 remove_leading_char
= true;
2362 case OPTION_REDEFINE_SYM
:
2364 /* Push this redefinition onto redefine_symbol_list. */
2368 const char *nextarg
;
2369 char *source
, *target
;
2371 s
= strchr (optarg
, '=');
2373 fatal (_("bad format for %s"), "--redefine-sym");
2376 source
= (char *) xmalloc (len
+ 1);
2377 strncpy (source
, optarg
, len
);
2381 len
= strlen (nextarg
);
2382 target
= (char *) xmalloc (len
+ 1);
2383 strcpy (target
, nextarg
);
2385 redefine_list_append (source
, target
);
2392 case OPTION_SET_SECTION_FLAGS
:
2398 s
= strchr (optarg
, '=');
2400 fatal (_("bad format for %s"), "--set-section-flags");
2403 name
= (char *) xmalloc (len
+ 1);
2404 strncpy (name
, optarg
, len
);
2407 p
= find_section_list (name
, true);
2409 p
->set_flags
= true;
2410 p
->flags
= parse_flags (s
+ 1);
2414 case OPTION_RENAME_SECTION
:
2417 const char *eq
, *fl
;
2422 eq
= strchr (optarg
, '=');
2424 fatal (_("bad format for %s"), "--rename-section");
2428 fatal (_("bad format for %s"), "--rename-section");
2430 old_name
= (char *) xmalloc (len
+ 1);
2431 strncpy (old_name
, optarg
, len
);
2435 fl
= strchr (eq
, ',');
2438 flags
= parse_flags (fl
+ 1);
2448 fatal (_("bad format for %s"), "--rename-section");
2450 new_name
= (char *) xmalloc (len
+ 1);
2451 strncpy (new_name
, eq
, len
);
2454 add_section_rename (old_name
, new_name
, flags
);
2458 case OPTION_SET_START
:
2459 set_start
= parse_vma (optarg
, "--set-start");
2460 set_start_set
= true;
2463 case OPTION_SREC_LEN
:
2464 Chunk
= parse_vma (optarg
, "--srec-len");
2467 case OPTION_SREC_FORCES3
:
2471 case OPTION_STRIP_SYMBOLS
:
2472 add_specific_symbols (optarg
, &strip_specific_list
);
2475 case OPTION_KEEP_SYMBOLS
:
2476 add_specific_symbols (optarg
, &keep_specific_list
);
2479 case OPTION_LOCALIZE_SYMBOLS
:
2480 add_specific_symbols (optarg
, &localize_specific_list
);
2483 case OPTION_KEEPGLOBAL_SYMBOLS
:
2484 add_specific_symbols (optarg
, &keepglobal_specific_list
);
2487 case OPTION_WEAKEN_SYMBOLS
:
2488 add_specific_symbols (optarg
, &weaken_specific_list
);
2491 case OPTION_ALT_MACH_CODE
:
2492 use_alt_mach_code
= atoi (optarg
);
2493 if (use_alt_mach_code
<= 0)
2494 fatal (_("alternate machine code index must be positive"));
2498 break; /* we've been given a long option */
2501 copy_usage (stdout
, 0);
2504 copy_usage (stderr
, 1);
2509 print_version ("objcopy");
2511 if (copy_byte
>= interleave
)
2512 fatal (_("byte number must be less than interleave"));
2514 if (optind
== argc
|| optind
+ 2 < argc
)
2515 copy_usage (stderr
, 1);
2517 input_filename
= argv
[optind
];
2518 if (optind
+ 1 < argc
)
2519 output_filename
= argv
[optind
+ 1];
2521 /* Default is to strip no symbols. */
2522 if (strip_symbols
== STRIP_UNDEF
&& discard_locals
== LOCALS_UNDEF
)
2523 strip_symbols
= STRIP_NONE
;
2525 if (output_target
== (char *) NULL
)
2526 output_target
= input_target
;
2528 if (binary_architecture
!= (char *) NULL
)
2530 if (input_target
&& strcmp (input_target
, "binary") == 0)
2532 const bfd_arch_info_type
* temp_arch_info
;
2534 temp_arch_info
= bfd_scan_arch (binary_architecture
);
2536 if (temp_arch_info
!= NULL
)
2537 bfd_external_binary_architecture
= temp_arch_info
->arch
;
2539 fatal (_("architecture %s unknown"), binary_architecture
);
2543 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2544 non_fatal (_(" Argument %s ignored"), binary_architecture
);
2549 if (stat (input_filename
, & statbuf
) < 0)
2550 fatal (_("Cannot stat: %s: %s"), input_filename
, strerror (errno
));
2552 /* If there is no destination file then create a temp and rename
2553 the result into the input. */
2555 if (output_filename
== (char *) NULL
)
2557 char *tmpname
= make_tempname (input_filename
);
2559 copy_file (input_filename
, tmpname
, input_target
, output_target
);
2563 set_times (tmpname
, &statbuf
);
2564 smart_rename (tmpname
, input_filename
, preserve_dates
);
2571 copy_file (input_filename
, output_filename
, input_target
, output_target
);
2573 if (status
== 0 && preserve_dates
)
2574 set_times (output_filename
, &statbuf
);
2579 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
2583 if (p
->change_vma
!= CHANGE_IGNORE
)
2587 sprintf_vma (buff
, p
->vma_val
);
2589 /* xgettext:c-format */
2590 non_fatal (_("%s %s%c0x%s never used"),
2591 "--change-section-vma",
2593 p
->change_vma
== CHANGE_SET
? '=' : '+',
2597 if (p
->change_lma
!= CHANGE_IGNORE
)
2601 sprintf_vma (buff
, p
->lma_val
);
2603 /* xgettext:c-format */
2604 non_fatal (_("%s %s%c0x%s never used"),
2605 "--change-section-lma",
2607 p
->change_lma
== CHANGE_SET
? '=' : '+',
2617 int main
PARAMS ((int, char **));
2624 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2625 setlocale (LC_MESSAGES
, "");
2627 #if defined (HAVE_SETLOCALE)
2628 setlocale (LC_CTYPE
, "");
2630 bindtextdomain (PACKAGE
, LOCALEDIR
);
2631 textdomain (PACKAGE
);
2633 program_name
= argv
[0];
2634 xmalloc_set_program_name (program_name
);
2636 START_PROGRESS (program_name
, 0);
2638 strip_symbols
= STRIP_UNDEF
;
2639 discard_locals
= LOCALS_UNDEF
;
2642 set_default_bfd_target ();
2646 int i
= strlen (program_name
);
2647 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2648 /* Drop the .exe suffix, if any. */
2649 if (i
> 4 && FILENAME_CMP (program_name
+ i
- 4, ".exe") == 0)
2652 program_name
[i
] = '\0';
2655 is_strip
= (i
>= 5 && FILENAME_CMP (program_name
+ i
- 5, "strip") == 0);
2659 strip_main (argc
, argv
);
2661 copy_main (argc
, argv
);
2663 END_PROGRESS (program_name
);