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