* ldlang.c (lang_get_regions): Add extra parameter 'have_vma' which if true will
[deliverable/binutils-gdb.git] / binutils / objcopy.c
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, 2004
4 Free Software Foundation, Inc.
5
6 This file is part of GNU Binutils.
7
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.
12
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.
17
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. */
22 \f
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 "fnmatch.h"
31 #include <sys/stat.h>
32
33 /* A list of symbols to explicitly strip out, or to keep. A linked
34 list is good enough for a small number from the command line, but
35 this will slow things down a lot if many symbols are being
36 deleted. */
37
38 struct symlist
39 {
40 const char *name;
41 struct symlist *next;
42 };
43
44 /* A list to support redefine_sym. */
45 struct redefine_node
46 {
47 char *source;
48 char *target;
49 struct redefine_node *next;
50 };
51
52 typedef struct section_rename
53 {
54 const char * old_name;
55 const char * new_name;
56 flagword flags;
57 struct section_rename * next;
58 }
59 section_rename;
60
61 /* List of sections to be renamed. */
62 static section_rename *section_rename_list;
63
64 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
65
66 static asymbol **isympp = NULL; /* Input symbols. */
67 static asymbol **osympp = NULL; /* Output symbols that survive stripping. */
68
69 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
70 static int copy_byte = -1;
71 static int interleave = 4;
72
73 static bfd_boolean verbose; /* Print file and target names. */
74 static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
75 static int status = 0; /* Exit status. */
76
77 enum strip_action
78 {
79 STRIP_UNDEF,
80 STRIP_NONE, /* Don't strip. */
81 STRIP_DEBUG, /* Strip all debugger symbols. */
82 STRIP_UNNEEDED, /* Strip unnecessary symbols. */
83 STRIP_NONDEBUG, /* Strip everything but debug info. */
84 STRIP_ALL /* Strip all symbols. */
85 };
86
87 /* Which symbols to remove. */
88 static enum strip_action strip_symbols;
89
90 enum locals_action
91 {
92 LOCALS_UNDEF,
93 LOCALS_START_L, /* Discard locals starting with L. */
94 LOCALS_ALL /* Discard all locals. */
95 };
96
97 /* Which local symbols to remove. Overrides STRIP_ALL. */
98 static enum locals_action discard_locals;
99
100 /* What kind of change to perform. */
101 enum change_action
102 {
103 CHANGE_IGNORE,
104 CHANGE_MODIFY,
105 CHANGE_SET
106 };
107
108 /* Structure used to hold lists of sections and actions to take. */
109 struct section_list
110 {
111 struct section_list * next; /* Next section to change. */
112 const char * name; /* Section name. */
113 bfd_boolean used; /* Whether this entry was used. */
114 bfd_boolean remove; /* Whether to remove this section. */
115 bfd_boolean copy; /* Whether to copy this section. */
116 enum change_action change_vma;/* Whether to change or set VMA. */
117 bfd_vma vma_val; /* Amount to change by or set to. */
118 enum change_action change_lma;/* Whether to change or set LMA. */
119 bfd_vma lma_val; /* Amount to change by or set to. */
120 bfd_boolean set_flags; /* Whether to set the section flags. */
121 flagword flags; /* What to set the section flags to. */
122 };
123
124 static struct section_list *change_sections;
125
126 /* TRUE if some sections are to be removed. */
127 static bfd_boolean sections_removed;
128
129 /* TRUE if only some sections are to be copied. */
130 static bfd_boolean sections_copied;
131
132 /* Changes to the start address. */
133 static bfd_vma change_start = 0;
134 static bfd_boolean set_start_set = FALSE;
135 static bfd_vma set_start;
136
137 /* Changes to section addresses. */
138 static bfd_vma change_section_address = 0;
139
140 /* Filling gaps between sections. */
141 static bfd_boolean gap_fill_set = FALSE;
142 static bfd_byte gap_fill = 0;
143
144 /* Pad to a given address. */
145 static bfd_boolean pad_to_set = FALSE;
146 static bfd_vma pad_to;
147
148 /* Use alternate machine code? */
149 static int use_alt_mach_code = 0;
150
151 /* Output BFD flags user wants to set or clear */
152 static flagword bfd_flags_to_set;
153 static flagword bfd_flags_to_clear;
154
155 /* List of sections to add. */
156 struct section_add
157 {
158 /* Next section to add. */
159 struct section_add *next;
160 /* Name of section to add. */
161 const char *name;
162 /* Name of file holding section contents. */
163 const char *filename;
164 /* Size of file. */
165 size_t size;
166 /* Contents of file. */
167 bfd_byte *contents;
168 /* BFD section, after it has been added. */
169 asection *section;
170 };
171
172 /* List of sections to add to the output BFD. */
173 static struct section_add *add_sections;
174
175 /* If non-NULL the argument to --add-gnu-debuglink.
176 This should be the filename to store in the .gnu_debuglink section. */
177 static const char * gnu_debuglink_filename = NULL;
178
179 /* Whether to convert debugging information. */
180 static bfd_boolean convert_debugging = FALSE;
181
182 /* Whether to change the leading character in symbol names. */
183 static bfd_boolean change_leading_char = FALSE;
184
185 /* Whether to remove the leading character from global symbol names. */
186 static bfd_boolean remove_leading_char = FALSE;
187
188 /* Whether to permit wildcard in symbol comparison. */
189 static bfd_boolean wildcard = FALSE;
190
191 /* List of symbols to strip, keep, localize, keep-global, weaken,
192 or redefine. */
193 static struct symlist *strip_specific_list = NULL;
194 static struct symlist *keep_specific_list = NULL;
195 static struct symlist *localize_specific_list = NULL;
196 static struct symlist *keepglobal_specific_list = NULL;
197 static struct symlist *weaken_specific_list = NULL;
198 static struct redefine_node *redefine_sym_list = NULL;
199
200 /* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
201 static bfd_boolean weaken = FALSE;
202
203 /* Prefix symbols/sections. */
204 static char *prefix_symbols_string = 0;
205 static char *prefix_sections_string = 0;
206 static char *prefix_alloc_sections_string = 0;
207
208 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
209 enum command_line_switch
210 {
211 OPTION_ADD_SECTION=150,
212 OPTION_CHANGE_ADDRESSES,
213 OPTION_CHANGE_LEADING_CHAR,
214 OPTION_CHANGE_START,
215 OPTION_CHANGE_SECTION_ADDRESS,
216 OPTION_CHANGE_SECTION_LMA,
217 OPTION_CHANGE_SECTION_VMA,
218 OPTION_CHANGE_WARNINGS,
219 OPTION_DEBUGGING,
220 OPTION_GAP_FILL,
221 OPTION_NO_CHANGE_WARNINGS,
222 OPTION_PAD_TO,
223 OPTION_REMOVE_LEADING_CHAR,
224 OPTION_SET_SECTION_FLAGS,
225 OPTION_SET_START,
226 OPTION_STRIP_UNNEEDED,
227 OPTION_WEAKEN,
228 OPTION_REDEFINE_SYM,
229 OPTION_REDEFINE_SYMS,
230 OPTION_SREC_LEN,
231 OPTION_SREC_FORCES3,
232 OPTION_STRIP_SYMBOLS,
233 OPTION_KEEP_SYMBOLS,
234 OPTION_LOCALIZE_SYMBOLS,
235 OPTION_KEEPGLOBAL_SYMBOLS,
236 OPTION_WEAKEN_SYMBOLS,
237 OPTION_RENAME_SECTION,
238 OPTION_ALT_MACH_CODE,
239 OPTION_PREFIX_SYMBOLS,
240 OPTION_PREFIX_SECTIONS,
241 OPTION_PREFIX_ALLOC_SECTIONS,
242 OPTION_FORMATS_INFO,
243 OPTION_ADD_GNU_DEBUGLINK,
244 OPTION_ONLY_KEEP_DEBUG,
245 OPTION_READONLY_TEXT,
246 OPTION_WRITABLE_TEXT,
247 OPTION_PURE,
248 OPTION_IMPURE
249 };
250
251 /* Options to handle if running as "strip". */
252
253 static struct option strip_options[] =
254 {
255 {"discard-all", no_argument, 0, 'x'},
256 {"discard-locals", no_argument, 0, 'X'},
257 {"format", required_argument, 0, 'F'}, /* Obsolete */
258 {"help", no_argument, 0, 'h'},
259 {"info", no_argument, 0, OPTION_FORMATS_INFO},
260 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
261 {"input-target", required_argument, 0, 'I'},
262 {"keep-symbol", required_argument, 0, 'K'},
263 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
264 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
265 {"output-target", required_argument, 0, 'O'},
266 {"output-file", required_argument, 0, 'o'},
267 {"preserve-dates", no_argument, 0, 'p'},
268 {"remove-section", required_argument, 0, 'R'},
269 {"strip-all", no_argument, 0, 's'},
270 {"strip-debug", no_argument, 0, 'S'},
271 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
272 {"strip-symbol", required_argument, 0, 'N'},
273 {"target", required_argument, 0, 'F'},
274 {"verbose", no_argument, 0, 'v'},
275 {"version", no_argument, 0, 'V'},
276 {"wildcard", no_argument, 0, 'w'},
277 {0, no_argument, 0, 0}
278 };
279
280 /* Options to handle if running as "objcopy". */
281
282 static struct option copy_options[] =
283 {
284 {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
285 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
286 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
287 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
288 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
289 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
290 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
291 {"binary-architecture", required_argument, 0, 'B'},
292 {"byte", required_argument, 0, 'b'},
293 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
294 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
295 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
296 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
297 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
298 {"change-start", required_argument, 0, OPTION_CHANGE_START},
299 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
300 {"debugging", no_argument, 0, OPTION_DEBUGGING},
301 {"discard-all", no_argument, 0, 'x'},
302 {"discard-locals", no_argument, 0, 'X'},
303 {"format", required_argument, 0, 'F'}, /* Obsolete */
304 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
305 {"help", no_argument, 0, 'h'},
306 {"impure", no_argument, 0, OPTION_IMPURE},
307 {"info", no_argument, 0, OPTION_FORMATS_INFO},
308 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
309 {"input-target", required_argument, 0, 'I'},
310 {"interleave", required_argument, 0, 'i'},
311 {"keep-global-symbol", required_argument, 0, 'G'},
312 {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
313 {"keep-symbol", required_argument, 0, 'K'},
314 {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
315 {"localize-symbol", required_argument, 0, 'L'},
316 {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
317 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
318 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
319 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
320 {"only-section", required_argument, 0, 'j'},
321 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
322 {"output-target", required_argument, 0, 'O'},
323 {"pad-to", required_argument, 0, OPTION_PAD_TO},
324 {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
325 {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
326 {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
327 {"preserve-dates", no_argument, 0, 'p'},
328 {"pure", no_argument, 0, OPTION_PURE},
329 {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
330 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
331 {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
332 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
333 {"remove-section", required_argument, 0, 'R'},
334 {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
335 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
336 {"set-start", required_argument, 0, OPTION_SET_START},
337 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
338 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
339 {"strip-all", no_argument, 0, 'S'},
340 {"strip-debug", no_argument, 0, 'g'},
341 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
342 {"strip-symbol", required_argument, 0, 'N'},
343 {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
344 {"target", required_argument, 0, 'F'},
345 {"verbose", no_argument, 0, 'v'},
346 {"version", no_argument, 0, 'V'},
347 {"weaken", no_argument, 0, OPTION_WEAKEN},
348 {"weaken-symbol", required_argument, 0, 'W'},
349 {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
350 {"wildcard", no_argument, 0, 'w'},
351 {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
352 {0, no_argument, 0, 0}
353 };
354
355 /* IMPORTS */
356 extern char *program_name;
357
358 /* This flag distinguishes between strip and objcopy:
359 1 means this is 'strip'; 0 means this is 'objcopy'.
360 -1 means if we should use argv[0] to decide. */
361 extern int is_strip;
362
363 /* The maximum length of an S record. This variable is declared in srec.c
364 and can be modified by the --srec-len parameter. */
365 extern unsigned int Chunk;
366
367 /* Restrict the generation of Srecords to type S3 only.
368 This variable is declare in bfd/srec.c and can be toggled
369 on by the --srec-forceS3 command line switch. */
370 extern bfd_boolean S3Forced;
371
372 /* Defined in bfd/binary.c. Used to set architecture and machine of input
373 binary files. */
374 extern enum bfd_architecture bfd_external_binary_architecture;
375 extern unsigned long bfd_external_machine;
376
377 /* Forward declarations. */
378 static void setup_section (bfd *, asection *, void *);
379 static void copy_section (bfd *, asection *, void *);
380 static void get_sections (bfd *, asection *, void *);
381 static int compare_section_lma (const void *, const void *);
382 static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
383 static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
384 static const char *lookup_sym_redefinition (const char *);
385 \f
386 static void
387 copy_usage (FILE *stream, int exit_status)
388 {
389 fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
390 fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
391 fprintf (stream, _(" The options are:\n"));
392 fprintf (stream, _("\
393 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
394 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
395 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
396 -F --target <bfdname> Set both input and output format to <bfdname>\n\
397 --debugging Convert debugging information, if possible\n\
398 -p --preserve-dates Copy modified/access timestamps to the output\n\
399 -j --only-section <name> Only copy section <name> into the output\n\
400 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
401 -R --remove-section <name> Remove section <name> from the output\n\
402 -S --strip-all Remove all symbol and relocation information\n\
403 -g --strip-debug Remove all debugging symbols & sections\n\
404 --strip-unneeded Remove all symbols not needed by relocations\n\
405 -N --strip-symbol <name> Do not copy symbol <name>\n\
406 --only-keep-debug Strip everything but the debug information\n\
407 -K --keep-symbol <name> Only copy symbol <name>\n\
408 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
409 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
410 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
411 --weaken Force all global symbols to be marked as weak\n\
412 -w --wildcard Permit wildcard in symbol comparasion\n\
413 -x --discard-all Remove all non-global symbols\n\
414 -X --discard-locals Remove any compiler-generated symbols\n\
415 -i --interleave <number> Only copy one out of every <number> bytes\n\
416 -b --byte <num> Select byte <num> in every interleaved block\n\
417 --gap-fill <val> Fill gaps between sections with <val>\n\
418 --pad-to <addr> Pad the last section up to address <addr>\n\
419 --set-start <addr> Set the start address to <addr>\n\
420 {--change-start|--adjust-start} <incr>\n\
421 Add <incr> to the start address\n\
422 {--change-addresses|--adjust-vma} <incr>\n\
423 Add <incr> to LMA, VMA and start addresses\n\
424 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
425 Change LMA and VMA of section <name> by <val>\n\
426 --change-section-lma <name>{=|+|-}<val>\n\
427 Change the LMA of section <name> by <val>\n\
428 --change-section-vma <name>{=|+|-}<val>\n\
429 Change the VMA of section <name> by <val>\n\
430 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
431 Warn if a named section does not exist\n\
432 --set-section-flags <name>=<flags>\n\
433 Set section <name>'s properties to <flags>\n\
434 --add-section <name>=<file> Add section <name> found in <file> to output\n\
435 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
436 --change-leading-char Force output format's leading character style\n\
437 --remove-leading-char Remove leading character from global symbols\n\
438 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
439 --redefine-syms <file> --redefine-sym for all symbol pairs \n\
440 listed in <file>\n\
441 --srec-len <number> Restrict the length of generated Srecords\n\
442 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
443 --strip-symbols <file> -N for all symbols listed in <file>\n\
444 --keep-symbols <file> -K for all symbols listed in <file>\n\
445 --localize-symbols <file> -L for all symbols listed in <file>\n\
446 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
447 --weaken-symbols <file> -W for all symbols listed in <file>\n\
448 --alt-machine-code <index> Use alternate machine code for output\n\
449 --writable-text Mark the output text as writable\n\
450 --readonly-text Make the output text write protected\n\
451 --pure Mark the output file as demand paged\n\
452 --impure Mark the output file as impure\n\
453 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\
454 --prefix-sections <prefix> Add <prefix> to start of every section name\n\
455 --prefix-alloc-sections <prefix>\n\
456 Add <prefix> to start of every allocatable\n\
457 section name\n\
458 -v --verbose List all object files modified\n\
459 -V --version Display this program's version number\n\
460 -h --help Display this output\n\
461 --info List object formats & architectures supported\n\
462 "));
463 list_supported_targets (program_name, stream);
464 if (exit_status == 0)
465 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
466 exit (exit_status);
467 }
468
469 static void
470 strip_usage (FILE *stream, int exit_status)
471 {
472 fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
473 fprintf (stream, _(" Removes symbols and sections from files\n"));
474 fprintf (stream, _(" The options are:\n"));
475 fprintf (stream, _("\
476 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\
477 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\
478 -F --target=<bfdname> Set both input and output format to <bfdname>\n\
479 -p --preserve-dates Copy modified/access timestamps to the output\n\
480 -R --remove-section=<name> Remove section <name> from the output\n\
481 -s --strip-all Remove all symbol and relocation information\n\
482 -g -S -d --strip-debug Remove all debugging symbols & sections\n\
483 --strip-unneeded Remove all symbols not needed by relocations\n\
484 --only-keep-debug Strip everything but the debug information\n\
485 -N --strip-symbol=<name> Do not copy symbol <name>\n\
486 -K --keep-symbol=<name> Only copy symbol <name>\n\
487 -w --wildcard Permit wildcard in symbol comparasion\n\
488 -x --discard-all Remove all non-global symbols\n\
489 -X --discard-locals Remove any compiler-generated symbols\n\
490 -v --verbose List all object files modified\n\
491 -V --version Display this program's version number\n\
492 -h --help Display this output\n\
493 --info List object formats & architectures supported\n\
494 -o <file> Place stripped output into <file>\n\
495 "));
496
497 list_supported_targets (program_name, stream);
498 if (exit_status == 0)
499 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
500 exit (exit_status);
501 }
502
503 /* Parse section flags into a flagword, with a fatal error if the
504 string can't be parsed. */
505
506 static flagword
507 parse_flags (const char *s)
508 {
509 flagword ret;
510 const char *snext;
511 int len;
512
513 ret = SEC_NO_FLAGS;
514
515 do
516 {
517 snext = strchr (s, ',');
518 if (snext == NULL)
519 len = strlen (s);
520 else
521 {
522 len = snext - s;
523 ++snext;
524 }
525
526 if (0) ;
527 #define PARSE_FLAG(fname,fval) \
528 else if (strncasecmp (fname, s, len) == 0) ret |= fval
529 PARSE_FLAG ("alloc", SEC_ALLOC);
530 PARSE_FLAG ("load", SEC_LOAD);
531 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
532 PARSE_FLAG ("readonly", SEC_READONLY);
533 PARSE_FLAG ("debug", SEC_DEBUGGING);
534 PARSE_FLAG ("code", SEC_CODE);
535 PARSE_FLAG ("data", SEC_DATA);
536 PARSE_FLAG ("rom", SEC_ROM);
537 PARSE_FLAG ("share", SEC_SHARED);
538 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
539 #undef PARSE_FLAG
540 else
541 {
542 char *copy;
543
544 copy = xmalloc (len + 1);
545 strncpy (copy, s, len);
546 copy[len] = '\0';
547 non_fatal (_("unrecognized section flag `%s'"), copy);
548 fatal (_("supported flags: %s"),
549 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
550 }
551
552 s = snext;
553 }
554 while (s != NULL);
555
556 return ret;
557 }
558
559 /* Find and optionally add an entry in the change_sections list. */
560
561 static struct section_list *
562 find_section_list (const char *name, bfd_boolean add)
563 {
564 struct section_list *p;
565
566 for (p = change_sections; p != NULL; p = p->next)
567 if (strcmp (p->name, name) == 0)
568 return p;
569
570 if (! add)
571 return NULL;
572
573 p = xmalloc (sizeof (struct section_list));
574 p->name = name;
575 p->used = FALSE;
576 p->remove = FALSE;
577 p->copy = FALSE;
578 p->change_vma = CHANGE_IGNORE;
579 p->change_lma = CHANGE_IGNORE;
580 p->vma_val = 0;
581 p->lma_val = 0;
582 p->set_flags = FALSE;
583 p->flags = 0;
584
585 p->next = change_sections;
586 change_sections = p;
587
588 return p;
589 }
590
591 /* Add a symbol to strip_specific_list. */
592
593 static void
594 add_specific_symbol (const char *name, struct symlist **list)
595 {
596 struct symlist *tmp_list;
597
598 tmp_list = xmalloc (sizeof (struct symlist));
599 tmp_list->name = name;
600 tmp_list->next = *list;
601 *list = tmp_list;
602 }
603
604 /* Add symbols listed in `filename' to strip_specific_list. */
605
606 #define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
607 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
608
609 static void
610 add_specific_symbols (const char *filename, struct symlist **list)
611 {
612 off_t size;
613 FILE * f;
614 char * line;
615 char * buffer;
616 unsigned int line_count;
617
618 size = get_file_size (filename);
619 if (size == 0)
620 return;
621
622 buffer = xmalloc (size + 2);
623 f = fopen (filename, FOPEN_RT);
624 if (f == NULL)
625 fatal (_("cannot open '%s': %s"), filename, strerror (errno));
626
627 if (fread (buffer, 1, size, f) == 0 || ferror (f))
628 fatal (_("%s: fread failed"), filename);
629
630 fclose (f);
631 buffer [size] = '\n';
632 buffer [size + 1] = '\0';
633
634 line_count = 1;
635
636 for (line = buffer; * line != '\0'; line ++)
637 {
638 char * eol;
639 char * name;
640 char * name_end;
641 int finished = FALSE;
642
643 for (eol = line;; eol ++)
644 {
645 switch (* eol)
646 {
647 case '\n':
648 * eol = '\0';
649 /* Cope with \n\r. */
650 if (eol[1] == '\r')
651 ++ eol;
652 finished = TRUE;
653 break;
654
655 case '\r':
656 * eol = '\0';
657 /* Cope with \r\n. */
658 if (eol[1] == '\n')
659 ++ eol;
660 finished = TRUE;
661 break;
662
663 case 0:
664 finished = TRUE;
665 break;
666
667 case '#':
668 /* Line comment, Terminate the line here, in case a
669 name is present and then allow the rest of the
670 loop to find the real end of the line. */
671 * eol = '\0';
672 break;
673
674 default:
675 break;
676 }
677
678 if (finished)
679 break;
680 }
681
682 /* A name may now exist somewhere between 'line' and 'eol'.
683 Strip off leading whitespace and trailing whitespace,
684 then add it to the list. */
685 for (name = line; IS_WHITESPACE (* name); name ++)
686 ;
687 for (name_end = name;
688 (! IS_WHITESPACE (* name_end))
689 && (! IS_LINE_TERMINATOR (* name_end));
690 name_end ++)
691 ;
692
693 if (! IS_LINE_TERMINATOR (* name_end))
694 {
695 char * extra;
696
697 for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
698 ;
699
700 if (! IS_LINE_TERMINATOR (* extra))
701 non_fatal (_("Ignoring rubbish found on line %d of %s"),
702 line_count, filename);
703 }
704
705 * name_end = '\0';
706
707 if (name_end > name)
708 add_specific_symbol (name, list);
709
710 /* Advance line pointer to end of line. The 'eol ++' in the for
711 loop above will then advance us to the start of the next line. */
712 line = eol;
713 line_count ++;
714 }
715 }
716
717 /* See whether a symbol should be stripped or kept based on
718 strip_specific_list and keep_symbols. */
719
720 static bfd_boolean
721 is_specified_symbol (const char *name, struct symlist *list)
722 {
723 struct symlist *tmp_list;
724
725 if (wildcard)
726 {
727 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
728 if (*(tmp_list->name) != '!')
729 {
730 if (!fnmatch (tmp_list->name, name, 0))
731 return TRUE;
732 }
733 else
734 {
735 if (fnmatch (tmp_list->name + 1, name, 0))
736 return TRUE;
737 }
738 }
739 else
740 {
741 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
742 if (strcmp (name, tmp_list->name) == 0)
743 return TRUE;
744 }
745
746 return FALSE;
747 }
748
749 /* See if a section is being removed. */
750
751 static bfd_boolean
752 is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
753 {
754 if (sections_removed || sections_copied)
755 {
756 struct section_list *p;
757
758 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
759
760 if (sections_removed && p != NULL && p->remove)
761 return TRUE;
762 if (sections_copied && (p == NULL || ! p->copy))
763 return TRUE;
764 }
765
766 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
767 {
768 if (strip_symbols == STRIP_DEBUG
769 || strip_symbols == STRIP_UNNEEDED
770 || strip_symbols == STRIP_ALL
771 || discard_locals == LOCALS_ALL
772 || convert_debugging)
773 return TRUE;
774
775 if (strip_symbols == STRIP_NONDEBUG)
776 return FALSE;
777 }
778
779 return strip_symbols == STRIP_NONDEBUG ? TRUE : FALSE;
780 }
781
782 /* Choose which symbol entries to copy; put the result in OSYMS.
783 We don't copy in place, because that confuses the relocs.
784 Return the number of symbols to print. */
785
786 static unsigned int
787 filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
788 asymbol **isyms, long symcount)
789 {
790 asymbol **from = isyms, **to = osyms;
791 long src_count = 0, dst_count = 0;
792 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
793 == HAS_RELOC;
794
795 for (; src_count < symcount; src_count++)
796 {
797 asymbol *sym = from[src_count];
798 flagword flags = sym->flags;
799 char *name = (char *) bfd_asymbol_name (sym);
800 int keep;
801 bfd_boolean undefined;
802 bfd_boolean rem_leading_char;
803 bfd_boolean add_leading_char;
804
805 undefined = bfd_is_und_section (bfd_get_section (sym));
806
807 if (redefine_sym_list)
808 {
809 char *old_name, *new_name;
810
811 old_name = (char *) bfd_asymbol_name (sym);
812 new_name = (char *) lookup_sym_redefinition (old_name);
813 bfd_asymbol_name (sym) = new_name;
814 name = new_name;
815 }
816
817 /* Check if we will remove the current leading character. */
818 rem_leading_char =
819 (name[0] == bfd_get_symbol_leading_char (abfd))
820 && (change_leading_char
821 || (remove_leading_char
822 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
823 || undefined
824 || bfd_is_com_section (bfd_get_section (sym)))));
825
826 /* Check if we will add a new leading character. */
827 add_leading_char =
828 change_leading_char
829 && (bfd_get_symbol_leading_char (obfd) != '\0')
830 && (bfd_get_symbol_leading_char (abfd) == '\0'
831 || (name[0] == bfd_get_symbol_leading_char (abfd)));
832
833 /* Short circuit for change_leading_char if we can do it in-place. */
834 if (rem_leading_char && add_leading_char && !prefix_symbols_string)
835 {
836 name[0] = bfd_get_symbol_leading_char (obfd);
837 bfd_asymbol_name (sym) = name;
838 rem_leading_char = FALSE;
839 add_leading_char = FALSE;
840 }
841
842 /* Remove leading char. */
843 if (rem_leading_char)
844 bfd_asymbol_name (sym) = ++name;
845
846 /* Add new leading char and/or prefix. */
847 if (add_leading_char || prefix_symbols_string)
848 {
849 char *n, *ptr;
850
851 ptr = n = xmalloc (1 + strlen (prefix_symbols_string)
852 + strlen (name) + 1);
853 if (add_leading_char)
854 *ptr++ = bfd_get_symbol_leading_char (obfd);
855
856 if (prefix_symbols_string)
857 {
858 strcpy (ptr, prefix_symbols_string);
859 ptr += strlen (prefix_symbols_string);
860 }
861
862 strcpy (ptr, name);
863 bfd_asymbol_name (sym) = n;
864 name = n;
865 }
866
867 if (strip_symbols == STRIP_ALL)
868 keep = 0;
869 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
870 || ((flags & BSF_SECTION_SYM) != 0
871 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
872 & BSF_KEEP) != 0))
873 keep = 1;
874 else if (relocatable /* Relocatable file. */
875 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
876 keep = 1;
877 else if (bfd_decode_symclass (sym) == 'I')
878 /* Global symbols in $idata sections need to be retained
879 even if relocatable is FALSE. External users of the
880 library containing the $idata section may reference these
881 symbols. */
882 keep = 1;
883 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
884 || (flags & BSF_WEAK) != 0
885 || undefined
886 || bfd_is_com_section (bfd_get_section (sym)))
887 keep = strip_symbols != STRIP_UNNEEDED;
888 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
889 keep = (strip_symbols != STRIP_DEBUG
890 && strip_symbols != STRIP_UNNEEDED
891 && ! convert_debugging);
892 else if (bfd_get_section (sym)->comdat)
893 /* COMDAT sections store special information in local
894 symbols, so we cannot risk stripping any of them. */
895 keep = 1;
896 else /* Local symbol. */
897 keep = (strip_symbols != STRIP_UNNEEDED
898 && (discard_locals != LOCALS_ALL
899 && (discard_locals != LOCALS_START_L
900 || ! bfd_is_local_label (abfd, sym))));
901
902 if (keep && is_specified_symbol (name, strip_specific_list))
903 keep = 0;
904 if (!keep && is_specified_symbol (name, keep_specific_list))
905 keep = 1;
906 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
907 keep = 0;
908
909 if (keep && (flags & BSF_GLOBAL) != 0
910 && (weaken || is_specified_symbol (name, weaken_specific_list)))
911 {
912 sym->flags &=~ BSF_GLOBAL;
913 sym->flags |= BSF_WEAK;
914 }
915 if (keep && !undefined && (flags & (BSF_GLOBAL | BSF_WEAK))
916 && (is_specified_symbol (name, localize_specific_list)
917 || (keepglobal_specific_list != NULL
918 && ! is_specified_symbol (name, keepglobal_specific_list))))
919 {
920 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
921 sym->flags |= BSF_LOCAL;
922 }
923
924 if (keep)
925 to[dst_count++] = sym;
926 }
927
928 to[dst_count] = NULL;
929
930 return dst_count;
931 }
932
933 /* Find the redefined name of symbol SOURCE. */
934
935 static const char *
936 lookup_sym_redefinition (const char *source)
937 {
938 struct redefine_node *list;
939
940 for (list = redefine_sym_list; list != NULL; list = list->next)
941 if (strcmp (source, list->source) == 0)
942 return list->target;
943
944 return source;
945 }
946
947 /* Add a node to a symbol redefine list. */
948
949 static void
950 redefine_list_append (const char *cause, const char *source, const char *target)
951 {
952 struct redefine_node **p;
953 struct redefine_node *list;
954 struct redefine_node *new_node;
955
956 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
957 {
958 if (strcmp (source, list->source) == 0)
959 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
960 cause, source);
961
962 if (strcmp (target, list->target) == 0)
963 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
964 cause, target);
965 }
966
967 new_node = xmalloc (sizeof (struct redefine_node));
968
969 new_node->source = strdup (source);
970 new_node->target = strdup (target);
971 new_node->next = NULL;
972
973 *p = new_node;
974 }
975
976 /* Handle the --redefine-syms option. Read lines containing "old new"
977 from the file, and add them to the symbol redefine list. */
978
979 static void
980 add_redefine_syms_file (const char *filename)
981 {
982 FILE *file;
983 char *buf;
984 size_t bufsize;
985 size_t len;
986 size_t outsym_off;
987 int c, lineno;
988
989 file = fopen (filename, "r");
990 if (file == NULL)
991 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
992 filename, strerror (errno));
993
994 bufsize = 100;
995 buf = xmalloc (bufsize);
996
997 lineno = 1;
998 c = getc (file);
999 len = 0;
1000 outsym_off = 0;
1001 while (c != EOF)
1002 {
1003 /* Collect the input symbol name. */
1004 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1005 {
1006 if (c == '#')
1007 goto comment;
1008 buf[len++] = c;
1009 if (len >= bufsize)
1010 {
1011 bufsize *= 2;
1012 buf = xrealloc (buf, bufsize);
1013 }
1014 c = getc (file);
1015 }
1016 buf[len++] = '\0';
1017 if (c == EOF)
1018 break;
1019
1020 /* Eat white space between the symbol names. */
1021 while (IS_WHITESPACE (c))
1022 c = getc (file);
1023 if (c == '#' || IS_LINE_TERMINATOR (c))
1024 goto comment;
1025 if (c == EOF)
1026 break;
1027
1028 /* Collect the output symbol name. */
1029 outsym_off = len;
1030 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1031 {
1032 if (c == '#')
1033 goto comment;
1034 buf[len++] = c;
1035 if (len >= bufsize)
1036 {
1037 bufsize *= 2;
1038 buf = xrealloc (buf, bufsize);
1039 }
1040 c = getc (file);
1041 }
1042 buf[len++] = '\0';
1043 if (c == EOF)
1044 break;
1045
1046 /* Eat white space at end of line. */
1047 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1048 c = getc (file);
1049 if (c == '#')
1050 goto comment;
1051 /* Handle \r\n. */
1052 if ((c == '\r' && (c = getc (file)) == '\n')
1053 || c == '\n' || c == EOF)
1054 {
1055 end_of_line:
1056 /* Append the redefinition to the list. */
1057 if (buf[0] != '\0')
1058 redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1059
1060 lineno++;
1061 len = 0;
1062 outsym_off = 0;
1063 if (c == EOF)
1064 break;
1065 c = getc (file);
1066 continue;
1067 }
1068 else
1069 fatal (_("%s: garbage at end of line %d"), filename, lineno);
1070 comment:
1071 if (len != 0 && (outsym_off == 0 || outsym_off == len))
1072 fatal (_("%s: missing new symbol name at line %d"), filename, lineno);
1073 buf[len++] = '\0';
1074
1075 /* Eat the rest of the line and finish it. */
1076 while (c != '\n' && c != EOF)
1077 c = getc (file);
1078 goto end_of_line;
1079 }
1080
1081 if (len != 0)
1082 fatal (_("%s: premature end of file at line %d"), filename, lineno);
1083
1084 free (buf);
1085 }
1086
1087 /* Copy object file IBFD onto OBFD.
1088 Returns TRUE upon success, FALSE otherwise. */
1089
1090 static bfd_boolean
1091 copy_object (bfd *ibfd, bfd *obfd)
1092 {
1093 bfd_vma start;
1094 long symcount;
1095 asection **osections = NULL;
1096 asection *gnu_debuglink_section = NULL;
1097 bfd_size_type *gaps = NULL;
1098 bfd_size_type max_gap = 0;
1099 long symsize;
1100 void *dhandle;
1101 enum bfd_architecture iarch;
1102 unsigned int imach;
1103
1104 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1105 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1106 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1107 fatal (_("Unable to change endianness of input file(s)"));
1108
1109 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1110 {
1111 bfd_nonfatal (bfd_get_filename (obfd));
1112 return FALSE;
1113 }
1114
1115 if (verbose)
1116 printf (_("copy from %s(%s) to %s(%s)\n"),
1117 bfd_get_filename (ibfd), bfd_get_target (ibfd),
1118 bfd_get_filename (obfd), bfd_get_target (obfd));
1119
1120 if (set_start_set)
1121 start = set_start;
1122 else
1123 start = bfd_get_start_address (ibfd);
1124 start += change_start;
1125
1126 /* Neither the start address nor the flags
1127 need to be set for a core file. */
1128 if (bfd_get_format (obfd) != bfd_core)
1129 {
1130 flagword flags;
1131
1132 flags = bfd_get_file_flags (ibfd);
1133 flags |= bfd_flags_to_set;
1134 flags &= ~bfd_flags_to_clear;
1135 flags &= bfd_applicable_file_flags (obfd);
1136
1137 if (!bfd_set_start_address (obfd, start)
1138 || !bfd_set_file_flags (obfd, flags))
1139 {
1140 bfd_nonfatal (bfd_get_filename (ibfd));
1141 return FALSE;
1142 }
1143 }
1144
1145 /* Copy architecture of input file to output file. */
1146 iarch = bfd_get_arch (ibfd);
1147 imach = bfd_get_mach (ibfd);
1148 if (!bfd_set_arch_mach (obfd, iarch, imach)
1149 && (ibfd->target_defaulted
1150 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1151 {
1152 if (bfd_get_arch (ibfd) == bfd_arch_unknown)
1153 fatal (_("Unable to recognise the format of the input file %s"),
1154 bfd_get_filename (ibfd));
1155 else
1156 {
1157 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1158 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1159 bfd_get_mach (ibfd)));
1160 return FALSE;
1161 }
1162 }
1163
1164 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1165 {
1166 bfd_nonfatal (bfd_get_filename (ibfd));
1167 return FALSE;
1168 }
1169
1170 if (isympp)
1171 free (isympp);
1172
1173 if (osympp != isympp)
1174 free (osympp);
1175
1176 /* BFD mandates that all output sections be created and sizes set before
1177 any output is done. Thus, we traverse all sections multiple times. */
1178 bfd_map_over_sections (ibfd, setup_section, obfd);
1179
1180 if (add_sections != NULL)
1181 {
1182 struct section_add *padd;
1183 struct section_list *pset;
1184
1185 for (padd = add_sections; padd != NULL; padd = padd->next)
1186 {
1187 flagword flags;
1188
1189 padd->section = bfd_make_section (obfd, padd->name);
1190 if (padd->section == NULL)
1191 {
1192 non_fatal (_("can't create section `%s': %s"),
1193 padd->name, bfd_errmsg (bfd_get_error ()));
1194 return FALSE;
1195 }
1196
1197 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1198 {
1199 bfd_nonfatal (bfd_get_filename (obfd));
1200 return FALSE;
1201 }
1202
1203 pset = find_section_list (padd->name, FALSE);
1204 if (pset != NULL)
1205 pset->used = TRUE;
1206
1207 if (pset != NULL && pset->set_flags)
1208 flags = pset->flags | SEC_HAS_CONTENTS;
1209 else
1210 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1211
1212 if (! bfd_set_section_flags (obfd, padd->section, flags))
1213 {
1214 bfd_nonfatal (bfd_get_filename (obfd));
1215 return FALSE;
1216 }
1217
1218 if (pset != NULL)
1219 {
1220 if (pset->change_vma != CHANGE_IGNORE)
1221 if (! bfd_set_section_vma (obfd, padd->section,
1222 pset->vma_val))
1223 {
1224 bfd_nonfatal (bfd_get_filename (obfd));
1225 return FALSE;
1226 }
1227
1228 if (pset->change_lma != CHANGE_IGNORE)
1229 {
1230 padd->section->lma = pset->lma_val;
1231
1232 if (! bfd_set_section_alignment
1233 (obfd, padd->section,
1234 bfd_section_alignment (obfd, padd->section)))
1235 {
1236 bfd_nonfatal (bfd_get_filename (obfd));
1237 return FALSE;
1238 }
1239 }
1240 }
1241 }
1242 }
1243
1244 if (gnu_debuglink_filename != NULL)
1245 {
1246 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1247 (obfd, gnu_debuglink_filename);
1248
1249 if (gnu_debuglink_section == NULL)
1250 {
1251 bfd_nonfatal (gnu_debuglink_filename);
1252 return FALSE;
1253 }
1254 }
1255
1256 if (bfd_count_sections (obfd) == 0)
1257 {
1258 non_fatal (_("there are no sections to be copied!"));
1259 return FALSE;
1260 }
1261
1262 if (gap_fill_set || pad_to_set)
1263 {
1264 asection **set;
1265 unsigned int c, i;
1266
1267 /* We must fill in gaps between the sections and/or we must pad
1268 the last section to a specified address. We do this by
1269 grabbing a list of the sections, sorting them by VMA, and
1270 increasing the section sizes as required to fill the gaps.
1271 We write out the gap contents below. */
1272
1273 c = bfd_count_sections (obfd);
1274 osections = xmalloc (c * sizeof (asection *));
1275 set = osections;
1276 bfd_map_over_sections (obfd, get_sections, &set);
1277
1278 qsort (osections, c, sizeof (asection *), compare_section_lma);
1279
1280 gaps = xmalloc (c * sizeof (bfd_size_type));
1281 memset (gaps, 0, c * sizeof (bfd_size_type));
1282
1283 if (gap_fill_set)
1284 {
1285 for (i = 0; i < c - 1; i++)
1286 {
1287 flagword flags;
1288 bfd_size_type size;
1289 bfd_vma gap_start, gap_stop;
1290
1291 flags = bfd_get_section_flags (obfd, osections[i]);
1292 if ((flags & SEC_HAS_CONTENTS) == 0
1293 || (flags & SEC_LOAD) == 0)
1294 continue;
1295
1296 size = bfd_section_size (obfd, osections[i]);
1297 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1298 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1299 if (gap_start < gap_stop)
1300 {
1301 if (! bfd_set_section_size (obfd, osections[i],
1302 size + (gap_stop - gap_start)))
1303 {
1304 non_fatal (_("Can't fill gap after %s: %s"),
1305 bfd_get_section_name (obfd, osections[i]),
1306 bfd_errmsg (bfd_get_error ()));
1307 status = 1;
1308 break;
1309 }
1310 gaps[i] = gap_stop - gap_start;
1311 if (max_gap < gap_stop - gap_start)
1312 max_gap = gap_stop - gap_start;
1313 }
1314 }
1315 }
1316
1317 if (pad_to_set)
1318 {
1319 bfd_vma lma;
1320 bfd_size_type size;
1321
1322 lma = bfd_section_lma (obfd, osections[c - 1]);
1323 size = bfd_section_size (obfd, osections[c - 1]);
1324 if (lma + size < pad_to)
1325 {
1326 if (! bfd_set_section_size (obfd, osections[c - 1],
1327 pad_to - lma))
1328 {
1329 non_fatal (_("Can't add padding to %s: %s"),
1330 bfd_get_section_name (obfd, osections[c - 1]),
1331 bfd_errmsg (bfd_get_error ()));
1332 status = 1;
1333 }
1334 else
1335 {
1336 gaps[c - 1] = pad_to - (lma + size);
1337 if (max_gap < pad_to - (lma + size))
1338 max_gap = pad_to - (lma + size);
1339 }
1340 }
1341 }
1342 }
1343
1344 /* Symbol filtering must happen after the output sections
1345 have been created, but before their contents are set. */
1346 dhandle = NULL;
1347 symsize = bfd_get_symtab_upper_bound (ibfd);
1348 if (symsize < 0)
1349 {
1350 bfd_nonfatal (bfd_get_filename (ibfd));
1351 return FALSE;
1352 }
1353
1354 osympp = isympp = xmalloc (symsize);
1355 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1356 if (symcount < 0)
1357 {
1358 bfd_nonfatal (bfd_get_filename (ibfd));
1359 return FALSE;
1360 }
1361
1362 if (convert_debugging)
1363 dhandle = read_debugging_info (ibfd, isympp, symcount);
1364
1365 if (strip_symbols == STRIP_DEBUG
1366 || strip_symbols == STRIP_ALL
1367 || strip_symbols == STRIP_UNNEEDED
1368 || strip_symbols == STRIP_NONDEBUG
1369 || discard_locals != LOCALS_UNDEF
1370 || strip_specific_list != NULL
1371 || keep_specific_list != NULL
1372 || localize_specific_list != NULL
1373 || keepglobal_specific_list != NULL
1374 || weaken_specific_list != NULL
1375 || prefix_symbols_string
1376 || sections_removed
1377 || sections_copied
1378 || convert_debugging
1379 || change_leading_char
1380 || remove_leading_char
1381 || redefine_sym_list
1382 || weaken)
1383 {
1384 /* Mark symbols used in output relocations so that they
1385 are kept, even if they are local labels or static symbols.
1386
1387 Note we iterate over the input sections examining their
1388 relocations since the relocations for the output sections
1389 haven't been set yet. mark_symbols_used_in_relocations will
1390 ignore input sections which have no corresponding output
1391 section. */
1392 if (strip_symbols != STRIP_ALL)
1393 bfd_map_over_sections (ibfd,
1394 mark_symbols_used_in_relocations,
1395 isympp);
1396 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1397 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1398 }
1399
1400 if (convert_debugging && dhandle != NULL)
1401 {
1402 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1403 {
1404 status = 1;
1405 return FALSE;
1406 }
1407 }
1408
1409 bfd_set_symtab (obfd, osympp, symcount);
1410
1411 /* This has to happen after the symbol table has been set. */
1412 bfd_map_over_sections (ibfd, copy_section, obfd);
1413
1414 if (add_sections != NULL)
1415 {
1416 struct section_add *padd;
1417
1418 for (padd = add_sections; padd != NULL; padd = padd->next)
1419 {
1420 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1421 0, padd->size))
1422 {
1423 bfd_nonfatal (bfd_get_filename (obfd));
1424 return FALSE;
1425 }
1426 }
1427 }
1428
1429 if (gnu_debuglink_filename != NULL)
1430 {
1431 if (! bfd_fill_in_gnu_debuglink_section
1432 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1433 {
1434 bfd_nonfatal (gnu_debuglink_filename);
1435 return FALSE;
1436 }
1437 }
1438
1439 if (gap_fill_set || pad_to_set)
1440 {
1441 bfd_byte *buf;
1442 int c, i;
1443
1444 /* Fill in the gaps. */
1445 if (max_gap > 8192)
1446 max_gap = 8192;
1447 buf = xmalloc (max_gap);
1448 memset (buf, gap_fill, max_gap);
1449
1450 c = bfd_count_sections (obfd);
1451 for (i = 0; i < c; i++)
1452 {
1453 if (gaps[i] != 0)
1454 {
1455 bfd_size_type left;
1456 file_ptr off;
1457
1458 left = gaps[i];
1459 off = bfd_section_size (obfd, osections[i]) - left;
1460
1461 while (left > 0)
1462 {
1463 bfd_size_type now;
1464
1465 if (left > 8192)
1466 now = 8192;
1467 else
1468 now = left;
1469
1470 if (! bfd_set_section_contents (obfd, osections[i], buf,
1471 off, now))
1472 {
1473 bfd_nonfatal (bfd_get_filename (obfd));
1474 return FALSE;
1475 }
1476
1477 left -= now;
1478 off += now;
1479 }
1480 }
1481 }
1482 }
1483
1484 /* Allow the BFD backend to copy any private data it understands
1485 from the input BFD to the output BFD. This is done last to
1486 permit the routine to look at the filtered symbol table, which is
1487 important for the ECOFF code at least. */
1488 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1489 && strip_symbols == STRIP_NONDEBUG)
1490 /* Do not copy the private data when creating an ELF format
1491 debug info file. We do not want the program headers. */
1492 ;
1493 else if (! bfd_copy_private_bfd_data (ibfd, obfd))
1494 {
1495 non_fatal (_("%s: error copying private BFD data: %s"),
1496 bfd_get_filename (obfd),
1497 bfd_errmsg (bfd_get_error ()));
1498 return FALSE;
1499 }
1500
1501 /* Switch to the alternate machine code. We have to do this at the
1502 very end, because we only initialize the header when we create
1503 the first section. */
1504 if (use_alt_mach_code != 0
1505 && ! bfd_alt_mach_code (obfd, use_alt_mach_code))
1506 non_fatal (_("unknown alternate machine code, ignored"));
1507
1508 return TRUE;
1509 }
1510
1511 #undef MKDIR
1512 #if defined (_WIN32) && !defined (__CYGWIN32__)
1513 #define MKDIR(DIR, MODE) mkdir (DIR)
1514 #else
1515 #define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1516 #endif
1517
1518 /* Read each archive element in turn from IBFD, copy the
1519 contents to temp file, and keep the temp file handle. */
1520
1521 static void
1522 copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
1523 {
1524 struct name_list
1525 {
1526 struct name_list *next;
1527 const char *name;
1528 bfd *obfd;
1529 } *list, *l;
1530 bfd **ptr = &obfd->archive_head;
1531 bfd *this_element;
1532 char *dir = make_tempname (bfd_get_filename (obfd));
1533
1534 /* Make a temp directory to hold the contents. */
1535 if (MKDIR (dir, 0700) != 0)
1536 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1537 dir, strerror (errno));
1538
1539 obfd->has_armap = ibfd->has_armap;
1540
1541 list = NULL;
1542
1543 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1544
1545 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1546 RETURN_NONFATAL (bfd_get_filename (obfd));
1547
1548 while (!status && this_element != NULL)
1549 {
1550 char *output_name;
1551 bfd *output_bfd;
1552 bfd *last_element;
1553 struct stat buf;
1554 int stat_status = 0;
1555 bfd_boolean delete = TRUE;
1556
1557 /* Create an output file for this member. */
1558 output_name = concat (dir, "/",
1559 bfd_get_filename (this_element), (char *) 0);
1560
1561 /* If the file already exists, make another temp dir. */
1562 if (stat (output_name, &buf) >= 0)
1563 {
1564 output_name = make_tempname (output_name);
1565 if (MKDIR (output_name, 0700) != 0)
1566 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1567 output_name, strerror (errno));
1568
1569 l = xmalloc (sizeof (struct name_list));
1570 l->name = output_name;
1571 l->next = list;
1572 l->obfd = NULL;
1573 list = l;
1574 output_name = concat (output_name, "/",
1575 bfd_get_filename (this_element), (char *) 0);
1576 }
1577
1578 output_bfd = bfd_openw (output_name, output_target);
1579 if (preserve_dates)
1580 {
1581 stat_status = bfd_stat_arch_elt (this_element, &buf);
1582
1583 if (stat_status != 0)
1584 non_fatal (_("internal stat error on %s"),
1585 bfd_get_filename (this_element));
1586 }
1587
1588 l = xmalloc (sizeof (struct name_list));
1589 l->name = output_name;
1590 l->next = list;
1591 list = l;
1592
1593 if (output_bfd == NULL)
1594 RETURN_NONFATAL (output_name);
1595
1596 if (bfd_check_format (this_element, bfd_object))
1597 delete = ! copy_object (this_element, output_bfd);
1598
1599 if (!bfd_close (output_bfd))
1600 {
1601 bfd_nonfatal (bfd_get_filename (output_bfd));
1602 /* Error in new object file. Don't change archive. */
1603 status = 1;
1604 }
1605
1606 if (delete)
1607 {
1608 unlink (output_name);
1609 status = 1;
1610 }
1611 else
1612 {
1613 if (preserve_dates && stat_status == 0)
1614 set_times (output_name, &buf);
1615
1616 /* Open the newly output file and attach to our list. */
1617 output_bfd = bfd_openr (output_name, output_target);
1618
1619 l->obfd = output_bfd;
1620
1621 *ptr = output_bfd;
1622 ptr = &output_bfd->next;
1623
1624 last_element = this_element;
1625
1626 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1627
1628 bfd_close (last_element);
1629 }
1630 }
1631 *ptr = NULL;
1632
1633 if (!bfd_close (obfd))
1634 RETURN_NONFATAL (bfd_get_filename (obfd));
1635
1636 if (!bfd_close (ibfd))
1637 RETURN_NONFATAL (bfd_get_filename (ibfd));
1638
1639 /* Delete all the files that we opened. */
1640 for (l = list; l != NULL; l = l->next)
1641 {
1642 if (l->obfd == NULL)
1643 rmdir (l->name);
1644 else
1645 {
1646 bfd_close (l->obfd);
1647 unlink (l->name);
1648 }
1649 }
1650 rmdir (dir);
1651 }
1652
1653 /* The top-level control. */
1654
1655 static void
1656 copy_file (const char *input_filename, const char *output_filename,
1657 const char *input_target, const char *output_target)
1658 {
1659 bfd *ibfd;
1660 char **obj_matching;
1661 char **core_matching;
1662
1663 if (get_file_size (input_filename) < 1)
1664 {
1665 status = 1;
1666 return;
1667 }
1668
1669 /* To allow us to do "strip *" without dying on the first
1670 non-object file, failures are nonfatal. */
1671 ibfd = bfd_openr (input_filename, input_target);
1672 if (ibfd == NULL)
1673 RETURN_NONFATAL (input_filename);
1674
1675 if (bfd_check_format (ibfd, bfd_archive))
1676 {
1677 bfd *obfd;
1678
1679 /* bfd_get_target does not return the correct value until
1680 bfd_check_format succeeds. */
1681 if (output_target == NULL)
1682 output_target = bfd_get_target (ibfd);
1683
1684 obfd = bfd_openw (output_filename, output_target);
1685 if (obfd == NULL)
1686 RETURN_NONFATAL (output_filename);
1687
1688 copy_archive (ibfd, obfd, output_target);
1689 }
1690 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
1691 {
1692 bfd *obfd;
1693 bfd_boolean delete;
1694 do_copy:
1695
1696 /* bfd_get_target does not return the correct value until
1697 bfd_check_format succeeds. */
1698 if (output_target == NULL)
1699 output_target = bfd_get_target (ibfd);
1700
1701 obfd = bfd_openw (output_filename, output_target);
1702 if (obfd == NULL)
1703 RETURN_NONFATAL (output_filename);
1704
1705 delete = ! copy_object (ibfd, obfd);
1706
1707 if (!bfd_close (obfd))
1708 RETURN_NONFATAL (output_filename);
1709
1710 if (!bfd_close (ibfd))
1711 RETURN_NONFATAL (input_filename);
1712
1713 if (delete)
1714 {
1715 unlink (output_filename);
1716 status = 1;
1717 }
1718 }
1719 else
1720 {
1721 bfd_error_type obj_error = bfd_get_error ();
1722 bfd_error_type core_error;
1723
1724 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
1725 {
1726 /* This probably can't happen.. */
1727 if (obj_error == bfd_error_file_ambiguously_recognized)
1728 free (obj_matching);
1729 goto do_copy;
1730 }
1731
1732 core_error = bfd_get_error ();
1733 /* Report the object error in preference to the core error. */
1734 if (obj_error != core_error)
1735 bfd_set_error (obj_error);
1736
1737 bfd_nonfatal (input_filename);
1738
1739 if (obj_error == bfd_error_file_ambiguously_recognized)
1740 {
1741 list_matching_formats (obj_matching);
1742 free (obj_matching);
1743 }
1744 if (core_error == bfd_error_file_ambiguously_recognized)
1745 {
1746 list_matching_formats (core_matching);
1747 free (core_matching);
1748 }
1749
1750 status = 1;
1751 }
1752 }
1753
1754 /* Add a name to the section renaming list. */
1755
1756 static void
1757 add_section_rename (const char * old_name, const char * new_name,
1758 flagword flags)
1759 {
1760 section_rename * rename;
1761
1762 /* Check for conflicts first. */
1763 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1764 if (strcmp (rename->old_name, old_name) == 0)
1765 {
1766 /* Silently ignore duplicate definitions. */
1767 if (strcmp (rename->new_name, new_name) == 0
1768 && rename->flags == flags)
1769 return;
1770
1771 fatal (_("Multiple renames of section %s"), old_name);
1772 }
1773
1774 rename = xmalloc (sizeof (* rename));
1775
1776 rename->old_name = old_name;
1777 rename->new_name = new_name;
1778 rename->flags = flags;
1779 rename->next = section_rename_list;
1780
1781 section_rename_list = rename;
1782 }
1783
1784 /* Check the section rename list for a new name of the input section
1785 ISECTION. Return the new name if one is found.
1786 Also set RETURNED_FLAGS to the flags to be used for this section. */
1787
1788 static const char *
1789 find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
1790 flagword * returned_flags)
1791 {
1792 const char * old_name = bfd_section_name (ibfd, isection);
1793 section_rename * rename;
1794
1795 /* Default to using the flags of the input section. */
1796 * returned_flags = bfd_get_section_flags (ibfd, isection);
1797
1798 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1799 if (strcmp (rename->old_name, old_name) == 0)
1800 {
1801 if (rename->flags != (flagword) -1)
1802 * returned_flags = rename->flags;
1803
1804 return rename->new_name;
1805 }
1806
1807 return old_name;
1808 }
1809
1810 /* Create a section in OBFD with the same
1811 name and attributes as ISECTION in IBFD. */
1812
1813 static void
1814 setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1815 {
1816 bfd *obfd = obfdarg;
1817 struct section_list *p;
1818 sec_ptr osection;
1819 bfd_size_type size;
1820 bfd_vma vma;
1821 bfd_vma lma;
1822 flagword flags;
1823 const char *err;
1824 const char * name;
1825 char *prefix = NULL;
1826
1827 if (is_strip_section (ibfd, isection))
1828 return;
1829
1830 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
1831 if (p != NULL)
1832 p->used = TRUE;
1833
1834 /* Get the, possibly new, name of the output section. */
1835 name = find_section_rename (ibfd, isection, & flags);
1836
1837 /* Prefix sections. */
1838 if ((prefix_alloc_sections_string)
1839 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
1840 prefix = prefix_alloc_sections_string;
1841 else if (prefix_sections_string)
1842 prefix = prefix_sections_string;
1843
1844 if (prefix)
1845 {
1846 char *n;
1847
1848 n = xmalloc (strlen (prefix) + strlen (name) + 1);
1849 strcpy (n, prefix);
1850 strcat (n, name);
1851 name = n;
1852 }
1853
1854 osection = bfd_make_section_anyway (obfd, name);
1855
1856 if (osection == NULL)
1857 {
1858 err = _("making");
1859 goto loser;
1860 }
1861
1862 size = bfd_section_size (ibfd, isection);
1863 if (copy_byte >= 0)
1864 size = (size + interleave - 1) / interleave;
1865 if (! bfd_set_section_size (obfd, osection, size))
1866 {
1867 err = _("size");
1868 goto loser;
1869 }
1870
1871 vma = bfd_section_vma (ibfd, isection);
1872 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1873 vma += p->vma_val;
1874 else if (p != NULL && p->change_vma == CHANGE_SET)
1875 vma = p->vma_val;
1876 else
1877 vma += change_section_address;
1878
1879 if (! bfd_set_section_vma (obfd, osection, vma))
1880 {
1881 err = _("vma");
1882 goto loser;
1883 }
1884
1885 lma = isection->lma;
1886 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1887 {
1888 if (p->change_lma == CHANGE_MODIFY)
1889 lma += p->lma_val;
1890 else if (p->change_lma == CHANGE_SET)
1891 lma = p->lma_val;
1892 else
1893 abort ();
1894 }
1895 else
1896 lma += change_section_address;
1897
1898 osection->lma = lma;
1899
1900 /* FIXME: This is probably not enough. If we change the LMA we
1901 may have to recompute the header for the file as well. */
1902 if (!bfd_set_section_alignment (obfd,
1903 osection,
1904 bfd_section_alignment (ibfd, isection)))
1905 {
1906 err = _("alignment");
1907 goto loser;
1908 }
1909
1910 if (p != NULL && p->set_flags)
1911 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
1912 if (!bfd_set_section_flags (obfd, osection, flags))
1913 {
1914 err = _("flags");
1915 goto loser;
1916 }
1917
1918 /* Copy merge entity size. */
1919 osection->entsize = isection->entsize;
1920
1921 /* This used to be mangle_section; we do here to avoid using
1922 bfd_get_section_by_name since some formats allow multiple
1923 sections with the same name. */
1924 isection->output_section = osection;
1925 isection->output_offset = 0;
1926
1927 /* Allow the BFD backend to copy any private data it understands
1928 from the input section to the output section. */
1929 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1930 && strip_symbols == STRIP_NONDEBUG)
1931 /* Do not copy the private data when creating an ELF format
1932 debug info file. We do not want the program headers. */
1933 ;
1934 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1935 {
1936 err = _("private data");
1937 goto loser;
1938 }
1939
1940 /* All went well. */
1941 return;
1942
1943 loser:
1944 non_fatal (_("%s: section `%s': error in %s: %s"),
1945 bfd_get_filename (ibfd),
1946 bfd_section_name (ibfd, isection),
1947 err, bfd_errmsg (bfd_get_error ()));
1948 status = 1;
1949 }
1950
1951 /* Copy the data of input section ISECTION of IBFD
1952 to an output section with the same name in OBFD.
1953 If stripping then don't copy any relocation info. */
1954
1955 static void
1956 copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1957 {
1958 bfd *obfd = obfdarg;
1959 struct section_list *p;
1960 arelent **relpp;
1961 long relcount;
1962 sec_ptr osection;
1963 bfd_size_type size;
1964 long relsize;
1965 flagword flags;
1966
1967 /* If we have already failed earlier on,
1968 do not keep on generating complaints now. */
1969 if (status != 0)
1970 return;
1971
1972 if (is_strip_section (ibfd, isection))
1973 return;
1974
1975 flags = bfd_get_section_flags (ibfd, isection);
1976 if ((flags & SEC_GROUP) != 0)
1977 return;
1978
1979 osection = isection->output_section;
1980 size = bfd_get_section_size_before_reloc (isection);
1981
1982 if (size == 0 || osection == 0)
1983 return;
1984
1985 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
1986
1987 /* Core files do not need to be relocated. */
1988 if (bfd_get_format (obfd) == bfd_core)
1989 relsize = 0;
1990 else
1991 {
1992 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1993
1994 if (relsize < 0)
1995 {
1996 /* Do not complain if the target does not support relocations. */
1997 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
1998 relsize = 0;
1999 else
2000 RETURN_NONFATAL (bfd_get_filename (ibfd));
2001 }
2002 }
2003
2004 if (relsize == 0)
2005 bfd_set_reloc (obfd, osection, NULL, 0);
2006 else
2007 {
2008 relpp = xmalloc (relsize);
2009 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2010 if (relcount < 0)
2011 RETURN_NONFATAL (bfd_get_filename (ibfd));
2012
2013 if (strip_symbols == STRIP_ALL)
2014 {
2015 /* Remove relocations which are not in
2016 keep_strip_specific_list. */
2017 arelent **temp_relpp;
2018 long temp_relcount = 0;
2019 long i;
2020
2021 temp_relpp = xmalloc (relsize);
2022 for (i = 0; i < relcount; i++)
2023 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
2024 keep_specific_list))
2025 temp_relpp [temp_relcount++] = relpp [i];
2026 relcount = temp_relcount;
2027 free (relpp);
2028 relpp = temp_relpp;
2029 }
2030
2031 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
2032 }
2033
2034 isection->_cooked_size = isection->_raw_size;
2035 isection->reloc_done = TRUE;
2036
2037 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
2038 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
2039 {
2040 void *memhunk = xmalloc (size);
2041
2042 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2043 RETURN_NONFATAL (bfd_get_filename (ibfd));
2044
2045 if (copy_byte >= 0)
2046 {
2047 /* Keep only every `copy_byte'th byte in MEMHUNK. */
2048 char *from = memhunk + copy_byte;
2049 char *to = memhunk;
2050 char *end = memhunk + size;
2051
2052 for (; from < end; from += interleave)
2053 *to++ = *from;
2054
2055 size = (size + interleave - 1 - copy_byte) / interleave;
2056 osection->lma /= interleave;
2057 }
2058
2059 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2060 RETURN_NONFATAL (bfd_get_filename (obfd));
2061
2062 free (memhunk);
2063 }
2064 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2065 {
2066 void *memhunk = xmalloc (size);
2067
2068 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2069 flag--they can just remove the section entirely and add it
2070 back again. However, we do permit them to turn on the
2071 SEC_HAS_CONTENTS flag, and take it to mean that the section
2072 contents should be zeroed out. */
2073
2074 memset (memhunk, 0, size);
2075 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2076 RETURN_NONFATAL (bfd_get_filename (obfd));
2077 free (memhunk);
2078 }
2079 }
2080
2081 /* Get all the sections. This is used when --gap-fill or --pad-to is
2082 used. */
2083
2084 static void
2085 get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2086 {
2087 asection ***secppp = secppparg;
2088
2089 **secppp = osection;
2090 ++(*secppp);
2091 }
2092
2093 /* Sort sections by VMA. This is called via qsort, and is used when
2094 --gap-fill or --pad-to is used. We force non loadable or empty
2095 sections to the front, where they are easier to ignore. */
2096
2097 static int
2098 compare_section_lma (const void *arg1, const void *arg2)
2099 {
2100 const asection *const *sec1 = arg1;
2101 const asection *const *sec2 = arg2;
2102 flagword flags1, flags2;
2103
2104 /* Sort non loadable sections to the front. */
2105 flags1 = (*sec1)->flags;
2106 flags2 = (*sec2)->flags;
2107 if ((flags1 & SEC_HAS_CONTENTS) == 0
2108 || (flags1 & SEC_LOAD) == 0)
2109 {
2110 if ((flags2 & SEC_HAS_CONTENTS) != 0
2111 && (flags2 & SEC_LOAD) != 0)
2112 return -1;
2113 }
2114 else
2115 {
2116 if ((flags2 & SEC_HAS_CONTENTS) == 0
2117 || (flags2 & SEC_LOAD) == 0)
2118 return 1;
2119 }
2120
2121 /* Sort sections by LMA. */
2122 if ((*sec1)->lma > (*sec2)->lma)
2123 return 1;
2124 else if ((*sec1)->lma < (*sec2)->lma)
2125 return -1;
2126
2127 /* Sort sections with the same LMA by size. */
2128 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
2129 return 1;
2130 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
2131 return -1;
2132
2133 return 0;
2134 }
2135
2136 /* Mark all the symbols which will be used in output relocations with
2137 the BSF_KEEP flag so that those symbols will not be stripped.
2138
2139 Ignore relocations which will not appear in the output file. */
2140
2141 static void
2142 mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2143 {
2144 asymbol **symbols = symbolsarg;
2145 long relsize;
2146 arelent **relpp;
2147 long relcount, i;
2148
2149 /* Ignore an input section with no corresponding output section. */
2150 if (isection->output_section == NULL)
2151 return;
2152
2153 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2154 if (relsize < 0)
2155 {
2156 /* Do not complain if the target does not support relocations. */
2157 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2158 return;
2159 bfd_fatal (bfd_get_filename (ibfd));
2160 }
2161
2162 if (relsize == 0)
2163 return;
2164
2165 relpp = xmalloc (relsize);
2166 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2167 if (relcount < 0)
2168 bfd_fatal (bfd_get_filename (ibfd));
2169
2170 /* Examine each symbol used in a relocation. If it's not one of the
2171 special bfd section symbols, then mark it with BSF_KEEP. */
2172 for (i = 0; i < relcount; i++)
2173 {
2174 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2175 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2176 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2177 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2178 }
2179
2180 if (relpp != NULL)
2181 free (relpp);
2182 }
2183
2184 /* Write out debugging information. */
2185
2186 static bfd_boolean
2187 write_debugging_info (bfd *obfd, void *dhandle,
2188 long *symcountp ATTRIBUTE_UNUSED,
2189 asymbol ***symppp ATTRIBUTE_UNUSED)
2190 {
2191 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2192 return write_ieee_debugging_info (obfd, dhandle);
2193
2194 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2195 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2196 {
2197 bfd_byte *syms, *strings;
2198 bfd_size_type symsize, stringsize;
2199 asection *stabsec, *stabstrsec;
2200
2201 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2202 &symsize, &strings,
2203 &stringsize))
2204 return FALSE;
2205
2206 stabsec = bfd_make_section (obfd, ".stab");
2207 stabstrsec = bfd_make_section (obfd, ".stabstr");
2208 if (stabsec == NULL
2209 || stabstrsec == NULL
2210 || ! bfd_set_section_size (obfd, stabsec, symsize)
2211 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2212 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2213 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
2214 || ! bfd_set_section_flags (obfd, stabsec,
2215 (SEC_HAS_CONTENTS
2216 | SEC_READONLY
2217 | SEC_DEBUGGING))
2218 || ! bfd_set_section_flags (obfd, stabstrsec,
2219 (SEC_HAS_CONTENTS
2220 | SEC_READONLY
2221 | SEC_DEBUGGING)))
2222 {
2223 non_fatal (_("%s: can't create debugging section: %s"),
2224 bfd_get_filename (obfd),
2225 bfd_errmsg (bfd_get_error ()));
2226 return FALSE;
2227 }
2228
2229 /* We can get away with setting the section contents now because
2230 the next thing the caller is going to do is copy over the
2231 real sections. We may someday have to split the contents
2232 setting out of this function. */
2233 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2234 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2235 stringsize))
2236 {
2237 non_fatal (_("%s: can't set debugging section contents: %s"),
2238 bfd_get_filename (obfd),
2239 bfd_errmsg (bfd_get_error ()));
2240 return FALSE;
2241 }
2242
2243 return TRUE;
2244 }
2245
2246 non_fatal (_("%s: don't know how to write debugging information for %s"),
2247 bfd_get_filename (obfd), bfd_get_target (obfd));
2248 return FALSE;
2249 }
2250
2251 static int
2252 strip_main (int argc, char *argv[])
2253 {
2254 char *input_target = NULL;
2255 char *output_target = NULL;
2256 bfd_boolean show_version = FALSE;
2257 bfd_boolean formats_info = FALSE;
2258 int c;
2259 int i;
2260 struct section_list *p;
2261 char *output_file = NULL;
2262
2263 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2264 strip_options, (int *) 0)) != EOF)
2265 {
2266 switch (c)
2267 {
2268 case 'I':
2269 input_target = optarg;
2270 break;
2271 case 'O':
2272 output_target = optarg;
2273 break;
2274 case 'F':
2275 input_target = output_target = optarg;
2276 break;
2277 case 'R':
2278 p = find_section_list (optarg, TRUE);
2279 p->remove = TRUE;
2280 sections_removed = TRUE;
2281 break;
2282 case 's':
2283 strip_symbols = STRIP_ALL;
2284 break;
2285 case 'S':
2286 case 'g':
2287 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2288 strip_symbols = STRIP_DEBUG;
2289 break;
2290 case OPTION_STRIP_UNNEEDED:
2291 strip_symbols = STRIP_UNNEEDED;
2292 break;
2293 case 'K':
2294 add_specific_symbol (optarg, &keep_specific_list);
2295 break;
2296 case 'N':
2297 add_specific_symbol (optarg, &strip_specific_list);
2298 break;
2299 case 'o':
2300 output_file = optarg;
2301 break;
2302 case 'p':
2303 preserve_dates = TRUE;
2304 break;
2305 case 'x':
2306 discard_locals = LOCALS_ALL;
2307 break;
2308 case 'X':
2309 discard_locals = LOCALS_START_L;
2310 break;
2311 case 'v':
2312 verbose = TRUE;
2313 break;
2314 case 'V':
2315 show_version = TRUE;
2316 break;
2317 case OPTION_FORMATS_INFO:
2318 formats_info = TRUE;
2319 break;
2320 case OPTION_ONLY_KEEP_DEBUG:
2321 strip_symbols = STRIP_NONDEBUG;
2322 break;
2323 case 0:
2324 /* We've been given a long option. */
2325 break;
2326 case 'w':
2327 wildcard = TRUE;
2328 break;
2329 case 'H':
2330 case 'h':
2331 strip_usage (stdout, 0);
2332 default:
2333 strip_usage (stderr, 1);
2334 }
2335 }
2336
2337 if (formats_info)
2338 {
2339 display_info ();
2340 return 0;
2341 }
2342
2343 if (show_version)
2344 print_version ("strip");
2345
2346 /* Default is to strip all symbols. */
2347 if (strip_symbols == STRIP_UNDEF
2348 && discard_locals == LOCALS_UNDEF
2349 && strip_specific_list == NULL)
2350 strip_symbols = STRIP_ALL;
2351
2352 if (output_target == NULL)
2353 output_target = input_target;
2354
2355 i = optind;
2356 if (i == argc
2357 || (output_file != NULL && (i + 1) < argc))
2358 strip_usage (stderr, 1);
2359
2360 for (; i < argc; i++)
2361 {
2362 int hold_status = status;
2363 struct stat statbuf;
2364 char *tmpname;
2365
2366 if (get_file_size (argv[i]) < 1)
2367 continue;
2368
2369 if (preserve_dates)
2370 /* No need to check the return value of stat().
2371 It has already been checked in get_file_size(). */
2372 stat (argv[i], &statbuf);
2373
2374 if (output_file != NULL)
2375 tmpname = output_file;
2376 else
2377 tmpname = make_tempname (argv[i]);
2378 status = 0;
2379
2380 copy_file (argv[i], tmpname, input_target, output_target);
2381 if (status == 0)
2382 {
2383 if (preserve_dates)
2384 set_times (tmpname, &statbuf);
2385 if (output_file == NULL)
2386 smart_rename (tmpname, argv[i], preserve_dates);
2387 status = hold_status;
2388 }
2389 else
2390 unlink (tmpname);
2391 if (output_file == NULL)
2392 free (tmpname);
2393 }
2394
2395 return 0;
2396 }
2397
2398 static int
2399 copy_main (int argc, char *argv[])
2400 {
2401 char * binary_architecture = NULL;
2402 char *input_filename = NULL;
2403 char *output_filename = NULL;
2404 char *input_target = NULL;
2405 char *output_target = NULL;
2406 bfd_boolean show_version = FALSE;
2407 bfd_boolean change_warn = TRUE;
2408 bfd_boolean formats_info = FALSE;
2409 int c;
2410 struct section_list *p;
2411 struct stat statbuf;
2412
2413 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2414 copy_options, (int *) 0)) != EOF)
2415 {
2416 switch (c)
2417 {
2418 case 'b':
2419 copy_byte = atoi (optarg);
2420 if (copy_byte < 0)
2421 fatal (_("byte number must be non-negative"));
2422 break;
2423
2424 case 'B':
2425 binary_architecture = optarg;
2426 break;
2427
2428 case 'i':
2429 interleave = atoi (optarg);
2430 if (interleave < 1)
2431 fatal (_("interleave must be positive"));
2432 break;
2433
2434 case 'I':
2435 case 's': /* "source" - 'I' is preferred */
2436 input_target = optarg;
2437 break;
2438
2439 case 'O':
2440 case 'd': /* "destination" - 'O' is preferred */
2441 output_target = optarg;
2442 break;
2443
2444 case 'F':
2445 input_target = output_target = optarg;
2446 break;
2447
2448 case 'j':
2449 p = find_section_list (optarg, TRUE);
2450 if (p->remove)
2451 fatal (_("%s both copied and removed"), optarg);
2452 p->copy = TRUE;
2453 sections_copied = TRUE;
2454 break;
2455
2456 case 'R':
2457 p = find_section_list (optarg, TRUE);
2458 if (p->copy)
2459 fatal (_("%s both copied and removed"), optarg);
2460 p->remove = TRUE;
2461 sections_removed = TRUE;
2462 break;
2463
2464 case 'S':
2465 strip_symbols = STRIP_ALL;
2466 break;
2467
2468 case 'g':
2469 strip_symbols = STRIP_DEBUG;
2470 break;
2471
2472 case OPTION_STRIP_UNNEEDED:
2473 strip_symbols = STRIP_UNNEEDED;
2474 break;
2475
2476 case OPTION_ONLY_KEEP_DEBUG:
2477 strip_symbols = STRIP_NONDEBUG;
2478 break;
2479
2480 case OPTION_ADD_GNU_DEBUGLINK:
2481 gnu_debuglink_filename = optarg;
2482 break;
2483
2484 case 'K':
2485 add_specific_symbol (optarg, &keep_specific_list);
2486 break;
2487
2488 case 'N':
2489 add_specific_symbol (optarg, &strip_specific_list);
2490 break;
2491
2492 case 'L':
2493 add_specific_symbol (optarg, &localize_specific_list);
2494 break;
2495
2496 case 'G':
2497 add_specific_symbol (optarg, &keepglobal_specific_list);
2498 break;
2499
2500 case 'W':
2501 add_specific_symbol (optarg, &weaken_specific_list);
2502 break;
2503
2504 case 'p':
2505 preserve_dates = TRUE;
2506 break;
2507
2508 case 'w':
2509 wildcard = TRUE;
2510 break;
2511
2512 case 'x':
2513 discard_locals = LOCALS_ALL;
2514 break;
2515
2516 case 'X':
2517 discard_locals = LOCALS_START_L;
2518 break;
2519
2520 case 'v':
2521 verbose = TRUE;
2522 break;
2523
2524 case 'V':
2525 show_version = TRUE;
2526 break;
2527
2528 case OPTION_FORMATS_INFO:
2529 formats_info = TRUE;
2530 break;
2531
2532 case OPTION_WEAKEN:
2533 weaken = TRUE;
2534 break;
2535
2536 case OPTION_ADD_SECTION:
2537 {
2538 const char *s;
2539 off_t size;
2540 struct section_add *pa;
2541 int len;
2542 char *name;
2543 FILE *f;
2544
2545 s = strchr (optarg, '=');
2546
2547 if (s == NULL)
2548 fatal (_("bad format for %s"), "--add-section");
2549
2550 size = get_file_size (s + 1);
2551 if (size < 1)
2552 break;
2553
2554 pa = xmalloc (sizeof (struct section_add));
2555
2556 len = s - optarg;
2557 name = xmalloc (len + 1);
2558 strncpy (name, optarg, len);
2559 name[len] = '\0';
2560 pa->name = name;
2561
2562 pa->filename = s + 1;
2563 pa->size = size;
2564 pa->contents = xmalloc (size);
2565
2566 f = fopen (pa->filename, FOPEN_RB);
2567
2568 if (f == NULL)
2569 fatal (_("cannot open: %s: %s"),
2570 pa->filename, strerror (errno));
2571
2572 if (fread (pa->contents, 1, pa->size, f) == 0
2573 || ferror (f))
2574 fatal (_("%s: fread failed"), pa->filename);
2575
2576 fclose (f);
2577
2578 pa->next = add_sections;
2579 add_sections = pa;
2580 }
2581 break;
2582
2583 case OPTION_CHANGE_START:
2584 change_start = parse_vma (optarg, "--change-start");
2585 break;
2586
2587 case OPTION_CHANGE_SECTION_ADDRESS:
2588 case OPTION_CHANGE_SECTION_LMA:
2589 case OPTION_CHANGE_SECTION_VMA:
2590 {
2591 const char *s;
2592 int len;
2593 char *name;
2594 char *option = NULL;
2595 bfd_vma val;
2596 enum change_action what = CHANGE_IGNORE;
2597
2598 switch (c)
2599 {
2600 case OPTION_CHANGE_SECTION_ADDRESS:
2601 option = "--change-section-address";
2602 break;
2603 case OPTION_CHANGE_SECTION_LMA:
2604 option = "--change-section-lma";
2605 break;
2606 case OPTION_CHANGE_SECTION_VMA:
2607 option = "--change-section-vma";
2608 break;
2609 }
2610
2611 s = strchr (optarg, '=');
2612 if (s == NULL)
2613 {
2614 s = strchr (optarg, '+');
2615 if (s == NULL)
2616 {
2617 s = strchr (optarg, '-');
2618 if (s == NULL)
2619 fatal (_("bad format for %s"), option);
2620 }
2621 }
2622
2623 len = s - optarg;
2624 name = xmalloc (len + 1);
2625 strncpy (name, optarg, len);
2626 name[len] = '\0';
2627
2628 p = find_section_list (name, TRUE);
2629
2630 val = parse_vma (s + 1, option);
2631
2632 switch (*s)
2633 {
2634 case '=': what = CHANGE_SET; break;
2635 case '-': val = - val; /* Drop through. */
2636 case '+': what = CHANGE_MODIFY; break;
2637 }
2638
2639 switch (c)
2640 {
2641 case OPTION_CHANGE_SECTION_ADDRESS:
2642 p->change_vma = what;
2643 p->vma_val = val;
2644 /* Drop through. */
2645
2646 case OPTION_CHANGE_SECTION_LMA:
2647 p->change_lma = what;
2648 p->lma_val = val;
2649 break;
2650
2651 case OPTION_CHANGE_SECTION_VMA:
2652 p->change_vma = what;
2653 p->vma_val = val;
2654 break;
2655 }
2656 }
2657 break;
2658
2659 case OPTION_CHANGE_ADDRESSES:
2660 change_section_address = parse_vma (optarg, "--change-addresses");
2661 change_start = change_section_address;
2662 break;
2663
2664 case OPTION_CHANGE_WARNINGS:
2665 change_warn = TRUE;
2666 break;
2667
2668 case OPTION_CHANGE_LEADING_CHAR:
2669 change_leading_char = TRUE;
2670 break;
2671
2672 case OPTION_DEBUGGING:
2673 convert_debugging = TRUE;
2674 break;
2675
2676 case OPTION_GAP_FILL:
2677 {
2678 bfd_vma gap_fill_vma;
2679
2680 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2681 gap_fill = (bfd_byte) gap_fill_vma;
2682 if ((bfd_vma) gap_fill != gap_fill_vma)
2683 {
2684 char buff[20];
2685
2686 sprintf_vma (buff, gap_fill_vma);
2687
2688 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2689 buff, gap_fill);
2690 }
2691 gap_fill_set = TRUE;
2692 }
2693 break;
2694
2695 case OPTION_NO_CHANGE_WARNINGS:
2696 change_warn = FALSE;
2697 break;
2698
2699 case OPTION_PAD_TO:
2700 pad_to = parse_vma (optarg, "--pad-to");
2701 pad_to_set = TRUE;
2702 break;
2703
2704 case OPTION_REMOVE_LEADING_CHAR:
2705 remove_leading_char = TRUE;
2706 break;
2707
2708 case OPTION_REDEFINE_SYM:
2709 {
2710 /* Push this redefinition onto redefine_symbol_list. */
2711
2712 int len;
2713 const char *s;
2714 const char *nextarg;
2715 char *source, *target;
2716
2717 s = strchr (optarg, '=');
2718 if (s == NULL)
2719 fatal (_("bad format for %s"), "--redefine-sym");
2720
2721 len = s - optarg;
2722 source = xmalloc (len + 1);
2723 strncpy (source, optarg, len);
2724 source[len] = '\0';
2725
2726 nextarg = s + 1;
2727 len = strlen (nextarg);
2728 target = xmalloc (len + 1);
2729 strcpy (target, nextarg);
2730
2731 redefine_list_append ("--redefine-sym", source, target);
2732
2733 free (source);
2734 free (target);
2735 }
2736 break;
2737
2738 case OPTION_REDEFINE_SYMS:
2739 add_redefine_syms_file (optarg);
2740 break;
2741
2742 case OPTION_SET_SECTION_FLAGS:
2743 {
2744 const char *s;
2745 int len;
2746 char *name;
2747
2748 s = strchr (optarg, '=');
2749 if (s == NULL)
2750 fatal (_("bad format for %s"), "--set-section-flags");
2751
2752 len = s - optarg;
2753 name = xmalloc (len + 1);
2754 strncpy (name, optarg, len);
2755 name[len] = '\0';
2756
2757 p = find_section_list (name, TRUE);
2758
2759 p->set_flags = TRUE;
2760 p->flags = parse_flags (s + 1);
2761 }
2762 break;
2763
2764 case OPTION_RENAME_SECTION:
2765 {
2766 flagword flags;
2767 const char *eq, *fl;
2768 char *old_name;
2769 char *new_name;
2770 unsigned int len;
2771
2772 eq = strchr (optarg, '=');
2773 if (eq == NULL)
2774 fatal (_("bad format for %s"), "--rename-section");
2775
2776 len = eq - optarg;
2777 if (len == 0)
2778 fatal (_("bad format for %s"), "--rename-section");
2779
2780 old_name = xmalloc (len + 1);
2781 strncpy (old_name, optarg, len);
2782 old_name[len] = 0;
2783
2784 eq++;
2785 fl = strchr (eq, ',');
2786 if (fl)
2787 {
2788 flags = parse_flags (fl + 1);
2789 len = fl - eq;
2790 }
2791 else
2792 {
2793 flags = -1;
2794 len = strlen (eq);
2795 }
2796
2797 if (len == 0)
2798 fatal (_("bad format for %s"), "--rename-section");
2799
2800 new_name = xmalloc (len + 1);
2801 strncpy (new_name, eq, len);
2802 new_name[len] = 0;
2803
2804 add_section_rename (old_name, new_name, flags);
2805 }
2806 break;
2807
2808 case OPTION_SET_START:
2809 set_start = parse_vma (optarg, "--set-start");
2810 set_start_set = TRUE;
2811 break;
2812
2813 case OPTION_SREC_LEN:
2814 Chunk = parse_vma (optarg, "--srec-len");
2815 break;
2816
2817 case OPTION_SREC_FORCES3:
2818 S3Forced = TRUE;
2819 break;
2820
2821 case OPTION_STRIP_SYMBOLS:
2822 add_specific_symbols (optarg, &strip_specific_list);
2823 break;
2824
2825 case OPTION_KEEP_SYMBOLS:
2826 add_specific_symbols (optarg, &keep_specific_list);
2827 break;
2828
2829 case OPTION_LOCALIZE_SYMBOLS:
2830 add_specific_symbols (optarg, &localize_specific_list);
2831 break;
2832
2833 case OPTION_KEEPGLOBAL_SYMBOLS:
2834 add_specific_symbols (optarg, &keepglobal_specific_list);
2835 break;
2836
2837 case OPTION_WEAKEN_SYMBOLS:
2838 add_specific_symbols (optarg, &weaken_specific_list);
2839 break;
2840
2841 case OPTION_ALT_MACH_CODE:
2842 use_alt_mach_code = atoi (optarg);
2843 if (use_alt_mach_code <= 0)
2844 fatal (_("alternate machine code index must be positive"));
2845 break;
2846
2847 case OPTION_PREFIX_SYMBOLS:
2848 prefix_symbols_string = optarg;
2849 break;
2850
2851 case OPTION_PREFIX_SECTIONS:
2852 prefix_sections_string = optarg;
2853 break;
2854
2855 case OPTION_PREFIX_ALLOC_SECTIONS:
2856 prefix_alloc_sections_string = optarg;
2857 break;
2858
2859 case OPTION_READONLY_TEXT:
2860 bfd_flags_to_set |= WP_TEXT;
2861 bfd_flags_to_clear &= ~WP_TEXT;
2862 break;
2863
2864 case OPTION_WRITABLE_TEXT:
2865 bfd_flags_to_clear |= WP_TEXT;
2866 bfd_flags_to_set &= ~WP_TEXT;
2867 break;
2868
2869 case OPTION_PURE:
2870 bfd_flags_to_set |= D_PAGED;
2871 bfd_flags_to_clear &= ~D_PAGED;
2872 break;
2873
2874 case OPTION_IMPURE:
2875 bfd_flags_to_clear |= D_PAGED;
2876 bfd_flags_to_set &= ~D_PAGED;
2877 break;
2878
2879 case 0:
2880 /* We've been given a long option. */
2881 break;
2882
2883 case 'H':
2884 case 'h':
2885 copy_usage (stdout, 0);
2886
2887 default:
2888 copy_usage (stderr, 1);
2889 }
2890 }
2891
2892 if (formats_info)
2893 {
2894 display_info ();
2895 return 0;
2896 }
2897
2898 if (show_version)
2899 print_version ("objcopy");
2900
2901 if (copy_byte >= interleave)
2902 fatal (_("byte number must be less than interleave"));
2903
2904 if (optind == argc || optind + 2 < argc)
2905 copy_usage (stderr, 1);
2906
2907 input_filename = argv[optind];
2908 if (optind + 1 < argc)
2909 output_filename = argv[optind + 1];
2910
2911 /* Default is to strip no symbols. */
2912 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2913 strip_symbols = STRIP_NONE;
2914
2915 if (output_target == NULL)
2916 output_target = input_target;
2917
2918 if (binary_architecture != NULL)
2919 {
2920 if (input_target && strcmp (input_target, "binary") == 0)
2921 {
2922 const bfd_arch_info_type * temp_arch_info;
2923
2924 temp_arch_info = bfd_scan_arch (binary_architecture);
2925
2926 if (temp_arch_info != NULL)
2927 {
2928 bfd_external_binary_architecture = temp_arch_info->arch;
2929 bfd_external_machine = temp_arch_info->mach;
2930 }
2931 else
2932 fatal (_("architecture %s unknown"), binary_architecture);
2933 }
2934 else
2935 {
2936 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2937 non_fatal (_(" Argument %s ignored"), binary_architecture);
2938 }
2939 }
2940
2941 if (preserve_dates)
2942 if (stat (input_filename, & statbuf) < 0)
2943 fatal (_("warning: could not locate '%s'. System error message: %s"),
2944 input_filename, strerror (errno));
2945
2946 /* If there is no destination file, or the source and destination files
2947 are the same, then create a temp and rename the result into the input. */
2948 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
2949 {
2950 char *tmpname = make_tempname (input_filename);
2951
2952 copy_file (input_filename, tmpname, input_target, output_target);
2953 if (status == 0)
2954 {
2955 if (preserve_dates)
2956 set_times (tmpname, &statbuf);
2957 smart_rename (tmpname, input_filename, preserve_dates);
2958 }
2959 else
2960 unlink (tmpname);
2961 }
2962 else
2963 {
2964 copy_file (input_filename, output_filename, input_target, output_target);
2965
2966 if (status == 0 && preserve_dates)
2967 set_times (output_filename, &statbuf);
2968 }
2969
2970 if (change_warn)
2971 {
2972 for (p = change_sections; p != NULL; p = p->next)
2973 {
2974 if (! p->used)
2975 {
2976 if (p->change_vma != CHANGE_IGNORE)
2977 {
2978 char buff [20];
2979
2980 sprintf_vma (buff, p->vma_val);
2981
2982 /* xgettext:c-format */
2983 non_fatal (_("%s %s%c0x%s never used"),
2984 "--change-section-vma",
2985 p->name,
2986 p->change_vma == CHANGE_SET ? '=' : '+',
2987 buff);
2988 }
2989
2990 if (p->change_lma != CHANGE_IGNORE)
2991 {
2992 char buff [20];
2993
2994 sprintf_vma (buff, p->lma_val);
2995
2996 /* xgettext:c-format */
2997 non_fatal (_("%s %s%c0x%s never used"),
2998 "--change-section-lma",
2999 p->name,
3000 p->change_lma == CHANGE_SET ? '=' : '+',
3001 buff);
3002 }
3003 }
3004 }
3005 }
3006
3007 return 0;
3008 }
3009
3010 int
3011 main (int argc, char *argv[])
3012 {
3013 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3014 setlocale (LC_MESSAGES, "");
3015 #endif
3016 #if defined (HAVE_SETLOCALE)
3017 setlocale (LC_CTYPE, "");
3018 #endif
3019 bindtextdomain (PACKAGE, LOCALEDIR);
3020 textdomain (PACKAGE);
3021
3022 program_name = argv[0];
3023 xmalloc_set_program_name (program_name);
3024
3025 START_PROGRESS (program_name, 0);
3026
3027 strip_symbols = STRIP_UNDEF;
3028 discard_locals = LOCALS_UNDEF;
3029
3030 bfd_init ();
3031 set_default_bfd_target ();
3032
3033 if (is_strip < 0)
3034 {
3035 int i = strlen (program_name);
3036 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
3037 /* Drop the .exe suffix, if any. */
3038 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3039 {
3040 i -= 4;
3041 program_name[i] = '\0';
3042 }
3043 #endif
3044 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
3045 }
3046
3047 if (is_strip)
3048 strip_main (argc, argv);
3049 else
3050 copy_main (argc, argv);
3051
3052 END_PROGRESS (program_name);
3053
3054 return status;
3055 }
This page took 0.096023 seconds and 5 git commands to generate.