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"
33 /* A list of symbols to explicitly strip out, or to keep. A linked
34 list is good enough for a small number from the command line, but
35 this will slow things down a lot if many symbols are being
44 /* A list to support redefine_sym. */
49 struct redefine_node
*next
;
52 typedef struct section_rename
54 const char * old_name
;
55 const char * new_name
;
57 struct section_rename
* next
;
61 /* List of sections to be renamed. */
62 static section_rename
*section_rename_list
;
64 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
66 static asymbol
**isympp
= NULL
; /* Input symbols. */
67 static asymbol
**osympp
= NULL
; /* Output symbols that survive stripping. */
69 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
70 static int copy_byte
= -1;
71 static int interleave
= 4;
73 static bfd_boolean verbose
; /* Print file and target names. */
74 static bfd_boolean preserve_dates
; /* Preserve input file timestamp. */
75 static int status
= 0; /* Exit status. */
80 STRIP_NONE
, /* Don't strip. */
81 STRIP_DEBUG
, /* Strip all debugger symbols. */
82 STRIP_UNNEEDED
, /* Strip unnecessary symbols. */
83 STRIP_NONDEBUG
, /* Strip everything but debug info. */
84 STRIP_ALL
/* Strip all symbols. */
87 /* Which symbols to remove. */
88 static enum strip_action strip_symbols
;
93 LOCALS_START_L
, /* Discard locals starting with L. */
94 LOCALS_ALL
/* Discard all locals. */
97 /* Which local symbols to remove. Overrides STRIP_ALL. */
98 static enum locals_action discard_locals
;
100 /* What kind of change to perform. */
108 /* Structure used to hold lists of sections and actions to take. */
111 struct section_list
* next
; /* Next section to change. */
112 const char * name
; /* Section name. */
113 bfd_boolean used
; /* Whether this entry was used. */
114 bfd_boolean remove
; /* Whether to remove this section. */
115 bfd_boolean copy
; /* Whether to copy this section. */
116 enum change_action change_vma
;/* Whether to change or set VMA. */
117 bfd_vma vma_val
; /* Amount to change by or set to. */
118 enum change_action change_lma
;/* Whether to change or set LMA. */
119 bfd_vma lma_val
; /* Amount to change by or set to. */
120 bfd_boolean set_flags
; /* Whether to set the section flags. */
121 flagword flags
; /* What to set the section flags to. */
124 static struct section_list
*change_sections
;
126 /* TRUE if some sections are to be removed. */
127 static bfd_boolean sections_removed
;
129 /* TRUE if only some sections are to be copied. */
130 static bfd_boolean sections_copied
;
132 /* Changes to the start address. */
133 static bfd_vma change_start
= 0;
134 static bfd_boolean set_start_set
= FALSE
;
135 static bfd_vma set_start
;
137 /* Changes to section addresses. */
138 static bfd_vma change_section_address
= 0;
140 /* Filling gaps between sections. */
141 static bfd_boolean gap_fill_set
= FALSE
;
142 static bfd_byte gap_fill
= 0;
144 /* Pad to a given address. */
145 static bfd_boolean pad_to_set
= FALSE
;
146 static bfd_vma pad_to
;
148 /* Use alternate machine code? */
149 static int use_alt_mach_code
= 0;
151 /* Output BFD flags user wants to set or clear */
152 static flagword bfd_flags_to_set
;
153 static flagword bfd_flags_to_clear
;
155 /* List of sections to add. */
158 /* Next section to add. */
159 struct section_add
*next
;
160 /* Name of section to add. */
162 /* Name of file holding section contents. */
163 const char *filename
;
166 /* Contents of file. */
168 /* BFD section, after it has been added. */
172 /* List of sections to add to the output BFD. */
173 static struct section_add
*add_sections
;
175 /* If non-NULL the argument to --add-gnu-debuglink.
176 This should be the filename to store in the .gnu_debuglink section. */
177 static const char * gnu_debuglink_filename
= NULL
;
179 /* Whether to convert debugging information. */
180 static bfd_boolean convert_debugging
= FALSE
;
182 /* Whether to change the leading character in symbol names. */
183 static bfd_boolean change_leading_char
= FALSE
;
185 /* Whether to remove the leading character from global symbol names. */
186 static bfd_boolean remove_leading_char
= FALSE
;
188 /* Whether to permit wildcard in symbol comparison. */
189 static bfd_boolean wildcard
= FALSE
;
191 /* List of symbols to strip, keep, localize, keep-global, weaken,
193 static struct symlist
*strip_specific_list
= NULL
;
194 static struct symlist
*keep_specific_list
= NULL
;
195 static struct symlist
*localize_specific_list
= NULL
;
196 static struct symlist
*keepglobal_specific_list
= NULL
;
197 static struct symlist
*weaken_specific_list
= NULL
;
198 static struct redefine_node
*redefine_sym_list
= NULL
;
200 /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
201 static bfd_boolean weaken
= FALSE
;
203 /* Prefix symbols/sections. */
204 static char *prefix_symbols_string
= 0;
205 static char *prefix_sections_string
= 0;
206 static char *prefix_alloc_sections_string
= 0;
208 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
209 enum command_line_switch
211 OPTION_ADD_SECTION
=150,
212 OPTION_CHANGE_ADDRESSES
,
213 OPTION_CHANGE_LEADING_CHAR
,
215 OPTION_CHANGE_SECTION_ADDRESS
,
216 OPTION_CHANGE_SECTION_LMA
,
217 OPTION_CHANGE_SECTION_VMA
,
218 OPTION_CHANGE_WARNINGS
,
221 OPTION_NO_CHANGE_WARNINGS
,
223 OPTION_REMOVE_LEADING_CHAR
,
224 OPTION_SET_SECTION_FLAGS
,
226 OPTION_STRIP_UNNEEDED
,
229 OPTION_REDEFINE_SYMS
,
232 OPTION_STRIP_SYMBOLS
,
234 OPTION_LOCALIZE_SYMBOLS
,
235 OPTION_KEEPGLOBAL_SYMBOLS
,
236 OPTION_WEAKEN_SYMBOLS
,
237 OPTION_RENAME_SECTION
,
238 OPTION_ALT_MACH_CODE
,
239 OPTION_PREFIX_SYMBOLS
,
240 OPTION_PREFIX_SECTIONS
,
241 OPTION_PREFIX_ALLOC_SECTIONS
,
243 OPTION_ADD_GNU_DEBUGLINK
,
244 OPTION_ONLY_KEEP_DEBUG
,
245 OPTION_READONLY_TEXT
,
246 OPTION_WRITABLE_TEXT
,
251 /* Options to handle if running as "strip". */
253 static struct option strip_options
[] =
255 {"discard-all", no_argument
, 0, 'x'},
256 {"discard-locals", no_argument
, 0, 'X'},
257 {"format", required_argument
, 0, 'F'}, /* Obsolete */
258 {"help", no_argument
, 0, 'h'},
259 {"info", no_argument
, 0, OPTION_FORMATS_INFO
},
260 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
261 {"input-target", required_argument
, 0, 'I'},
262 {"keep-symbol", required_argument
, 0, 'K'},
263 {"only-keep-debug", no_argument
, 0, OPTION_ONLY_KEEP_DEBUG
},
264 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
265 {"output-target", required_argument
, 0, 'O'},
266 {"output-file", required_argument
, 0, 'o'},
267 {"preserve-dates", no_argument
, 0, 'p'},
268 {"remove-section", required_argument
, 0, 'R'},
269 {"strip-all", no_argument
, 0, 's'},
270 {"strip-debug", no_argument
, 0, 'S'},
271 {"strip-unneeded", no_argument
, 0, OPTION_STRIP_UNNEEDED
},
272 {"strip-symbol", required_argument
, 0, 'N'},
273 {"target", required_argument
, 0, 'F'},
274 {"verbose", no_argument
, 0, 'v'},
275 {"version", no_argument
, 0, 'V'},
276 {"wildcard", no_argument
, 0, 'w'},
277 {0, no_argument
, 0, 0}
280 /* Options to handle if running as "objcopy". */
282 static struct option copy_options
[] =
284 {"add-gnu-debuglink", required_argument
, 0, OPTION_ADD_GNU_DEBUGLINK
},
285 {"add-section", required_argument
, 0, OPTION_ADD_SECTION
},
286 {"adjust-start", required_argument
, 0, OPTION_CHANGE_START
},
287 {"adjust-vma", required_argument
, 0, OPTION_CHANGE_ADDRESSES
},
288 {"adjust-section-vma", required_argument
, 0, OPTION_CHANGE_SECTION_ADDRESS
},
289 {"adjust-warnings", no_argument
, 0, OPTION_CHANGE_WARNINGS
},
290 {"alt-machine-code", required_argument
, 0, OPTION_ALT_MACH_CODE
},
291 {"binary-architecture", required_argument
, 0, 'B'},
292 {"byte", required_argument
, 0, 'b'},
293 {"change-addresses", required_argument
, 0, OPTION_CHANGE_ADDRESSES
},
294 {"change-leading-char", no_argument
, 0, OPTION_CHANGE_LEADING_CHAR
},
295 {"change-section-address", required_argument
, 0, OPTION_CHANGE_SECTION_ADDRESS
},
296 {"change-section-lma", required_argument
, 0, OPTION_CHANGE_SECTION_LMA
},
297 {"change-section-vma", required_argument
, 0, OPTION_CHANGE_SECTION_VMA
},
298 {"change-start", required_argument
, 0, OPTION_CHANGE_START
},
299 {"change-warnings", no_argument
, 0, OPTION_CHANGE_WARNINGS
},
300 {"debugging", no_argument
, 0, OPTION_DEBUGGING
},
301 {"discard-all", no_argument
, 0, 'x'},
302 {"discard-locals", no_argument
, 0, 'X'},
303 {"format", required_argument
, 0, 'F'}, /* Obsolete */
304 {"gap-fill", required_argument
, 0, OPTION_GAP_FILL
},
305 {"help", no_argument
, 0, 'h'},
306 {"impure", no_argument
, 0, OPTION_IMPURE
},
307 {"info", no_argument
, 0, OPTION_FORMATS_INFO
},
308 {"input-format", required_argument
, 0, 'I'}, /* Obsolete */
309 {"input-target", required_argument
, 0, 'I'},
310 {"interleave", required_argument
, 0, 'i'},
311 {"keep-global-symbol", required_argument
, 0, 'G'},
312 {"keep-global-symbols", required_argument
, 0, OPTION_KEEPGLOBAL_SYMBOLS
},
313 {"keep-symbol", required_argument
, 0, 'K'},
314 {"keep-symbols", required_argument
, 0, OPTION_KEEP_SYMBOLS
},
315 {"localize-symbol", required_argument
, 0, 'L'},
316 {"localize-symbols", required_argument
, 0, OPTION_LOCALIZE_SYMBOLS
},
317 {"no-adjust-warnings", no_argument
, 0, OPTION_NO_CHANGE_WARNINGS
},
318 {"no-change-warnings", no_argument
, 0, OPTION_NO_CHANGE_WARNINGS
},
319 {"only-keep-debug", no_argument
, 0, OPTION_ONLY_KEEP_DEBUG
},
320 {"only-section", required_argument
, 0, 'j'},
321 {"output-format", required_argument
, 0, 'O'}, /* Obsolete */
322 {"output-target", required_argument
, 0, 'O'},
323 {"pad-to", required_argument
, 0, OPTION_PAD_TO
},
324 {"prefix-symbols", required_argument
, 0, OPTION_PREFIX_SYMBOLS
},
325 {"prefix-sections", required_argument
, 0, OPTION_PREFIX_SECTIONS
},
326 {"prefix-alloc-sections", required_argument
, 0, OPTION_PREFIX_ALLOC_SECTIONS
},
327 {"preserve-dates", no_argument
, 0, 'p'},
328 {"pure", no_argument
, 0, OPTION_PURE
},
329 {"readonly-text", no_argument
, 0, OPTION_READONLY_TEXT
},
330 {"redefine-sym", required_argument
, 0, OPTION_REDEFINE_SYM
},
331 {"redefine-syms", required_argument
, 0, OPTION_REDEFINE_SYMS
},
332 {"remove-leading-char", no_argument
, 0, OPTION_REMOVE_LEADING_CHAR
},
333 {"remove-section", required_argument
, 0, 'R'},
334 {"rename-section", required_argument
, 0, OPTION_RENAME_SECTION
},
335 {"set-section-flags", required_argument
, 0, OPTION_SET_SECTION_FLAGS
},
336 {"set-start", required_argument
, 0, OPTION_SET_START
},
337 {"srec-len", required_argument
, 0, OPTION_SREC_LEN
},
338 {"srec-forceS3", no_argument
, 0, OPTION_SREC_FORCES3
},
339 {"strip-all", no_argument
, 0, 'S'},
340 {"strip-debug", no_argument
, 0, 'g'},
341 {"strip-unneeded", no_argument
, 0, OPTION_STRIP_UNNEEDED
},
342 {"strip-symbol", required_argument
, 0, 'N'},
343 {"strip-symbols", required_argument
, 0, OPTION_STRIP_SYMBOLS
},
344 {"target", required_argument
, 0, 'F'},
345 {"verbose", no_argument
, 0, 'v'},
346 {"version", no_argument
, 0, 'V'},
347 {"weaken", no_argument
, 0, OPTION_WEAKEN
},
348 {"weaken-symbol", required_argument
, 0, 'W'},
349 {"weaken-symbols", required_argument
, 0, OPTION_WEAKEN_SYMBOLS
},
350 {"wildcard", no_argument
, 0, 'w'},
351 {"writable-text", no_argument
, 0, OPTION_WRITABLE_TEXT
},
352 {0, no_argument
, 0, 0}
356 extern char *program_name
;
358 /* This flag distinguishes between strip and objcopy:
359 1 means this is 'strip'; 0 means this is 'objcopy'.
360 -1 means if we should use argv[0] to decide. */
363 /* The maximum length of an S record. This variable is declared in srec.c
364 and can be modified by the --srec-len parameter. */
365 extern unsigned int Chunk
;
367 /* Restrict the generation of Srecords to type S3 only.
368 This variable is declare in bfd/srec.c and can be toggled
369 on by the --srec-forceS3 command line switch. */
370 extern bfd_boolean S3Forced
;
372 /* Defined in bfd/binary.c. Used to set architecture and machine of input
374 extern enum bfd_architecture bfd_external_binary_architecture
;
375 extern unsigned long bfd_external_machine
;
377 /* Forward declarations. */
378 static void setup_section (bfd
*, asection
*, void *);
379 static void copy_section (bfd
*, asection
*, void *);
380 static void get_sections (bfd
*, asection
*, void *);
381 static int compare_section_lma (const void *, const void *);
382 static void mark_symbols_used_in_relocations (bfd
*, asection
*, void *);
383 static bfd_boolean
write_debugging_info (bfd
*, void *, long *, asymbol
***);
384 static const char *lookup_sym_redefinition (const char *);
387 copy_usage (FILE *stream
, int exit_status
)
389 fprintf (stream
, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name
);
390 fprintf (stream
, _(" Copies a binary file, possibly transforming it in the process\n"));
391 fprintf (stream
, _(" The options are:\n"));
392 fprintf (stream
, _("\
393 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
394 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
395 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
396 -F --target <bfdname> Set both input and output format to <bfdname>\n\
397 --debugging Convert debugging information, if possible\n\
398 -p --preserve-dates Copy modified/access timestamps to the output\n\
399 -j --only-section <name> Only copy section <name> into the output\n\
400 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
401 -R --remove-section <name> Remove section <name> from the output\n\
402 -S --strip-all Remove all symbol and relocation information\n\
403 -g --strip-debug Remove all debugging symbols & sections\n\
404 --strip-unneeded Remove all symbols not needed by relocations\n\
405 -N --strip-symbol <name> Do not copy symbol <name>\n\
406 --only-keep-debug Strip everything but the debug information\n\
407 -K --keep-symbol <name> Only copy symbol <name>\n\
408 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
409 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
410 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
411 --weaken Force all global symbols to be marked as weak\n\
412 -w --wildcard Permit wildcard in symbol comparasion\n\
413 -x --discard-all Remove all non-global symbols\n\
414 -X --discard-locals Remove any compiler-generated symbols\n\
415 -i --interleave <number> Only copy one out of every <number> bytes\n\
416 -b --byte <num> Select byte <num> in every interleaved block\n\
417 --gap-fill <val> Fill gaps between sections with <val>\n\
418 --pad-to <addr> Pad the last section up to address <addr>\n\
419 --set-start <addr> Set the start address to <addr>\n\
420 {--change-start|--adjust-start} <incr>\n\
421 Add <incr> to the start address\n\
422 {--change-addresses|--adjust-vma} <incr>\n\
423 Add <incr> to LMA, VMA and start addresses\n\
424 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
425 Change LMA and VMA of section <name> by <val>\n\
426 --change-section-lma <name>{=|+|-}<val>\n\
427 Change the LMA of section <name> by <val>\n\
428 --change-section-vma <name>{=|+|-}<val>\n\
429 Change the VMA of section <name> by <val>\n\
430 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
431 Warn if a named section does not exist\n\
432 --set-section-flags <name>=<flags>\n\
433 Set section <name>'s properties to <flags>\n\
434 --add-section <name>=<file> Add section <name> found in <file> to output\n\
435 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
436 --change-leading-char Force output format's leading character style\n\
437 --remove-leading-char Remove leading character from global symbols\n\
438 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
439 --redefine-syms <file> --redefine-sym for all symbol pairs \n\
441 --srec-len <number> Restrict the length of generated Srecords\n\
442 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
443 --strip-symbols <file> -N for all symbols listed in <file>\n\
444 --keep-symbols <file> -K for all symbols listed in <file>\n\
445 --localize-symbols <file> -L for all symbols listed in <file>\n\
446 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
447 --weaken-symbols <file> -W for all symbols listed in <file>\n\
448 --alt-machine-code <index> Use alternate machine code for output\n\
449 --writable-text Mark the output text as writable\n\
450 --readonly-text Make the output text write protected\n\
451 --pure Mark the output file as demand paged\n\
452 --impure Mark the output file as impure\n\
453 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\
454 --prefix-sections <prefix> Add <prefix> to start of every section name\n\
455 --prefix-alloc-sections <prefix>\n\
456 Add <prefix> to start of every allocatable\n\
458 -v --verbose List all object files modified\n\
459 -V --version Display this program's version number\n\
460 -h --help Display this output\n\
461 --info List object formats & architectures supported\n\
463 list_supported_targets (program_name
, stream
);
464 if (exit_status
== 0)
465 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
470 strip_usage (FILE *stream
, int exit_status
)
472 fprintf (stream
, _("Usage: %s <option(s)> in-file(s)\n"), program_name
);
473 fprintf (stream
, _(" Removes symbols and sections from files\n"));
474 fprintf (stream
, _(" The options are:\n"));
475 fprintf (stream
, _("\
476 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\
477 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\
478 -F --target=<bfdname> Set both input and output format to <bfdname>\n\
479 -p --preserve-dates Copy modified/access timestamps to the output\n\
480 -R --remove-section=<name> Remove section <name> from the output\n\
481 -s --strip-all Remove all symbol and relocation information\n\
482 -g -S -d --strip-debug Remove all debugging symbols & sections\n\
483 --strip-unneeded Remove all symbols not needed by relocations\n\
484 --only-keep-debug Strip everything but the debug information\n\
485 -N --strip-symbol=<name> Do not copy symbol <name>\n\
486 -K --keep-symbol=<name> Only copy symbol <name>\n\
487 -w --wildcard Permit wildcard in symbol comparasion\n\
488 -x --discard-all Remove all non-global symbols\n\
489 -X --discard-locals Remove any compiler-generated symbols\n\
490 -v --verbose List all object files modified\n\
491 -V --version Display this program's version number\n\
492 -h --help Display this output\n\
493 --info List object formats & architectures supported\n\
494 -o <file> Place stripped output into <file>\n\
497 list_supported_targets (program_name
, stream
);
498 if (exit_status
== 0)
499 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
503 /* Parse section flags into a flagword, with a fatal error if the
504 string can't be parsed. */
507 parse_flags (const char *s
)
517 snext
= strchr (s
, ',');
527 #define PARSE_FLAG(fname,fval) \
528 else if (strncasecmp (fname, s, len) == 0) ret |= fval
529 PARSE_FLAG ("alloc", SEC_ALLOC
);
530 PARSE_FLAG ("load", SEC_LOAD
);
531 PARSE_FLAG ("noload", SEC_NEVER_LOAD
);
532 PARSE_FLAG ("readonly", SEC_READONLY
);
533 PARSE_FLAG ("debug", SEC_DEBUGGING
);
534 PARSE_FLAG ("code", SEC_CODE
);
535 PARSE_FLAG ("data", SEC_DATA
);
536 PARSE_FLAG ("rom", SEC_ROM
);
537 PARSE_FLAG ("share", SEC_SHARED
);
538 PARSE_FLAG ("contents", SEC_HAS_CONTENTS
);
544 copy
= xmalloc (len
+ 1);
545 strncpy (copy
, s
, len
);
547 non_fatal (_("unrecognized section flag `%s'"), copy
);
548 fatal (_("supported flags: %s"),
549 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
559 /* Find and optionally add an entry in the change_sections list. */
561 static struct section_list
*
562 find_section_list (const char *name
, bfd_boolean add
)
564 struct section_list
*p
;
566 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
567 if (strcmp (p
->name
, name
) == 0)
573 p
= xmalloc (sizeof (struct section_list
));
578 p
->change_vma
= CHANGE_IGNORE
;
579 p
->change_lma
= CHANGE_IGNORE
;
582 p
->set_flags
= FALSE
;
585 p
->next
= change_sections
;
591 /* Add a symbol to strip_specific_list. */
594 add_specific_symbol (const char *name
, struct symlist
**list
)
596 struct symlist
*tmp_list
;
598 tmp_list
= xmalloc (sizeof (struct symlist
));
599 tmp_list
->name
= name
;
600 tmp_list
->next
= *list
;
604 /* Add symbols listed in `filename' to strip_specific_list. */
606 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
607 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
610 add_specific_symbols (const char *filename
, struct symlist
**list
)
616 unsigned int line_count
;
618 size
= get_file_size (filename
);
622 buffer
= xmalloc (size
+ 2);
623 f
= fopen (filename
, FOPEN_RT
);
625 fatal (_("cannot open '%s': %s"), filename
, strerror (errno
));
627 if (fread (buffer
, 1, size
, f
) == 0 || ferror (f
))
628 fatal (_("%s: fread failed"), filename
);
631 buffer
[size
] = '\n';
632 buffer
[size
+ 1] = '\0';
636 for (line
= buffer
; * line
!= '\0'; line
++)
641 int finished
= FALSE
;
643 for (eol
= line
;; eol
++)
649 /* Cope with \n\r. */
657 /* Cope with \r\n. */
668 /* Line comment, Terminate the line here, in case a
669 name is present and then allow the rest of the
670 loop to find the real end of the line. */
682 /* A name may now exist somewhere between 'line' and 'eol'.
683 Strip off leading whitespace and trailing whitespace,
684 then add it to the list. */
685 for (name
= line
; IS_WHITESPACE (* name
); name
++)
687 for (name_end
= name
;
688 (! IS_WHITESPACE (* name_end
))
689 && (! IS_LINE_TERMINATOR (* name_end
));
693 if (! IS_LINE_TERMINATOR (* name_end
))
697 for (extra
= name_end
+ 1; IS_WHITESPACE (* extra
); extra
++)
700 if (! IS_LINE_TERMINATOR (* extra
))
701 non_fatal (_("Ignoring rubbish found on line %d of %s"),
702 line_count
, filename
);
708 add_specific_symbol (name
, list
);
710 /* Advance line pointer to end of line. The 'eol ++' in the for
711 loop above will then advance us to the start of the next line. */
717 /* See whether a symbol should be stripped or kept based on
718 strip_specific_list and keep_symbols. */
721 is_specified_symbol (const char *name
, struct symlist
*list
)
723 struct symlist
*tmp_list
;
727 for (tmp_list
= list
; tmp_list
; tmp_list
= tmp_list
->next
)
728 if (*(tmp_list
->name
) != '!')
730 if (!fnmatch (tmp_list
->name
, name
, 0))
735 if (fnmatch (tmp_list
->name
+ 1, name
, 0))
741 for (tmp_list
= list
; tmp_list
; tmp_list
= tmp_list
->next
)
742 if (strcmp (name
, tmp_list
->name
) == 0)
749 /* See if a section is being removed. */
752 is_strip_section (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
)
754 if (sections_removed
|| sections_copied
)
756 struct section_list
*p
;
758 p
= find_section_list (bfd_get_section_name (abfd
, sec
), FALSE
);
760 if (sections_removed
&& p
!= NULL
&& p
->remove
)
762 if (sections_copied
&& (p
== NULL
|| ! p
->copy
))
766 if ((bfd_get_section_flags (abfd
, sec
) & SEC_DEBUGGING
) != 0)
768 if (strip_symbols
== STRIP_DEBUG
769 || strip_symbols
== STRIP_UNNEEDED
770 || strip_symbols
== STRIP_ALL
771 || discard_locals
== LOCALS_ALL
772 || convert_debugging
)
775 if (strip_symbols
== STRIP_NONDEBUG
)
779 return strip_symbols
== STRIP_NONDEBUG
? TRUE
: FALSE
;
782 /* Choose which symbol entries to copy; put the result in OSYMS.
783 We don't copy in place, because that confuses the relocs.
784 Return the number of symbols to print. */
787 filter_symbols (bfd
*abfd
, bfd
*obfd
, asymbol
**osyms
,
788 asymbol
**isyms
, long symcount
)
790 asymbol
**from
= isyms
, **to
= osyms
;
791 long src_count
= 0, dst_count
= 0;
792 int relocatable
= (abfd
->flags
& (HAS_RELOC
| EXEC_P
| DYNAMIC
))
795 for (; src_count
< symcount
; src_count
++)
797 asymbol
*sym
= from
[src_count
];
798 flagword flags
= sym
->flags
;
799 char *name
= (char *) bfd_asymbol_name (sym
);
801 bfd_boolean undefined
;
802 bfd_boolean rem_leading_char
;
803 bfd_boolean add_leading_char
;
805 undefined
= bfd_is_und_section (bfd_get_section (sym
));
807 if (redefine_sym_list
)
809 char *old_name
, *new_name
;
811 old_name
= (char *) bfd_asymbol_name (sym
);
812 new_name
= (char *) lookup_sym_redefinition (old_name
);
813 bfd_asymbol_name (sym
) = new_name
;
817 /* Check if we will remove the current leading character. */
819 (name
[0] == bfd_get_symbol_leading_char (abfd
))
820 && (change_leading_char
821 || (remove_leading_char
822 && ((flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0
824 || bfd_is_com_section (bfd_get_section (sym
)))));
826 /* Check if we will add a new leading character. */
829 && (bfd_get_symbol_leading_char (obfd
) != '\0')
830 && (bfd_get_symbol_leading_char (abfd
) == '\0'
831 || (name
[0] == bfd_get_symbol_leading_char (abfd
)));
833 /* Short circuit for change_leading_char if we can do it in-place. */
834 if (rem_leading_char
&& add_leading_char
&& !prefix_symbols_string
)
836 name
[0] = bfd_get_symbol_leading_char (obfd
);
837 bfd_asymbol_name (sym
) = name
;
838 rem_leading_char
= FALSE
;
839 add_leading_char
= FALSE
;
842 /* Remove leading char. */
843 if (rem_leading_char
)
844 bfd_asymbol_name (sym
) = ++name
;
846 /* Add new leading char and/or prefix. */
847 if (add_leading_char
|| prefix_symbols_string
)
851 ptr
= n
= xmalloc (1 + strlen (prefix_symbols_string
)
852 + strlen (name
) + 1);
853 if (add_leading_char
)
854 *ptr
++ = bfd_get_symbol_leading_char (obfd
);
856 if (prefix_symbols_string
)
858 strcpy (ptr
, prefix_symbols_string
);
859 ptr
+= strlen (prefix_symbols_string
);
863 bfd_asymbol_name (sym
) = n
;
867 if (strip_symbols
== STRIP_ALL
)
869 else if ((flags
& BSF_KEEP
) != 0 /* Used in relocation. */
870 || ((flags
& BSF_SECTION_SYM
) != 0
871 && ((*bfd_get_section (sym
)->symbol_ptr_ptr
)->flags
874 else if (relocatable
/* Relocatable file. */
875 && (flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0)
877 else if (bfd_decode_symclass (sym
) == 'I')
878 /* Global symbols in $idata sections need to be retained
879 even if relocatable is FALSE. External users of the
880 library containing the $idata section may reference these
883 else if ((flags
& BSF_GLOBAL
) != 0 /* Global symbol. */
884 || (flags
& BSF_WEAK
) != 0
886 || bfd_is_com_section (bfd_get_section (sym
)))
887 keep
= strip_symbols
!= STRIP_UNNEEDED
;
888 else if ((flags
& BSF_DEBUGGING
) != 0) /* Debugging symbol. */
889 keep
= (strip_symbols
!= STRIP_DEBUG
890 && strip_symbols
!= STRIP_UNNEEDED
891 && ! convert_debugging
);
892 else if (bfd_get_section (sym
)->comdat
)
893 /* COMDAT sections store special information in local
894 symbols, so we cannot risk stripping any of them. */
896 else /* Local symbol. */
897 keep
= (strip_symbols
!= STRIP_UNNEEDED
898 && (discard_locals
!= LOCALS_ALL
899 && (discard_locals
!= LOCALS_START_L
900 || ! bfd_is_local_label (abfd
, sym
))));
902 if (keep
&& is_specified_symbol (name
, strip_specific_list
))
904 if (!keep
&& is_specified_symbol (name
, keep_specific_list
))
906 if (keep
&& is_strip_section (abfd
, bfd_get_section (sym
)))
909 if (keep
&& (flags
& BSF_GLOBAL
) != 0
910 && (weaken
|| is_specified_symbol (name
, weaken_specific_list
)))
912 sym
->flags
&=~ BSF_GLOBAL
;
913 sym
->flags
|= BSF_WEAK
;
915 if (keep
&& !undefined
&& (flags
& (BSF_GLOBAL
| BSF_WEAK
))
916 && (is_specified_symbol (name
, localize_specific_list
)
917 || (keepglobal_specific_list
!= NULL
918 && ! is_specified_symbol (name
, keepglobal_specific_list
))))
920 sym
->flags
&= ~(BSF_GLOBAL
| BSF_WEAK
);
921 sym
->flags
|= BSF_LOCAL
;
925 to
[dst_count
++] = sym
;
928 to
[dst_count
] = NULL
;
933 /* Find the redefined name of symbol SOURCE. */
936 lookup_sym_redefinition (const char *source
)
938 struct redefine_node
*list
;
940 for (list
= redefine_sym_list
; list
!= NULL
; list
= list
->next
)
941 if (strcmp (source
, list
->source
) == 0)
947 /* Add a node to a symbol redefine list. */
950 redefine_list_append (const char *cause
, const char *source
, const char *target
)
952 struct redefine_node
**p
;
953 struct redefine_node
*list
;
954 struct redefine_node
*new_node
;
956 for (p
= &redefine_sym_list
; (list
= *p
) != NULL
; p
= &list
->next
)
958 if (strcmp (source
, list
->source
) == 0)
959 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
962 if (strcmp (target
, list
->target
) == 0)
963 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
967 new_node
= xmalloc (sizeof (struct redefine_node
));
969 new_node
->source
= strdup (source
);
970 new_node
->target
= strdup (target
);
971 new_node
->next
= NULL
;
976 /* Handle the --redefine-syms option. Read lines containing "old new"
977 from the file, and add them to the symbol redefine list. */
980 add_redefine_syms_file (const char *filename
)
989 file
= fopen (filename
, "r");
991 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
992 filename
, strerror (errno
));
995 buf
= xmalloc (bufsize
);
1003 /* Collect the input symbol name. */
1004 while (! IS_WHITESPACE (c
) && ! IS_LINE_TERMINATOR (c
) && c
!= EOF
)
1012 buf
= xrealloc (buf
, bufsize
);
1020 /* Eat white space between the symbol names. */
1021 while (IS_WHITESPACE (c
))
1023 if (c
== '#' || IS_LINE_TERMINATOR (c
))
1028 /* Collect the output symbol name. */
1030 while (! IS_WHITESPACE (c
) && ! IS_LINE_TERMINATOR (c
) && c
!= EOF
)
1038 buf
= xrealloc (buf
, bufsize
);
1046 /* Eat white space at end of line. */
1047 while (! IS_LINE_TERMINATOR(c
) && c
!= EOF
&& IS_WHITESPACE (c
))
1052 if ((c
== '\r' && (c
= getc (file
)) == '\n')
1053 || c
== '\n' || c
== EOF
)
1056 /* Append the redefinition to the list. */
1058 redefine_list_append (filename
, &buf
[0], &buf
[outsym_off
]);
1069 fatal (_("%s: garbage at end of line %d"), filename
, lineno
);
1071 if (len
!= 0 && (outsym_off
== 0 || outsym_off
== len
))
1072 fatal (_("%s: missing new symbol name at line %d"), filename
, lineno
);
1075 /* Eat the rest of the line and finish it. */
1076 while (c
!= '\n' && c
!= EOF
)
1082 fatal (_("%s: premature end of file at line %d"), filename
, lineno
);
1087 /* Copy object file IBFD onto OBFD. */
1090 copy_object (bfd
*ibfd
, bfd
*obfd
)
1094 asection
**osections
= NULL
;
1095 asection
*gnu_debuglink_section
= NULL
;
1096 bfd_size_type
*gaps
= NULL
;
1097 bfd_size_type max_gap
= 0;
1100 enum bfd_architecture iarch
;
1103 if (ibfd
->xvec
->byteorder
!= obfd
->xvec
->byteorder
1104 && ibfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
1105 && obfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
1107 fatal (_("Unable to change endianness of input file(s)"));
1111 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1112 RETURN_NONFATAL (bfd_get_filename (obfd
));
1115 printf (_("copy from %s(%s) to %s(%s)\n"),
1116 bfd_get_filename (ibfd
), bfd_get_target (ibfd
),
1117 bfd_get_filename (obfd
), bfd_get_target (obfd
));
1122 start
= bfd_get_start_address (ibfd
);
1123 start
+= change_start
;
1125 /* Neither the start address nor the flags
1126 need to be set for a core file. */
1127 if (bfd_get_format (obfd
) != bfd_core
)
1131 flags
= bfd_get_file_flags (ibfd
);
1132 flags
|= bfd_flags_to_set
;
1133 flags
&= ~bfd_flags_to_clear
;
1134 flags
&= bfd_applicable_file_flags (obfd
);
1136 if (!bfd_set_start_address (obfd
, start
)
1137 || !bfd_set_file_flags (obfd
, flags
))
1138 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1141 /* Copy architecture of input file to output file. */
1142 iarch
= bfd_get_arch (ibfd
);
1143 imach
= bfd_get_mach (ibfd
);
1144 if (!bfd_set_arch_mach (obfd
, iarch
, imach
)
1145 && (ibfd
->target_defaulted
1146 || bfd_get_arch (ibfd
) != bfd_get_arch (obfd
)))
1148 if (bfd_get_arch (ibfd
) == bfd_arch_unknown
)
1149 fatal (_("Unable to recognise the format of the input file %s"),
1150 bfd_get_filename (ibfd
));
1153 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1154 bfd_printable_arch_mach (bfd_get_arch (ibfd
),
1155 bfd_get_mach (ibfd
)));
1161 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1162 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1167 if (osympp
!= isympp
)
1170 /* BFD mandates that all output sections be created and sizes set before
1171 any output is done. Thus, we traverse all sections multiple times. */
1172 bfd_map_over_sections (ibfd
, setup_section
, obfd
);
1174 if (add_sections
!= NULL
)
1176 struct section_add
*padd
;
1177 struct section_list
*pset
;
1179 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1183 padd
->section
= bfd_make_section (obfd
, padd
->name
);
1184 if (padd
->section
== NULL
)
1186 non_fatal (_("can't create section `%s': %s"),
1187 padd
->name
, bfd_errmsg (bfd_get_error ()));
1192 if (! bfd_set_section_size (obfd
, padd
->section
, padd
->size
))
1193 RETURN_NONFATAL (bfd_get_filename (obfd
));
1195 pset
= find_section_list (padd
->name
, FALSE
);
1199 if (pset
!= NULL
&& pset
->set_flags
)
1200 flags
= pset
->flags
| SEC_HAS_CONTENTS
;
1202 flags
= SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_DATA
;
1204 if (! bfd_set_section_flags (obfd
, padd
->section
, flags
))
1205 RETURN_NONFATAL (bfd_get_filename (obfd
));
1209 if (pset
->change_vma
!= CHANGE_IGNORE
)
1210 if (! bfd_set_section_vma (obfd
, padd
->section
,
1212 RETURN_NONFATAL (bfd_get_filename (obfd
));
1214 if (pset
->change_lma
!= CHANGE_IGNORE
)
1216 padd
->section
->lma
= pset
->lma_val
;
1218 if (! bfd_set_section_alignment
1219 (obfd
, padd
->section
,
1220 bfd_section_alignment (obfd
, padd
->section
)))
1221 RETURN_NONFATAL (bfd_get_filename (obfd
));
1227 if (gnu_debuglink_filename
!= NULL
)
1229 gnu_debuglink_section
= bfd_create_gnu_debuglink_section
1230 (obfd
, gnu_debuglink_filename
);
1232 if (gnu_debuglink_section
== NULL
)
1233 RETURN_NONFATAL (gnu_debuglink_filename
);
1236 if (gap_fill_set
|| pad_to_set
)
1241 /* We must fill in gaps between the sections and/or we must pad
1242 the last section to a specified address. We do this by
1243 grabbing a list of the sections, sorting them by VMA, and
1244 increasing the section sizes as required to fill the gaps.
1245 We write out the gap contents below. */
1247 c
= bfd_count_sections (obfd
);
1248 osections
= xmalloc (c
* sizeof (asection
*));
1250 bfd_map_over_sections (obfd
, get_sections
, &set
);
1252 qsort (osections
, c
, sizeof (asection
*), compare_section_lma
);
1254 gaps
= xmalloc (c
* sizeof (bfd_size_type
));
1255 memset (gaps
, 0, c
* sizeof (bfd_size_type
));
1259 for (i
= 0; i
< c
- 1; i
++)
1263 bfd_vma gap_start
, gap_stop
;
1265 flags
= bfd_get_section_flags (obfd
, osections
[i
]);
1266 if ((flags
& SEC_HAS_CONTENTS
) == 0
1267 || (flags
& SEC_LOAD
) == 0)
1270 size
= bfd_section_size (obfd
, osections
[i
]);
1271 gap_start
= bfd_section_lma (obfd
, osections
[i
]) + size
;
1272 gap_stop
= bfd_section_lma (obfd
, osections
[i
+ 1]);
1273 if (gap_start
< gap_stop
)
1275 if (! bfd_set_section_size (obfd
, osections
[i
],
1276 size
+ (gap_stop
- gap_start
)))
1278 non_fatal (_("Can't fill gap after %s: %s"),
1279 bfd_get_section_name (obfd
, osections
[i
]),
1280 bfd_errmsg (bfd_get_error ()));
1284 gaps
[i
] = gap_stop
- gap_start
;
1285 if (max_gap
< gap_stop
- gap_start
)
1286 max_gap
= gap_stop
- gap_start
;
1296 lma
= bfd_section_lma (obfd
, osections
[c
- 1]);
1297 size
= bfd_section_size (obfd
, osections
[c
- 1]);
1298 if (lma
+ size
< pad_to
)
1300 if (! bfd_set_section_size (obfd
, osections
[c
- 1],
1303 non_fatal (_("Can't add padding to %s: %s"),
1304 bfd_get_section_name (obfd
, osections
[c
- 1]),
1305 bfd_errmsg (bfd_get_error ()));
1310 gaps
[c
- 1] = pad_to
- (lma
+ size
);
1311 if (max_gap
< pad_to
- (lma
+ size
))
1312 max_gap
= pad_to
- (lma
+ size
);
1318 /* Symbol filtering must happen after the output sections
1319 have been created, but before their contents are set. */
1321 symsize
= bfd_get_symtab_upper_bound (ibfd
);
1323 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1325 osympp
= isympp
= xmalloc (symsize
);
1326 symcount
= bfd_canonicalize_symtab (ibfd
, isympp
);
1328 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1330 if (convert_debugging
)
1331 dhandle
= read_debugging_info (ibfd
, isympp
, symcount
);
1333 if (strip_symbols
== STRIP_DEBUG
1334 || strip_symbols
== STRIP_ALL
1335 || strip_symbols
== STRIP_UNNEEDED
1336 || strip_symbols
== STRIP_NONDEBUG
1337 || discard_locals
!= LOCALS_UNDEF
1338 || strip_specific_list
!= NULL
1339 || keep_specific_list
!= NULL
1340 || localize_specific_list
!= NULL
1341 || keepglobal_specific_list
!= NULL
1342 || weaken_specific_list
!= NULL
1343 || prefix_symbols_string
1346 || convert_debugging
1347 || change_leading_char
1348 || remove_leading_char
1349 || redefine_sym_list
1352 /* Mark symbols used in output relocations so that they
1353 are kept, even if they are local labels or static symbols.
1355 Note we iterate over the input sections examining their
1356 relocations since the relocations for the output sections
1357 haven't been set yet. mark_symbols_used_in_relocations will
1358 ignore input sections which have no corresponding output
1360 if (strip_symbols
!= STRIP_ALL
)
1361 bfd_map_over_sections (ibfd
,
1362 mark_symbols_used_in_relocations
,
1364 osympp
= xmalloc ((symcount
+ 1) * sizeof (asymbol
*));
1365 symcount
= filter_symbols (ibfd
, obfd
, osympp
, isympp
, symcount
);
1368 if (convert_debugging
&& dhandle
!= NULL
)
1370 if (! write_debugging_info (obfd
, dhandle
, &symcount
, &osympp
))
1377 bfd_set_symtab (obfd
, osympp
, symcount
);
1379 /* This has to happen after the symbol table has been set. */
1380 bfd_map_over_sections (ibfd
, copy_section
, obfd
);
1382 if (add_sections
!= NULL
)
1384 struct section_add
*padd
;
1386 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1388 if (! bfd_set_section_contents (obfd
, padd
->section
, padd
->contents
,
1390 RETURN_NONFATAL (bfd_get_filename (obfd
));
1394 if (gnu_debuglink_filename
!= NULL
)
1396 if (! bfd_fill_in_gnu_debuglink_section
1397 (obfd
, gnu_debuglink_section
, gnu_debuglink_filename
))
1398 RETURN_NONFATAL (gnu_debuglink_filename
);
1401 if (gap_fill_set
|| pad_to_set
)
1406 /* Fill in the gaps. */
1409 buf
= xmalloc (max_gap
);
1410 memset (buf
, gap_fill
, max_gap
);
1412 c
= bfd_count_sections (obfd
);
1413 for (i
= 0; i
< c
; i
++)
1421 off
= bfd_section_size (obfd
, osections
[i
]) - left
;
1432 if (! bfd_set_section_contents (obfd
, osections
[i
], buf
,
1434 RETURN_NONFATAL (bfd_get_filename (obfd
));
1443 /* Allow the BFD backend to copy any private data it understands
1444 from the input BFD to the output BFD. This is done last to
1445 permit the routine to look at the filtered symbol table, which is
1446 important for the ECOFF code at least. */
1447 if (bfd_get_flavour (ibfd
) == bfd_target_elf_flavour
1448 && strip_symbols
== STRIP_NONDEBUG
)
1449 /* Do not copy the private data when creating an ELF format
1450 debug info file. We do not want the program headers. */
1452 else if (! bfd_copy_private_bfd_data (ibfd
, obfd
))
1454 non_fatal (_("%s: error copying private BFD data: %s"),
1455 bfd_get_filename (obfd
),
1456 bfd_errmsg (bfd_get_error ()));
1461 /* Switch to the alternate machine code. We have to do this at the
1462 very end, because we only initialize the header when we create
1463 the first section. */
1464 if (use_alt_mach_code
!= 0)
1466 if (!bfd_alt_mach_code (obfd
, use_alt_mach_code
))
1467 non_fatal (_("unknown alternate machine code, ignored"));
1472 #if defined (_WIN32) && !defined (__CYGWIN32__)
1473 #define MKDIR(DIR, MODE) mkdir (DIR)
1475 #define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1478 /* Read each archive element in turn from IBFD, copy the
1479 contents to temp file, and keep the temp file handle. */
1482 copy_archive (bfd
*ibfd
, bfd
*obfd
, const char *output_target
)
1486 struct name_list
*next
;
1490 bfd
**ptr
= &obfd
->archive_head
;
1492 char *dir
= make_tempname (bfd_get_filename (obfd
));
1494 /* Make a temp directory to hold the contents. */
1495 if (MKDIR (dir
, 0700) != 0)
1496 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1497 dir
, strerror (errno
));
1499 obfd
->has_armap
= ibfd
->has_armap
;
1503 this_element
= bfd_openr_next_archived_file (ibfd
, NULL
);
1505 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1506 RETURN_NONFATAL (bfd_get_filename (obfd
));
1508 while (!status
&& this_element
!= NULL
)
1514 int stat_status
= 0;
1516 /* Create an output file for this member. */
1517 output_name
= concat (dir
, "/",
1518 bfd_get_filename (this_element
), (char *) 0);
1520 /* If the file already exists, make another temp dir. */
1521 if (stat (output_name
, &buf
) >= 0)
1523 output_name
= make_tempname (output_name
);
1524 if (MKDIR (output_name
, 0700) != 0)
1525 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1526 output_name
, strerror (errno
));
1528 l
= xmalloc (sizeof (struct name_list
));
1529 l
->name
= output_name
;
1533 output_name
= concat (output_name
, "/",
1534 bfd_get_filename (this_element
), (char *) 0);
1537 output_bfd
= bfd_openw (output_name
, output_target
);
1540 stat_status
= bfd_stat_arch_elt (this_element
, &buf
);
1542 if (stat_status
!= 0)
1543 non_fatal (_("internal stat error on %s"),
1544 bfd_get_filename (this_element
));
1547 l
= xmalloc (sizeof (struct name_list
));
1548 l
->name
= output_name
;
1552 if (output_bfd
== NULL
)
1553 RETURN_NONFATAL (output_name
);
1555 if (bfd_check_format (this_element
, bfd_object
))
1556 copy_object (this_element
, output_bfd
);
1558 if (!bfd_close (output_bfd
))
1560 bfd_nonfatal (bfd_get_filename (output_bfd
));
1561 /* Error in new object file. Don't change archive. */
1565 if (preserve_dates
&& stat_status
== 0)
1566 set_times (output_name
, &buf
);
1568 /* Open the newly output file and attach to our list. */
1569 output_bfd
= bfd_openr (output_name
, output_target
);
1571 l
->obfd
= output_bfd
;
1574 ptr
= &output_bfd
->next
;
1576 last_element
= this_element
;
1578 this_element
= bfd_openr_next_archived_file (ibfd
, last_element
);
1580 bfd_close (last_element
);
1584 if (!bfd_close (obfd
))
1585 RETURN_NONFATAL (bfd_get_filename (obfd
));
1587 if (!bfd_close (ibfd
))
1588 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1590 /* Delete all the files that we opened. */
1591 for (l
= list
; l
!= NULL
; l
= l
->next
)
1593 if (l
->obfd
== NULL
)
1597 bfd_close (l
->obfd
);
1604 /* The top-level control. */
1607 copy_file (const char *input_filename
, const char *output_filename
,
1608 const char *input_target
, const char *output_target
)
1611 char **obj_matching
;
1612 char **core_matching
;
1614 if (get_file_size (input_filename
) < 1)
1620 /* To allow us to do "strip *" without dying on the first
1621 non-object file, failures are nonfatal. */
1622 ibfd
= bfd_openr (input_filename
, input_target
);
1624 RETURN_NONFATAL (input_filename
);
1626 if (bfd_check_format (ibfd
, bfd_archive
))
1630 /* bfd_get_target does not return the correct value until
1631 bfd_check_format succeeds. */
1632 if (output_target
== NULL
)
1633 output_target
= bfd_get_target (ibfd
);
1635 obfd
= bfd_openw (output_filename
, output_target
);
1637 RETURN_NONFATAL (output_filename
);
1639 copy_archive (ibfd
, obfd
, output_target
);
1641 else if (bfd_check_format_matches (ibfd
, bfd_object
, &obj_matching
))
1645 /* bfd_get_target does not return the correct value until
1646 bfd_check_format succeeds. */
1647 if (output_target
== NULL
)
1648 output_target
= bfd_get_target (ibfd
);
1650 obfd
= bfd_openw (output_filename
, output_target
);
1652 RETURN_NONFATAL (output_filename
);
1654 copy_object (ibfd
, obfd
);
1656 if (!bfd_close (obfd
))
1657 RETURN_NONFATAL (output_filename
);
1659 if (!bfd_close (ibfd
))
1660 RETURN_NONFATAL (input_filename
);
1664 bfd_error_type obj_error
= bfd_get_error ();
1665 bfd_error_type core_error
;
1667 if (bfd_check_format_matches (ibfd
, bfd_core
, &core_matching
))
1669 /* This probably can't happen.. */
1670 if (obj_error
== bfd_error_file_ambiguously_recognized
)
1671 free (obj_matching
);
1675 core_error
= bfd_get_error ();
1676 /* Report the object error in preference to the core error. */
1677 if (obj_error
!= core_error
)
1678 bfd_set_error (obj_error
);
1680 bfd_nonfatal (input_filename
);
1682 if (obj_error
== bfd_error_file_ambiguously_recognized
)
1684 list_matching_formats (obj_matching
);
1685 free (obj_matching
);
1687 if (core_error
== bfd_error_file_ambiguously_recognized
)
1689 list_matching_formats (core_matching
);
1690 free (core_matching
);
1697 /* Add a name to the section renaming list. */
1700 add_section_rename (const char * old_name
, const char * new_name
,
1703 section_rename
* rename
;
1705 /* Check for conflicts first. */
1706 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1707 if (strcmp (rename
->old_name
, old_name
) == 0)
1709 /* Silently ignore duplicate definitions. */
1710 if (strcmp (rename
->new_name
, new_name
) == 0
1711 && rename
->flags
== flags
)
1714 fatal (_("Multiple renames of section %s"), old_name
);
1717 rename
= xmalloc (sizeof (* rename
));
1719 rename
->old_name
= old_name
;
1720 rename
->new_name
= new_name
;
1721 rename
->flags
= flags
;
1722 rename
->next
= section_rename_list
;
1724 section_rename_list
= rename
;
1727 /* Check the section rename list for a new name of the input section
1728 ISECTION. Return the new name if one is found.
1729 Also set RETURNED_FLAGS to the flags to be used for this section. */
1732 find_section_rename (bfd
* ibfd ATTRIBUTE_UNUSED
, sec_ptr isection
,
1733 flagword
* returned_flags
)
1735 const char * old_name
= bfd_section_name (ibfd
, isection
);
1736 section_rename
* rename
;
1738 /* Default to using the flags of the input section. */
1739 * returned_flags
= bfd_get_section_flags (ibfd
, isection
);
1741 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1742 if (strcmp (rename
->old_name
, old_name
) == 0)
1744 if (rename
->flags
!= (flagword
) -1)
1745 * returned_flags
= rename
->flags
;
1747 return rename
->new_name
;
1753 /* Create a section in OBFD with the same
1754 name and attributes as ISECTION in IBFD. */
1757 setup_section (bfd
*ibfd
, sec_ptr isection
, void *obfdarg
)
1759 bfd
*obfd
= obfdarg
;
1760 struct section_list
*p
;
1768 char *prefix
= NULL
;
1770 if (is_strip_section (ibfd
, isection
))
1773 p
= find_section_list (bfd_section_name (ibfd
, isection
), FALSE
);
1777 /* Get the, possibly new, name of the output section. */
1778 name
= find_section_rename (ibfd
, isection
, & flags
);
1780 /* Prefix sections. */
1781 if ((prefix_alloc_sections_string
)
1782 && (bfd_get_section_flags (ibfd
, isection
) & SEC_ALLOC
))
1783 prefix
= prefix_alloc_sections_string
;
1784 else if (prefix_sections_string
)
1785 prefix
= prefix_sections_string
;
1791 n
= xmalloc (strlen (prefix
) + strlen (name
) + 1);
1797 osection
= bfd_make_section_anyway (obfd
, name
);
1799 if (osection
== NULL
)
1805 size
= bfd_section_size (ibfd
, isection
);
1807 size
= (size
+ interleave
- 1) / interleave
;
1808 if (! bfd_set_section_size (obfd
, osection
, size
))
1814 vma
= bfd_section_vma (ibfd
, isection
);
1815 if (p
!= NULL
&& p
->change_vma
== CHANGE_MODIFY
)
1817 else if (p
!= NULL
&& p
->change_vma
== CHANGE_SET
)
1820 vma
+= change_section_address
;
1822 if (! bfd_set_section_vma (obfd
, osection
, vma
))
1828 lma
= isection
->lma
;
1829 if ((p
!= NULL
) && p
->change_lma
!= CHANGE_IGNORE
)
1831 if (p
->change_lma
== CHANGE_MODIFY
)
1833 else if (p
->change_lma
== CHANGE_SET
)
1839 lma
+= change_section_address
;
1841 osection
->lma
= lma
;
1843 /* FIXME: This is probably not enough. If we change the LMA we
1844 may have to recompute the header for the file as well. */
1845 if (!bfd_set_section_alignment (obfd
,
1847 bfd_section_alignment (ibfd
, isection
)))
1849 err
= _("alignment");
1853 if (p
!= NULL
&& p
->set_flags
)
1854 flags
= p
->flags
| (flags
& (SEC_HAS_CONTENTS
| SEC_RELOC
));
1855 if (!bfd_set_section_flags (obfd
, osection
, flags
))
1861 /* Copy merge entity size. */
1862 osection
->entsize
= isection
->entsize
;
1864 /* This used to be mangle_section; we do here to avoid using
1865 bfd_get_section_by_name since some formats allow multiple
1866 sections with the same name. */
1867 isection
->output_section
= osection
;
1868 isection
->output_offset
= 0;
1870 /* Allow the BFD backend to copy any private data it understands
1871 from the input section to the output section. */
1872 if (bfd_get_flavour (ibfd
) == bfd_target_elf_flavour
1873 && strip_symbols
== STRIP_NONDEBUG
)
1874 /* Do not copy the private data when creating an ELF format
1875 debug info file. We do not want the program headers. */
1877 else if (!bfd_copy_private_section_data (ibfd
, isection
, obfd
, osection
))
1879 err
= _("private data");
1883 /* All went well. */
1887 non_fatal (_("%s: section `%s': error in %s: %s"),
1888 bfd_get_filename (ibfd
),
1889 bfd_section_name (ibfd
, isection
),
1890 err
, bfd_errmsg (bfd_get_error ()));
1894 /* Copy the data of input section ISECTION of IBFD
1895 to an output section with the same name in OBFD.
1896 If stripping then don't copy any relocation info. */
1899 copy_section (bfd
*ibfd
, sec_ptr isection
, void *obfdarg
)
1901 bfd
*obfd
= obfdarg
;
1902 struct section_list
*p
;
1910 /* If we have already failed earlier on,
1911 do not keep on generating complaints now. */
1915 if (is_strip_section (ibfd
, isection
))
1918 flags
= bfd_get_section_flags (ibfd
, isection
);
1919 if ((flags
& SEC_GROUP
) != 0)
1922 osection
= isection
->output_section
;
1923 size
= bfd_get_section_size_before_reloc (isection
);
1925 if (size
== 0 || osection
== 0)
1928 p
= find_section_list (bfd_get_section_name (ibfd
, isection
), FALSE
);
1930 /* Core files do not need to be relocated. */
1931 if (bfd_get_format (obfd
) == bfd_core
)
1935 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1939 /* Do not complain if the target does not support relocations. */
1940 if (relsize
== -1 && bfd_get_error () == bfd_error_invalid_operation
)
1943 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1948 bfd_set_reloc (obfd
, osection
, NULL
, 0);
1951 relpp
= xmalloc (relsize
);
1952 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
1954 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1956 if (strip_symbols
== STRIP_ALL
)
1958 /* Remove relocations which are not in
1959 keep_strip_specific_list. */
1960 arelent
**temp_relpp
;
1961 long temp_relcount
= 0;
1964 temp_relpp
= xmalloc (relsize
);
1965 for (i
= 0; i
< relcount
; i
++)
1966 if (is_specified_symbol (bfd_asymbol_name (*relpp
[i
]->sym_ptr_ptr
),
1967 keep_specific_list
))
1968 temp_relpp
[temp_relcount
++] = relpp
[i
];
1969 relcount
= temp_relcount
;
1974 bfd_set_reloc (obfd
, osection
, relcount
== 0 ? NULL
: relpp
, relcount
);
1977 isection
->_cooked_size
= isection
->_raw_size
;
1978 isection
->reloc_done
= TRUE
;
1980 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
1981 && bfd_get_section_flags (obfd
, osection
) & SEC_HAS_CONTENTS
)
1983 void *memhunk
= xmalloc (size
);
1985 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, 0, size
))
1986 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1990 /* Keep only every `copy_byte'th byte in MEMHUNK. */
1991 char *from
= memhunk
+ copy_byte
;
1993 char *end
= memhunk
+ size
;
1995 for (; from
< end
; from
+= interleave
)
1998 size
= (size
+ interleave
- 1 - copy_byte
) / interleave
;
1999 osection
->lma
/= interleave
;
2002 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, 0, size
))
2003 RETURN_NONFATAL (bfd_get_filename (obfd
));
2007 else if (p
!= NULL
&& p
->set_flags
&& (p
->flags
& SEC_HAS_CONTENTS
) != 0)
2009 void *memhunk
= xmalloc (size
);
2011 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2012 flag--they can just remove the section entirely and add it
2013 back again. However, we do permit them to turn on the
2014 SEC_HAS_CONTENTS flag, and take it to mean that the section
2015 contents should be zeroed out. */
2017 memset (memhunk
, 0, size
);
2018 if (! bfd_set_section_contents (obfd
, osection
, memhunk
, 0, size
))
2019 RETURN_NONFATAL (bfd_get_filename (obfd
));
2024 /* Get all the sections. This is used when --gap-fill or --pad-to is
2028 get_sections (bfd
*obfd ATTRIBUTE_UNUSED
, asection
*osection
, void *secppparg
)
2030 asection
***secppp
= secppparg
;
2032 **secppp
= osection
;
2036 /* Sort sections by VMA. This is called via qsort, and is used when
2037 --gap-fill or --pad-to is used. We force non loadable or empty
2038 sections to the front, where they are easier to ignore. */
2041 compare_section_lma (const void *arg1
, const void *arg2
)
2043 const asection
*const *sec1
= arg1
;
2044 const asection
*const *sec2
= arg2
;
2045 flagword flags1
, flags2
;
2047 /* Sort non loadable sections to the front. */
2048 flags1
= (*sec1
)->flags
;
2049 flags2
= (*sec2
)->flags
;
2050 if ((flags1
& SEC_HAS_CONTENTS
) == 0
2051 || (flags1
& SEC_LOAD
) == 0)
2053 if ((flags2
& SEC_HAS_CONTENTS
) != 0
2054 && (flags2
& SEC_LOAD
) != 0)
2059 if ((flags2
& SEC_HAS_CONTENTS
) == 0
2060 || (flags2
& SEC_LOAD
) == 0)
2064 /* Sort sections by LMA. */
2065 if ((*sec1
)->lma
> (*sec2
)->lma
)
2067 else if ((*sec1
)->lma
< (*sec2
)->lma
)
2070 /* Sort sections with the same LMA by size. */
2071 if ((*sec1
)->_raw_size
> (*sec2
)->_raw_size
)
2073 else if ((*sec1
)->_raw_size
< (*sec2
)->_raw_size
)
2079 /* Mark all the symbols which will be used in output relocations with
2080 the BSF_KEEP flag so that those symbols will not be stripped.
2082 Ignore relocations which will not appear in the output file. */
2085 mark_symbols_used_in_relocations (bfd
*ibfd
, sec_ptr isection
, void *symbolsarg
)
2087 asymbol
**symbols
= symbolsarg
;
2092 /* Ignore an input section with no corresponding output section. */
2093 if (isection
->output_section
== NULL
)
2096 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
2099 /* Do not complain if the target does not support relocations. */
2100 if (relsize
== -1 && bfd_get_error () == bfd_error_invalid_operation
)
2102 bfd_fatal (bfd_get_filename (ibfd
));
2108 relpp
= xmalloc (relsize
);
2109 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, symbols
);
2111 bfd_fatal (bfd_get_filename (ibfd
));
2113 /* Examine each symbol used in a relocation. If it's not one of the
2114 special bfd section symbols, then mark it with BSF_KEEP. */
2115 for (i
= 0; i
< relcount
; i
++)
2117 if (*relpp
[i
]->sym_ptr_ptr
!= bfd_com_section_ptr
->symbol
2118 && *relpp
[i
]->sym_ptr_ptr
!= bfd_abs_section_ptr
->symbol
2119 && *relpp
[i
]->sym_ptr_ptr
!= bfd_und_section_ptr
->symbol
)
2120 (*relpp
[i
]->sym_ptr_ptr
)->flags
|= BSF_KEEP
;
2127 /* Write out debugging information. */
2130 write_debugging_info (bfd
*obfd
, void *dhandle
,
2131 long *symcountp ATTRIBUTE_UNUSED
,
2132 asymbol
***symppp ATTRIBUTE_UNUSED
)
2134 if (bfd_get_flavour (obfd
) == bfd_target_ieee_flavour
)
2135 return write_ieee_debugging_info (obfd
, dhandle
);
2137 if (bfd_get_flavour (obfd
) == bfd_target_coff_flavour
2138 || bfd_get_flavour (obfd
) == bfd_target_elf_flavour
)
2140 bfd_byte
*syms
, *strings
;
2141 bfd_size_type symsize
, stringsize
;
2142 asection
*stabsec
, *stabstrsec
;
2144 if (! write_stabs_in_sections_debugging_info (obfd
, dhandle
, &syms
,
2149 stabsec
= bfd_make_section (obfd
, ".stab");
2150 stabstrsec
= bfd_make_section (obfd
, ".stabstr");
2152 || stabstrsec
== NULL
2153 || ! bfd_set_section_size (obfd
, stabsec
, symsize
)
2154 || ! bfd_set_section_size (obfd
, stabstrsec
, stringsize
)
2155 || ! bfd_set_section_alignment (obfd
, stabsec
, 2)
2156 || ! bfd_set_section_alignment (obfd
, stabstrsec
, 0)
2157 || ! bfd_set_section_flags (obfd
, stabsec
,
2161 || ! bfd_set_section_flags (obfd
, stabstrsec
,
2166 non_fatal (_("%s: can't create debugging section: %s"),
2167 bfd_get_filename (obfd
),
2168 bfd_errmsg (bfd_get_error ()));
2172 /* We can get away with setting the section contents now because
2173 the next thing the caller is going to do is copy over the
2174 real sections. We may someday have to split the contents
2175 setting out of this function. */
2176 if (! bfd_set_section_contents (obfd
, stabsec
, syms
, 0, symsize
)
2177 || ! bfd_set_section_contents (obfd
, stabstrsec
, strings
, 0,
2180 non_fatal (_("%s: can't set debugging section contents: %s"),
2181 bfd_get_filename (obfd
),
2182 bfd_errmsg (bfd_get_error ()));
2189 non_fatal (_("%s: don't know how to write debugging information for %s"),
2190 bfd_get_filename (obfd
), bfd_get_target (obfd
));
2195 strip_main (int argc
, char *argv
[])
2197 char *input_target
= NULL
;
2198 char *output_target
= NULL
;
2199 bfd_boolean show_version
= FALSE
;
2200 bfd_boolean formats_info
= FALSE
;
2203 struct section_list
*p
;
2204 char *output_file
= NULL
;
2206 while ((c
= getopt_long (argc
, argv
, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2207 strip_options
, (int *) 0)) != EOF
)
2212 input_target
= optarg
;
2215 output_target
= optarg
;
2218 input_target
= output_target
= optarg
;
2221 p
= find_section_list (optarg
, TRUE
);
2223 sections_removed
= TRUE
;
2226 strip_symbols
= STRIP_ALL
;
2230 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2231 strip_symbols
= STRIP_DEBUG
;
2233 case OPTION_STRIP_UNNEEDED
:
2234 strip_symbols
= STRIP_UNNEEDED
;
2237 add_specific_symbol (optarg
, &keep_specific_list
);
2240 add_specific_symbol (optarg
, &strip_specific_list
);
2243 output_file
= optarg
;
2246 preserve_dates
= TRUE
;
2249 discard_locals
= LOCALS_ALL
;
2252 discard_locals
= LOCALS_START_L
;
2258 show_version
= TRUE
;
2260 case OPTION_FORMATS_INFO
:
2261 formats_info
= TRUE
;
2263 case OPTION_ONLY_KEEP_DEBUG
:
2264 strip_symbols
= STRIP_NONDEBUG
;
2267 /* We've been given a long option. */
2274 strip_usage (stdout
, 0);
2276 strip_usage (stderr
, 1);
2287 print_version ("strip");
2289 /* Default is to strip all symbols. */
2290 if (strip_symbols
== STRIP_UNDEF
2291 && discard_locals
== LOCALS_UNDEF
2292 && strip_specific_list
== NULL
)
2293 strip_symbols
= STRIP_ALL
;
2295 if (output_target
== NULL
)
2296 output_target
= input_target
;
2300 || (output_file
!= NULL
&& (i
+ 1) < argc
))
2301 strip_usage (stderr
, 1);
2303 for (; i
< argc
; i
++)
2305 int hold_status
= status
;
2306 struct stat statbuf
;
2309 if (get_file_size (argv
[i
]) < 1)
2313 /* No need to check the return value of stat().
2314 It has already been checked in get_file_size(). */
2315 stat (argv
[i
], &statbuf
);
2317 if (output_file
!= NULL
)
2318 tmpname
= output_file
;
2320 tmpname
= make_tempname (argv
[i
]);
2323 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
2327 set_times (tmpname
, &statbuf
);
2328 if (output_file
== NULL
)
2329 smart_rename (tmpname
, argv
[i
], preserve_dates
);
2330 status
= hold_status
;
2334 if (output_file
== NULL
)
2342 copy_main (int argc
, char *argv
[])
2344 char * binary_architecture
= NULL
;
2345 char *input_filename
= NULL
;
2346 char *output_filename
= NULL
;
2347 char *input_target
= NULL
;
2348 char *output_target
= NULL
;
2349 bfd_boolean show_version
= FALSE
;
2350 bfd_boolean change_warn
= TRUE
;
2351 bfd_boolean formats_info
= FALSE
;
2353 struct section_list
*p
;
2354 struct stat statbuf
;
2356 while ((c
= getopt_long (argc
, argv
, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2357 copy_options
, (int *) 0)) != EOF
)
2362 copy_byte
= atoi (optarg
);
2364 fatal (_("byte number must be non-negative"));
2368 binary_architecture
= optarg
;
2372 interleave
= atoi (optarg
);
2374 fatal (_("interleave must be positive"));
2378 case 's': /* "source" - 'I' is preferred */
2379 input_target
= optarg
;
2383 case 'd': /* "destination" - 'O' is preferred */
2384 output_target
= optarg
;
2388 input_target
= output_target
= optarg
;
2392 p
= find_section_list (optarg
, TRUE
);
2394 fatal (_("%s both copied and removed"), optarg
);
2396 sections_copied
= TRUE
;
2400 p
= find_section_list (optarg
, TRUE
);
2402 fatal (_("%s both copied and removed"), optarg
);
2404 sections_removed
= TRUE
;
2408 strip_symbols
= STRIP_ALL
;
2412 strip_symbols
= STRIP_DEBUG
;
2415 case OPTION_STRIP_UNNEEDED
:
2416 strip_symbols
= STRIP_UNNEEDED
;
2419 case OPTION_ONLY_KEEP_DEBUG
:
2420 strip_symbols
= STRIP_NONDEBUG
;
2423 case OPTION_ADD_GNU_DEBUGLINK
:
2424 gnu_debuglink_filename
= optarg
;
2428 add_specific_symbol (optarg
, &keep_specific_list
);
2432 add_specific_symbol (optarg
, &strip_specific_list
);
2436 add_specific_symbol (optarg
, &localize_specific_list
);
2440 add_specific_symbol (optarg
, &keepglobal_specific_list
);
2444 add_specific_symbol (optarg
, &weaken_specific_list
);
2448 preserve_dates
= TRUE
;
2456 discard_locals
= LOCALS_ALL
;
2460 discard_locals
= LOCALS_START_L
;
2468 show_version
= TRUE
;
2471 case OPTION_FORMATS_INFO
:
2472 formats_info
= TRUE
;
2479 case OPTION_ADD_SECTION
:
2483 struct section_add
*pa
;
2488 s
= strchr (optarg
, '=');
2491 fatal (_("bad format for %s"), "--add-section");
2493 size
= get_file_size (s
+ 1);
2497 pa
= xmalloc (sizeof (struct section_add
));
2500 name
= xmalloc (len
+ 1);
2501 strncpy (name
, optarg
, len
);
2505 pa
->filename
= s
+ 1;
2507 pa
->contents
= xmalloc (size
);
2509 f
= fopen (pa
->filename
, FOPEN_RB
);
2512 fatal (_("cannot open: %s: %s"),
2513 pa
->filename
, strerror (errno
));
2515 if (fread (pa
->contents
, 1, pa
->size
, f
) == 0
2517 fatal (_("%s: fread failed"), pa
->filename
);
2521 pa
->next
= add_sections
;
2526 case OPTION_CHANGE_START
:
2527 change_start
= parse_vma (optarg
, "--change-start");
2530 case OPTION_CHANGE_SECTION_ADDRESS
:
2531 case OPTION_CHANGE_SECTION_LMA
:
2532 case OPTION_CHANGE_SECTION_VMA
:
2537 char *option
= NULL
;
2539 enum change_action what
= CHANGE_IGNORE
;
2543 case OPTION_CHANGE_SECTION_ADDRESS
:
2544 option
= "--change-section-address";
2546 case OPTION_CHANGE_SECTION_LMA
:
2547 option
= "--change-section-lma";
2549 case OPTION_CHANGE_SECTION_VMA
:
2550 option
= "--change-section-vma";
2554 s
= strchr (optarg
, '=');
2557 s
= strchr (optarg
, '+');
2560 s
= strchr (optarg
, '-');
2562 fatal (_("bad format for %s"), option
);
2567 name
= xmalloc (len
+ 1);
2568 strncpy (name
, optarg
, len
);
2571 p
= find_section_list (name
, TRUE
);
2573 val
= parse_vma (s
+ 1, option
);
2577 case '=': what
= CHANGE_SET
; break;
2578 case '-': val
= - val
; /* Drop through. */
2579 case '+': what
= CHANGE_MODIFY
; break;
2584 case OPTION_CHANGE_SECTION_ADDRESS
:
2585 p
->change_vma
= what
;
2589 case OPTION_CHANGE_SECTION_LMA
:
2590 p
->change_lma
= what
;
2594 case OPTION_CHANGE_SECTION_VMA
:
2595 p
->change_vma
= what
;
2602 case OPTION_CHANGE_ADDRESSES
:
2603 change_section_address
= parse_vma (optarg
, "--change-addresses");
2604 change_start
= change_section_address
;
2607 case OPTION_CHANGE_WARNINGS
:
2611 case OPTION_CHANGE_LEADING_CHAR
:
2612 change_leading_char
= TRUE
;
2615 case OPTION_DEBUGGING
:
2616 convert_debugging
= TRUE
;
2619 case OPTION_GAP_FILL
:
2621 bfd_vma gap_fill_vma
;
2623 gap_fill_vma
= parse_vma (optarg
, "--gap-fill");
2624 gap_fill
= (bfd_byte
) gap_fill_vma
;
2625 if ((bfd_vma
) gap_fill
!= gap_fill_vma
)
2629 sprintf_vma (buff
, gap_fill_vma
);
2631 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2634 gap_fill_set
= TRUE
;
2638 case OPTION_NO_CHANGE_WARNINGS
:
2639 change_warn
= FALSE
;
2643 pad_to
= parse_vma (optarg
, "--pad-to");
2647 case OPTION_REMOVE_LEADING_CHAR
:
2648 remove_leading_char
= TRUE
;
2651 case OPTION_REDEFINE_SYM
:
2653 /* Push this redefinition onto redefine_symbol_list. */
2657 const char *nextarg
;
2658 char *source
, *target
;
2660 s
= strchr (optarg
, '=');
2662 fatal (_("bad format for %s"), "--redefine-sym");
2665 source
= xmalloc (len
+ 1);
2666 strncpy (source
, optarg
, len
);
2670 len
= strlen (nextarg
);
2671 target
= xmalloc (len
+ 1);
2672 strcpy (target
, nextarg
);
2674 redefine_list_append ("--redefine-sym", source
, target
);
2681 case OPTION_REDEFINE_SYMS
:
2682 add_redefine_syms_file (optarg
);
2685 case OPTION_SET_SECTION_FLAGS
:
2691 s
= strchr (optarg
, '=');
2693 fatal (_("bad format for %s"), "--set-section-flags");
2696 name
= xmalloc (len
+ 1);
2697 strncpy (name
, optarg
, len
);
2700 p
= find_section_list (name
, TRUE
);
2702 p
->set_flags
= TRUE
;
2703 p
->flags
= parse_flags (s
+ 1);
2707 case OPTION_RENAME_SECTION
:
2710 const char *eq
, *fl
;
2715 eq
= strchr (optarg
, '=');
2717 fatal (_("bad format for %s"), "--rename-section");
2721 fatal (_("bad format for %s"), "--rename-section");
2723 old_name
= xmalloc (len
+ 1);
2724 strncpy (old_name
, optarg
, len
);
2728 fl
= strchr (eq
, ',');
2731 flags
= parse_flags (fl
+ 1);
2741 fatal (_("bad format for %s"), "--rename-section");
2743 new_name
= xmalloc (len
+ 1);
2744 strncpy (new_name
, eq
, len
);
2747 add_section_rename (old_name
, new_name
, flags
);
2751 case OPTION_SET_START
:
2752 set_start
= parse_vma (optarg
, "--set-start");
2753 set_start_set
= TRUE
;
2756 case OPTION_SREC_LEN
:
2757 Chunk
= parse_vma (optarg
, "--srec-len");
2760 case OPTION_SREC_FORCES3
:
2764 case OPTION_STRIP_SYMBOLS
:
2765 add_specific_symbols (optarg
, &strip_specific_list
);
2768 case OPTION_KEEP_SYMBOLS
:
2769 add_specific_symbols (optarg
, &keep_specific_list
);
2772 case OPTION_LOCALIZE_SYMBOLS
:
2773 add_specific_symbols (optarg
, &localize_specific_list
);
2776 case OPTION_KEEPGLOBAL_SYMBOLS
:
2777 add_specific_symbols (optarg
, &keepglobal_specific_list
);
2780 case OPTION_WEAKEN_SYMBOLS
:
2781 add_specific_symbols (optarg
, &weaken_specific_list
);
2784 case OPTION_ALT_MACH_CODE
:
2785 use_alt_mach_code
= atoi (optarg
);
2786 if (use_alt_mach_code
<= 0)
2787 fatal (_("alternate machine code index must be positive"));
2790 case OPTION_PREFIX_SYMBOLS
:
2791 prefix_symbols_string
= optarg
;
2794 case OPTION_PREFIX_SECTIONS
:
2795 prefix_sections_string
= optarg
;
2798 case OPTION_PREFIX_ALLOC_SECTIONS
:
2799 prefix_alloc_sections_string
= optarg
;
2802 case OPTION_READONLY_TEXT
:
2803 bfd_flags_to_set
|= WP_TEXT
;
2804 bfd_flags_to_clear
&= ~WP_TEXT
;
2807 case OPTION_WRITABLE_TEXT
:
2808 bfd_flags_to_clear
|= WP_TEXT
;
2809 bfd_flags_to_set
&= ~WP_TEXT
;
2813 bfd_flags_to_set
|= D_PAGED
;
2814 bfd_flags_to_clear
&= ~D_PAGED
;
2818 bfd_flags_to_clear
|= D_PAGED
;
2819 bfd_flags_to_set
&= ~D_PAGED
;
2823 /* We've been given a long option. */
2828 copy_usage (stdout
, 0);
2831 copy_usage (stderr
, 1);
2842 print_version ("objcopy");
2844 if (copy_byte
>= interleave
)
2845 fatal (_("byte number must be less than interleave"));
2847 if (optind
== argc
|| optind
+ 2 < argc
)
2848 copy_usage (stderr
, 1);
2850 input_filename
= argv
[optind
];
2851 if (optind
+ 1 < argc
)
2852 output_filename
= argv
[optind
+ 1];
2854 /* Default is to strip no symbols. */
2855 if (strip_symbols
== STRIP_UNDEF
&& discard_locals
== LOCALS_UNDEF
)
2856 strip_symbols
= STRIP_NONE
;
2858 if (output_target
== NULL
)
2859 output_target
= input_target
;
2861 if (binary_architecture
!= NULL
)
2863 if (input_target
&& strcmp (input_target
, "binary") == 0)
2865 const bfd_arch_info_type
* temp_arch_info
;
2867 temp_arch_info
= bfd_scan_arch (binary_architecture
);
2869 if (temp_arch_info
!= NULL
)
2871 bfd_external_binary_architecture
= temp_arch_info
->arch
;
2872 bfd_external_machine
= temp_arch_info
->mach
;
2875 fatal (_("architecture %s unknown"), binary_architecture
);
2879 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2880 non_fatal (_(" Argument %s ignored"), binary_architecture
);
2885 if (stat (input_filename
, & statbuf
) < 0)
2886 fatal (_("warning: could not locate '%s'. System error message: %s"),
2887 input_filename
, strerror (errno
));
2889 /* If there is no destination file, or the source and destination files
2890 are the same, then create a temp and rename the result into the input. */
2891 if (output_filename
== NULL
|| strcmp (input_filename
, output_filename
) == 0)
2893 char *tmpname
= make_tempname (input_filename
);
2895 copy_file (input_filename
, tmpname
, input_target
, output_target
);
2899 set_times (tmpname
, &statbuf
);
2900 smart_rename (tmpname
, input_filename
, preserve_dates
);
2907 copy_file (input_filename
, output_filename
, input_target
, output_target
);
2909 if (status
== 0 && preserve_dates
)
2910 set_times (output_filename
, &statbuf
);
2915 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
2919 if (p
->change_vma
!= CHANGE_IGNORE
)
2923 sprintf_vma (buff
, p
->vma_val
);
2925 /* xgettext:c-format */
2926 non_fatal (_("%s %s%c0x%s never used"),
2927 "--change-section-vma",
2929 p
->change_vma
== CHANGE_SET
? '=' : '+',
2933 if (p
->change_lma
!= CHANGE_IGNORE
)
2937 sprintf_vma (buff
, p
->lma_val
);
2939 /* xgettext:c-format */
2940 non_fatal (_("%s %s%c0x%s never used"),
2941 "--change-section-lma",
2943 p
->change_lma
== CHANGE_SET
? '=' : '+',
2954 main (int argc
, char *argv
[])
2956 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2957 setlocale (LC_MESSAGES
, "");
2959 #if defined (HAVE_SETLOCALE)
2960 setlocale (LC_CTYPE
, "");
2962 bindtextdomain (PACKAGE
, LOCALEDIR
);
2963 textdomain (PACKAGE
);
2965 program_name
= argv
[0];
2966 xmalloc_set_program_name (program_name
);
2968 START_PROGRESS (program_name
, 0);
2970 strip_symbols
= STRIP_UNDEF
;
2971 discard_locals
= LOCALS_UNDEF
;
2974 set_default_bfd_target ();
2978 int i
= strlen (program_name
);
2979 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2980 /* Drop the .exe suffix, if any. */
2981 if (i
> 4 && FILENAME_CMP (program_name
+ i
- 4, ".exe") == 0)
2984 program_name
[i
] = '\0';
2987 is_strip
= (i
>= 5 && FILENAME_CMP (program_name
+ i
- 5, "strip") == 0);
2991 strip_main (argc
, argv
);
2993 copy_main (argc
, argv
);
2995 END_PROGRESS (program_name
);