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