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