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.
1088 Trues TRUE upon success, FALSE otherwise. */
1091 copy_object (bfd
*ibfd
, bfd
*obfd
)
1095 asection
**osections
= NULL
;
1096 asection
*gnu_debuglink_section
= NULL
;
1097 bfd_size_type
*gaps
= NULL
;
1098 bfd_size_type max_gap
= 0;
1101 enum bfd_architecture iarch
;
1104 if (ibfd
->xvec
->byteorder
!= obfd
->xvec
->byteorder
1105 && ibfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
1106 && obfd
->xvec
->byteorder
!= BFD_ENDIAN_UNKNOWN
)
1107 fatal (_("Unable to change endianness of input file(s)"));
1109 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1111 bfd_nonfatal (bfd_get_filename (obfd
));
1116 printf (_("copy from %s(%s) to %s(%s)\n"),
1117 bfd_get_filename (ibfd
), bfd_get_target (ibfd
),
1118 bfd_get_filename (obfd
), bfd_get_target (obfd
));
1123 start
= bfd_get_start_address (ibfd
);
1124 start
+= change_start
;
1126 /* Neither the start address nor the flags
1127 need to be set for a core file. */
1128 if (bfd_get_format (obfd
) != bfd_core
)
1132 flags
= bfd_get_file_flags (ibfd
);
1133 flags
|= bfd_flags_to_set
;
1134 flags
&= ~bfd_flags_to_clear
;
1135 flags
&= bfd_applicable_file_flags (obfd
);
1137 if (!bfd_set_start_address (obfd
, start
)
1138 || !bfd_set_file_flags (obfd
, flags
))
1140 bfd_nonfatal (bfd_get_filename (ibfd
));
1145 /* Copy architecture of input file to output file. */
1146 iarch
= bfd_get_arch (ibfd
);
1147 imach
= bfd_get_mach (ibfd
);
1148 if (!bfd_set_arch_mach (obfd
, iarch
, imach
)
1149 && (ibfd
->target_defaulted
1150 || bfd_get_arch (ibfd
) != bfd_get_arch (obfd
)))
1152 if (bfd_get_arch (ibfd
) == bfd_arch_unknown
)
1153 fatal (_("Unable to recognise the format of the input file %s"),
1154 bfd_get_filename (ibfd
));
1157 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1158 bfd_printable_arch_mach (bfd_get_arch (ibfd
),
1159 bfd_get_mach (ibfd
)));
1164 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1166 bfd_nonfatal (bfd_get_filename (ibfd
));
1173 if (osympp
!= isympp
)
1176 /* BFD mandates that all output sections be created and sizes set before
1177 any output is done. Thus, we traverse all sections multiple times. */
1178 bfd_map_over_sections (ibfd
, setup_section
, obfd
);
1180 if (add_sections
!= NULL
)
1182 struct section_add
*padd
;
1183 struct section_list
*pset
;
1185 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1189 padd
->section
= bfd_make_section (obfd
, padd
->name
);
1190 if (padd
->section
== NULL
)
1192 non_fatal (_("can't create section `%s': %s"),
1193 padd
->name
, bfd_errmsg (bfd_get_error ()));
1197 if (! bfd_set_section_size (obfd
, padd
->section
, padd
->size
))
1199 bfd_nonfatal (bfd_get_filename (obfd
));
1203 pset
= find_section_list (padd
->name
, FALSE
);
1207 if (pset
!= NULL
&& pset
->set_flags
)
1208 flags
= pset
->flags
| SEC_HAS_CONTENTS
;
1210 flags
= SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_DATA
;
1212 if (! bfd_set_section_flags (obfd
, padd
->section
, flags
))
1214 bfd_nonfatal (bfd_get_filename (obfd
));
1220 if (pset
->change_vma
!= CHANGE_IGNORE
)
1221 if (! bfd_set_section_vma (obfd
, padd
->section
,
1224 bfd_nonfatal (bfd_get_filename (obfd
));
1228 if (pset
->change_lma
!= CHANGE_IGNORE
)
1230 padd
->section
->lma
= pset
->lma_val
;
1232 if (! bfd_set_section_alignment
1233 (obfd
, padd
->section
,
1234 bfd_section_alignment (obfd
, padd
->section
)))
1236 bfd_nonfatal (bfd_get_filename (obfd
));
1244 if (gnu_debuglink_filename
!= NULL
)
1246 gnu_debuglink_section
= bfd_create_gnu_debuglink_section
1247 (obfd
, gnu_debuglink_filename
);
1249 if (gnu_debuglink_section
== NULL
)
1251 bfd_nonfatal (gnu_debuglink_filename
);
1256 if (bfd_count_sections (obfd
) == 0)
1258 non_fatal (_("there are no sections to be copied!"));
1262 if (gap_fill_set
|| pad_to_set
)
1267 /* We must fill in gaps between the sections and/or we must pad
1268 the last section to a specified address. We do this by
1269 grabbing a list of the sections, sorting them by VMA, and
1270 increasing the section sizes as required to fill the gaps.
1271 We write out the gap contents below. */
1273 c
= bfd_count_sections (obfd
);
1274 osections
= xmalloc (c
* sizeof (asection
*));
1276 bfd_map_over_sections (obfd
, get_sections
, &set
);
1278 qsort (osections
, c
, sizeof (asection
*), compare_section_lma
);
1280 gaps
= xmalloc (c
* sizeof (bfd_size_type
));
1281 memset (gaps
, 0, c
* sizeof (bfd_size_type
));
1285 for (i
= 0; i
< c
- 1; i
++)
1289 bfd_vma gap_start
, gap_stop
;
1291 flags
= bfd_get_section_flags (obfd
, osections
[i
]);
1292 if ((flags
& SEC_HAS_CONTENTS
) == 0
1293 || (flags
& SEC_LOAD
) == 0)
1296 size
= bfd_section_size (obfd
, osections
[i
]);
1297 gap_start
= bfd_section_lma (obfd
, osections
[i
]) + size
;
1298 gap_stop
= bfd_section_lma (obfd
, osections
[i
+ 1]);
1299 if (gap_start
< gap_stop
)
1301 if (! bfd_set_section_size (obfd
, osections
[i
],
1302 size
+ (gap_stop
- gap_start
)))
1304 non_fatal (_("Can't fill gap after %s: %s"),
1305 bfd_get_section_name (obfd
, osections
[i
]),
1306 bfd_errmsg (bfd_get_error ()));
1310 gaps
[i
] = gap_stop
- gap_start
;
1311 if (max_gap
< gap_stop
- gap_start
)
1312 max_gap
= gap_stop
- gap_start
;
1322 lma
= bfd_section_lma (obfd
, osections
[c
- 1]);
1323 size
= bfd_section_size (obfd
, osections
[c
- 1]);
1324 if (lma
+ size
< pad_to
)
1326 if (! bfd_set_section_size (obfd
, osections
[c
- 1],
1329 non_fatal (_("Can't add padding to %s: %s"),
1330 bfd_get_section_name (obfd
, osections
[c
- 1]),
1331 bfd_errmsg (bfd_get_error ()));
1336 gaps
[c
- 1] = pad_to
- (lma
+ size
);
1337 if (max_gap
< pad_to
- (lma
+ size
))
1338 max_gap
= pad_to
- (lma
+ size
);
1344 /* Symbol filtering must happen after the output sections
1345 have been created, but before their contents are set. */
1347 symsize
= bfd_get_symtab_upper_bound (ibfd
);
1350 bfd_nonfatal (bfd_get_filename (ibfd
));
1354 osympp
= isympp
= xmalloc (symsize
);
1355 symcount
= bfd_canonicalize_symtab (ibfd
, isympp
);
1358 bfd_nonfatal (bfd_get_filename (ibfd
));
1362 if (convert_debugging
)
1363 dhandle
= read_debugging_info (ibfd
, isympp
, symcount
);
1365 if (strip_symbols
== STRIP_DEBUG
1366 || strip_symbols
== STRIP_ALL
1367 || strip_symbols
== STRIP_UNNEEDED
1368 || strip_symbols
== STRIP_NONDEBUG
1369 || discard_locals
!= LOCALS_UNDEF
1370 || strip_specific_list
!= NULL
1371 || keep_specific_list
!= NULL
1372 || localize_specific_list
!= NULL
1373 || keepglobal_specific_list
!= NULL
1374 || weaken_specific_list
!= NULL
1375 || prefix_symbols_string
1378 || convert_debugging
1379 || change_leading_char
1380 || remove_leading_char
1381 || redefine_sym_list
1384 /* Mark symbols used in output relocations so that they
1385 are kept, even if they are local labels or static symbols.
1387 Note we iterate over the input sections examining their
1388 relocations since the relocations for the output sections
1389 haven't been set yet. mark_symbols_used_in_relocations will
1390 ignore input sections which have no corresponding output
1392 if (strip_symbols
!= STRIP_ALL
)
1393 bfd_map_over_sections (ibfd
,
1394 mark_symbols_used_in_relocations
,
1396 osympp
= xmalloc ((symcount
+ 1) * sizeof (asymbol
*));
1397 symcount
= filter_symbols (ibfd
, obfd
, osympp
, isympp
, symcount
);
1400 if (convert_debugging
&& dhandle
!= NULL
)
1402 if (! write_debugging_info (obfd
, dhandle
, &symcount
, &osympp
))
1409 bfd_set_symtab (obfd
, osympp
, symcount
);
1411 /* This has to happen after the symbol table has been set. */
1412 bfd_map_over_sections (ibfd
, copy_section
, obfd
);
1414 if (add_sections
!= NULL
)
1416 struct section_add
*padd
;
1418 for (padd
= add_sections
; padd
!= NULL
; padd
= padd
->next
)
1420 if (! bfd_set_section_contents (obfd
, padd
->section
, padd
->contents
,
1423 bfd_nonfatal (bfd_get_filename (obfd
));
1429 if (gnu_debuglink_filename
!= NULL
)
1431 if (! bfd_fill_in_gnu_debuglink_section
1432 (obfd
, gnu_debuglink_section
, gnu_debuglink_filename
))
1434 bfd_nonfatal (gnu_debuglink_filename
);
1439 if (gap_fill_set
|| pad_to_set
)
1444 /* Fill in the gaps. */
1447 buf
= xmalloc (max_gap
);
1448 memset (buf
, gap_fill
, max_gap
);
1450 c
= bfd_count_sections (obfd
);
1451 for (i
= 0; i
< c
; i
++)
1459 off
= bfd_section_size (obfd
, osections
[i
]) - left
;
1470 if (! bfd_set_section_contents (obfd
, osections
[i
], buf
,
1473 bfd_nonfatal (bfd_get_filename (obfd
));
1484 /* Allow the BFD backend to copy any private data it understands
1485 from the input BFD to the output BFD. This is done last to
1486 permit the routine to look at the filtered symbol table, which is
1487 important for the ECOFF code at least. */
1488 if (bfd_get_flavour (ibfd
) == bfd_target_elf_flavour
1489 && strip_symbols
== STRIP_NONDEBUG
)
1490 /* Do not copy the private data when creating an ELF format
1491 debug info file. We do not want the program headers. */
1493 else if (! bfd_copy_private_bfd_data (ibfd
, obfd
))
1495 non_fatal (_("%s: error copying private BFD data: %s"),
1496 bfd_get_filename (obfd
),
1497 bfd_errmsg (bfd_get_error ()));
1501 /* Switch to the alternate machine code. We have to do this at the
1502 very end, because we only initialize the header when we create
1503 the first section. */
1504 if (use_alt_mach_code
!= 0
1505 && ! bfd_alt_mach_code (obfd
, use_alt_mach_code
))
1506 non_fatal (_("unknown alternate machine code, ignored"));
1512 #if defined (_WIN32) && !defined (__CYGWIN32__)
1513 #define MKDIR(DIR, MODE) mkdir (DIR)
1515 #define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1518 /* Read each archive element in turn from IBFD, copy the
1519 contents to temp file, and keep the temp file handle. */
1522 copy_archive (bfd
*ibfd
, bfd
*obfd
, const char *output_target
)
1526 struct name_list
*next
;
1530 bfd
**ptr
= &obfd
->archive_head
;
1532 char *dir
= make_tempname (bfd_get_filename (obfd
));
1534 /* Make a temp directory to hold the contents. */
1535 if (MKDIR (dir
, 0700) != 0)
1536 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1537 dir
, strerror (errno
));
1539 obfd
->has_armap
= ibfd
->has_armap
;
1543 this_element
= bfd_openr_next_archived_file (ibfd
, NULL
);
1545 if (!bfd_set_format (obfd
, bfd_get_format (ibfd
)))
1546 RETURN_NONFATAL (bfd_get_filename (obfd
));
1548 while (!status
&& this_element
!= NULL
)
1554 int stat_status
= 0;
1555 bfd_boolean
delete = TRUE
;
1557 /* Create an output file for this member. */
1558 output_name
= concat (dir
, "/",
1559 bfd_get_filename (this_element
), (char *) 0);
1561 /* If the file already exists, make another temp dir. */
1562 if (stat (output_name
, &buf
) >= 0)
1564 output_name
= make_tempname (output_name
);
1565 if (MKDIR (output_name
, 0700) != 0)
1566 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1567 output_name
, strerror (errno
));
1569 l
= xmalloc (sizeof (struct name_list
));
1570 l
->name
= output_name
;
1574 output_name
= concat (output_name
, "/",
1575 bfd_get_filename (this_element
), (char *) 0);
1578 output_bfd
= bfd_openw (output_name
, output_target
);
1581 stat_status
= bfd_stat_arch_elt (this_element
, &buf
);
1583 if (stat_status
!= 0)
1584 non_fatal (_("internal stat error on %s"),
1585 bfd_get_filename (this_element
));
1588 l
= xmalloc (sizeof (struct name_list
));
1589 l
->name
= output_name
;
1593 if (output_bfd
== NULL
)
1594 RETURN_NONFATAL (output_name
);
1596 if (bfd_check_format (this_element
, bfd_object
))
1597 delete = ! copy_object (this_element
, output_bfd
);
1599 if (!bfd_close (output_bfd
))
1601 bfd_nonfatal (bfd_get_filename (output_bfd
));
1602 /* Error in new object file. Don't change archive. */
1608 unlink (output_name
);
1613 if (preserve_dates
&& stat_status
== 0)
1614 set_times (output_name
, &buf
);
1616 /* Open the newly output file and attach to our list. */
1617 output_bfd
= bfd_openr (output_name
, output_target
);
1619 l
->obfd
= output_bfd
;
1622 ptr
= &output_bfd
->next
;
1624 last_element
= this_element
;
1626 this_element
= bfd_openr_next_archived_file (ibfd
, last_element
);
1628 bfd_close (last_element
);
1633 if (!bfd_close (obfd
))
1634 RETURN_NONFATAL (bfd_get_filename (obfd
));
1636 if (!bfd_close (ibfd
))
1637 RETURN_NONFATAL (bfd_get_filename (ibfd
));
1639 /* Delete all the files that we opened. */
1640 for (l
= list
; l
!= NULL
; l
= l
->next
)
1642 if (l
->obfd
== NULL
)
1646 bfd_close (l
->obfd
);
1653 /* The top-level control. */
1656 copy_file (const char *input_filename
, const char *output_filename
,
1657 const char *input_target
, const char *output_target
)
1660 char **obj_matching
;
1661 char **core_matching
;
1663 if (get_file_size (input_filename
) < 1)
1669 /* To allow us to do "strip *" without dying on the first
1670 non-object file, failures are nonfatal. */
1671 ibfd
= bfd_openr (input_filename
, input_target
);
1673 RETURN_NONFATAL (input_filename
);
1675 if (bfd_check_format (ibfd
, bfd_archive
))
1679 /* bfd_get_target does not return the correct value until
1680 bfd_check_format succeeds. */
1681 if (output_target
== NULL
)
1682 output_target
= bfd_get_target (ibfd
);
1684 obfd
= bfd_openw (output_filename
, output_target
);
1686 RETURN_NONFATAL (output_filename
);
1688 copy_archive (ibfd
, obfd
, output_target
);
1690 else if (bfd_check_format_matches (ibfd
, bfd_object
, &obj_matching
))
1696 /* bfd_get_target does not return the correct value until
1697 bfd_check_format succeeds. */
1698 if (output_target
== NULL
)
1699 output_target
= bfd_get_target (ibfd
);
1701 obfd
= bfd_openw (output_filename
, output_target
);
1703 RETURN_NONFATAL (output_filename
);
1705 delete = ! copy_object (ibfd
, obfd
);
1707 if (!bfd_close (obfd
))
1708 RETURN_NONFATAL (output_filename
);
1710 if (!bfd_close (ibfd
))
1711 RETURN_NONFATAL (input_filename
);
1715 unlink (output_filename
);
1721 bfd_error_type obj_error
= bfd_get_error ();
1722 bfd_error_type core_error
;
1724 if (bfd_check_format_matches (ibfd
, bfd_core
, &core_matching
))
1726 /* This probably can't happen.. */
1727 if (obj_error
== bfd_error_file_ambiguously_recognized
)
1728 free (obj_matching
);
1732 core_error
= bfd_get_error ();
1733 /* Report the object error in preference to the core error. */
1734 if (obj_error
!= core_error
)
1735 bfd_set_error (obj_error
);
1737 bfd_nonfatal (input_filename
);
1739 if (obj_error
== bfd_error_file_ambiguously_recognized
)
1741 list_matching_formats (obj_matching
);
1742 free (obj_matching
);
1744 if (core_error
== bfd_error_file_ambiguously_recognized
)
1746 list_matching_formats (core_matching
);
1747 free (core_matching
);
1754 /* Add a name to the section renaming list. */
1757 add_section_rename (const char * old_name
, const char * new_name
,
1760 section_rename
* rename
;
1762 /* Check for conflicts first. */
1763 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1764 if (strcmp (rename
->old_name
, old_name
) == 0)
1766 /* Silently ignore duplicate definitions. */
1767 if (strcmp (rename
->new_name
, new_name
) == 0
1768 && rename
->flags
== flags
)
1771 fatal (_("Multiple renames of section %s"), old_name
);
1774 rename
= xmalloc (sizeof (* rename
));
1776 rename
->old_name
= old_name
;
1777 rename
->new_name
= new_name
;
1778 rename
->flags
= flags
;
1779 rename
->next
= section_rename_list
;
1781 section_rename_list
= rename
;
1784 /* Check the section rename list for a new name of the input section
1785 ISECTION. Return the new name if one is found.
1786 Also set RETURNED_FLAGS to the flags to be used for this section. */
1789 find_section_rename (bfd
* ibfd ATTRIBUTE_UNUSED
, sec_ptr isection
,
1790 flagword
* returned_flags
)
1792 const char * old_name
= bfd_section_name (ibfd
, isection
);
1793 section_rename
* rename
;
1795 /* Default to using the flags of the input section. */
1796 * returned_flags
= bfd_get_section_flags (ibfd
, isection
);
1798 for (rename
= section_rename_list
; rename
!= NULL
; rename
= rename
->next
)
1799 if (strcmp (rename
->old_name
, old_name
) == 0)
1801 if (rename
->flags
!= (flagword
) -1)
1802 * returned_flags
= rename
->flags
;
1804 return rename
->new_name
;
1810 /* Create a section in OBFD with the same
1811 name and attributes as ISECTION in IBFD. */
1814 setup_section (bfd
*ibfd
, sec_ptr isection
, void *obfdarg
)
1816 bfd
*obfd
= obfdarg
;
1817 struct section_list
*p
;
1825 char *prefix
= NULL
;
1827 if (is_strip_section (ibfd
, isection
))
1830 p
= find_section_list (bfd_section_name (ibfd
, isection
), FALSE
);
1834 /* Get the, possibly new, name of the output section. */
1835 name
= find_section_rename (ibfd
, isection
, & flags
);
1837 /* Prefix sections. */
1838 if ((prefix_alloc_sections_string
)
1839 && (bfd_get_section_flags (ibfd
, isection
) & SEC_ALLOC
))
1840 prefix
= prefix_alloc_sections_string
;
1841 else if (prefix_sections_string
)
1842 prefix
= prefix_sections_string
;
1848 n
= xmalloc (strlen (prefix
) + strlen (name
) + 1);
1854 osection
= bfd_make_section_anyway (obfd
, name
);
1856 if (osection
== NULL
)
1862 size
= bfd_section_size (ibfd
, isection
);
1864 size
= (size
+ interleave
- 1) / interleave
;
1865 if (! bfd_set_section_size (obfd
, osection
, size
))
1871 vma
= bfd_section_vma (ibfd
, isection
);
1872 if (p
!= NULL
&& p
->change_vma
== CHANGE_MODIFY
)
1874 else if (p
!= NULL
&& p
->change_vma
== CHANGE_SET
)
1877 vma
+= change_section_address
;
1879 if (! bfd_set_section_vma (obfd
, osection
, vma
))
1885 lma
= isection
->lma
;
1886 if ((p
!= NULL
) && p
->change_lma
!= CHANGE_IGNORE
)
1888 if (p
->change_lma
== CHANGE_MODIFY
)
1890 else if (p
->change_lma
== CHANGE_SET
)
1896 lma
+= change_section_address
;
1898 osection
->lma
= lma
;
1900 /* FIXME: This is probably not enough. If we change the LMA we
1901 may have to recompute the header for the file as well. */
1902 if (!bfd_set_section_alignment (obfd
,
1904 bfd_section_alignment (ibfd
, isection
)))
1906 err
= _("alignment");
1910 if (p
!= NULL
&& p
->set_flags
)
1911 flags
= p
->flags
| (flags
& (SEC_HAS_CONTENTS
| SEC_RELOC
));
1912 if (!bfd_set_section_flags (obfd
, osection
, flags
))
1918 /* Copy merge entity size. */
1919 osection
->entsize
= isection
->entsize
;
1921 /* This used to be mangle_section; we do here to avoid using
1922 bfd_get_section_by_name since some formats allow multiple
1923 sections with the same name. */
1924 isection
->output_section
= osection
;
1925 isection
->output_offset
= 0;
1927 /* Allow the BFD backend to copy any private data it understands
1928 from the input section to the output section. */
1929 if (bfd_get_flavour (ibfd
) == bfd_target_elf_flavour
1930 && strip_symbols
== STRIP_NONDEBUG
)
1931 /* Do not copy the private data when creating an ELF format
1932 debug info file. We do not want the program headers. */
1934 else if (!bfd_copy_private_section_data (ibfd
, isection
, obfd
, osection
))
1936 err
= _("private data");
1940 /* All went well. */
1944 non_fatal (_("%s: section `%s': error in %s: %s"),
1945 bfd_get_filename (ibfd
),
1946 bfd_section_name (ibfd
, isection
),
1947 err
, bfd_errmsg (bfd_get_error ()));
1951 /* Copy the data of input section ISECTION of IBFD
1952 to an output section with the same name in OBFD.
1953 If stripping then don't copy any relocation info. */
1956 copy_section (bfd
*ibfd
, sec_ptr isection
, void *obfdarg
)
1958 bfd
*obfd
= obfdarg
;
1959 struct section_list
*p
;
1967 /* If we have already failed earlier on,
1968 do not keep on generating complaints now. */
1972 if (is_strip_section (ibfd
, isection
))
1975 flags
= bfd_get_section_flags (ibfd
, isection
);
1976 if ((flags
& SEC_GROUP
) != 0)
1979 osection
= isection
->output_section
;
1980 size
= bfd_get_section_size_before_reloc (isection
);
1982 if (size
== 0 || osection
== 0)
1985 p
= find_section_list (bfd_get_section_name (ibfd
, isection
), FALSE
);
1987 /* Core files do not need to be relocated. */
1988 if (bfd_get_format (obfd
) == bfd_core
)
1992 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
1996 /* Do not complain if the target does not support relocations. */
1997 if (relsize
== -1 && bfd_get_error () == bfd_error_invalid_operation
)
2000 RETURN_NONFATAL (bfd_get_filename (ibfd
));
2005 bfd_set_reloc (obfd
, osection
, NULL
, 0);
2008 relpp
= xmalloc (relsize
);
2009 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, isympp
);
2011 RETURN_NONFATAL (bfd_get_filename (ibfd
));
2013 if (strip_symbols
== STRIP_ALL
)
2015 /* Remove relocations which are not in
2016 keep_strip_specific_list. */
2017 arelent
**temp_relpp
;
2018 long temp_relcount
= 0;
2021 temp_relpp
= xmalloc (relsize
);
2022 for (i
= 0; i
< relcount
; i
++)
2023 if (is_specified_symbol (bfd_asymbol_name (*relpp
[i
]->sym_ptr_ptr
),
2024 keep_specific_list
))
2025 temp_relpp
[temp_relcount
++] = relpp
[i
];
2026 relcount
= temp_relcount
;
2031 bfd_set_reloc (obfd
, osection
, relcount
== 0 ? NULL
: relpp
, relcount
);
2034 isection
->_cooked_size
= isection
->_raw_size
;
2035 isection
->reloc_done
= TRUE
;
2037 if (bfd_get_section_flags (ibfd
, isection
) & SEC_HAS_CONTENTS
2038 && bfd_get_section_flags (obfd
, osection
) & SEC_HAS_CONTENTS
)
2040 void *memhunk
= xmalloc (size
);
2042 if (!bfd_get_section_contents (ibfd
, isection
, memhunk
, 0, size
))
2043 RETURN_NONFATAL (bfd_get_filename (ibfd
));
2047 /* Keep only every `copy_byte'th byte in MEMHUNK. */
2048 char *from
= memhunk
+ copy_byte
;
2050 char *end
= memhunk
+ size
;
2052 for (; from
< end
; from
+= interleave
)
2055 size
= (size
+ interleave
- 1 - copy_byte
) / interleave
;
2056 osection
->lma
/= interleave
;
2059 if (!bfd_set_section_contents (obfd
, osection
, memhunk
, 0, size
))
2060 RETURN_NONFATAL (bfd_get_filename (obfd
));
2064 else if (p
!= NULL
&& p
->set_flags
&& (p
->flags
& SEC_HAS_CONTENTS
) != 0)
2066 void *memhunk
= xmalloc (size
);
2068 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2069 flag--they can just remove the section entirely and add it
2070 back again. However, we do permit them to turn on the
2071 SEC_HAS_CONTENTS flag, and take it to mean that the section
2072 contents should be zeroed out. */
2074 memset (memhunk
, 0, size
);
2075 if (! bfd_set_section_contents (obfd
, osection
, memhunk
, 0, size
))
2076 RETURN_NONFATAL (bfd_get_filename (obfd
));
2081 /* Get all the sections. This is used when --gap-fill or --pad-to is
2085 get_sections (bfd
*obfd ATTRIBUTE_UNUSED
, asection
*osection
, void *secppparg
)
2087 asection
***secppp
= secppparg
;
2089 **secppp
= osection
;
2093 /* Sort sections by VMA. This is called via qsort, and is used when
2094 --gap-fill or --pad-to is used. We force non loadable or empty
2095 sections to the front, where they are easier to ignore. */
2098 compare_section_lma (const void *arg1
, const void *arg2
)
2100 const asection
*const *sec1
= arg1
;
2101 const asection
*const *sec2
= arg2
;
2102 flagword flags1
, flags2
;
2104 /* Sort non loadable sections to the front. */
2105 flags1
= (*sec1
)->flags
;
2106 flags2
= (*sec2
)->flags
;
2107 if ((flags1
& SEC_HAS_CONTENTS
) == 0
2108 || (flags1
& SEC_LOAD
) == 0)
2110 if ((flags2
& SEC_HAS_CONTENTS
) != 0
2111 && (flags2
& SEC_LOAD
) != 0)
2116 if ((flags2
& SEC_HAS_CONTENTS
) == 0
2117 || (flags2
& SEC_LOAD
) == 0)
2121 /* Sort sections by LMA. */
2122 if ((*sec1
)->lma
> (*sec2
)->lma
)
2124 else if ((*sec1
)->lma
< (*sec2
)->lma
)
2127 /* Sort sections with the same LMA by size. */
2128 if ((*sec1
)->_raw_size
> (*sec2
)->_raw_size
)
2130 else if ((*sec1
)->_raw_size
< (*sec2
)->_raw_size
)
2136 /* Mark all the symbols which will be used in output relocations with
2137 the BSF_KEEP flag so that those symbols will not be stripped.
2139 Ignore relocations which will not appear in the output file. */
2142 mark_symbols_used_in_relocations (bfd
*ibfd
, sec_ptr isection
, void *symbolsarg
)
2144 asymbol
**symbols
= symbolsarg
;
2149 /* Ignore an input section with no corresponding output section. */
2150 if (isection
->output_section
== NULL
)
2153 relsize
= bfd_get_reloc_upper_bound (ibfd
, isection
);
2156 /* Do not complain if the target does not support relocations. */
2157 if (relsize
== -1 && bfd_get_error () == bfd_error_invalid_operation
)
2159 bfd_fatal (bfd_get_filename (ibfd
));
2165 relpp
= xmalloc (relsize
);
2166 relcount
= bfd_canonicalize_reloc (ibfd
, isection
, relpp
, symbols
);
2168 bfd_fatal (bfd_get_filename (ibfd
));
2170 /* Examine each symbol used in a relocation. If it's not one of the
2171 special bfd section symbols, then mark it with BSF_KEEP. */
2172 for (i
= 0; i
< relcount
; i
++)
2174 if (*relpp
[i
]->sym_ptr_ptr
!= bfd_com_section_ptr
->symbol
2175 && *relpp
[i
]->sym_ptr_ptr
!= bfd_abs_section_ptr
->symbol
2176 && *relpp
[i
]->sym_ptr_ptr
!= bfd_und_section_ptr
->symbol
)
2177 (*relpp
[i
]->sym_ptr_ptr
)->flags
|= BSF_KEEP
;
2184 /* Write out debugging information. */
2187 write_debugging_info (bfd
*obfd
, void *dhandle
,
2188 long *symcountp ATTRIBUTE_UNUSED
,
2189 asymbol
***symppp ATTRIBUTE_UNUSED
)
2191 if (bfd_get_flavour (obfd
) == bfd_target_ieee_flavour
)
2192 return write_ieee_debugging_info (obfd
, dhandle
);
2194 if (bfd_get_flavour (obfd
) == bfd_target_coff_flavour
2195 || bfd_get_flavour (obfd
) == bfd_target_elf_flavour
)
2197 bfd_byte
*syms
, *strings
;
2198 bfd_size_type symsize
, stringsize
;
2199 asection
*stabsec
, *stabstrsec
;
2201 if (! write_stabs_in_sections_debugging_info (obfd
, dhandle
, &syms
,
2206 stabsec
= bfd_make_section (obfd
, ".stab");
2207 stabstrsec
= bfd_make_section (obfd
, ".stabstr");
2209 || stabstrsec
== NULL
2210 || ! bfd_set_section_size (obfd
, stabsec
, symsize
)
2211 || ! bfd_set_section_size (obfd
, stabstrsec
, stringsize
)
2212 || ! bfd_set_section_alignment (obfd
, stabsec
, 2)
2213 || ! bfd_set_section_alignment (obfd
, stabstrsec
, 0)
2214 || ! bfd_set_section_flags (obfd
, stabsec
,
2218 || ! bfd_set_section_flags (obfd
, stabstrsec
,
2223 non_fatal (_("%s: can't create debugging section: %s"),
2224 bfd_get_filename (obfd
),
2225 bfd_errmsg (bfd_get_error ()));
2229 /* We can get away with setting the section contents now because
2230 the next thing the caller is going to do is copy over the
2231 real sections. We may someday have to split the contents
2232 setting out of this function. */
2233 if (! bfd_set_section_contents (obfd
, stabsec
, syms
, 0, symsize
)
2234 || ! bfd_set_section_contents (obfd
, stabstrsec
, strings
, 0,
2237 non_fatal (_("%s: can't set debugging section contents: %s"),
2238 bfd_get_filename (obfd
),
2239 bfd_errmsg (bfd_get_error ()));
2246 non_fatal (_("%s: don't know how to write debugging information for %s"),
2247 bfd_get_filename (obfd
), bfd_get_target (obfd
));
2252 strip_main (int argc
, char *argv
[])
2254 char *input_target
= NULL
;
2255 char *output_target
= NULL
;
2256 bfd_boolean show_version
= FALSE
;
2257 bfd_boolean formats_info
= FALSE
;
2260 struct section_list
*p
;
2261 char *output_file
= NULL
;
2263 while ((c
= getopt_long (argc
, argv
, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2264 strip_options
, (int *) 0)) != EOF
)
2269 input_target
= optarg
;
2272 output_target
= optarg
;
2275 input_target
= output_target
= optarg
;
2278 p
= find_section_list (optarg
, TRUE
);
2280 sections_removed
= TRUE
;
2283 strip_symbols
= STRIP_ALL
;
2287 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2288 strip_symbols
= STRIP_DEBUG
;
2290 case OPTION_STRIP_UNNEEDED
:
2291 strip_symbols
= STRIP_UNNEEDED
;
2294 add_specific_symbol (optarg
, &keep_specific_list
);
2297 add_specific_symbol (optarg
, &strip_specific_list
);
2300 output_file
= optarg
;
2303 preserve_dates
= TRUE
;
2306 discard_locals
= LOCALS_ALL
;
2309 discard_locals
= LOCALS_START_L
;
2315 show_version
= TRUE
;
2317 case OPTION_FORMATS_INFO
:
2318 formats_info
= TRUE
;
2320 case OPTION_ONLY_KEEP_DEBUG
:
2321 strip_symbols
= STRIP_NONDEBUG
;
2324 /* We've been given a long option. */
2331 strip_usage (stdout
, 0);
2333 strip_usage (stderr
, 1);
2344 print_version ("strip");
2346 /* Default is to strip all symbols. */
2347 if (strip_symbols
== STRIP_UNDEF
2348 && discard_locals
== LOCALS_UNDEF
2349 && strip_specific_list
== NULL
)
2350 strip_symbols
= STRIP_ALL
;
2352 if (output_target
== NULL
)
2353 output_target
= input_target
;
2357 || (output_file
!= NULL
&& (i
+ 1) < argc
))
2358 strip_usage (stderr
, 1);
2360 for (; i
< argc
; i
++)
2362 int hold_status
= status
;
2363 struct stat statbuf
;
2366 if (get_file_size (argv
[i
]) < 1)
2370 /* No need to check the return value of stat().
2371 It has already been checked in get_file_size(). */
2372 stat (argv
[i
], &statbuf
);
2374 if (output_file
!= NULL
)
2375 tmpname
= output_file
;
2377 tmpname
= make_tempname (argv
[i
]);
2380 copy_file (argv
[i
], tmpname
, input_target
, output_target
);
2384 set_times (tmpname
, &statbuf
);
2385 if (output_file
== NULL
)
2386 smart_rename (tmpname
, argv
[i
], preserve_dates
);
2387 status
= hold_status
;
2391 if (output_file
== NULL
)
2399 copy_main (int argc
, char *argv
[])
2401 char * binary_architecture
= NULL
;
2402 char *input_filename
= NULL
;
2403 char *output_filename
= NULL
;
2404 char *input_target
= NULL
;
2405 char *output_target
= NULL
;
2406 bfd_boolean show_version
= FALSE
;
2407 bfd_boolean change_warn
= TRUE
;
2408 bfd_boolean formats_info
= FALSE
;
2410 struct section_list
*p
;
2411 struct stat statbuf
;
2413 while ((c
= getopt_long (argc
, argv
, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2414 copy_options
, (int *) 0)) != EOF
)
2419 copy_byte
= atoi (optarg
);
2421 fatal (_("byte number must be non-negative"));
2425 binary_architecture
= optarg
;
2429 interleave
= atoi (optarg
);
2431 fatal (_("interleave must be positive"));
2435 case 's': /* "source" - 'I' is preferred */
2436 input_target
= optarg
;
2440 case 'd': /* "destination" - 'O' is preferred */
2441 output_target
= optarg
;
2445 input_target
= output_target
= optarg
;
2449 p
= find_section_list (optarg
, TRUE
);
2451 fatal (_("%s both copied and removed"), optarg
);
2453 sections_copied
= TRUE
;
2457 p
= find_section_list (optarg
, TRUE
);
2459 fatal (_("%s both copied and removed"), optarg
);
2461 sections_removed
= TRUE
;
2465 strip_symbols
= STRIP_ALL
;
2469 strip_symbols
= STRIP_DEBUG
;
2472 case OPTION_STRIP_UNNEEDED
:
2473 strip_symbols
= STRIP_UNNEEDED
;
2476 case OPTION_ONLY_KEEP_DEBUG
:
2477 strip_symbols
= STRIP_NONDEBUG
;
2480 case OPTION_ADD_GNU_DEBUGLINK
:
2481 gnu_debuglink_filename
= optarg
;
2485 add_specific_symbol (optarg
, &keep_specific_list
);
2489 add_specific_symbol (optarg
, &strip_specific_list
);
2493 add_specific_symbol (optarg
, &localize_specific_list
);
2497 add_specific_symbol (optarg
, &keepglobal_specific_list
);
2501 add_specific_symbol (optarg
, &weaken_specific_list
);
2505 preserve_dates
= TRUE
;
2513 discard_locals
= LOCALS_ALL
;
2517 discard_locals
= LOCALS_START_L
;
2525 show_version
= TRUE
;
2528 case OPTION_FORMATS_INFO
:
2529 formats_info
= TRUE
;
2536 case OPTION_ADD_SECTION
:
2540 struct section_add
*pa
;
2545 s
= strchr (optarg
, '=');
2548 fatal (_("bad format for %s"), "--add-section");
2550 size
= get_file_size (s
+ 1);
2554 pa
= xmalloc (sizeof (struct section_add
));
2557 name
= xmalloc (len
+ 1);
2558 strncpy (name
, optarg
, len
);
2562 pa
->filename
= s
+ 1;
2564 pa
->contents
= xmalloc (size
);
2566 f
= fopen (pa
->filename
, FOPEN_RB
);
2569 fatal (_("cannot open: %s: %s"),
2570 pa
->filename
, strerror (errno
));
2572 if (fread (pa
->contents
, 1, pa
->size
, f
) == 0
2574 fatal (_("%s: fread failed"), pa
->filename
);
2578 pa
->next
= add_sections
;
2583 case OPTION_CHANGE_START
:
2584 change_start
= parse_vma (optarg
, "--change-start");
2587 case OPTION_CHANGE_SECTION_ADDRESS
:
2588 case OPTION_CHANGE_SECTION_LMA
:
2589 case OPTION_CHANGE_SECTION_VMA
:
2594 char *option
= NULL
;
2596 enum change_action what
= CHANGE_IGNORE
;
2600 case OPTION_CHANGE_SECTION_ADDRESS
:
2601 option
= "--change-section-address";
2603 case OPTION_CHANGE_SECTION_LMA
:
2604 option
= "--change-section-lma";
2606 case OPTION_CHANGE_SECTION_VMA
:
2607 option
= "--change-section-vma";
2611 s
= strchr (optarg
, '=');
2614 s
= strchr (optarg
, '+');
2617 s
= strchr (optarg
, '-');
2619 fatal (_("bad format for %s"), option
);
2624 name
= xmalloc (len
+ 1);
2625 strncpy (name
, optarg
, len
);
2628 p
= find_section_list (name
, TRUE
);
2630 val
= parse_vma (s
+ 1, option
);
2634 case '=': what
= CHANGE_SET
; break;
2635 case '-': val
= - val
; /* Drop through. */
2636 case '+': what
= CHANGE_MODIFY
; break;
2641 case OPTION_CHANGE_SECTION_ADDRESS
:
2642 p
->change_vma
= what
;
2646 case OPTION_CHANGE_SECTION_LMA
:
2647 p
->change_lma
= what
;
2651 case OPTION_CHANGE_SECTION_VMA
:
2652 p
->change_vma
= what
;
2659 case OPTION_CHANGE_ADDRESSES
:
2660 change_section_address
= parse_vma (optarg
, "--change-addresses");
2661 change_start
= change_section_address
;
2664 case OPTION_CHANGE_WARNINGS
:
2668 case OPTION_CHANGE_LEADING_CHAR
:
2669 change_leading_char
= TRUE
;
2672 case OPTION_DEBUGGING
:
2673 convert_debugging
= TRUE
;
2676 case OPTION_GAP_FILL
:
2678 bfd_vma gap_fill_vma
;
2680 gap_fill_vma
= parse_vma (optarg
, "--gap-fill");
2681 gap_fill
= (bfd_byte
) gap_fill_vma
;
2682 if ((bfd_vma
) gap_fill
!= gap_fill_vma
)
2686 sprintf_vma (buff
, gap_fill_vma
);
2688 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2691 gap_fill_set
= TRUE
;
2695 case OPTION_NO_CHANGE_WARNINGS
:
2696 change_warn
= FALSE
;
2700 pad_to
= parse_vma (optarg
, "--pad-to");
2704 case OPTION_REMOVE_LEADING_CHAR
:
2705 remove_leading_char
= TRUE
;
2708 case OPTION_REDEFINE_SYM
:
2710 /* Push this redefinition onto redefine_symbol_list. */
2714 const char *nextarg
;
2715 char *source
, *target
;
2717 s
= strchr (optarg
, '=');
2719 fatal (_("bad format for %s"), "--redefine-sym");
2722 source
= xmalloc (len
+ 1);
2723 strncpy (source
, optarg
, len
);
2727 len
= strlen (nextarg
);
2728 target
= xmalloc (len
+ 1);
2729 strcpy (target
, nextarg
);
2731 redefine_list_append ("--redefine-sym", source
, target
);
2738 case OPTION_REDEFINE_SYMS
:
2739 add_redefine_syms_file (optarg
);
2742 case OPTION_SET_SECTION_FLAGS
:
2748 s
= strchr (optarg
, '=');
2750 fatal (_("bad format for %s"), "--set-section-flags");
2753 name
= xmalloc (len
+ 1);
2754 strncpy (name
, optarg
, len
);
2757 p
= find_section_list (name
, TRUE
);
2759 p
->set_flags
= TRUE
;
2760 p
->flags
= parse_flags (s
+ 1);
2764 case OPTION_RENAME_SECTION
:
2767 const char *eq
, *fl
;
2772 eq
= strchr (optarg
, '=');
2774 fatal (_("bad format for %s"), "--rename-section");
2778 fatal (_("bad format for %s"), "--rename-section");
2780 old_name
= xmalloc (len
+ 1);
2781 strncpy (old_name
, optarg
, len
);
2785 fl
= strchr (eq
, ',');
2788 flags
= parse_flags (fl
+ 1);
2798 fatal (_("bad format for %s"), "--rename-section");
2800 new_name
= xmalloc (len
+ 1);
2801 strncpy (new_name
, eq
, len
);
2804 add_section_rename (old_name
, new_name
, flags
);
2808 case OPTION_SET_START
:
2809 set_start
= parse_vma (optarg
, "--set-start");
2810 set_start_set
= TRUE
;
2813 case OPTION_SREC_LEN
:
2814 Chunk
= parse_vma (optarg
, "--srec-len");
2817 case OPTION_SREC_FORCES3
:
2821 case OPTION_STRIP_SYMBOLS
:
2822 add_specific_symbols (optarg
, &strip_specific_list
);
2825 case OPTION_KEEP_SYMBOLS
:
2826 add_specific_symbols (optarg
, &keep_specific_list
);
2829 case OPTION_LOCALIZE_SYMBOLS
:
2830 add_specific_symbols (optarg
, &localize_specific_list
);
2833 case OPTION_KEEPGLOBAL_SYMBOLS
:
2834 add_specific_symbols (optarg
, &keepglobal_specific_list
);
2837 case OPTION_WEAKEN_SYMBOLS
:
2838 add_specific_symbols (optarg
, &weaken_specific_list
);
2841 case OPTION_ALT_MACH_CODE
:
2842 use_alt_mach_code
= atoi (optarg
);
2843 if (use_alt_mach_code
<= 0)
2844 fatal (_("alternate machine code index must be positive"));
2847 case OPTION_PREFIX_SYMBOLS
:
2848 prefix_symbols_string
= optarg
;
2851 case OPTION_PREFIX_SECTIONS
:
2852 prefix_sections_string
= optarg
;
2855 case OPTION_PREFIX_ALLOC_SECTIONS
:
2856 prefix_alloc_sections_string
= optarg
;
2859 case OPTION_READONLY_TEXT
:
2860 bfd_flags_to_set
|= WP_TEXT
;
2861 bfd_flags_to_clear
&= ~WP_TEXT
;
2864 case OPTION_WRITABLE_TEXT
:
2865 bfd_flags_to_clear
|= WP_TEXT
;
2866 bfd_flags_to_set
&= ~WP_TEXT
;
2870 bfd_flags_to_set
|= D_PAGED
;
2871 bfd_flags_to_clear
&= ~D_PAGED
;
2875 bfd_flags_to_clear
|= D_PAGED
;
2876 bfd_flags_to_set
&= ~D_PAGED
;
2880 /* We've been given a long option. */
2885 copy_usage (stdout
, 0);
2888 copy_usage (stderr
, 1);
2899 print_version ("objcopy");
2901 if (copy_byte
>= interleave
)
2902 fatal (_("byte number must be less than interleave"));
2904 if (optind
== argc
|| optind
+ 2 < argc
)
2905 copy_usage (stderr
, 1);
2907 input_filename
= argv
[optind
];
2908 if (optind
+ 1 < argc
)
2909 output_filename
= argv
[optind
+ 1];
2911 /* Default is to strip no symbols. */
2912 if (strip_symbols
== STRIP_UNDEF
&& discard_locals
== LOCALS_UNDEF
)
2913 strip_symbols
= STRIP_NONE
;
2915 if (output_target
== NULL
)
2916 output_target
= input_target
;
2918 if (binary_architecture
!= NULL
)
2920 if (input_target
&& strcmp (input_target
, "binary") == 0)
2922 const bfd_arch_info_type
* temp_arch_info
;
2924 temp_arch_info
= bfd_scan_arch (binary_architecture
);
2926 if (temp_arch_info
!= NULL
)
2928 bfd_external_binary_architecture
= temp_arch_info
->arch
;
2929 bfd_external_machine
= temp_arch_info
->mach
;
2932 fatal (_("architecture %s unknown"), binary_architecture
);
2936 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2937 non_fatal (_(" Argument %s ignored"), binary_architecture
);
2942 if (stat (input_filename
, & statbuf
) < 0)
2943 fatal (_("warning: could not locate '%s'. System error message: %s"),
2944 input_filename
, strerror (errno
));
2946 /* If there is no destination file, or the source and destination files
2947 are the same, then create a temp and rename the result into the input. */
2948 if (output_filename
== NULL
|| strcmp (input_filename
, output_filename
) == 0)
2950 char *tmpname
= make_tempname (input_filename
);
2952 copy_file (input_filename
, tmpname
, input_target
, output_target
);
2956 set_times (tmpname
, &statbuf
);
2957 smart_rename (tmpname
, input_filename
, preserve_dates
);
2964 copy_file (input_filename
, output_filename
, input_target
, output_target
);
2966 if (status
== 0 && preserve_dates
)
2967 set_times (output_filename
, &statbuf
);
2972 for (p
= change_sections
; p
!= NULL
; p
= p
->next
)
2976 if (p
->change_vma
!= CHANGE_IGNORE
)
2980 sprintf_vma (buff
, p
->vma_val
);
2982 /* xgettext:c-format */
2983 non_fatal (_("%s %s%c0x%s never used"),
2984 "--change-section-vma",
2986 p
->change_vma
== CHANGE_SET
? '=' : '+',
2990 if (p
->change_lma
!= CHANGE_IGNORE
)
2994 sprintf_vma (buff
, p
->lma_val
);
2996 /* xgettext:c-format */
2997 non_fatal (_("%s %s%c0x%s never used"),
2998 "--change-section-lma",
3000 p
->change_lma
== CHANGE_SET
? '=' : '+',
3011 main (int argc
, char *argv
[])
3013 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3014 setlocale (LC_MESSAGES
, "");
3016 #if defined (HAVE_SETLOCALE)
3017 setlocale (LC_CTYPE
, "");
3019 bindtextdomain (PACKAGE
, LOCALEDIR
);
3020 textdomain (PACKAGE
);
3022 program_name
= argv
[0];
3023 xmalloc_set_program_name (program_name
);
3025 START_PROGRESS (program_name
, 0);
3027 strip_symbols
= STRIP_UNDEF
;
3028 discard_locals
= LOCALS_UNDEF
;
3031 set_default_bfd_target ();
3035 int i
= strlen (program_name
);
3036 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
3037 /* Drop the .exe suffix, if any. */
3038 if (i
> 4 && FILENAME_CMP (program_name
+ i
- 4, ".exe") == 0)
3041 program_name
[i
] = '\0';
3044 is_strip
= (i
>= 5 && FILENAME_CMP (program_name
+ i
- 5, "strip") == 0);
3048 strip_main (argc
, argv
);
3050 copy_main (argc
, argv
);
3052 END_PROGRESS (program_name
);