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