daily update
[binutils.git] / binutils / objcopy.c
blobc6512217f7f3963f37b3d00dc49ef0fbcd6afb6c
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, 2002, 2003
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 typedef struct section_rename
53 const char * old_name;
54 const char * new_name;
55 flagword flags;
56 struct section_rename * next;
58 section_rename;
60 /* List of sections to be renamed. */
61 static section_rename *section_rename_list;
63 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
65 static asymbol **isympp = NULL; /* Input symbols. */
66 static asymbol **osympp = NULL; /* Output symbols that survive stripping. */
68 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
69 static int copy_byte = -1;
70 static int interleave = 4;
72 static bfd_boolean verbose; /* Print file and target names. */
73 static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
74 static int status = 0; /* Exit status. */
76 enum strip_action
78 STRIP_UNDEF,
79 STRIP_NONE, /* Don't strip. */
80 STRIP_DEBUG, /* Strip all debugger symbols. */
81 STRIP_UNNEEDED, /* Strip unnecessary symbols. */
82 STRIP_NONDEBUG, /* Strip everything but debug info. */
83 STRIP_ALL /* Strip all symbols. */
86 /* Which symbols to remove. */
87 static enum strip_action strip_symbols;
89 enum locals_action
91 LOCALS_UNDEF,
92 LOCALS_START_L, /* Discard locals starting with L. */
93 LOCALS_ALL /* Discard all locals. */
96 /* Which local symbols to remove. Overrides STRIP_ALL. */
97 static enum locals_action discard_locals;
99 /* What kind of change to perform. */
100 enum change_action
102 CHANGE_IGNORE,
103 CHANGE_MODIFY,
104 CHANGE_SET
107 /* Structure used to hold lists of sections and actions to take. */
108 struct section_list
110 struct section_list * next; /* Next section to change. */
111 const char * name; /* Section name. */
112 bfd_boolean used; /* Whether this entry was used. */
113 bfd_boolean remove; /* Whether to remove this section. */
114 bfd_boolean copy; /* Whether to copy this section. */
115 enum change_action change_vma;/* Whether to change or set VMA. */
116 bfd_vma vma_val; /* Amount to change by or set to. */
117 enum change_action change_lma;/* Whether to change or set LMA. */
118 bfd_vma lma_val; /* Amount to change by or set to. */
119 bfd_boolean set_flags; /* Whether to set the section flags. */
120 flagword flags; /* What to set the section flags to. */
123 static struct section_list *change_sections;
125 /* TRUE if some sections are to be removed. */
126 static bfd_boolean sections_removed;
128 /* TRUE if only some sections are to be copied. */
129 static bfd_boolean sections_copied;
131 /* Changes to the start address. */
132 static bfd_vma change_start = 0;
133 static bfd_boolean set_start_set = FALSE;
134 static bfd_vma set_start;
136 /* Changes to section addresses. */
137 static bfd_vma change_section_address = 0;
139 /* Filling gaps between sections. */
140 static bfd_boolean gap_fill_set = FALSE;
141 static bfd_byte gap_fill = 0;
143 /* Pad to a given address. */
144 static bfd_boolean pad_to_set = FALSE;
145 static bfd_vma pad_to;
147 /* Use alternate machine code? */
148 static int use_alt_mach_code = 0;
150 /* List of sections to add. */
151 struct section_add
153 /* Next section to add. */
154 struct section_add *next;
155 /* Name of section to add. */
156 const char *name;
157 /* Name of file holding section contents. */
158 const char *filename;
159 /* Size of file. */
160 size_t size;
161 /* Contents of file. */
162 bfd_byte *contents;
163 /* BFD section, after it has been added. */
164 asection *section;
167 /* List of sections to add to the output BFD. */
168 static struct section_add *add_sections;
170 /* If non-NULL the argument to --add-gnu-debuglink.
171 This should be the filename to store in the .gnu_debuglink section. */
172 static const char * gnu_debuglink_filename = NULL;
174 /* Whether to convert debugging information. */
175 static bfd_boolean convert_debugging = FALSE;
177 /* Whether to change the leading character in symbol names. */
178 static bfd_boolean change_leading_char = FALSE;
180 /* Whether to remove the leading character from global symbol names. */
181 static bfd_boolean remove_leading_char = FALSE;
183 /* List of symbols to strip, keep, localize, keep-global, weaken,
184 or redefine. */
185 static struct symlist *strip_specific_list = NULL;
186 static struct symlist *keep_specific_list = NULL;
187 static struct symlist *localize_specific_list = NULL;
188 static struct symlist *keepglobal_specific_list = NULL;
189 static struct symlist *weaken_specific_list = NULL;
190 static struct redefine_node *redefine_sym_list = NULL;
192 /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
193 static bfd_boolean weaken = FALSE;
195 /* Prefix symbols/sections. */
196 static char *prefix_symbols_string = 0;
197 static char *prefix_sections_string = 0;
198 static char *prefix_alloc_sections_string = 0;
200 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
201 enum command_line_switch
203 OPTION_ADD_SECTION=150,
204 OPTION_CHANGE_ADDRESSES,
205 OPTION_CHANGE_LEADING_CHAR,
206 OPTION_CHANGE_START,
207 OPTION_CHANGE_SECTION_ADDRESS,
208 OPTION_CHANGE_SECTION_LMA,
209 OPTION_CHANGE_SECTION_VMA,
210 OPTION_CHANGE_WARNINGS,
211 OPTION_DEBUGGING,
212 OPTION_GAP_FILL,
213 OPTION_NO_CHANGE_WARNINGS,
214 OPTION_PAD_TO,
215 OPTION_REMOVE_LEADING_CHAR,
216 OPTION_SET_SECTION_FLAGS,
217 OPTION_SET_START,
218 OPTION_STRIP_UNNEEDED,
219 OPTION_WEAKEN,
220 OPTION_REDEFINE_SYM,
221 OPTION_REDEFINE_SYMS,
222 OPTION_SREC_LEN,
223 OPTION_SREC_FORCES3,
224 OPTION_STRIP_SYMBOLS,
225 OPTION_KEEP_SYMBOLS,
226 OPTION_LOCALIZE_SYMBOLS,
227 OPTION_KEEPGLOBAL_SYMBOLS,
228 OPTION_WEAKEN_SYMBOLS,
229 OPTION_RENAME_SECTION,
230 OPTION_ALT_MACH_CODE,
231 OPTION_PREFIX_SYMBOLS,
232 OPTION_PREFIX_SECTIONS,
233 OPTION_PREFIX_ALLOC_SECTIONS,
234 OPTION_FORMATS_INFO,
235 OPTION_ADD_GNU_DEBUGLINK,
236 OPTION_ONLY_KEEP_DEBUG
239 /* Options to handle if running as "strip". */
241 static struct option strip_options[] =
243 {"discard-all", no_argument, 0, 'x'},
244 {"discard-locals", no_argument, 0, 'X'},
245 {"format", required_argument, 0, 'F'}, /* Obsolete */
246 {"help", no_argument, 0, 'h'},
247 {"info", no_argument, 0, OPTION_FORMATS_INFO},
248 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
249 {"input-target", required_argument, 0, 'I'},
250 {"keep-symbol", required_argument, 0, 'K'},
251 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
252 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
253 {"output-target", required_argument, 0, 'O'},
254 {"output-file", required_argument, 0, 'o'},
255 {"preserve-dates", no_argument, 0, 'p'},
256 {"remove-section", required_argument, 0, 'R'},
257 {"strip-all", no_argument, 0, 's'},
258 {"strip-debug", no_argument, 0, 'S'},
259 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
260 {"strip-symbol", required_argument, 0, 'N'},
261 {"target", required_argument, 0, 'F'},
262 {"verbose", no_argument, 0, 'v'},
263 {"version", no_argument, 0, 'V'},
264 {0, no_argument, 0, 0}
267 /* Options to handle if running as "objcopy". */
269 static struct option copy_options[] =
271 {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
272 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
273 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
274 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
275 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
276 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
277 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
278 {"binary-architecture", required_argument, 0, 'B'},
279 {"byte", required_argument, 0, 'b'},
280 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
281 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
282 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
283 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
284 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
285 {"change-start", required_argument, 0, OPTION_CHANGE_START},
286 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
287 {"debugging", no_argument, 0, OPTION_DEBUGGING},
288 {"discard-all", no_argument, 0, 'x'},
289 {"discard-locals", no_argument, 0, 'X'},
290 {"format", required_argument, 0, 'F'}, /* Obsolete */
291 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
292 {"help", no_argument, 0, 'h'},
293 {"info", no_argument, 0, OPTION_FORMATS_INFO},
294 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
295 {"input-target", required_argument, 0, 'I'},
296 {"interleave", required_argument, 0, 'i'},
297 {"keep-global-symbol", required_argument, 0, 'G'},
298 {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
299 {"keep-symbol", required_argument, 0, 'K'},
300 {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
301 {"localize-symbol", required_argument, 0, 'L'},
302 {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
303 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
304 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
305 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
306 {"only-section", required_argument, 0, 'j'},
307 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
308 {"output-target", required_argument, 0, 'O'},
309 {"pad-to", required_argument, 0, OPTION_PAD_TO},
310 {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
311 {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
312 {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
313 {"preserve-dates", no_argument, 0, 'p'},
314 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
315 {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
316 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
317 {"remove-section", required_argument, 0, 'R'},
318 {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
319 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
320 {"set-start", required_argument, 0, OPTION_SET_START},
321 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
322 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
323 {"strip-all", no_argument, 0, 'S'},
324 {"strip-debug", no_argument, 0, 'g'},
325 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
326 {"strip-symbol", required_argument, 0, 'N'},
327 {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
328 {"target", required_argument, 0, 'F'},
329 {"verbose", no_argument, 0, 'v'},
330 {"version", no_argument, 0, 'V'},
331 {"weaken", no_argument, 0, OPTION_WEAKEN},
332 {"weaken-symbol", required_argument, 0, 'W'},
333 {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
334 {0, no_argument, 0, 0}
337 /* IMPORTS */
338 extern char *program_name;
340 /* This flag distinguishes between strip and objcopy:
341 1 means this is 'strip'; 0 means this is 'objcopy'.
342 -1 means if we should use argv[0] to decide. */
343 extern int is_strip;
345 /* The maximum length of an S record. This variable is declared in srec.c
346 and can be modified by the --srec-len parameter. */
347 extern unsigned int Chunk;
349 /* Restrict the generation of Srecords to type S3 only.
350 This variable is declare in bfd/srec.c and can be toggled
351 on by the --srec-forceS3 command line switch. */
352 extern bfd_boolean S3Forced;
354 /* Defined in bfd/binary.c. Used to set architecture of input binary files. */
355 extern enum bfd_architecture bfd_external_binary_architecture;
357 /* Forward declarations. */
358 static void setup_section (bfd *, asection *, void *);
359 static void copy_section (bfd *, asection *, void *);
360 static void get_sections (bfd *, asection *, void *);
361 static int compare_section_lma (const void *, const void *);
362 static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
363 static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
364 static const char *lookup_sym_redefinition (const char *);
366 static void
367 copy_usage (FILE *stream, int exit_status)
369 fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
370 fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
371 fprintf (stream, _(" The options are:\n"));
372 fprintf (stream, _("\
373 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
374 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
375 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
376 -F --target <bfdname> Set both input and output format to <bfdname>\n\
377 --debugging Convert debugging information, if possible\n\
378 -p --preserve-dates Copy modified/access timestamps to the output\n\
379 -j --only-section <name> Only copy section <name> into the output\n\
380 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
381 -R --remove-section <name> Remove section <name> from the output\n\
382 -S --strip-all Remove all symbol and relocation information\n\
383 -g --strip-debug Remove all debugging symbols & sections\n\
384 --strip-unneeded Remove all symbols not needed by relocations\n\
385 -N --strip-symbol <name> Do not copy symbol <name>\n\
386 -K --keep-symbol <name> Only copy symbol <name>\n\
387 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
388 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
389 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
390 --weaken Force all global symbols to be marked as weak\n\
391 -x --discard-all Remove all non-global symbols\n\
392 -X --discard-locals Remove any compiler-generated symbols\n\
393 -i --interleave <number> Only copy one out of every <number> bytes\n\
394 -b --byte <num> Select byte <num> in every interleaved block\n\
395 --gap-fill <val> Fill gaps between sections with <val>\n\
396 --pad-to <addr> Pad the last section up to address <addr>\n\
397 --set-start <addr> Set the start address to <addr>\n\
398 {--change-start|--adjust-start} <incr>\n\
399 Add <incr> to the start address\n\
400 {--change-addresses|--adjust-vma} <incr>\n\
401 Add <incr> to LMA, VMA and start addresses\n\
402 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
403 Change LMA and VMA of section <name> by <val>\n\
404 --change-section-lma <name>{=|+|-}<val>\n\
405 Change the LMA of section <name> by <val>\n\
406 --change-section-vma <name>{=|+|-}<val>\n\
407 Change the VMA of section <name> by <val>\n\
408 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
409 Warn if a named section does not exist\n\
410 --set-section-flags <name>=<flags>\n\
411 Set section <name>'s properties to <flags>\n\
412 --add-section <name>=<file> Add section <name> found in <file> to output\n\
413 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
414 --change-leading-char Force output format's leading character style\n\
415 --remove-leading-char Remove leading character from global symbols\n\
416 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
417 --redefine-syms <file> --redefine-sym for all symbol pairs \n\
418 listed in <file>\n\
419 --srec-len <number> Restrict the length of generated Srecords\n\
420 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
421 --strip-symbols <file> -N for all symbols listed in <file>\n\
422 --keep-symbols <file> -K for all symbols listed in <file>\n\
423 --localize-symbols <file> -L for all symbols listed in <file>\n\
424 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
425 --weaken-symbols <file> -W for all symbols listed in <file>\n\
426 --alt-machine-code <index> Use alternate machine code for output\n\
427 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\
428 --prefix-sections <prefix> Add <prefix> to start of every section name\n\
429 --prefix-alloc-sections <prefix>\n\
430 Add <prefix> to start of every allocatable\n\
431 section name\n\
432 -v --verbose List all object files modified\n\
433 -V --version Display this program's version number\n\
434 -h --help Display this output\n\
435 --info List object formats & architectures supported\n\
436 "));
437 list_supported_targets (program_name, stream);
438 if (exit_status == 0)
439 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
440 exit (exit_status);
443 static void
444 strip_usage (FILE *stream, int exit_status)
446 fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
447 fprintf (stream, _(" Removes symbols and sections from files\n"));
448 fprintf (stream, _(" The options are:\n"));
449 fprintf (stream, _("\
450 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\
451 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\
452 -F --target=<bfdname> Set both input and output format to <bfdname>\n\
453 -p --preserve-dates Copy modified/access timestamps to the output\n\
454 -R --remove-section=<name> Remove section <name> from the output\n\
455 -s --strip-all Remove all symbol and relocation information\n\
456 -g -S -d --strip-debug Remove all debugging symbols & sections\n\
457 --strip-unneeded Remove all symbols not needed by relocations\n\
458 -N --strip-symbol=<name> Do not copy symbol <name>\n\
459 -K --keep-symbol=<name> Only copy symbol <name>\n\
460 -x --discard-all Remove all non-global symbols\n\
461 -X --discard-locals Remove any compiler-generated symbols\n\
462 -v --verbose List all object files modified\n\
463 -V --version Display this program's version number\n\
464 -h --help Display this output\n\
465 --info List object formats & architectures supported\n\
466 -o <file> Place stripped output into <file>\n\
467 "));
469 list_supported_targets (program_name, stream);
470 if (exit_status == 0)
471 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
472 exit (exit_status);
475 /* Parse section flags into a flagword, with a fatal error if the
476 string can't be parsed. */
478 static flagword
479 parse_flags (const char *s)
481 flagword ret;
482 const char *snext;
483 int len;
485 ret = SEC_NO_FLAGS;
489 snext = strchr (s, ',');
490 if (snext == NULL)
491 len = strlen (s);
492 else
494 len = snext - s;
495 ++snext;
498 if (0) ;
499 #define PARSE_FLAG(fname,fval) \
500 else if (strncasecmp (fname, s, len) == 0) ret |= fval
501 PARSE_FLAG ("alloc", SEC_ALLOC);
502 PARSE_FLAG ("load", SEC_LOAD);
503 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
504 PARSE_FLAG ("readonly", SEC_READONLY);
505 PARSE_FLAG ("debug", SEC_DEBUGGING);
506 PARSE_FLAG ("code", SEC_CODE);
507 PARSE_FLAG ("data", SEC_DATA);
508 PARSE_FLAG ("rom", SEC_ROM);
509 PARSE_FLAG ("share", SEC_SHARED);
510 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
511 #undef PARSE_FLAG
512 else
514 char *copy;
516 copy = xmalloc (len + 1);
517 strncpy (copy, s, len);
518 copy[len] = '\0';
519 non_fatal (_("unrecognized section flag `%s'"), copy);
520 fatal (_("supported flags: %s"),
521 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
524 s = snext;
526 while (s != NULL);
528 return ret;
531 /* Find and optionally add an entry in the change_sections list. */
533 static struct section_list *
534 find_section_list (const char *name, bfd_boolean add)
536 struct section_list *p;
538 for (p = change_sections; p != NULL; p = p->next)
539 if (strcmp (p->name, name) == 0)
540 return p;
542 if (! add)
543 return NULL;
545 p = xmalloc (sizeof (struct section_list));
546 p->name = name;
547 p->used = FALSE;
548 p->remove = FALSE;
549 p->copy = FALSE;
550 p->change_vma = CHANGE_IGNORE;
551 p->change_lma = CHANGE_IGNORE;
552 p->vma_val = 0;
553 p->lma_val = 0;
554 p->set_flags = FALSE;
555 p->flags = 0;
557 p->next = change_sections;
558 change_sections = p;
560 return p;
563 /* Add a symbol to strip_specific_list. */
565 static void
566 add_specific_symbol (const char *name, struct symlist **list)
568 struct symlist *tmp_list;
570 tmp_list = xmalloc (sizeof (struct symlist));
571 tmp_list->name = name;
572 tmp_list->next = *list;
573 *list = tmp_list;
576 /* Add symbols listed in `filename' to strip_specific_list. */
578 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
579 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
581 static void
582 add_specific_symbols (const char *filename, struct symlist **list)
584 struct stat st;
585 FILE * f;
586 char * line;
587 char * buffer;
588 unsigned int line_count;
590 if (stat (filename, & st) < 0)
591 fatal (_("cannot stat: %s: %s"), filename, strerror (errno));
592 if (st.st_size == 0)
593 return;
595 buffer = xmalloc (st.st_size + 2);
596 f = fopen (filename, FOPEN_RT);
597 if (f == NULL)
598 fatal (_("cannot open: %s: %s"), filename, strerror (errno));
600 if (fread (buffer, 1, st.st_size, f) == 0 || ferror (f))
601 fatal (_("%s: fread failed"), filename);
603 fclose (f);
604 buffer [st.st_size] = '\n';
605 buffer [st.st_size + 1] = '\0';
607 line_count = 1;
609 for (line = buffer; * line != '\0'; line ++)
611 char * eol;
612 char * name;
613 char * name_end;
614 int finished = FALSE;
616 for (eol = line;; eol ++)
618 switch (* eol)
620 case '\n':
621 * eol = '\0';
622 /* Cope with \n\r. */
623 if (eol[1] == '\r')
624 ++ eol;
625 finished = TRUE;
626 break;
628 case '\r':
629 * eol = '\0';
630 /* Cope with \r\n. */
631 if (eol[1] == '\n')
632 ++ eol;
633 finished = TRUE;
634 break;
636 case 0:
637 finished = TRUE;
638 break;
640 case '#':
641 /* Line comment, Terminate the line here, in case a
642 name is present and then allow the rest of the
643 loop to find the real end of the line. */
644 * eol = '\0';
645 break;
647 default:
648 break;
651 if (finished)
652 break;
655 /* A name may now exist somewhere between 'line' and 'eol'.
656 Strip off leading whitespace and trailing whitespace,
657 then add it to the list. */
658 for (name = line; IS_WHITESPACE (* name); name ++)
660 for (name_end = name;
661 (! IS_WHITESPACE (* name_end))
662 && (! IS_LINE_TERMINATOR (* name_end));
663 name_end ++)
666 if (! IS_LINE_TERMINATOR (* name_end))
668 char * extra;
670 for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
673 if (! IS_LINE_TERMINATOR (* extra))
674 non_fatal (_("Ignoring rubbish found on line %d of %s"),
675 line_count, filename);
678 * name_end = '\0';
680 if (name_end > name)
681 add_specific_symbol (name, list);
683 /* Advance line pointer to end of line. The 'eol ++' in the for
684 loop above will then advance us to the start of the next line. */
685 line = eol;
686 line_count ++;
690 /* See whether a symbol should be stripped or kept based on
691 strip_specific_list and keep_symbols. */
693 static bfd_boolean
694 is_specified_symbol (const char *name, struct symlist *list)
696 struct symlist *tmp_list;
698 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
699 if (strcmp (name, tmp_list->name) == 0)
700 return TRUE;
702 return FALSE;
705 /* See if a section is being removed. */
707 static bfd_boolean
708 is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
710 if (sections_removed || sections_copied)
712 struct section_list *p;
714 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
716 if (sections_removed && p != NULL && p->remove)
717 return TRUE;
718 if (sections_copied && (p == NULL || ! p->copy))
719 return TRUE;
722 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
724 if (strip_symbols == STRIP_DEBUG
725 || strip_symbols == STRIP_UNNEEDED
726 || strip_symbols == STRIP_ALL
727 || discard_locals == LOCALS_ALL
728 || convert_debugging)
729 return TRUE;
731 if (strip_symbols == STRIP_NONDEBUG)
732 return FALSE;
735 return strip_symbols == STRIP_NONDEBUG ? TRUE : FALSE;
738 /* Choose which symbol entries to copy; put the result in OSYMS.
739 We don't copy in place, because that confuses the relocs.
740 Return the number of symbols to print. */
742 static unsigned int
743 filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
744 asymbol **isyms, long symcount)
746 asymbol **from = isyms, **to = osyms;
747 long src_count = 0, dst_count = 0;
748 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
749 == HAS_RELOC;
751 for (; src_count < symcount; src_count++)
753 asymbol *sym = from[src_count];
754 flagword flags = sym->flags;
755 char *name = (char *) bfd_asymbol_name (sym);
756 int keep;
757 bfd_boolean undefined;
758 bfd_boolean rem_leading_char;
759 bfd_boolean add_leading_char;
761 undefined = bfd_is_und_section (bfd_get_section (sym));
763 if (redefine_sym_list)
765 char *old_name, *new_name;
767 old_name = (char *) bfd_asymbol_name (sym);
768 new_name = (char *) lookup_sym_redefinition (old_name);
769 bfd_asymbol_name (sym) = new_name;
770 name = new_name;
773 /* Check if we will remove the current leading character. */
774 rem_leading_char =
775 (name[0] == bfd_get_symbol_leading_char (abfd))
776 && (change_leading_char
777 || (remove_leading_char
778 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
779 || undefined
780 || bfd_is_com_section (bfd_get_section (sym)))));
782 /* Check if we will add a new leading character. */
783 add_leading_char =
784 change_leading_char
785 && (bfd_get_symbol_leading_char (obfd) != '\0')
786 && (bfd_get_symbol_leading_char (abfd) == '\0'
787 || (name[0] == bfd_get_symbol_leading_char (abfd)));
789 /* Short circuit for change_leading_char if we can do it in-place. */
790 if (rem_leading_char && add_leading_char && !prefix_symbols_string)
792 name[0] = bfd_get_symbol_leading_char (obfd);
793 bfd_asymbol_name (sym) = name;
794 rem_leading_char = FALSE;
795 add_leading_char = FALSE;
798 /* Remove leading char. */
799 if (rem_leading_char)
800 bfd_asymbol_name (sym) = ++name;
802 /* Add new leading char and/or prefix. */
803 if (add_leading_char || prefix_symbols_string)
805 char *n, *ptr;
807 ptr = n = xmalloc (1 + strlen (prefix_symbols_string)
808 + strlen (name) + 1);
809 if (add_leading_char)
810 *ptr++ = bfd_get_symbol_leading_char (obfd);
812 if (prefix_symbols_string)
814 strcpy (ptr, prefix_symbols_string);
815 ptr += strlen (prefix_symbols_string);
818 strcpy (ptr, name);
819 bfd_asymbol_name (sym) = n;
820 name = n;
823 if (strip_symbols == STRIP_ALL)
824 keep = 0;
825 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
826 || ((flags & BSF_SECTION_SYM) != 0
827 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
828 & BSF_KEEP) != 0))
829 keep = 1;
830 else if (relocatable /* Relocatable file. */
831 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
832 keep = 1;
833 else if (bfd_decode_symclass (sym) == 'I')
834 /* Global symbols in $idata sections need to be retained
835 even if relocatable is FALSE. External users of the
836 library containing the $idata section may reference these
837 symbols. */
838 keep = 1;
839 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
840 || (flags & BSF_WEAK) != 0
841 || undefined
842 || bfd_is_com_section (bfd_get_section (sym)))
843 keep = strip_symbols != STRIP_UNNEEDED;
844 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
845 keep = (strip_symbols != STRIP_DEBUG
846 && strip_symbols != STRIP_UNNEEDED
847 && ! convert_debugging);
848 else if (bfd_get_section (sym)->comdat)
849 /* COMDAT sections store special information in local
850 symbols, so we cannot risk stripping any of them. */
851 keep = 1;
852 else /* Local symbol. */
853 keep = (strip_symbols != STRIP_UNNEEDED
854 && (discard_locals != LOCALS_ALL
855 && (discard_locals != LOCALS_START_L
856 || ! bfd_is_local_label (abfd, sym))));
858 if (keep && is_specified_symbol (name, strip_specific_list))
859 keep = 0;
860 if (!keep && is_specified_symbol (name, keep_specific_list))
861 keep = 1;
862 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
863 keep = 0;
865 if (keep && (flags & BSF_GLOBAL) != 0
866 && (weaken || is_specified_symbol (name, weaken_specific_list)))
868 sym->flags &=~ BSF_GLOBAL;
869 sym->flags |= BSF_WEAK;
871 if (keep && !undefined && (flags & (BSF_GLOBAL | BSF_WEAK))
872 && (is_specified_symbol (name, localize_specific_list)
873 || (keepglobal_specific_list != NULL
874 && ! is_specified_symbol (name, keepglobal_specific_list))))
876 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
877 sym->flags |= BSF_LOCAL;
880 if (keep)
881 to[dst_count++] = sym;
884 to[dst_count] = NULL;
886 return dst_count;
889 /* Find the redefined name of symbol SOURCE. */
891 static const char *
892 lookup_sym_redefinition (const char *source)
894 struct redefine_node *list;
896 for (list = redefine_sym_list; list != NULL; list = list->next)
897 if (strcmp (source, list->source) == 0)
898 return list->target;
900 return source;
903 /* Add a node to a symbol redefine list. */
905 static void
906 redefine_list_append (const char *cause, const char *source, const char *target)
908 struct redefine_node **p;
909 struct redefine_node *list;
910 struct redefine_node *new_node;
912 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
914 if (strcmp (source, list->source) == 0)
915 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
916 cause, source);
918 if (strcmp (target, list->target) == 0)
919 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
920 cause, target);
923 new_node = xmalloc (sizeof (struct redefine_node));
925 new_node->source = strdup (source);
926 new_node->target = strdup (target);
927 new_node->next = NULL;
929 *p = new_node;
932 /* Handle the --redefine-syms option. Read lines containing "old new"
933 from the file, and add them to the symbol redefine list. */
935 static void
936 add_redefine_syms_file (const char *filename)
938 FILE *file;
939 char *buf;
940 size_t bufsize;
941 size_t len;
942 size_t outsym_off;
943 int c, lineno;
945 file = fopen (filename, "r");
946 if (file == NULL)
947 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
948 filename, strerror (errno));
950 bufsize = 100;
951 buf = xmalloc (bufsize);
953 lineno = 1;
954 c = getc (file);
955 len = 0;
956 outsym_off = 0;
957 while (c != EOF)
959 /* Collect the input symbol name. */
960 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
962 if (c == '#')
963 goto comment;
964 buf[len++] = c;
965 if (len >= bufsize)
967 bufsize *= 2;
968 buf = xrealloc (buf, bufsize);
970 c = getc (file);
972 buf[len++] = '\0';
973 if (c == EOF)
974 break;
976 /* Eat white space between the symbol names. */
977 while (IS_WHITESPACE (c))
978 c = getc (file);
979 if (c == '#' || IS_LINE_TERMINATOR (c))
980 goto comment;
981 if (c == EOF)
982 break;
984 /* Collect the output symbol name. */
985 outsym_off = len;
986 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
988 if (c == '#')
989 goto comment;
990 buf[len++] = c;
991 if (len >= bufsize)
993 bufsize *= 2;
994 buf = xrealloc (buf, bufsize);
996 c = getc (file);
998 buf[len++] = '\0';
999 if (c == EOF)
1000 break;
1002 /* Eat white space at end of line. */
1003 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1004 c = getc (file);
1005 if (c == '#')
1006 goto comment;
1007 /* Handle \r\n. */
1008 if ((c == '\r' && (c = getc (file)) == '\n')
1009 || c == '\n' || c == EOF)
1011 end_of_line:
1012 /* Append the redefinition to the list. */
1013 if (buf[0] != '\0')
1014 redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1016 lineno++;
1017 len = 0;
1018 outsym_off = 0;
1019 if (c == EOF)
1020 break;
1021 c = getc (file);
1022 continue;
1024 else
1025 fatal (_("%s: garbage at end of line %d"), filename, lineno);
1026 comment:
1027 if (len != 0 && (outsym_off == 0 || outsym_off == len))
1028 fatal (_("%s: missing new symbol name at line %d"), filename, lineno);
1029 buf[len++] = '\0';
1031 /* Eat the rest of the line and finish it. */
1032 while (c != '\n' && c != EOF)
1033 c = getc (file);
1034 goto end_of_line;
1037 if (len != 0)
1038 fatal (_("%s: premature end of file at line %d"), filename, lineno);
1040 free (buf);
1043 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
1044 Adjust *SIZE. */
1046 static void
1047 filter_bytes (char *memhunk, bfd_size_type *size)
1049 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
1051 for (; from < end; from += interleave)
1052 *to++ = *from;
1054 if (*size % interleave > (bfd_size_type) copy_byte)
1055 *size = (*size / interleave) + 1;
1056 else
1057 *size /= interleave;
1060 /* Copy object file IBFD onto OBFD. */
1062 static void
1063 copy_object (bfd *ibfd, bfd *obfd)
1065 bfd_vma start;
1066 long symcount;
1067 asection **osections = NULL;
1068 asection *gnu_debuglink_section = NULL;
1069 bfd_size_type *gaps = NULL;
1070 bfd_size_type max_gap = 0;
1071 long symsize;
1072 void *dhandle;
1073 enum bfd_architecture iarch;
1074 unsigned int imach;
1076 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1077 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1078 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1080 fatal (_("Unable to change endianness of input file(s)"));
1081 return;
1084 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1085 RETURN_NONFATAL (bfd_get_filename (obfd));
1087 if (verbose)
1088 printf (_("copy from %s(%s) to %s(%s)\n"),
1089 bfd_get_filename (ibfd), bfd_get_target (ibfd),
1090 bfd_get_filename (obfd), bfd_get_target (obfd));
1092 if (set_start_set)
1093 start = set_start;
1094 else
1095 start = bfd_get_start_address (ibfd);
1096 start += change_start;
1098 /* Neither the start address nor the flags
1099 need to be set for a core file. */
1100 if (bfd_get_format (obfd) != bfd_core)
1102 if (!bfd_set_start_address (obfd, start)
1103 || !bfd_set_file_flags (obfd,
1104 (bfd_get_file_flags (ibfd)
1105 & bfd_applicable_file_flags (obfd))))
1106 RETURN_NONFATAL (bfd_get_filename (ibfd));
1109 /* Copy architecture of input file to output file. */
1110 iarch = bfd_get_arch (ibfd);
1111 imach = bfd_get_mach (ibfd);
1112 if (!bfd_set_arch_mach (obfd, iarch, imach)
1113 && (ibfd->target_defaulted
1114 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1115 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1116 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1117 bfd_get_mach (ibfd)));
1119 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1120 RETURN_NONFATAL (bfd_get_filename (ibfd));
1122 if (isympp)
1123 free (isympp);
1125 if (osympp != isympp)
1126 free (osympp);
1128 /* BFD mandates that all output sections be created and sizes set before
1129 any output is done. Thus, we traverse all sections multiple times. */
1130 bfd_map_over_sections (ibfd, setup_section, obfd);
1132 if (add_sections != NULL)
1134 struct section_add *padd;
1135 struct section_list *pset;
1137 for (padd = add_sections; padd != NULL; padd = padd->next)
1139 flagword flags;
1141 padd->section = bfd_make_section (obfd, padd->name);
1142 if (padd->section == NULL)
1144 non_fatal (_("can't create section `%s': %s"),
1145 padd->name, bfd_errmsg (bfd_get_error ()));
1146 status = 1;
1147 return;
1150 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1151 RETURN_NONFATAL (bfd_get_filename (obfd));
1153 pset = find_section_list (padd->name, FALSE);
1154 if (pset != NULL)
1155 pset->used = TRUE;
1157 if (pset != NULL && pset->set_flags)
1158 flags = pset->flags | SEC_HAS_CONTENTS;
1159 else
1160 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1162 if (! bfd_set_section_flags (obfd, padd->section, flags))
1163 RETURN_NONFATAL (bfd_get_filename (obfd));
1165 if (pset != NULL)
1167 if (pset->change_vma != CHANGE_IGNORE)
1168 if (! bfd_set_section_vma (obfd, padd->section,
1169 pset->vma_val))
1170 RETURN_NONFATAL (bfd_get_filename (obfd));
1172 if (pset->change_lma != CHANGE_IGNORE)
1174 padd->section->lma = pset->lma_val;
1176 if (! bfd_set_section_alignment
1177 (obfd, padd->section,
1178 bfd_section_alignment (obfd, padd->section)))
1179 RETURN_NONFATAL (bfd_get_filename (obfd));
1185 if (gnu_debuglink_filename != NULL)
1187 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1188 (obfd, gnu_debuglink_filename);
1190 if (gnu_debuglink_section == NULL)
1191 RETURN_NONFATAL (gnu_debuglink_filename);
1194 if (gap_fill_set || pad_to_set)
1196 asection **set;
1197 unsigned int c, i;
1199 /* We must fill in gaps between the sections and/or we must pad
1200 the last section to a specified address. We do this by
1201 grabbing a list of the sections, sorting them by VMA, and
1202 increasing the section sizes as required to fill the gaps.
1203 We write out the gap contents below. */
1205 c = bfd_count_sections (obfd);
1206 osections = xmalloc (c * sizeof (asection *));
1207 set = osections;
1208 bfd_map_over_sections (obfd, get_sections, &set);
1210 qsort (osections, c, sizeof (asection *), compare_section_lma);
1212 gaps = xmalloc (c * sizeof (bfd_size_type));
1213 memset (gaps, 0, c * sizeof (bfd_size_type));
1215 if (gap_fill_set)
1217 for (i = 0; i < c - 1; i++)
1219 flagword flags;
1220 bfd_size_type size;
1221 bfd_vma gap_start, gap_stop;
1223 flags = bfd_get_section_flags (obfd, osections[i]);
1224 if ((flags & SEC_HAS_CONTENTS) == 0
1225 || (flags & SEC_LOAD) == 0)
1226 continue;
1228 size = bfd_section_size (obfd, osections[i]);
1229 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1230 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1231 if (gap_start < gap_stop)
1233 if (! bfd_set_section_size (obfd, osections[i],
1234 size + (gap_stop - gap_start)))
1236 non_fatal (_("Can't fill gap after %s: %s"),
1237 bfd_get_section_name (obfd, osections[i]),
1238 bfd_errmsg (bfd_get_error ()));
1239 status = 1;
1240 break;
1242 gaps[i] = gap_stop - gap_start;
1243 if (max_gap < gap_stop - gap_start)
1244 max_gap = gap_stop - gap_start;
1249 if (pad_to_set)
1251 bfd_vma lma;
1252 bfd_size_type size;
1254 lma = bfd_section_lma (obfd, osections[c - 1]);
1255 size = bfd_section_size (obfd, osections[c - 1]);
1256 if (lma + size < pad_to)
1258 if (! bfd_set_section_size (obfd, osections[c - 1],
1259 pad_to - lma))
1261 non_fatal (_("Can't add padding to %s: %s"),
1262 bfd_get_section_name (obfd, osections[c - 1]),
1263 bfd_errmsg (bfd_get_error ()));
1264 status = 1;
1266 else
1268 gaps[c - 1] = pad_to - (lma + size);
1269 if (max_gap < pad_to - (lma + size))
1270 max_gap = pad_to - (lma + size);
1276 /* Symbol filtering must happen after the output sections
1277 have been created, but before their contents are set. */
1278 dhandle = NULL;
1279 symsize = bfd_get_symtab_upper_bound (ibfd);
1280 if (symsize < 0)
1281 RETURN_NONFATAL (bfd_get_filename (ibfd));
1283 osympp = isympp = xmalloc (symsize);
1284 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1285 if (symcount < 0)
1286 RETURN_NONFATAL (bfd_get_filename (ibfd));
1288 if (convert_debugging)
1289 dhandle = read_debugging_info (ibfd, isympp, symcount);
1291 if (strip_symbols == STRIP_DEBUG
1292 || strip_symbols == STRIP_ALL
1293 || strip_symbols == STRIP_UNNEEDED
1294 || strip_symbols == STRIP_NONDEBUG
1295 || discard_locals != LOCALS_UNDEF
1296 || strip_specific_list != NULL
1297 || keep_specific_list != NULL
1298 || localize_specific_list != NULL
1299 || keepglobal_specific_list != NULL
1300 || weaken_specific_list != NULL
1301 || prefix_symbols_string
1302 || sections_removed
1303 || sections_copied
1304 || convert_debugging
1305 || change_leading_char
1306 || remove_leading_char
1307 || redefine_sym_list
1308 || weaken)
1310 /* Mark symbols used in output relocations so that they
1311 are kept, even if they are local labels or static symbols.
1313 Note we iterate over the input sections examining their
1314 relocations since the relocations for the output sections
1315 haven't been set yet. mark_symbols_used_in_relocations will
1316 ignore input sections which have no corresponding output
1317 section. */
1318 if (strip_symbols != STRIP_ALL)
1319 bfd_map_over_sections (ibfd,
1320 mark_symbols_used_in_relocations,
1321 isympp);
1322 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1323 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1326 if (convert_debugging && dhandle != NULL)
1328 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1330 status = 1;
1331 return;
1335 bfd_set_symtab (obfd, osympp, symcount);
1337 /* This has to happen after the symbol table has been set. */
1338 bfd_map_over_sections (ibfd, copy_section, obfd);
1340 if (add_sections != NULL)
1342 struct section_add *padd;
1344 for (padd = add_sections; padd != NULL; padd = padd->next)
1346 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1347 0, padd->size))
1348 RETURN_NONFATAL (bfd_get_filename (obfd));
1352 if (gnu_debuglink_filename != NULL)
1354 if (! bfd_fill_in_gnu_debuglink_section
1355 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1356 RETURN_NONFATAL (gnu_debuglink_filename);
1359 if (gap_fill_set || pad_to_set)
1361 bfd_byte *buf;
1362 int c, i;
1364 /* Fill in the gaps. */
1365 if (max_gap > 8192)
1366 max_gap = 8192;
1367 buf = xmalloc (max_gap);
1368 memset (buf, gap_fill, max_gap);
1370 c = bfd_count_sections (obfd);
1371 for (i = 0; i < c; i++)
1373 if (gaps[i] != 0)
1375 bfd_size_type left;
1376 file_ptr off;
1378 left = gaps[i];
1379 off = bfd_section_size (obfd, osections[i]) - left;
1381 while (left > 0)
1383 bfd_size_type now;
1385 if (left > 8192)
1386 now = 8192;
1387 else
1388 now = left;
1390 if (! bfd_set_section_contents (obfd, osections[i], buf,
1391 off, now))
1392 RETURN_NONFATAL (bfd_get_filename (obfd));
1394 left -= now;
1395 off += now;
1401 /* Allow the BFD backend to copy any private data it understands
1402 from the input BFD to the output BFD. This is done last to
1403 permit the routine to look at the filtered symbol table, which is
1404 important for the ECOFF code at least. */
1405 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1406 && strip_symbols == STRIP_NONDEBUG)
1407 /* Do not copy the private data when creating an ELF format
1408 debug info file. We do not want the program headers. */
1410 else if (! bfd_copy_private_bfd_data (ibfd, obfd))
1412 non_fatal (_("%s: error copying private BFD data: %s"),
1413 bfd_get_filename (obfd),
1414 bfd_errmsg (bfd_get_error ()));
1415 status = 1;
1416 return;
1419 /* Switch to the alternate machine code. We have to do this at the
1420 very end, because we only initialize the header when we create
1421 the first section. */
1422 if (use_alt_mach_code != 0)
1424 if (!bfd_alt_mach_code (obfd, use_alt_mach_code))
1425 non_fatal (_("unknown alternate machine code, ignored"));
1429 #undef MKDIR
1430 #if defined (_WIN32) && !defined (__CYGWIN32__)
1431 #define MKDIR(DIR, MODE) mkdir (DIR)
1432 #else
1433 #define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1434 #endif
1436 /* Read each archive element in turn from IBFD, copy the
1437 contents to temp file, and keep the temp file handle. */
1439 static void
1440 copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
1442 struct name_list
1444 struct name_list *next;
1445 const char *name;
1446 bfd *obfd;
1447 } *list, *l;
1448 bfd **ptr = &obfd->archive_head;
1449 bfd *this_element;
1450 char *dir = make_tempname (bfd_get_filename (obfd));
1452 /* Make a temp directory to hold the contents. */
1453 if (MKDIR (dir, 0700) != 0)
1454 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1455 dir, strerror (errno));
1457 obfd->has_armap = ibfd->has_armap;
1459 list = NULL;
1461 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1463 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1464 RETURN_NONFATAL (bfd_get_filename (obfd));
1466 while (!status && this_element != NULL)
1468 char *output_name;
1469 bfd *output_bfd;
1470 bfd *last_element;
1471 struct stat buf;
1472 int stat_status = 0;
1474 /* Create an output file for this member. */
1475 output_name = concat (dir, "/",
1476 bfd_get_filename (this_element), (char *) 0);
1478 /* If the file already exists, make another temp dir. */
1479 if (stat (output_name, &buf) >= 0)
1481 output_name = make_tempname (output_name);
1482 if (MKDIR (output_name, 0700) != 0)
1483 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1484 output_name, strerror (errno));
1486 l = xmalloc (sizeof (struct name_list));
1487 l->name = output_name;
1488 l->next = list;
1489 l->obfd = NULL;
1490 list = l;
1491 output_name = concat (output_name, "/",
1492 bfd_get_filename (this_element), (char *) 0);
1495 output_bfd = bfd_openw (output_name, output_target);
1496 if (preserve_dates)
1498 stat_status = bfd_stat_arch_elt (this_element, &buf);
1500 if (stat_status != 0)
1501 non_fatal (_("internal stat error on %s"),
1502 bfd_get_filename (this_element));
1505 l = xmalloc (sizeof (struct name_list));
1506 l->name = output_name;
1507 l->next = list;
1508 list = l;
1510 if (output_bfd == NULL)
1511 RETURN_NONFATAL (output_name);
1513 if (bfd_check_format (this_element, bfd_object))
1514 copy_object (this_element, output_bfd);
1516 if (!bfd_close (output_bfd))
1518 bfd_nonfatal (bfd_get_filename (output_bfd));
1519 /* Error in new object file. Don't change archive. */
1520 status = 1;
1523 if (preserve_dates && stat_status == 0)
1524 set_times (output_name, &buf);
1526 /* Open the newly output file and attach to our list. */
1527 output_bfd = bfd_openr (output_name, output_target);
1529 l->obfd = output_bfd;
1531 *ptr = output_bfd;
1532 ptr = &output_bfd->next;
1534 last_element = this_element;
1536 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1538 bfd_close (last_element);
1540 *ptr = NULL;
1542 if (!bfd_close (obfd))
1543 RETURN_NONFATAL (bfd_get_filename (obfd));
1545 if (!bfd_close (ibfd))
1546 RETURN_NONFATAL (bfd_get_filename (ibfd));
1548 /* Delete all the files that we opened. */
1549 for (l = list; l != NULL; l = l->next)
1551 if (l->obfd == NULL)
1552 rmdir (l->name);
1553 else
1555 bfd_close (l->obfd);
1556 unlink (l->name);
1559 rmdir (dir);
1562 /* The top-level control. */
1564 static void
1565 copy_file (const char *input_filename, const char *output_filename,
1566 const char *input_target, const char *output_target)
1568 bfd *ibfd;
1569 char **obj_matching;
1570 char **core_matching;
1572 /* To allow us to do "strip *" without dying on the first
1573 non-object file, failures are nonfatal. */
1574 ibfd = bfd_openr (input_filename, input_target);
1575 if (ibfd == NULL)
1576 RETURN_NONFATAL (input_filename);
1578 if (bfd_check_format (ibfd, bfd_archive))
1580 bfd *obfd;
1582 /* bfd_get_target does not return the correct value until
1583 bfd_check_format succeeds. */
1584 if (output_target == NULL)
1585 output_target = bfd_get_target (ibfd);
1587 obfd = bfd_openw (output_filename, output_target);
1588 if (obfd == NULL)
1589 RETURN_NONFATAL (output_filename);
1591 copy_archive (ibfd, obfd, output_target);
1593 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
1595 bfd *obfd;
1596 do_copy:
1597 /* bfd_get_target does not return the correct value until
1598 bfd_check_format succeeds. */
1599 if (output_target == NULL)
1600 output_target = bfd_get_target (ibfd);
1602 obfd = bfd_openw (output_filename, output_target);
1603 if (obfd == NULL)
1604 RETURN_NONFATAL (output_filename);
1606 copy_object (ibfd, obfd);
1608 if (!bfd_close (obfd))
1609 RETURN_NONFATAL (output_filename);
1611 if (!bfd_close (ibfd))
1612 RETURN_NONFATAL (input_filename);
1614 else
1616 bfd_error_type obj_error = bfd_get_error ();
1617 bfd_error_type core_error;
1619 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
1621 /* This probably can't happen.. */
1622 if (obj_error == bfd_error_file_ambiguously_recognized)
1623 free (obj_matching);
1624 goto do_copy;
1627 core_error = bfd_get_error ();
1628 /* Report the object error in preference to the core error. */
1629 if (obj_error != core_error)
1630 bfd_set_error (obj_error);
1632 bfd_nonfatal (input_filename);
1634 if (obj_error == bfd_error_file_ambiguously_recognized)
1636 list_matching_formats (obj_matching);
1637 free (obj_matching);
1639 if (core_error == bfd_error_file_ambiguously_recognized)
1641 list_matching_formats (core_matching);
1642 free (core_matching);
1645 status = 1;
1649 /* Add a name to the section renaming list. */
1651 static void
1652 add_section_rename (const char * old_name, const char * new_name,
1653 flagword flags)
1655 section_rename * rename;
1657 /* Check for conflicts first. */
1658 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1659 if (strcmp (rename->old_name, old_name) == 0)
1661 /* Silently ignore duplicate definitions. */
1662 if (strcmp (rename->new_name, new_name) == 0
1663 && rename->flags == flags)
1664 return;
1666 fatal (_("Multiple renames of section %s"), old_name);
1669 rename = xmalloc (sizeof (* rename));
1671 rename->old_name = old_name;
1672 rename->new_name = new_name;
1673 rename->flags = flags;
1674 rename->next = section_rename_list;
1676 section_rename_list = rename;
1679 /* Check the section rename list for a new name of the input section
1680 ISECTION. Return the new name if one is found.
1681 Also set RETURNED_FLAGS to the flags to be used for this section. */
1683 static const char *
1684 find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
1685 flagword * returned_flags)
1687 const char * old_name = bfd_section_name (ibfd, isection);
1688 section_rename * rename;
1690 /* Default to using the flags of the input section. */
1691 * returned_flags = bfd_get_section_flags (ibfd, isection);
1693 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1694 if (strcmp (rename->old_name, old_name) == 0)
1696 if (rename->flags != (flagword) -1)
1697 * returned_flags = rename->flags;
1699 return rename->new_name;
1702 return old_name;
1705 /* Create a section in OBFD with the same
1706 name and attributes as ISECTION in IBFD. */
1708 static void
1709 setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1711 bfd *obfd = obfdarg;
1712 struct section_list *p;
1713 sec_ptr osection;
1714 bfd_size_type size;
1715 bfd_vma vma;
1716 bfd_vma lma;
1717 flagword flags;
1718 const char *err;
1719 const char * name;
1720 char *prefix = NULL;
1722 if (is_strip_section (ibfd, isection))
1723 return;
1725 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
1726 if (p != NULL)
1727 p->used = TRUE;
1729 /* Get the, possibly new, name of the output section. */
1730 name = find_section_rename (ibfd, isection, & flags);
1732 /* Prefix sections. */
1733 if ((prefix_alloc_sections_string)
1734 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
1735 prefix = prefix_alloc_sections_string;
1736 else if (prefix_sections_string)
1737 prefix = prefix_sections_string;
1739 if (prefix)
1741 char *n;
1743 n = xmalloc (strlen (prefix) + strlen (name) + 1);
1744 strcpy (n, prefix);
1745 strcat (n, name);
1746 name = n;
1749 osection = bfd_make_section_anyway (obfd, name);
1751 if (osection == NULL)
1753 err = _("making");
1754 goto loser;
1757 size = bfd_section_size (ibfd, isection);
1758 if (copy_byte >= 0)
1759 size = (size + interleave - 1) / interleave;
1760 if (! bfd_set_section_size (obfd, osection, size))
1762 err = _("size");
1763 goto loser;
1766 vma = bfd_section_vma (ibfd, isection);
1767 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1768 vma += p->vma_val;
1769 else if (p != NULL && p->change_vma == CHANGE_SET)
1770 vma = p->vma_val;
1771 else
1772 vma += change_section_address;
1774 if (! bfd_set_section_vma (obfd, osection, vma))
1776 err = _("vma");
1777 goto loser;
1780 lma = isection->lma;
1781 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1783 if (p->change_lma == CHANGE_MODIFY)
1784 lma += p->lma_val;
1785 else if (p->change_lma == CHANGE_SET)
1786 lma = p->lma_val;
1787 else
1788 abort ();
1790 else
1791 lma += change_section_address;
1793 osection->lma = lma;
1795 /* FIXME: This is probably not enough. If we change the LMA we
1796 may have to recompute the header for the file as well. */
1797 if (!bfd_set_section_alignment (obfd,
1798 osection,
1799 bfd_section_alignment (ibfd, isection)))
1801 err = _("alignment");
1802 goto loser;
1805 if (p != NULL && p->set_flags)
1806 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
1807 if (!bfd_set_section_flags (obfd, osection, flags))
1809 err = _("flags");
1810 goto loser;
1813 /* Copy merge entity size. */
1814 osection->entsize = isection->entsize;
1816 /* This used to be mangle_section; we do here to avoid using
1817 bfd_get_section_by_name since some formats allow multiple
1818 sections with the same name. */
1819 isection->output_section = osection;
1820 isection->output_offset = 0;
1822 /* Allow the BFD backend to copy any private data it understands
1823 from the input section to the output section. */
1824 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1825 && strip_symbols == STRIP_NONDEBUG)
1826 /* Do not copy the private data when creating an ELF format
1827 debug info file. We do not want the program headers. */
1829 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1831 err = _("private data");
1832 goto loser;
1835 /* All went well. */
1836 return;
1838 loser:
1839 non_fatal (_("%s: section `%s': error in %s: %s"),
1840 bfd_get_filename (ibfd),
1841 bfd_section_name (ibfd, isection),
1842 err, bfd_errmsg (bfd_get_error ()));
1843 status = 1;
1846 /* Copy the data of input section ISECTION of IBFD
1847 to an output section with the same name in OBFD.
1848 If stripping then don't copy any relocation info. */
1850 static void
1851 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1853 bfd *obfd = obfdarg;
1854 struct section_list *p;
1855 arelent **relpp;
1856 long relcount;
1857 sec_ptr osection;
1858 bfd_size_type size;
1859 long relsize;
1860 flagword flags;
1862 /* If we have already failed earlier on,
1863 do not keep on generating complaints now. */
1864 if (status != 0)
1865 return;
1867 if (is_strip_section (ibfd, isection))
1868 return;
1870 flags = bfd_get_section_flags (ibfd, isection);
1871 if ((flags & SEC_GROUP) != 0)
1872 return;
1874 osection = isection->output_section;
1875 size = bfd_get_section_size_before_reloc (isection);
1877 if (size == 0 || osection == 0)
1878 return;
1880 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
1882 /* Core files do not need to be relocated. */
1883 if (bfd_get_format (obfd) == bfd_core)
1884 relsize = 0;
1885 else
1886 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1888 if (relsize < 0)
1889 RETURN_NONFATAL (bfd_get_filename (ibfd));
1891 if (relsize == 0)
1892 bfd_set_reloc (obfd, osection, NULL, 0);
1893 else
1895 relpp = xmalloc (relsize);
1896 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1897 if (relcount < 0)
1898 RETURN_NONFATAL (bfd_get_filename (ibfd));
1900 if (strip_symbols == STRIP_ALL)
1902 /* Remove relocations which are not in
1903 keep_strip_specific_list. */
1904 arelent **temp_relpp;
1905 long temp_relcount = 0;
1906 long i;
1908 temp_relpp = xmalloc (relsize);
1909 for (i = 0; i < relcount; i++)
1910 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
1911 keep_specific_list))
1912 temp_relpp [temp_relcount++] = relpp [i];
1913 relcount = temp_relcount;
1914 free (relpp);
1915 relpp = temp_relpp;
1918 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
1921 isection->_cooked_size = isection->_raw_size;
1922 isection->reloc_done = TRUE;
1924 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
1925 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
1927 void *memhunk = xmalloc (size);
1929 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
1930 RETURN_NONFATAL (bfd_get_filename (ibfd));
1932 if (copy_byte >= 0)
1933 filter_bytes (memhunk, &size);
1935 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
1936 RETURN_NONFATAL (bfd_get_filename (obfd));
1938 free (memhunk);
1940 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1942 void *memhunk = xmalloc (size);
1944 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1945 flag--they can just remove the section entirely and add it
1946 back again. However, we do permit them to turn on the
1947 SEC_HAS_CONTENTS flag, and take it to mean that the section
1948 contents should be zeroed out. */
1950 memset (memhunk, 0, size);
1951 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
1952 RETURN_NONFATAL (bfd_get_filename (obfd));
1953 free (memhunk);
1957 /* Get all the sections. This is used when --gap-fill or --pad-to is
1958 used. */
1960 static void
1961 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
1963 asection ***secppp = secppparg;
1965 **secppp = osection;
1966 ++(*secppp);
1969 /* Sort sections by VMA. This is called via qsort, and is used when
1970 --gap-fill or --pad-to is used. We force non loadable or empty
1971 sections to the front, where they are easier to ignore. */
1973 static int
1974 compare_section_lma (const void *arg1, const void *arg2)
1976 const asection *const *sec1 = arg1;
1977 const asection *const *sec2 = arg2;
1978 flagword flags1, flags2;
1980 /* Sort non loadable sections to the front. */
1981 flags1 = (*sec1)->flags;
1982 flags2 = (*sec2)->flags;
1983 if ((flags1 & SEC_HAS_CONTENTS) == 0
1984 || (flags1 & SEC_LOAD) == 0)
1986 if ((flags2 & SEC_HAS_CONTENTS) != 0
1987 && (flags2 & SEC_LOAD) != 0)
1988 return -1;
1990 else
1992 if ((flags2 & SEC_HAS_CONTENTS) == 0
1993 || (flags2 & SEC_LOAD) == 0)
1994 return 1;
1997 /* Sort sections by LMA. */
1998 if ((*sec1)->lma > (*sec2)->lma)
1999 return 1;
2000 else if ((*sec1)->lma < (*sec2)->lma)
2001 return -1;
2003 /* Sort sections with the same LMA by size. */
2004 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
2005 return 1;
2006 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
2007 return -1;
2009 return 0;
2012 /* Mark all the symbols which will be used in output relocations with
2013 the BSF_KEEP flag so that those symbols will not be stripped.
2015 Ignore relocations which will not appear in the output file. */
2017 static void
2018 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2020 asymbol **symbols = symbolsarg;
2021 long relsize;
2022 arelent **relpp;
2023 long relcount, i;
2025 /* Ignore an input section with no corresponding output section. */
2026 if (isection->output_section == NULL)
2027 return;
2029 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2030 if (relsize < 0)
2031 bfd_fatal (bfd_get_filename (ibfd));
2033 if (relsize == 0)
2034 return;
2036 relpp = xmalloc (relsize);
2037 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2038 if (relcount < 0)
2039 bfd_fatal (bfd_get_filename (ibfd));
2041 /* Examine each symbol used in a relocation. If it's not one of the
2042 special bfd section symbols, then mark it with BSF_KEEP. */
2043 for (i = 0; i < relcount; i++)
2045 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2046 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2047 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2048 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2051 if (relpp != NULL)
2052 free (relpp);
2055 /* Write out debugging information. */
2057 static bfd_boolean
2058 write_debugging_info (bfd *obfd, void *dhandle,
2059 long *symcountp ATTRIBUTE_UNUSED,
2060 asymbol ***symppp ATTRIBUTE_UNUSED)
2062 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2063 return write_ieee_debugging_info (obfd, dhandle);
2065 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2066 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2068 bfd_byte *syms, *strings;
2069 bfd_size_type symsize, stringsize;
2070 asection *stabsec, *stabstrsec;
2072 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2073 &symsize, &strings,
2074 &stringsize))
2075 return FALSE;
2077 stabsec = bfd_make_section (obfd, ".stab");
2078 stabstrsec = bfd_make_section (obfd, ".stabstr");
2079 if (stabsec == NULL
2080 || stabstrsec == NULL
2081 || ! bfd_set_section_size (obfd, stabsec, symsize)
2082 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2083 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2084 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
2085 || ! bfd_set_section_flags (obfd, stabsec,
2086 (SEC_HAS_CONTENTS
2087 | SEC_READONLY
2088 | SEC_DEBUGGING))
2089 || ! bfd_set_section_flags (obfd, stabstrsec,
2090 (SEC_HAS_CONTENTS
2091 | SEC_READONLY
2092 | SEC_DEBUGGING)))
2094 non_fatal (_("%s: can't create debugging section: %s"),
2095 bfd_get_filename (obfd),
2096 bfd_errmsg (bfd_get_error ()));
2097 return FALSE;
2100 /* We can get away with setting the section contents now because
2101 the next thing the caller is going to do is copy over the
2102 real sections. We may someday have to split the contents
2103 setting out of this function. */
2104 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2105 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2106 stringsize))
2108 non_fatal (_("%s: can't set debugging section contents: %s"),
2109 bfd_get_filename (obfd),
2110 bfd_errmsg (bfd_get_error ()));
2111 return FALSE;
2114 return TRUE;
2117 non_fatal (_("%s: don't know how to write debugging information for %s"),
2118 bfd_get_filename (obfd), bfd_get_target (obfd));
2119 return FALSE;
2122 static int
2123 strip_main (int argc, char *argv[])
2125 char *input_target = NULL;
2126 char *output_target = NULL;
2127 bfd_boolean show_version = FALSE;
2128 bfd_boolean formats_info = FALSE;
2129 int c;
2130 int i;
2131 struct section_list *p;
2132 char *output_file = NULL;
2134 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVv",
2135 strip_options, (int *) 0)) != EOF)
2137 switch (c)
2139 case 'I':
2140 input_target = optarg;
2141 break;
2142 case 'O':
2143 output_target = optarg;
2144 break;
2145 case 'F':
2146 input_target = output_target = optarg;
2147 break;
2148 case 'R':
2149 p = find_section_list (optarg, TRUE);
2150 p->remove = TRUE;
2151 sections_removed = TRUE;
2152 break;
2153 case 's':
2154 strip_symbols = STRIP_ALL;
2155 break;
2156 case 'S':
2157 case 'g':
2158 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2159 strip_symbols = STRIP_DEBUG;
2160 break;
2161 case OPTION_STRIP_UNNEEDED:
2162 strip_symbols = STRIP_UNNEEDED;
2163 break;
2164 case 'K':
2165 add_specific_symbol (optarg, &keep_specific_list);
2166 break;
2167 case 'N':
2168 add_specific_symbol (optarg, &strip_specific_list);
2169 break;
2170 case 'o':
2171 output_file = optarg;
2172 break;
2173 case 'p':
2174 preserve_dates = TRUE;
2175 break;
2176 case 'x':
2177 discard_locals = LOCALS_ALL;
2178 break;
2179 case 'X':
2180 discard_locals = LOCALS_START_L;
2181 break;
2182 case 'v':
2183 verbose = TRUE;
2184 break;
2185 case 'V':
2186 show_version = TRUE;
2187 break;
2188 case OPTION_FORMATS_INFO:
2189 formats_info = TRUE;
2190 break;
2191 case OPTION_ONLY_KEEP_DEBUG:
2192 strip_symbols = STRIP_NONDEBUG;
2193 break;
2194 case 0:
2195 /* We've been given a long option. */
2196 break;
2197 case 'H':
2198 case 'h':
2199 strip_usage (stdout, 0);
2200 default:
2201 strip_usage (stderr, 1);
2205 if (formats_info)
2207 display_info ();
2208 return 0;
2211 if (show_version)
2212 print_version ("strip");
2214 /* Default is to strip all symbols. */
2215 if (strip_symbols == STRIP_UNDEF
2216 && discard_locals == LOCALS_UNDEF
2217 && strip_specific_list == NULL)
2218 strip_symbols = STRIP_ALL;
2220 if (output_target == NULL)
2221 output_target = input_target;
2223 i = optind;
2224 if (i == argc
2225 || (output_file != NULL && (i + 1) < argc))
2226 strip_usage (stderr, 1);
2228 for (; i < argc; i++)
2230 int hold_status = status;
2231 struct stat statbuf;
2232 char *tmpname;
2234 if (preserve_dates)
2236 if (stat (argv[i], &statbuf) < 0)
2238 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
2239 continue;
2243 if (output_file != NULL)
2244 tmpname = output_file;
2245 else
2246 tmpname = make_tempname (argv[i]);
2247 status = 0;
2249 copy_file (argv[i], tmpname, input_target, output_target);
2250 if (status == 0)
2252 if (preserve_dates)
2253 set_times (tmpname, &statbuf);
2254 if (output_file == NULL)
2255 smart_rename (tmpname, argv[i], preserve_dates);
2256 status = hold_status;
2258 else
2259 unlink (tmpname);
2260 if (output_file == NULL)
2261 free (tmpname);
2264 return 0;
2267 static int
2268 copy_main (int argc, char *argv[])
2270 char * binary_architecture = NULL;
2271 char *input_filename = NULL;
2272 char *output_filename = NULL;
2273 char *input_target = NULL;
2274 char *output_target = NULL;
2275 bfd_boolean show_version = FALSE;
2276 bfd_boolean change_warn = TRUE;
2277 bfd_boolean formats_info = FALSE;
2278 int c;
2279 struct section_list *p;
2280 struct stat statbuf;
2282 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:",
2283 copy_options, (int *) 0)) != EOF)
2285 switch (c)
2287 case 'b':
2288 copy_byte = atoi (optarg);
2289 if (copy_byte < 0)
2290 fatal (_("byte number must be non-negative"));
2291 break;
2293 case 'B':
2294 binary_architecture = optarg;
2295 break;
2297 case 'i':
2298 interleave = atoi (optarg);
2299 if (interleave < 1)
2300 fatal (_("interleave must be positive"));
2301 break;
2303 case 'I':
2304 case 's': /* "source" - 'I' is preferred */
2305 input_target = optarg;
2306 break;
2308 case 'O':
2309 case 'd': /* "destination" - 'O' is preferred */
2310 output_target = optarg;
2311 break;
2313 case 'F':
2314 input_target = output_target = optarg;
2315 break;
2317 case 'j':
2318 p = find_section_list (optarg, TRUE);
2319 if (p->remove)
2320 fatal (_("%s both copied and removed"), optarg);
2321 p->copy = TRUE;
2322 sections_copied = TRUE;
2323 break;
2325 case 'R':
2326 p = find_section_list (optarg, TRUE);
2327 if (p->copy)
2328 fatal (_("%s both copied and removed"), optarg);
2329 p->remove = TRUE;
2330 sections_removed = TRUE;
2331 break;
2333 case 'S':
2334 strip_symbols = STRIP_ALL;
2335 break;
2337 case 'g':
2338 strip_symbols = STRIP_DEBUG;
2339 break;
2341 case OPTION_STRIP_UNNEEDED:
2342 strip_symbols = STRIP_UNNEEDED;
2343 break;
2345 case OPTION_ONLY_KEEP_DEBUG:
2346 strip_symbols = STRIP_NONDEBUG;
2347 break;
2349 case OPTION_ADD_GNU_DEBUGLINK:
2350 gnu_debuglink_filename = optarg;
2351 break;
2353 case 'K':
2354 add_specific_symbol (optarg, &keep_specific_list);
2355 break;
2357 case 'N':
2358 add_specific_symbol (optarg, &strip_specific_list);
2359 break;
2361 case 'L':
2362 add_specific_symbol (optarg, &localize_specific_list);
2363 break;
2365 case 'G':
2366 add_specific_symbol (optarg, &keepglobal_specific_list);
2367 break;
2369 case 'W':
2370 add_specific_symbol (optarg, &weaken_specific_list);
2371 break;
2373 case 'p':
2374 preserve_dates = TRUE;
2375 break;
2377 case 'x':
2378 discard_locals = LOCALS_ALL;
2379 break;
2381 case 'X':
2382 discard_locals = LOCALS_START_L;
2383 break;
2385 case 'v':
2386 verbose = TRUE;
2387 break;
2389 case 'V':
2390 show_version = TRUE;
2391 break;
2393 case OPTION_FORMATS_INFO:
2394 formats_info = TRUE;
2395 break;
2397 case OPTION_WEAKEN:
2398 weaken = TRUE;
2399 break;
2401 case OPTION_ADD_SECTION:
2403 const char *s;
2404 struct stat st;
2405 struct section_add *pa;
2406 int len;
2407 char *name;
2408 FILE *f;
2410 s = strchr (optarg, '=');
2412 if (s == NULL)
2413 fatal (_("bad format for %s"), "--add-section");
2415 if (stat (s + 1, & st) < 0)
2416 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
2418 pa = xmalloc (sizeof (struct section_add));
2420 len = s - optarg;
2421 name = xmalloc (len + 1);
2422 strncpy (name, optarg, len);
2423 name[len] = '\0';
2424 pa->name = name;
2426 pa->filename = s + 1;
2428 pa->size = st.st_size;
2430 pa->contents = xmalloc (pa->size);
2431 f = fopen (pa->filename, FOPEN_RB);
2433 if (f == NULL)
2434 fatal (_("cannot open: %s: %s"),
2435 pa->filename, strerror (errno));
2437 if (fread (pa->contents, 1, pa->size, f) == 0
2438 || ferror (f))
2439 fatal (_("%s: fread failed"), pa->filename);
2441 fclose (f);
2443 pa->next = add_sections;
2444 add_sections = pa;
2446 break;
2448 case OPTION_CHANGE_START:
2449 change_start = parse_vma (optarg, "--change-start");
2450 break;
2452 case OPTION_CHANGE_SECTION_ADDRESS:
2453 case OPTION_CHANGE_SECTION_LMA:
2454 case OPTION_CHANGE_SECTION_VMA:
2456 const char *s;
2457 int len;
2458 char *name;
2459 char *option = NULL;
2460 bfd_vma val;
2461 enum change_action what = CHANGE_IGNORE;
2463 switch (c)
2465 case OPTION_CHANGE_SECTION_ADDRESS:
2466 option = "--change-section-address";
2467 break;
2468 case OPTION_CHANGE_SECTION_LMA:
2469 option = "--change-section-lma";
2470 break;
2471 case OPTION_CHANGE_SECTION_VMA:
2472 option = "--change-section-vma";
2473 break;
2476 s = strchr (optarg, '=');
2477 if (s == NULL)
2479 s = strchr (optarg, '+');
2480 if (s == NULL)
2482 s = strchr (optarg, '-');
2483 if (s == NULL)
2484 fatal (_("bad format for %s"), option);
2488 len = s - optarg;
2489 name = xmalloc (len + 1);
2490 strncpy (name, optarg, len);
2491 name[len] = '\0';
2493 p = find_section_list (name, TRUE);
2495 val = parse_vma (s + 1, option);
2497 switch (*s)
2499 case '=': what = CHANGE_SET; break;
2500 case '-': val = - val; /* Drop through. */
2501 case '+': what = CHANGE_MODIFY; break;
2504 switch (c)
2506 case OPTION_CHANGE_SECTION_ADDRESS:
2507 p->change_vma = what;
2508 p->vma_val = val;
2509 /* Drop through. */
2511 case OPTION_CHANGE_SECTION_LMA:
2512 p->change_lma = what;
2513 p->lma_val = val;
2514 break;
2516 case OPTION_CHANGE_SECTION_VMA:
2517 p->change_vma = what;
2518 p->vma_val = val;
2519 break;
2522 break;
2524 case OPTION_CHANGE_ADDRESSES:
2525 change_section_address = parse_vma (optarg, "--change-addresses");
2526 change_start = change_section_address;
2527 break;
2529 case OPTION_CHANGE_WARNINGS:
2530 change_warn = TRUE;
2531 break;
2533 case OPTION_CHANGE_LEADING_CHAR:
2534 change_leading_char = TRUE;
2535 break;
2537 case OPTION_DEBUGGING:
2538 convert_debugging = TRUE;
2539 break;
2541 case OPTION_GAP_FILL:
2543 bfd_vma gap_fill_vma;
2545 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2546 gap_fill = (bfd_byte) gap_fill_vma;
2547 if ((bfd_vma) gap_fill != gap_fill_vma)
2549 char buff[20];
2551 sprintf_vma (buff, gap_fill_vma);
2553 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2554 buff, gap_fill);
2556 gap_fill_set = TRUE;
2558 break;
2560 case OPTION_NO_CHANGE_WARNINGS:
2561 change_warn = FALSE;
2562 break;
2564 case OPTION_PAD_TO:
2565 pad_to = parse_vma (optarg, "--pad-to");
2566 pad_to_set = TRUE;
2567 break;
2569 case OPTION_REMOVE_LEADING_CHAR:
2570 remove_leading_char = TRUE;
2571 break;
2573 case OPTION_REDEFINE_SYM:
2575 /* Push this redefinition onto redefine_symbol_list. */
2577 int len;
2578 const char *s;
2579 const char *nextarg;
2580 char *source, *target;
2582 s = strchr (optarg, '=');
2583 if (s == NULL)
2584 fatal (_("bad format for %s"), "--redefine-sym");
2586 len = s - optarg;
2587 source = xmalloc (len + 1);
2588 strncpy (source, optarg, len);
2589 source[len] = '\0';
2591 nextarg = s + 1;
2592 len = strlen (nextarg);
2593 target = xmalloc (len + 1);
2594 strcpy (target, nextarg);
2596 redefine_list_append ("--redefine-sym", source, target);
2598 free (source);
2599 free (target);
2601 break;
2603 case OPTION_REDEFINE_SYMS:
2604 add_redefine_syms_file (optarg);
2605 break;
2607 case OPTION_SET_SECTION_FLAGS:
2609 const char *s;
2610 int len;
2611 char *name;
2613 s = strchr (optarg, '=');
2614 if (s == NULL)
2615 fatal (_("bad format for %s"), "--set-section-flags");
2617 len = s - optarg;
2618 name = xmalloc (len + 1);
2619 strncpy (name, optarg, len);
2620 name[len] = '\0';
2622 p = find_section_list (name, TRUE);
2624 p->set_flags = TRUE;
2625 p->flags = parse_flags (s + 1);
2627 break;
2629 case OPTION_RENAME_SECTION:
2631 flagword flags;
2632 const char *eq, *fl;
2633 char *old_name;
2634 char *new_name;
2635 unsigned int len;
2637 eq = strchr (optarg, '=');
2638 if (eq == NULL)
2639 fatal (_("bad format for %s"), "--rename-section");
2641 len = eq - optarg;
2642 if (len == 0)
2643 fatal (_("bad format for %s"), "--rename-section");
2645 old_name = xmalloc (len + 1);
2646 strncpy (old_name, optarg, len);
2647 old_name[len] = 0;
2649 eq++;
2650 fl = strchr (eq, ',');
2651 if (fl)
2653 flags = parse_flags (fl + 1);
2654 len = fl - eq;
2656 else
2658 flags = -1;
2659 len = strlen (eq);
2662 if (len == 0)
2663 fatal (_("bad format for %s"), "--rename-section");
2665 new_name = xmalloc (len + 1);
2666 strncpy (new_name, eq, len);
2667 new_name[len] = 0;
2669 add_section_rename (old_name, new_name, flags);
2671 break;
2673 case OPTION_SET_START:
2674 set_start = parse_vma (optarg, "--set-start");
2675 set_start_set = TRUE;
2676 break;
2678 case OPTION_SREC_LEN:
2679 Chunk = parse_vma (optarg, "--srec-len");
2680 break;
2682 case OPTION_SREC_FORCES3:
2683 S3Forced = TRUE;
2684 break;
2686 case OPTION_STRIP_SYMBOLS:
2687 add_specific_symbols (optarg, &strip_specific_list);
2688 break;
2690 case OPTION_KEEP_SYMBOLS:
2691 add_specific_symbols (optarg, &keep_specific_list);
2692 break;
2694 case OPTION_LOCALIZE_SYMBOLS:
2695 add_specific_symbols (optarg, &localize_specific_list);
2696 break;
2698 case OPTION_KEEPGLOBAL_SYMBOLS:
2699 add_specific_symbols (optarg, &keepglobal_specific_list);
2700 break;
2702 case OPTION_WEAKEN_SYMBOLS:
2703 add_specific_symbols (optarg, &weaken_specific_list);
2704 break;
2706 case OPTION_ALT_MACH_CODE:
2707 use_alt_mach_code = atoi (optarg);
2708 if (use_alt_mach_code <= 0)
2709 fatal (_("alternate machine code index must be positive"));
2710 break;
2712 case OPTION_PREFIX_SYMBOLS:
2713 prefix_symbols_string = optarg;
2714 break;
2716 case OPTION_PREFIX_SECTIONS:
2717 prefix_sections_string = optarg;
2718 break;
2720 case OPTION_PREFIX_ALLOC_SECTIONS:
2721 prefix_alloc_sections_string = optarg;
2722 break;
2724 case 0:
2725 /* We've been given a long option. */
2726 break;
2728 case 'H':
2729 case 'h':
2730 copy_usage (stdout, 0);
2732 default:
2733 copy_usage (stderr, 1);
2737 if (formats_info)
2739 display_info ();
2740 return 0;
2743 if (show_version)
2744 print_version ("objcopy");
2746 if (copy_byte >= interleave)
2747 fatal (_("byte number must be less than interleave"));
2749 if (optind == argc || optind + 2 < argc)
2750 copy_usage (stderr, 1);
2752 input_filename = argv[optind];
2753 if (optind + 1 < argc)
2754 output_filename = argv[optind + 1];
2756 /* Default is to strip no symbols. */
2757 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2758 strip_symbols = STRIP_NONE;
2760 if (output_target == NULL)
2761 output_target = input_target;
2763 if (binary_architecture != NULL)
2765 if (input_target && strcmp (input_target, "binary") == 0)
2767 const bfd_arch_info_type * temp_arch_info;
2769 temp_arch_info = bfd_scan_arch (binary_architecture);
2771 if (temp_arch_info != NULL)
2772 bfd_external_binary_architecture = temp_arch_info->arch;
2773 else
2774 fatal (_("architecture %s unknown"), binary_architecture);
2776 else
2778 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2779 non_fatal (_(" Argument %s ignored"), binary_architecture);
2783 if (preserve_dates)
2784 if (stat (input_filename, & statbuf) < 0)
2785 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2787 /* If there is no destination file, or the source and destination files
2788 are the same, then create a temp and rename the result into the input. */
2789 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
2791 char *tmpname = make_tempname (input_filename);
2793 copy_file (input_filename, tmpname, input_target, output_target);
2794 if (status == 0)
2796 if (preserve_dates)
2797 set_times (tmpname, &statbuf);
2798 smart_rename (tmpname, input_filename, preserve_dates);
2800 else
2801 unlink (tmpname);
2803 else
2805 copy_file (input_filename, output_filename, input_target, output_target);
2807 if (status == 0 && preserve_dates)
2808 set_times (output_filename, &statbuf);
2811 if (change_warn)
2813 for (p = change_sections; p != NULL; p = p->next)
2815 if (! p->used)
2817 if (p->change_vma != CHANGE_IGNORE)
2819 char buff [20];
2821 sprintf_vma (buff, p->vma_val);
2823 /* xgettext:c-format */
2824 non_fatal (_("%s %s%c0x%s never used"),
2825 "--change-section-vma",
2826 p->name,
2827 p->change_vma == CHANGE_SET ? '=' : '+',
2828 buff);
2831 if (p->change_lma != CHANGE_IGNORE)
2833 char buff [20];
2835 sprintf_vma (buff, p->lma_val);
2837 /* xgettext:c-format */
2838 non_fatal (_("%s %s%c0x%s never used"),
2839 "--change-section-lma",
2840 p->name,
2841 p->change_lma == CHANGE_SET ? '=' : '+',
2842 buff);
2848 return 0;
2852 main (int argc, char *argv[])
2854 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2855 setlocale (LC_MESSAGES, "");
2856 #endif
2857 #if defined (HAVE_SETLOCALE)
2858 setlocale (LC_CTYPE, "");
2859 #endif
2860 bindtextdomain (PACKAGE, LOCALEDIR);
2861 textdomain (PACKAGE);
2863 program_name = argv[0];
2864 xmalloc_set_program_name (program_name);
2866 START_PROGRESS (program_name, 0);
2868 strip_symbols = STRIP_UNDEF;
2869 discard_locals = LOCALS_UNDEF;
2871 bfd_init ();
2872 set_default_bfd_target ();
2874 if (is_strip < 0)
2876 int i = strlen (program_name);
2877 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2878 /* Drop the .exe suffix, if any. */
2879 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2881 i -= 4;
2882 program_name[i] = '\0';
2884 #endif
2885 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2888 if (is_strip)
2889 strip_main (argc, argv);
2890 else
2891 copy_main (argc, argv);
2893 END_PROGRESS (program_name);
2895 return status;