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