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