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