2001-03-26 H.J. Lu <hjl@gnu.org>
[binutils.git] / binutils / objcopy.c
blobde053b11287f3bd8231adadd77a40c30a478d07d
1 /* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include "bfd.h"
24 #include "progress.h"
25 #include "bucomm.h"
26 #include "getopt.h"
27 #include "libiberty.h"
28 #include "budbg.h"
29 #include "filenames.h"
30 #include <sys/stat.h>
32 /* A list of symbols to explicitly strip out, or to keep. A linked
33 list is good enough for a small number from the command line, but
34 this will slow things down a lot if many symbols are being
35 deleted. */
37 struct symlist
39 const char *name;
40 struct symlist *next;
43 /* A list to support redefine_sym. */
44 struct redefine_node
46 char *source;
47 char *target;
48 struct redefine_node *next;
51 static void copy_usage PARAMS ((FILE *, int));
52 static void strip_usage PARAMS ((FILE *, int));
53 static flagword parse_flags PARAMS ((const char *));
54 static struct section_list *find_section_list PARAMS ((const char *, boolean));
55 static void setup_section PARAMS ((bfd *, asection *, PTR));
56 static void copy_section PARAMS ((bfd *, asection *, PTR));
57 static void get_sections PARAMS ((bfd *, asection *, PTR));
58 static int compare_section_lma PARAMS ((const PTR, const PTR));
59 static void add_specific_symbol PARAMS ((const char *, struct symlist **));
60 static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
61 static boolean is_strip_section PARAMS ((bfd *, asection *));
62 static unsigned int filter_symbols
63 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
64 static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
65 static void filter_bytes PARAMS ((char *, bfd_size_type *));
66 static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
67 static void copy_object PARAMS ((bfd *, bfd *));
68 static void copy_archive PARAMS ((bfd *, bfd *, const char *));
69 static void copy_file
70 PARAMS ((const char *, const char *, const char *, const char *));
71 static int strip_main PARAMS ((int, char **));
72 static int copy_main PARAMS ((int, char **));
73 static const char *lookup_sym_redefinition PARAMS((const char *));
74 static void redefine_list_append PARAMS ((const char *, const char *));
76 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
78 static asymbol **isympp = NULL; /* Input symbols */
79 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
81 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
82 static int copy_byte = -1;
83 static int interleave = 4;
85 static boolean verbose; /* Print file and target names. */
86 static boolean preserve_dates; /* Preserve input file timestamp. */
87 static int status = 0; /* Exit status. */
89 enum strip_action
91 STRIP_UNDEF,
92 STRIP_NONE, /* don't strip */
93 STRIP_DEBUG, /* strip all debugger symbols */
94 STRIP_UNNEEDED, /* strip unnecessary symbols */
95 STRIP_ALL /* strip all symbols */
98 /* Which symbols to remove. */
99 static enum strip_action strip_symbols;
101 enum locals_action
103 LOCALS_UNDEF,
104 LOCALS_START_L, /* discard locals starting with L */
105 LOCALS_ALL /* discard all locals */
108 /* Which local symbols to remove. Overrides STRIP_ALL. */
109 static enum locals_action discard_locals;
111 /* What kind of change to perform. */
112 enum change_action
114 CHANGE_IGNORE,
115 CHANGE_MODIFY,
116 CHANGE_SET
119 /* Structure used to hold lists of sections and actions to take. */
120 struct section_list
122 struct section_list * next; /* Next section to change. */
123 const char * name; /* Section name. */
124 boolean used; /* Whether this entry was used. */
125 boolean remove; /* Whether to remove this section. */
126 boolean copy; /* Whether to copy this section. */
127 enum change_action change_vma;/* Whether to change or set VMA. */
128 bfd_vma vma_val; /* Amount to change by or set to. */
129 enum change_action change_lma;/* Whether to change or set LMA. */
130 bfd_vma lma_val; /* Amount to change by or set to. */
131 boolean set_flags; /* Whether to set the section flags. */
132 flagword flags; /* What to set the section flags to. */
135 static struct section_list *change_sections;
136 static boolean sections_removed;
137 static boolean sections_copied;
139 /* Changes to the start address. */
140 static bfd_vma change_start = 0;
141 static boolean set_start_set = false;
142 static bfd_vma set_start;
144 /* Changes to section addresses. */
145 static bfd_vma change_section_address = 0;
147 /* Filling gaps between sections. */
148 static boolean gap_fill_set = false;
149 static bfd_byte gap_fill = 0;
151 /* Pad to a given address. */
152 static boolean pad_to_set = false;
153 static bfd_vma pad_to;
155 /* List of sections to add. */
157 struct section_add
159 /* Next section to add. */
160 struct section_add *next;
161 /* Name of section to add. */
162 const char *name;
163 /* Name of file holding section contents. */
164 const char *filename;
165 /* Size of file. */
166 size_t size;
167 /* Contents of file. */
168 bfd_byte *contents;
169 /* BFD section, after it has been added. */
170 asection *section;
173 static struct section_add *add_sections;
175 /* Whether to convert debugging information. */
177 static boolean convert_debugging = false;
179 /* Whether to change the leading character in symbol names. */
181 static boolean change_leading_char = false;
183 /* Whether to remove the leading character from global symbol names. */
185 static boolean remove_leading_char = false;
187 /* List of symbols to strip, keep, localize, weaken, or redefine. */
189 static struct symlist *strip_specific_list = NULL;
190 static struct symlist *keep_specific_list = NULL;
191 static struct symlist *localize_specific_list = NULL;
192 static struct symlist *weaken_specific_list = NULL;
193 static struct redefine_node *redefine_sym_list = NULL;
195 /* If this is true, we weaken global symbols (set BSF_WEAK). */
197 static boolean weaken = false;
199 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
201 #define OPTION_ADD_SECTION 150
202 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
203 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
204 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
205 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
206 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
207 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
208 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
209 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
210 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
211 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
212 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
213 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
214 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
215 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
216 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
217 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
218 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
219 #define OPTION_SREC_LEN (OPTION_REDEFINE_SYM + 1)
220 #define OPTION_SREC_FORCES3 (OPTION_SREC_LEN + 1)
222 /* Options to handle if running as "strip". */
224 static struct option strip_options[] =
226 {"discard-all", no_argument, 0, 'x'},
227 {"discard-locals", no_argument, 0, 'X'},
228 {"format", required_argument, 0, 'F'}, /* Obsolete */
229 {"help", no_argument, 0, 'h'},
230 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
231 {"input-target", required_argument, 0, 'I'},
232 {"keep-symbol", required_argument, 0, 'K'},
233 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
234 {"output-target", required_argument, 0, 'O'},
235 {"preserve-dates", no_argument, 0, 'p'},
236 {"remove-section", required_argument, 0, 'R'},
237 {"strip-all", no_argument, 0, 's'},
238 {"strip-debug", no_argument, 0, 'S'},
239 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
240 {"strip-symbol", required_argument, 0, 'N'},
241 {"target", required_argument, 0, 'F'},
242 {"verbose", no_argument, 0, 'v'},
243 {"version", no_argument, 0, 'V'},
244 {0, no_argument, 0, 0}
247 /* Options to handle if running as "objcopy". */
249 static struct option copy_options[] =
251 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
252 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
253 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
254 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
255 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
256 {"binary-architecture", required_argument, 0, 'B'},
257 {"byte", required_argument, 0, 'b'},
258 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
259 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
260 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
261 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
262 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
263 {"change-start", required_argument, 0, OPTION_CHANGE_START},
264 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
265 {"debugging", no_argument, 0, OPTION_DEBUGGING},
266 {"discard-all", no_argument, 0, 'x'},
267 {"discard-locals", no_argument, 0, 'X'},
268 {"only-section", required_argument, 0, 'j'},
269 {"format", required_argument, 0, 'F'}, /* Obsolete */
270 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
271 {"help", no_argument, 0, 'h'},
272 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
273 {"input-target", required_argument, 0, 'I'},
274 {"interleave", required_argument, 0, 'i'},
275 {"keep-symbol", required_argument, 0, 'K'},
276 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
277 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
278 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
279 {"output-target", required_argument, 0, 'O'},
280 {"pad-to", required_argument, 0, OPTION_PAD_TO},
281 {"preserve-dates", no_argument, 0, 'p'},
282 {"localize-symbol", required_argument, 0, 'L'},
283 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
284 {"remove-section", required_argument, 0, 'R'},
285 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
286 {"set-start", required_argument, 0, OPTION_SET_START},
287 {"strip-all", no_argument, 0, 'S'},
288 {"strip-debug", no_argument, 0, 'g'},
289 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
290 {"strip-symbol", required_argument, 0, 'N'},
291 {"target", required_argument, 0, 'F'},
292 {"verbose", no_argument, 0, 'v'},
293 {"version", no_argument, 0, 'V'},
294 {"weaken", no_argument, 0, OPTION_WEAKEN},
295 {"weaken-symbol", required_argument, 0, 'W'},
296 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
297 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
298 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
299 {0, no_argument, 0, 0}
302 /* IMPORTS */
303 extern char *program_name;
305 /* This flag distinguishes between strip and objcopy:
306 1 means this is 'strip'; 0 means this is 'objcopy'.
307 -1 means if we should use argv[0] to decide. */
308 extern int is_strip;
310 /* The maximum length of an S record. This variable is declared in srec.c
311 and can be modified by the --srec-len parameter. */
312 extern unsigned int Chunk;
314 /* Restrict the generation of Srecords to type S3 only.
315 This variable is declare in bfd/srec.c and can be toggled
316 on by the --srec-forceS3 command line switch. */
317 extern boolean S3Forced;
319 /* Defined in bfd/binary.c. Used to set architecture of input binary files. */
320 extern enum bfd_architecture bfd_external_binary_architecture;
322 static void
323 copy_usage (stream, exit_status)
324 FILE *stream;
325 int exit_status;
327 fprintf (stream, _("Usage: %s <switches> in-file [out-file]\n"), program_name);
328 fprintf (stream, _(" The switches are:\n"));
329 fprintf (stream, _("\
330 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
331 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
332 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
333 -F --target <bfdname> Set both input and output format to <bfdname>\n\
334 --debugging Convert debugging information, if possible\n\
335 -p --preserve-dates Copy modified/access timestamps to the output\n\
336 -j --only-section <name> Only copy section <name> into the output\n\
337 -R --remove-section <name> Remove section <name> from the output\n\
338 -S --strip-all Remove all symbol and relocation information\n\
339 -g --strip-debug Remove all debugging symbols\n\
340 --strip-unneeded Remove all symbols not needed by relocations\n\
341 -N --strip-symbol <name> Do not copy symbol <name>\n\
342 -K --keep-symbol <name> Only copy symbol <name>\n\
343 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
344 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
345 --weaken Force all global symbols to be marked as weak\n\
346 -x --discard-all Remove all non-global symbols\n\
347 -X --discard-locals Remove any compiler-generated symbols\n\
348 -i --interleave <number> Only copy one out of every <number> bytes\n\
349 -b --byte <num> Select byte <num> in every interleaved block\n\
350 --gap-fill <val> Fill gaps between sections with <val>\n\
351 --pad-to <addr> Pad the last section up to address <addr>\n\
352 --set-start <addr> Set the start address to <addr>\n\
353 {--change-start|--adjust-start} <incr>\n\
354 Add <incr> to the start address\n\
355 {--change-addresses|--adjust-vma} <incr>\n\
356 Add <incr> to LMA, VMA and start addresses\n\
357 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
358 Change LMA and VMA of section <name> by <val>\n\
359 --change-section-lma <name>{=|+|-}<val>\n\
360 Change the LMA of section <name> by <val>\n\
361 --change-section-vma <name>{=|+|-}<val>\n\
362 Change the VMA of section <name> by <val>\n\
363 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
364 Warn if a named section does not exist\n\
365 --set-section-flags <name>=<flags>\n\
366 Set section <name>'s properties to <flags>\n\
367 --add-section <name>=<file> Add section <name> found in <file> to output\n\
368 --change-leading-char Force output format's leading character style\n\
369 --remove-leading-char Remove leading character from global symbols\n\
370 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
371 --srec-len <number> Restrict the length of generated Srecords\n\
372 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
373 -v --verbose List all object files modified\n\
374 -V --version Display this program's version number\n\
375 -h --help Display this output\n\
376 "));
377 list_supported_targets (program_name, stream);
378 if (exit_status == 0)
379 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
380 exit (exit_status);
383 static void
384 strip_usage (stream, exit_status)
385 FILE *stream;
386 int exit_status;
388 fprintf (stream, _("Usage: %s <switches> in-file(s)\n"), program_name);
389 fprintf (stream, _(" The switches are:\n"));
390 fprintf (stream, _("\
391 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
392 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
393 -F --target <bfdname> Set both input and output format to <bfdname>\n\
394 -p --preserve-dates Copy modified/access timestamps to the output\n\
395 -R --remove-section <name> Remove section <name> from the output\n\
396 -s --strip-all Remove all symbol and relocation information\n\
397 -g -S --strip-debug Remove all debugging symbols\n\
398 --strip-unneeded Remove all symbols not needed by relocations\n\
399 -N --strip-symbol <name> Do not copy symbol <name>\n\
400 -K --keep-symbol <name> Only copy symbol <name>\n\
401 -x --discard-all Remove all non-global symbols\n\
402 -X --discard-locals Remove any compiler-generated symbols\n\
403 -v --verbose List all object files modified\n\
404 -V --version Display this program's version number\n\
405 -h --help Display this output\n\
406 -o <file> Place stripped output into <file>\n\
407 "));
409 list_supported_targets (program_name, stream);
410 if (exit_status == 0)
411 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
412 exit (exit_status);
415 /* Parse section flags into a flagword, with a fatal error if the
416 string can't be parsed. */
418 static flagword
419 parse_flags (s)
420 const char *s;
422 flagword ret;
423 const char *snext;
424 int len;
426 ret = SEC_NO_FLAGS;
430 snext = strchr (s, ',');
431 if (snext == NULL)
432 len = strlen (s);
433 else
435 len = snext - s;
436 ++snext;
439 if (0) ;
440 #define PARSE_FLAG(fname,fval) \
441 else if (strncasecmp (fname, s, len) == 0) ret |= fval
442 PARSE_FLAG ("alloc", SEC_ALLOC);
443 PARSE_FLAG ("load", SEC_LOAD);
444 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
445 PARSE_FLAG ("readonly", SEC_READONLY);
446 PARSE_FLAG ("debug", SEC_DEBUGGING);
447 PARSE_FLAG ("code", SEC_CODE);
448 PARSE_FLAG ("data", SEC_DATA);
449 PARSE_FLAG ("rom", SEC_ROM);
450 PARSE_FLAG ("share", SEC_SHARED);
451 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
452 #undef PARSE_FLAG
453 else
455 char *copy;
457 copy = xmalloc (len + 1);
458 strncpy (copy, s, len);
459 copy[len] = '\0';
460 non_fatal (_("unrecognized section flag `%s'"), copy);
461 fatal (_("supported flags: %s"),
462 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
465 s = snext;
467 while (s != NULL);
469 return ret;
472 /* Find and optionally add an entry in the change_sections list. */
474 static struct section_list *
475 find_section_list (name, add)
476 const char *name;
477 boolean add;
479 register struct section_list *p;
481 for (p = change_sections; p != NULL; p = p->next)
482 if (strcmp (p->name, name) == 0)
483 return p;
485 if (! add)
486 return NULL;
488 p = (struct section_list *) xmalloc (sizeof (struct section_list));
489 p->name = name;
490 p->used = false;
491 p->remove = false;
492 p->copy = false;
493 p->change_vma = CHANGE_IGNORE;
494 p->change_lma = CHANGE_IGNORE;
495 p->vma_val = 0;
496 p->lma_val = 0;
497 p->set_flags = false;
498 p->flags = 0;
500 p->next = change_sections;
501 change_sections = p;
503 return p;
506 /* Add a symbol to strip_specific_list. */
508 static void
509 add_specific_symbol (name, list)
510 const char *name;
511 struct symlist **list;
513 struct symlist *tmp_list;
515 tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
516 tmp_list->name = name;
517 tmp_list->next = *list;
518 *list = tmp_list;
521 /* See whether a symbol should be stripped or kept based on
522 strip_specific_list and keep_symbols. */
524 static boolean
525 is_specified_symbol (name, list)
526 const char *name;
527 struct symlist *list;
529 struct symlist *tmp_list;
531 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
533 if (strcmp (name, tmp_list->name) == 0)
534 return true;
536 return false;
539 /* See if a section is being removed. */
541 static boolean
542 is_strip_section (abfd, sec)
543 bfd *abfd ATTRIBUTE_UNUSED;
544 asection *sec;
546 struct section_list *p;
548 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
549 && (strip_symbols == STRIP_DEBUG
550 || strip_symbols == STRIP_UNNEEDED
551 || strip_symbols == STRIP_ALL
552 || discard_locals == LOCALS_ALL
553 || convert_debugging))
554 return true;
556 if (! sections_removed && ! sections_copied)
557 return false;
559 p = find_section_list (bfd_get_section_name (abfd, sec), false);
560 if (sections_removed && p != NULL && p->remove)
561 return true;
562 if (sections_copied && (p == NULL || ! p->copy))
563 return true;
564 return false;
567 /* Choose which symbol entries to copy; put the result in OSYMS.
568 We don't copy in place, because that confuses the relocs.
569 Return the number of symbols to print. */
571 static unsigned int
572 filter_symbols (abfd, obfd, osyms, isyms, symcount)
573 bfd *abfd;
574 bfd *obfd;
575 asymbol **osyms, **isyms;
576 long symcount;
578 register asymbol **from = isyms, **to = osyms;
579 long src_count = 0, dst_count = 0;
580 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
581 == HAS_RELOC;
583 for (; src_count < symcount; src_count++)
585 asymbol *sym = from[src_count];
586 flagword flags = sym->flags;
587 const char *name = bfd_asymbol_name (sym);
588 int keep;
590 if (redefine_sym_list)
592 const char *old_name, *new_name;
594 old_name = bfd_asymbol_name (sym);
595 new_name = lookup_sym_redefinition (old_name);
596 name = bfd_asymbol_name (sym) = new_name;
599 if (change_leading_char
600 && (bfd_get_symbol_leading_char (abfd)
601 != bfd_get_symbol_leading_char (obfd))
602 && (bfd_get_symbol_leading_char (abfd) == '\0'
603 || (name[0] == bfd_get_symbol_leading_char (abfd))))
605 if (bfd_get_symbol_leading_char (obfd) == '\0')
606 name = bfd_asymbol_name (sym) = name + 1;
607 else
609 char *n;
611 n = xmalloc (strlen (name) + 2);
612 n[0] = bfd_get_symbol_leading_char (obfd);
613 if (bfd_get_symbol_leading_char (abfd) == '\0')
614 strcpy (n + 1, name);
615 else
616 strcpy (n + 1, name + 1);
617 name = bfd_asymbol_name (sym) = n;
621 if (remove_leading_char
622 && ((flags & BSF_GLOBAL) != 0
623 || (flags & BSF_WEAK) != 0
624 || bfd_is_und_section (bfd_get_section (sym))
625 || bfd_is_com_section (bfd_get_section (sym)))
626 && name[0] == bfd_get_symbol_leading_char (abfd))
627 name = bfd_asymbol_name (sym) = name + 1;
629 if (strip_symbols == STRIP_ALL)
630 keep = 0;
631 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
632 || ((flags & BSF_SECTION_SYM) != 0
633 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
634 & BSF_KEEP) != 0))
635 keep = 1;
636 else if (relocatable /* Relocatable file. */
637 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
638 keep = 1;
639 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
640 || (flags & BSF_WEAK) != 0
641 || bfd_is_und_section (bfd_get_section (sym))
642 || bfd_is_com_section (bfd_get_section (sym)))
643 keep = strip_symbols != STRIP_UNNEEDED;
644 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
645 keep = (strip_symbols != STRIP_DEBUG
646 && strip_symbols != STRIP_UNNEEDED
647 && ! convert_debugging);
648 else /* Local symbol. */
649 keep = (strip_symbols != STRIP_UNNEEDED
650 && (discard_locals != LOCALS_ALL
651 && (discard_locals != LOCALS_START_L
652 || ! bfd_is_local_label (abfd, sym))));
654 if (keep && is_specified_symbol (name, strip_specific_list))
655 keep = 0;
656 if (!keep && is_specified_symbol (name, keep_specific_list))
657 keep = 1;
658 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
659 keep = 0;
661 if (keep && (flags & BSF_GLOBAL) != 0
662 && (weaken || is_specified_symbol (name, weaken_specific_list)))
664 sym->flags &=~ BSF_GLOBAL;
665 sym->flags |= BSF_WEAK;
667 if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
668 && is_specified_symbol (name, localize_specific_list))
670 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
671 sym->flags |= BSF_LOCAL;
674 if (keep)
675 to[dst_count++] = sym;
678 to[dst_count] = NULL;
680 return dst_count;
683 static const char *
684 lookup_sym_redefinition (source)
685 const char *source;
687 const char *result;
688 struct redefine_node *list;
690 result = source;
692 for (list = redefine_sym_list; list != NULL; list = list->next)
694 if (strcmp (source, list->source) == 0)
696 result = list->target;
697 break;
700 return result;
703 /* Add a node to a symbol redefine list */
705 static void
706 redefine_list_append (source, target)
707 const char *source;
708 const char *target;
710 struct redefine_node **p;
711 struct redefine_node *list;
712 struct redefine_node *new_node;
714 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
716 if (strcmp (source, list->source) == 0)
718 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
719 "--redefine-sym",
720 source);
723 if (strcmp (target, list->target) == 0)
725 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
726 "--redefine-sym",
727 target);
731 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
733 new_node->source = strdup (source);
734 new_node->target = strdup (target);
735 new_node->next = NULL;
737 *p = new_node;
741 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
742 Adjust *SIZE. */
744 static void
745 filter_bytes (memhunk, size)
746 char *memhunk;
747 bfd_size_type *size;
749 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
751 for (; from < end; from += interleave)
752 *to++ = *from;
753 if (*size % interleave > (bfd_size_type) copy_byte)
754 *size = (*size / interleave) + 1;
755 else
756 *size /= interleave;
759 /* Copy object file IBFD onto OBFD. */
761 static void
762 copy_object (ibfd, obfd)
763 bfd *ibfd;
764 bfd *obfd;
766 bfd_vma start;
767 long symcount;
768 asection **osections = NULL;
769 bfd_size_type *gaps = NULL;
770 bfd_size_type max_gap = 0;
771 long symsize;
772 PTR dhandle;
774 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
775 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
776 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
778 fatal (_("Unable to change endianness of input file(s)"));
779 return;
782 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
783 RETURN_NONFATAL (bfd_get_filename (obfd));
785 if (verbose)
786 printf (_("copy from %s(%s) to %s(%s)\n"),
787 bfd_get_filename (ibfd), bfd_get_target (ibfd),
788 bfd_get_filename (obfd), bfd_get_target (obfd));
790 if (set_start_set)
791 start = set_start;
792 else
793 start = bfd_get_start_address (ibfd);
794 start += change_start;
796 if (!bfd_set_start_address (obfd, start)
797 || !bfd_set_file_flags (obfd,
798 (bfd_get_file_flags (ibfd)
799 & bfd_applicable_file_flags (obfd))))
800 RETURN_NONFATAL (bfd_get_filename (ibfd));
802 /* Copy architecture of input file to output file */
803 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
804 bfd_get_mach (ibfd)))
805 non_fatal (_("Warning: Output file cannot represent architecture %s"),
806 bfd_printable_arch_mach (bfd_get_arch (ibfd),
807 bfd_get_mach (ibfd)));
809 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
810 RETURN_NONFATAL (bfd_get_filename (ibfd));
812 if (isympp)
813 free (isympp);
815 if (osympp != isympp)
816 free (osympp);
818 /* BFD mandates that all output sections be created and sizes set before
819 any output is done. Thus, we traverse all sections multiple times. */
820 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
822 if (add_sections != NULL)
824 struct section_add *padd;
825 struct section_list *pset;
827 for (padd = add_sections; padd != NULL; padd = padd->next)
829 padd->section = bfd_make_section (obfd, padd->name);
830 if (padd->section == NULL)
832 non_fatal (_("can't create section `%s': %s"),
833 padd->name, bfd_errmsg (bfd_get_error ()));
834 status = 1;
835 return;
837 else
839 flagword flags;
841 if (! bfd_set_section_size (obfd, padd->section, padd->size))
842 RETURN_NONFATAL (bfd_get_filename (obfd));
844 pset = find_section_list (padd->name, false);
845 if (pset != NULL)
846 pset->used = true;
848 if (pset != NULL && pset->set_flags)
849 flags = pset->flags | SEC_HAS_CONTENTS;
850 else
851 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
853 if (! bfd_set_section_flags (obfd, padd->section, flags))
854 RETURN_NONFATAL (bfd_get_filename (obfd));
856 if (pset != NULL)
858 if (pset->change_vma != CHANGE_IGNORE)
859 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
860 RETURN_NONFATAL (bfd_get_filename (obfd));
862 if (pset->change_lma != CHANGE_IGNORE)
864 padd->section->lma = pset->lma_val;
866 if (! bfd_set_section_alignment
867 (obfd, padd->section,
868 bfd_section_alignment (obfd, padd->section)))
869 RETURN_NONFATAL (bfd_get_filename (obfd));
876 if (gap_fill_set || pad_to_set)
878 asection **set;
879 unsigned int c, i;
881 /* We must fill in gaps between the sections and/or we must pad
882 the last section to a specified address. We do this by
883 grabbing a list of the sections, sorting them by VMA, and
884 increasing the section sizes as required to fill the gaps.
885 We write out the gap contents below. */
887 c = bfd_count_sections (obfd);
888 osections = (asection **) xmalloc (c * sizeof (asection *));
889 set = osections;
890 bfd_map_over_sections (obfd, get_sections, (void *) &set);
892 qsort (osections, c, sizeof (asection *), compare_section_lma);
894 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
895 memset (gaps, 0, c * sizeof (bfd_size_type));
897 if (gap_fill_set)
899 for (i = 0; i < c - 1; i++)
901 flagword flags;
902 bfd_size_type size;
903 bfd_vma gap_start, gap_stop;
905 flags = bfd_get_section_flags (obfd, osections[i]);
906 if ((flags & SEC_HAS_CONTENTS) == 0
907 || (flags & SEC_LOAD) == 0)
908 continue;
910 size = bfd_section_size (obfd, osections[i]);
911 gap_start = bfd_section_lma (obfd, osections[i]) + size;
912 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
913 if (gap_start < gap_stop)
915 if (! bfd_set_section_size (obfd, osections[i],
916 size + (gap_stop - gap_start)))
918 non_fatal (_("Can't fill gap after %s: %s"),
919 bfd_get_section_name (obfd, osections[i]),
920 bfd_errmsg (bfd_get_error ()));
921 status = 1;
922 break;
924 gaps[i] = gap_stop - gap_start;
925 if (max_gap < gap_stop - gap_start)
926 max_gap = gap_stop - gap_start;
931 if (pad_to_set)
933 bfd_vma lma;
934 bfd_size_type size;
936 lma = bfd_section_lma (obfd, osections[c - 1]);
937 size = bfd_section_size (obfd, osections[c - 1]);
938 if (lma + size < pad_to)
940 if (! bfd_set_section_size (obfd, osections[c - 1],
941 pad_to - lma))
943 non_fatal (_("Can't add padding to %s: %s"),
944 bfd_get_section_name (obfd, osections[c - 1]),
945 bfd_errmsg (bfd_get_error ()));
946 status = 1;
948 else
950 gaps[c - 1] = pad_to - (lma + size);
951 if (max_gap < pad_to - (lma + size))
952 max_gap = pad_to - (lma + size);
958 /* Symbol filtering must happen after the output sections have
959 been created, but before their contents are set. */
960 dhandle = NULL;
961 symsize = bfd_get_symtab_upper_bound (ibfd);
962 if (symsize < 0)
963 RETURN_NONFATAL (bfd_get_filename (ibfd));
965 osympp = isympp = (asymbol **) xmalloc (symsize);
966 symcount = bfd_canonicalize_symtab (ibfd, isympp);
967 if (symcount < 0)
968 RETURN_NONFATAL (bfd_get_filename (ibfd));
970 if (convert_debugging)
971 dhandle = read_debugging_info (ibfd, isympp, symcount);
973 if (strip_symbols == STRIP_DEBUG
974 || strip_symbols == STRIP_ALL
975 || strip_symbols == STRIP_UNNEEDED
976 || discard_locals != LOCALS_UNDEF
977 || strip_specific_list != NULL
978 || keep_specific_list != NULL
979 || localize_specific_list != NULL
980 || weaken_specific_list != NULL
981 || sections_removed
982 || sections_copied
983 || convert_debugging
984 || change_leading_char
985 || remove_leading_char
986 || redefine_sym_list
987 || weaken)
989 /* Mark symbols used in output relocations so that they
990 are kept, even if they are local labels or static symbols.
992 Note we iterate over the input sections examining their
993 relocations since the relocations for the output sections
994 haven't been set yet. mark_symbols_used_in_relocations will
995 ignore input sections which have no corresponding output
996 section. */
997 if (strip_symbols != STRIP_ALL)
998 bfd_map_over_sections (ibfd,
999 mark_symbols_used_in_relocations,
1000 (PTR)isympp);
1001 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
1002 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1005 if (convert_debugging && dhandle != NULL)
1007 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1009 status = 1;
1010 return;
1014 bfd_set_symtab (obfd, osympp, symcount);
1016 /* This has to happen after the symbol table has been set. */
1017 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1019 if (add_sections != NULL)
1021 struct section_add *padd;
1023 for (padd = add_sections; padd != NULL; padd = padd->next)
1025 if (! bfd_set_section_contents (obfd, padd->section,
1026 (PTR) padd->contents,
1027 (file_ptr) 0,
1028 (bfd_size_type) padd->size))
1029 RETURN_NONFATAL (bfd_get_filename (obfd));
1033 if (gap_fill_set || pad_to_set)
1035 bfd_byte *buf;
1036 int c, i;
1038 /* Fill in the gaps. */
1040 if (max_gap > 8192)
1041 max_gap = 8192;
1042 buf = (bfd_byte *) xmalloc (max_gap);
1043 memset (buf, gap_fill, (size_t) max_gap);
1045 c = bfd_count_sections (obfd);
1046 for (i = 0; i < c; i++)
1048 if (gaps[i] != 0)
1050 bfd_size_type left;
1051 file_ptr off;
1053 left = gaps[i];
1054 off = bfd_section_size (obfd, osections[i]) - left;
1055 while (left > 0)
1057 bfd_size_type now;
1059 if (left > 8192)
1060 now = 8192;
1061 else
1062 now = left;
1064 if (! bfd_set_section_contents (obfd, osections[i], buf,
1065 off, now))
1066 RETURN_NONFATAL (bfd_get_filename (obfd));
1068 left -= now;
1069 off += now;
1075 /* Allow the BFD backend to copy any private data it understands
1076 from the input BFD to the output BFD. This is done last to
1077 permit the routine to look at the filtered symbol table, which is
1078 important for the ECOFF code at least. */
1079 if (!bfd_copy_private_bfd_data (ibfd, obfd))
1081 non_fatal (_("%s: error copying private BFD data: %s"),
1082 bfd_get_filename (obfd),
1083 bfd_errmsg (bfd_get_error ()));
1084 status = 1;
1085 return;
1089 /* Read each archive element in turn from IBFD, copy the
1090 contents to temp file, and keep the temp file handle. */
1092 static void
1093 copy_archive (ibfd, obfd, output_target)
1094 bfd *ibfd;
1095 bfd *obfd;
1096 const char *output_target;
1098 struct name_list
1100 struct name_list *next;
1101 char *name;
1102 bfd *obfd;
1103 } *list, *l;
1104 bfd **ptr = &obfd->archive_head;
1105 bfd *this_element;
1106 char *dir = make_tempname (bfd_get_filename (obfd));
1108 /* Make a temp directory to hold the contents. */
1109 #if defined (_WIN32) && !defined (__CYGWIN32__)
1110 if (mkdir (dir) != 0)
1111 #else
1112 if (mkdir (dir, 0700) != 0)
1113 #endif
1115 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1116 dir, strerror (errno));
1118 obfd->has_armap = ibfd->has_armap;
1120 list = NULL;
1122 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1123 while (!status && this_element != (bfd *) NULL)
1125 /* Create an output file for this member. */
1126 char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1127 (char *) NULL);
1128 bfd *output_bfd = bfd_openw (output_name, output_target);
1129 bfd *last_element;
1130 struct stat buf;
1131 int stat_status = 0;
1133 if (preserve_dates)
1135 stat_status = bfd_stat_arch_elt (this_element, &buf);
1136 if (stat_status != 0)
1137 non_fatal (_("internal stat error on %s"),
1138 bfd_get_filename (this_element));
1141 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1142 l->name = output_name;
1143 l->next = list;
1144 list = l;
1146 if (output_bfd == (bfd *) NULL)
1147 RETURN_NONFATAL (output_name);
1149 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1150 RETURN_NONFATAL (bfd_get_filename (obfd));
1152 if (bfd_check_format (this_element, bfd_object) == true)
1153 copy_object (this_element, output_bfd);
1155 if (!bfd_close (output_bfd))
1157 bfd_nonfatal (bfd_get_filename (output_bfd));
1158 /* Error in new object file. Don't change archive. */
1159 status = 1;
1162 if (preserve_dates && stat_status == 0)
1163 set_times (output_name, &buf);
1165 /* Open the newly output file and attach to our list. */
1166 output_bfd = bfd_openr (output_name, output_target);
1168 l->obfd = output_bfd;
1170 *ptr = output_bfd;
1171 ptr = &output_bfd->next;
1173 last_element = this_element;
1175 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1177 bfd_close (last_element);
1179 *ptr = (bfd *) NULL;
1181 if (!bfd_close (obfd))
1182 RETURN_NONFATAL (bfd_get_filename (obfd));
1184 if (!bfd_close (ibfd))
1185 RETURN_NONFATAL (bfd_get_filename (ibfd));
1187 /* Delete all the files that we opened. */
1188 for (l = list; l != NULL; l = l->next)
1190 bfd_close (l->obfd);
1191 unlink (l->name);
1193 rmdir (dir);
1196 /* The top-level control. */
1198 static void
1199 copy_file (input_filename, output_filename, input_target, output_target)
1200 const char *input_filename;
1201 const char *output_filename;
1202 const char *input_target;
1203 const char *output_target;
1205 bfd *ibfd;
1206 char **matching;
1208 /* To allow us to do "strip *" without dying on the first
1209 non-object file, failures are nonfatal. */
1211 ibfd = bfd_openr (input_filename, input_target);
1212 if (ibfd == NULL)
1213 RETURN_NONFATAL (input_filename);
1215 if (bfd_check_format (ibfd, bfd_archive))
1217 bfd *obfd;
1219 /* bfd_get_target does not return the correct value until
1220 bfd_check_format succeeds. */
1221 if (output_target == NULL)
1222 output_target = bfd_get_target (ibfd);
1224 obfd = bfd_openw (output_filename, output_target);
1225 if (obfd == NULL)
1226 RETURN_NONFATAL (output_filename);
1228 copy_archive (ibfd, obfd, output_target);
1230 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1232 bfd *obfd;
1234 /* bfd_get_target does not return the correct value until
1235 bfd_check_format succeeds. */
1236 if (output_target == NULL)
1237 output_target = bfd_get_target (ibfd);
1239 obfd = bfd_openw (output_filename, output_target);
1240 if (obfd == NULL)
1241 RETURN_NONFATAL (output_filename);
1243 copy_object (ibfd, obfd);
1245 if (!bfd_close (obfd))
1246 RETURN_NONFATAL (output_filename);
1248 if (!bfd_close (ibfd))
1249 RETURN_NONFATAL (input_filename);
1251 else
1253 bfd_nonfatal (input_filename);
1255 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1257 list_matching_formats (matching);
1258 free (matching);
1261 status = 1;
1265 /* Create a section in OBFD with the same name and attributes
1266 as ISECTION in IBFD. */
1268 static void
1269 setup_section (ibfd, isection, obfdarg)
1270 bfd *ibfd;
1271 sec_ptr isection;
1272 PTR obfdarg;
1274 bfd *obfd = (bfd *) obfdarg;
1275 struct section_list *p;
1276 sec_ptr osection;
1277 bfd_size_type size;
1278 bfd_vma vma;
1279 bfd_vma lma;
1280 flagword flags;
1281 const char *err;
1283 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1284 && (strip_symbols == STRIP_DEBUG
1285 || strip_symbols == STRIP_UNNEEDED
1286 || strip_symbols == STRIP_ALL
1287 || discard_locals == LOCALS_ALL
1288 || convert_debugging))
1289 return;
1291 p = find_section_list (bfd_section_name (ibfd, isection), false);
1292 if (p != NULL)
1293 p->used = true;
1295 if (sections_removed && p != NULL && p->remove)
1296 return;
1297 if (sections_copied && (p == NULL || ! p->copy))
1298 return;
1300 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1302 if (osection == NULL)
1304 err = _("making");
1305 goto loser;
1308 size = bfd_section_size (ibfd, isection);
1309 if (copy_byte >= 0)
1310 size = (size + interleave - 1) / interleave;
1311 if (! bfd_set_section_size (obfd, osection, size))
1313 err = _("size");
1314 goto loser;
1317 vma = bfd_section_vma (ibfd, isection);
1318 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1319 vma += p->vma_val;
1320 else if (p != NULL && p->change_vma == CHANGE_SET)
1321 vma = p->vma_val;
1322 else
1323 vma += change_section_address;
1325 if (! bfd_set_section_vma (obfd, osection, vma))
1327 err = _("vma");
1328 goto loser;
1331 lma = isection->lma;
1332 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1334 if (p->change_lma == CHANGE_MODIFY)
1335 lma += p->lma_val;
1336 else if (p->change_lma == CHANGE_SET)
1337 lma = p->lma_val;
1338 else
1339 abort ();
1341 else
1342 lma += change_section_address;
1344 osection->lma = lma;
1346 /* FIXME: This is probably not enough. If we change the LMA we
1347 may have to recompute the header for the file as well. */
1348 if (bfd_set_section_alignment (obfd,
1349 osection,
1350 bfd_section_alignment (ibfd, isection))
1351 == false)
1353 err = _("alignment");
1354 goto loser;
1357 flags = bfd_get_section_flags (ibfd, isection);
1358 if (p != NULL && p->set_flags)
1359 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1360 if (!bfd_set_section_flags (obfd, osection, flags))
1362 err = _("flags");
1363 goto loser;
1366 /* This used to be mangle_section; we do here to avoid using
1367 bfd_get_section_by_name since some formats allow multiple
1368 sections with the same name. */
1369 isection->output_section = osection;
1370 isection->output_offset = 0;
1372 /* Allow the BFD backend to copy any private data it understands
1373 from the input section to the output section. */
1374 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1376 err = _("private data");
1377 goto loser;
1380 /* All went well */
1381 return;
1383 loser:
1384 non_fatal (_("%s: section `%s': error in %s: %s"),
1385 bfd_get_filename (ibfd),
1386 bfd_section_name (ibfd, isection),
1387 err, bfd_errmsg (bfd_get_error ()));
1388 status = 1;
1391 /* Copy the data of input section ISECTION of IBFD
1392 to an output section with the same name in OBFD.
1393 If stripping then don't copy any relocation info. */
1395 static void
1396 copy_section (ibfd, isection, obfdarg)
1397 bfd *ibfd;
1398 sec_ptr isection;
1399 PTR obfdarg;
1401 bfd *obfd = (bfd *) obfdarg;
1402 struct section_list *p;
1403 arelent **relpp;
1404 long relcount;
1405 sec_ptr osection;
1406 bfd_size_type size;
1407 long relsize;
1409 /* If we have already failed earlier on, do not keep on generating
1410 complaints now. */
1411 if (status != 0)
1412 return;
1414 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1415 && (strip_symbols == STRIP_DEBUG
1416 || strip_symbols == STRIP_UNNEEDED
1417 || strip_symbols == STRIP_ALL
1418 || discard_locals == LOCALS_ALL
1419 || convert_debugging))
1421 return;
1424 p = find_section_list (bfd_section_name (ibfd, isection), false);
1426 if (sections_removed && p != NULL && p->remove)
1427 return;
1428 if (sections_copied && (p == NULL || ! p->copy))
1429 return;
1431 osection = isection->output_section;
1432 size = bfd_get_section_size_before_reloc (isection);
1434 if (size == 0 || osection == 0)
1435 return;
1438 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1439 if (relsize < 0)
1440 RETURN_NONFATAL (bfd_get_filename (ibfd));
1442 if (relsize == 0)
1443 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1444 else
1446 relpp = (arelent **) xmalloc (relsize);
1447 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1448 if (relcount < 0)
1449 RETURN_NONFATAL (bfd_get_filename (ibfd));
1451 if (strip_symbols == STRIP_ALL)
1453 /* Remove relocations which are not in
1454 keep_strip_specific_list. */
1455 arelent **temp_relpp;
1456 long temp_relcount = 0;
1457 long i;
1459 temp_relpp = (arelent **) xmalloc (relsize);
1460 for (i = 0; i < relcount; i++)
1461 if (is_specified_symbol
1462 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
1463 keep_specific_list))
1464 temp_relpp [temp_relcount++] = relpp [i];
1465 relcount = temp_relcount;
1466 free (relpp);
1467 relpp = temp_relpp;
1469 bfd_set_reloc (obfd, osection,
1470 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1473 isection->_cooked_size = isection->_raw_size;
1474 isection->reloc_done = true;
1476 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1478 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1480 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1481 size))
1482 RETURN_NONFATAL (bfd_get_filename (ibfd));
1484 if (copy_byte >= 0)
1485 filter_bytes (memhunk, &size);
1487 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1488 size))
1489 RETURN_NONFATAL (bfd_get_filename (obfd));
1491 free (memhunk);
1493 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1495 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1497 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1498 flag--they can just remove the section entirely and add it
1499 back again. However, we do permit them to turn on the
1500 SEC_HAS_CONTENTS flag, and take it to mean that the section
1501 contents should be zeroed out. */
1503 memset (memhunk, 0, size);
1504 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1505 size))
1506 RETURN_NONFATAL (bfd_get_filename (obfd));
1507 free (memhunk);
1511 /* Get all the sections. This is used when --gap-fill or --pad-to is
1512 used. */
1514 static void
1515 get_sections (obfd, osection, secppparg)
1516 bfd *obfd ATTRIBUTE_UNUSED;
1517 asection *osection;
1518 PTR secppparg;
1520 asection ***secppp = (asection ***) secppparg;
1522 **secppp = osection;
1523 ++(*secppp);
1526 /* Sort sections by VMA. This is called via qsort, and is used when
1527 --gap-fill or --pad-to is used. We force non loadable or empty
1528 sections to the front, where they are easier to ignore. */
1530 static int
1531 compare_section_lma (arg1, arg2)
1532 const PTR arg1;
1533 const PTR arg2;
1535 const asection **sec1 = (const asection **) arg1;
1536 const asection **sec2 = (const asection **) arg2;
1537 flagword flags1, flags2;
1539 /* Sort non loadable sections to the front. */
1540 flags1 = (*sec1)->flags;
1541 flags2 = (*sec2)->flags;
1542 if ((flags1 & SEC_HAS_CONTENTS) == 0
1543 || (flags1 & SEC_LOAD) == 0)
1545 if ((flags2 & SEC_HAS_CONTENTS) != 0
1546 && (flags2 & SEC_LOAD) != 0)
1547 return -1;
1549 else
1551 if ((flags2 & SEC_HAS_CONTENTS) == 0
1552 || (flags2 & SEC_LOAD) == 0)
1553 return 1;
1556 /* Sort sections by LMA. */
1557 if ((*sec1)->lma > (*sec2)->lma)
1558 return 1;
1559 else if ((*sec1)->lma < (*sec2)->lma)
1560 return -1;
1562 /* Sort sections with the same LMA by size. */
1563 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1564 return 1;
1565 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1566 return -1;
1568 return 0;
1571 /* Mark all the symbols which will be used in output relocations with
1572 the BSF_KEEP flag so that those symbols will not be stripped.
1574 Ignore relocations which will not appear in the output file. */
1576 static void
1577 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1578 bfd *ibfd;
1579 sec_ptr isection;
1580 PTR symbolsarg;
1582 asymbol **symbols = (asymbol **) symbolsarg;
1583 long relsize;
1584 arelent **relpp;
1585 long relcount, i;
1587 /* Ignore an input section with no corresponding output section. */
1588 if (isection->output_section == NULL)
1589 return;
1591 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1592 if (relsize < 0)
1593 bfd_fatal (bfd_get_filename (ibfd));
1595 if (relsize == 0)
1596 return;
1598 relpp = (arelent **) xmalloc (relsize);
1599 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1600 if (relcount < 0)
1601 bfd_fatal (bfd_get_filename (ibfd));
1603 /* Examine each symbol used in a relocation. If it's not one of the
1604 special bfd section symbols, then mark it with BSF_KEEP. */
1605 for (i = 0; i < relcount; i++)
1607 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1608 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1609 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1610 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1613 if (relpp != NULL)
1614 free (relpp);
1617 /* Write out debugging information. */
1619 static boolean
1620 write_debugging_info (obfd, dhandle, symcountp, symppp)
1621 bfd *obfd;
1622 PTR dhandle;
1623 long *symcountp ATTRIBUTE_UNUSED;
1624 asymbol ***symppp ATTRIBUTE_UNUSED;
1626 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1627 return write_ieee_debugging_info (obfd, dhandle);
1629 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1630 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1632 bfd_byte *syms, *strings;
1633 bfd_size_type symsize, stringsize;
1634 asection *stabsec, *stabstrsec;
1636 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1637 &symsize, &strings,
1638 &stringsize))
1639 return false;
1641 stabsec = bfd_make_section (obfd, ".stab");
1642 stabstrsec = bfd_make_section (obfd, ".stabstr");
1643 if (stabsec == NULL
1644 || stabstrsec == NULL
1645 || ! bfd_set_section_size (obfd, stabsec, symsize)
1646 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1647 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1648 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1649 || ! bfd_set_section_flags (obfd, stabsec,
1650 (SEC_HAS_CONTENTS
1651 | SEC_READONLY
1652 | SEC_DEBUGGING))
1653 || ! bfd_set_section_flags (obfd, stabstrsec,
1654 (SEC_HAS_CONTENTS
1655 | SEC_READONLY
1656 | SEC_DEBUGGING)))
1658 non_fatal (_("%s: can't create debugging section: %s"),
1659 bfd_get_filename (obfd),
1660 bfd_errmsg (bfd_get_error ()));
1661 return false;
1664 /* We can get away with setting the section contents now because
1665 the next thing the caller is going to do is copy over the
1666 real sections. We may someday have to split the contents
1667 setting out of this function. */
1668 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1669 symsize)
1670 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1671 (file_ptr) 0, stringsize))
1673 non_fatal (_("%s: can't set debugging section contents: %s"),
1674 bfd_get_filename (obfd),
1675 bfd_errmsg (bfd_get_error ()));
1676 return false;
1679 return true;
1682 non_fatal (_("%s: don't know how to write debugging information for %s"),
1683 bfd_get_filename (obfd), bfd_get_target (obfd));
1684 return false;
1687 static int
1688 strip_main (argc, argv)
1689 int argc;
1690 char *argv[];
1692 char *input_target = NULL, *output_target = NULL;
1693 boolean show_version = false;
1694 int c, i;
1695 struct section_list *p;
1696 char *output_file = NULL;
1698 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1699 strip_options, (int *) 0)) != EOF)
1701 switch (c)
1703 case 'I':
1704 input_target = optarg;
1705 break;
1706 case 'O':
1707 output_target = optarg;
1708 break;
1709 case 'F':
1710 input_target = output_target = optarg;
1711 break;
1712 case 'R':
1713 p = find_section_list (optarg, true);
1714 p->remove = true;
1715 sections_removed = true;
1716 break;
1717 case 's':
1718 strip_symbols = STRIP_ALL;
1719 break;
1720 case 'S':
1721 case 'g':
1722 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1723 strip_symbols = STRIP_DEBUG;
1724 break;
1725 case OPTION_STRIP_UNNEEDED:
1726 strip_symbols = STRIP_UNNEEDED;
1727 break;
1728 case 'K':
1729 add_specific_symbol (optarg, &keep_specific_list);
1730 break;
1731 case 'N':
1732 add_specific_symbol (optarg, &strip_specific_list);
1733 break;
1734 case 'o':
1735 output_file = optarg;
1736 break;
1737 case 'p':
1738 preserve_dates = true;
1739 break;
1740 case 'x':
1741 discard_locals = LOCALS_ALL;
1742 break;
1743 case 'X':
1744 discard_locals = LOCALS_START_L;
1745 break;
1746 case 'v':
1747 verbose = true;
1748 break;
1749 case 'V':
1750 show_version = true;
1751 break;
1752 case 0:
1753 break; /* we've been given a long option */
1754 case 'h':
1755 strip_usage (stdout, 0);
1756 default:
1757 strip_usage (stderr, 1);
1761 if (show_version)
1762 print_version ("strip");
1764 /* Default is to strip all symbols. */
1765 if (strip_symbols == STRIP_UNDEF
1766 && discard_locals == LOCALS_UNDEF
1767 && strip_specific_list == NULL)
1768 strip_symbols = STRIP_ALL;
1770 if (output_target == (char *) NULL)
1771 output_target = input_target;
1773 i = optind;
1774 if (i == argc
1775 || (output_file != NULL && (i + 1) < argc))
1776 strip_usage (stderr, 1);
1778 for (; i < argc; i++)
1780 int hold_status = status;
1781 struct stat statbuf;
1782 char *tmpname;
1784 if (preserve_dates)
1786 if (stat (argv[i], &statbuf) < 0)
1788 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1789 continue;
1793 if (output_file != NULL)
1794 tmpname = output_file;
1795 else
1796 tmpname = make_tempname (argv[i]);
1797 status = 0;
1799 copy_file (argv[i], tmpname, input_target, output_target);
1800 if (status == 0)
1802 if (preserve_dates)
1803 set_times (tmpname, &statbuf);
1804 if (output_file == NULL)
1805 smart_rename (tmpname, argv[i], preserve_dates);
1806 status = hold_status;
1808 else
1809 unlink (tmpname);
1810 if (output_file == NULL)
1811 free (tmpname);
1814 return 0;
1817 static int
1818 copy_main (argc, argv)
1819 int argc;
1820 char *argv[];
1822 char * binary_architecture = NULL;
1823 char *input_filename = NULL, *output_filename = NULL;
1824 char *input_target = NULL, *output_target = NULL;
1825 boolean show_version = false;
1826 boolean change_warn = true;
1827 int c;
1828 struct section_list *p;
1829 struct stat statbuf;
1831 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
1832 copy_options, (int *) 0)) != EOF)
1834 switch (c)
1836 case 'b':
1837 copy_byte = atoi (optarg);
1838 if (copy_byte < 0)
1839 fatal (_("byte number must be non-negative"));
1840 break;
1842 case 'B':
1843 binary_architecture = optarg;
1844 break;
1846 case 'i':
1847 interleave = atoi (optarg);
1848 if (interleave < 1)
1849 fatal (_("interleave must be positive"));
1850 break;
1852 case 'I':
1853 case 's': /* "source" - 'I' is preferred */
1854 input_target = optarg;
1855 break;
1857 case 'O':
1858 case 'd': /* "destination" - 'O' is preferred */
1859 output_target = optarg;
1860 break;
1862 case 'F':
1863 input_target = output_target = optarg;
1864 break;
1866 case 'j':
1867 p = find_section_list (optarg, true);
1868 if (p->remove)
1869 fatal (_("%s both copied and removed"), optarg);
1870 p->copy = true;
1871 sections_copied = true;
1872 break;
1874 case 'R':
1875 p = find_section_list (optarg, true);
1876 if (p->copy)
1877 fatal (_("%s both copied and removed"), optarg);
1878 p->remove = true;
1879 sections_removed = true;
1880 break;
1882 case 'S':
1883 strip_symbols = STRIP_ALL;
1884 break;
1886 case 'g':
1887 strip_symbols = STRIP_DEBUG;
1888 break;
1890 case OPTION_STRIP_UNNEEDED:
1891 strip_symbols = STRIP_UNNEEDED;
1892 break;
1894 case 'K':
1895 add_specific_symbol (optarg, &keep_specific_list);
1896 break;
1898 case 'N':
1899 add_specific_symbol (optarg, &strip_specific_list);
1900 break;
1902 case 'L':
1903 add_specific_symbol (optarg, &localize_specific_list);
1904 break;
1906 case 'W':
1907 add_specific_symbol (optarg, &weaken_specific_list);
1908 break;
1910 case 'p':
1911 preserve_dates = true;
1912 break;
1914 case 'x':
1915 discard_locals = LOCALS_ALL;
1916 break;
1918 case 'X':
1919 discard_locals = LOCALS_START_L;
1920 break;
1922 case 'v':
1923 verbose = true;
1924 break;
1926 case 'V':
1927 show_version = true;
1928 break;
1930 case OPTION_WEAKEN:
1931 weaken = true;
1932 break;
1934 case OPTION_ADD_SECTION:
1936 const char *s;
1937 struct stat st;
1938 struct section_add *pa;
1939 int len;
1940 char *name;
1941 FILE *f;
1943 s = strchr (optarg, '=');
1945 if (s == NULL)
1946 fatal (_("bad format for %s"), "--add-section");
1948 if (stat (s + 1, & st) < 0)
1949 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
1951 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1953 len = s - optarg;
1954 name = (char *) xmalloc (len + 1);
1955 strncpy (name, optarg, len);
1956 name[len] = '\0';
1957 pa->name = name;
1959 pa->filename = s + 1;
1961 pa->size = st.st_size;
1963 pa->contents = (bfd_byte *) xmalloc (pa->size);
1964 f = fopen (pa->filename, FOPEN_RB);
1966 if (f == NULL)
1967 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
1969 if (fread (pa->contents, 1, pa->size, f) == 0
1970 || ferror (f))
1971 fatal (_("%s: fread failed"), pa->filename);
1973 fclose (f);
1975 pa->next = add_sections;
1976 add_sections = pa;
1978 break;
1980 case OPTION_CHANGE_START:
1981 change_start = parse_vma (optarg, "--change-start");
1982 break;
1984 case OPTION_CHANGE_SECTION_ADDRESS:
1985 case OPTION_CHANGE_SECTION_LMA:
1986 case OPTION_CHANGE_SECTION_VMA:
1988 const char *s;
1989 int len;
1990 char *name;
1991 char *option = NULL;
1992 bfd_vma val;
1993 enum change_action what = CHANGE_IGNORE;
1995 switch (c)
1997 case OPTION_CHANGE_SECTION_ADDRESS:
1998 option = "--change-section-address";
1999 break;
2000 case OPTION_CHANGE_SECTION_LMA:
2001 option = "--change-section-lma";
2002 break;
2003 case OPTION_CHANGE_SECTION_VMA:
2004 option = "--change-section-vma";
2005 break;
2008 s = strchr (optarg, '=');
2009 if (s == NULL)
2011 s = strchr (optarg, '+');
2012 if (s == NULL)
2014 s = strchr (optarg, '-');
2015 if (s == NULL)
2016 fatal (_("bad format for %s"), option);
2020 len = s - optarg;
2021 name = (char *) xmalloc (len + 1);
2022 strncpy (name, optarg, len);
2023 name[len] = '\0';
2025 p = find_section_list (name, true);
2027 val = parse_vma (s + 1, option);
2029 switch (*s)
2031 case '=': what = CHANGE_SET; break;
2032 case '-': val = - val; /* Drop through. */
2033 case '+': what = CHANGE_MODIFY; break;
2036 switch (c)
2038 case OPTION_CHANGE_SECTION_ADDRESS:
2039 p->change_vma = what;
2040 p->vma_val = val;
2041 /* Drop through. */
2043 case OPTION_CHANGE_SECTION_LMA:
2044 p->change_lma = what;
2045 p->lma_val = val;
2046 break;
2048 case OPTION_CHANGE_SECTION_VMA:
2049 p->change_vma = what;
2050 p->vma_val = val;
2051 break;
2054 break;
2056 case OPTION_CHANGE_ADDRESSES:
2057 change_section_address = parse_vma (optarg, "--change-addresses");
2058 change_start = change_section_address;
2059 break;
2061 case OPTION_CHANGE_WARNINGS:
2062 change_warn = true;
2063 break;
2065 case OPTION_CHANGE_LEADING_CHAR:
2066 change_leading_char = true;
2067 break;
2069 case OPTION_DEBUGGING:
2070 convert_debugging = true;
2071 break;
2073 case OPTION_GAP_FILL:
2075 bfd_vma gap_fill_vma;
2077 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2078 gap_fill = (bfd_byte) gap_fill_vma;
2079 if ((bfd_vma) gap_fill != gap_fill_vma)
2081 char buff[20];
2083 sprintf_vma (buff, gap_fill_vma);
2085 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2086 buff, gap_fill);
2088 gap_fill_set = true;
2090 break;
2092 case OPTION_NO_CHANGE_WARNINGS:
2093 change_warn = false;
2094 break;
2096 case OPTION_PAD_TO:
2097 pad_to = parse_vma (optarg, "--pad-to");
2098 pad_to_set = true;
2099 break;
2101 case OPTION_REMOVE_LEADING_CHAR:
2102 remove_leading_char = true;
2103 break;
2105 case OPTION_REDEFINE_SYM:
2107 /* Push this redefinition onto redefine_symbol_list. */
2109 int len;
2110 const char *s;
2111 const char *nextarg;
2112 char *source, *target;
2114 s = strchr (optarg, '=');
2115 if (s == NULL)
2117 fatal (_("bad format for %s"), "--redefine-sym");
2120 len = s - optarg;
2121 source = (char *) xmalloc (len + 1);
2122 strncpy (source, optarg, len);
2123 source[len] = '\0';
2125 nextarg = s + 1;
2126 len = strlen (nextarg);
2127 target = (char *) xmalloc (len + 1);
2128 strcpy (target, nextarg);
2130 redefine_list_append (source, target);
2132 free (source);
2133 free (target);
2135 break;
2137 case OPTION_SET_SECTION_FLAGS:
2139 const char *s;
2140 int len;
2141 char *name;
2143 s = strchr (optarg, '=');
2144 if (s == NULL)
2145 fatal (_("bad format for %s"), "--set-section-flags");
2147 len = s - optarg;
2148 name = (char *) xmalloc (len + 1);
2149 strncpy (name, optarg, len);
2150 name[len] = '\0';
2152 p = find_section_list (name, true);
2154 p->set_flags = true;
2155 p->flags = parse_flags (s + 1);
2157 break;
2159 case OPTION_SET_START:
2160 set_start = parse_vma (optarg, "--set-start");
2161 set_start_set = true;
2162 break;
2164 case OPTION_SREC_LEN:
2165 Chunk = parse_vma (optarg, "--srec-len");
2166 break;
2168 case OPTION_SREC_FORCES3:
2169 S3Forced = true;
2170 break;
2172 case 0:
2173 break; /* we've been given a long option */
2175 case 'h':
2176 copy_usage (stdout, 0);
2178 default:
2179 copy_usage (stderr, 1);
2183 if (show_version)
2184 print_version ("objcopy");
2186 if (copy_byte >= interleave)
2187 fatal (_("byte number must be less than interleave"));
2189 if (optind == argc || optind + 2 < argc)
2190 copy_usage (stderr, 1);
2192 input_filename = argv[optind];
2193 if (optind + 1 < argc)
2194 output_filename = argv[optind + 1];
2196 /* Default is to strip no symbols. */
2197 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2198 strip_symbols = STRIP_NONE;
2200 if (output_target == (char *) NULL)
2201 output_target = input_target;
2203 if (binary_architecture != (char *) NULL)
2205 if (input_target && strcmp (input_target, "binary") == 0)
2207 const bfd_arch_info_type * temp_arch_info;
2209 temp_arch_info = bfd_scan_arch (binary_architecture);
2211 if (temp_arch_info != NULL)
2212 bfd_external_binary_architecture = temp_arch_info->arch;
2213 else
2214 fatal (_("architecture %s unknown"), binary_architecture);
2216 else
2218 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2219 non_fatal (_(" Argument %s ignored"), binary_architecture);
2223 if (preserve_dates)
2224 if (stat (input_filename, & statbuf) < 0)
2225 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2227 /* If there is no destination file then create a temp and rename
2228 the result into the input. */
2230 if (output_filename == (char *) NULL)
2232 char *tmpname = make_tempname (input_filename);
2234 copy_file (input_filename, tmpname, input_target, output_target);
2235 if (status == 0)
2237 if (preserve_dates)
2238 set_times (tmpname, &statbuf);
2239 smart_rename (tmpname, input_filename, preserve_dates);
2241 else
2242 unlink (tmpname);
2244 else
2246 copy_file (input_filename, output_filename, input_target, output_target);
2247 if (status == 0 && preserve_dates)
2248 set_times (output_filename, &statbuf);
2251 if (change_warn)
2253 for (p = change_sections; p != NULL; p = p->next)
2255 if (! p->used)
2257 if (p->change_vma != CHANGE_IGNORE)
2259 char buff [20];
2261 sprintf_vma (buff, p->vma_val);
2263 /* xgettext:c-format */
2264 non_fatal (_("%s %s%c0x%s never used"),
2265 "--change-section-vma",
2266 p->name,
2267 p->change_vma == CHANGE_SET ? '=' : '+',
2268 buff);
2271 if (p->change_lma != CHANGE_IGNORE)
2273 char buff [20];
2275 sprintf_vma (buff, p->lma_val);
2277 /* xgettext:c-format */
2278 non_fatal (_("%s %s%c0x%s never used"),
2279 "--change-section-lma",
2280 p->name,
2281 p->change_lma == CHANGE_SET ? '=' : '+',
2282 buff);
2288 return 0;
2292 main (argc, argv)
2293 int argc;
2294 char *argv[];
2296 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2297 setlocale (LC_MESSAGES, "");
2298 #endif
2299 bindtextdomain (PACKAGE, LOCALEDIR);
2300 textdomain (PACKAGE);
2302 program_name = argv[0];
2303 xmalloc_set_program_name (program_name);
2305 START_PROGRESS (program_name, 0);
2307 strip_symbols = STRIP_UNDEF;
2308 discard_locals = LOCALS_UNDEF;
2310 bfd_init ();
2311 set_default_bfd_target ();
2313 if (is_strip < 0)
2315 int i = strlen (program_name);
2316 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2317 /* Drop the .exe suffix, if any. */
2318 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2320 i -= 4;
2321 program_name[i] = '\0';
2323 #endif
2324 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2327 if (is_strip)
2328 strip_main (argc, argv);
2329 else
2330 copy_main (argc, argv);
2332 END_PROGRESS (program_name);
2334 return status;