]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/objcopy.c
gdb/testsuite/
[thirdparty/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
237dcb53
AM
1464 if (!extract_symbol)
1465 setup_bfd_headers (ibfd, obfd);
80fccad2 1466
252b5132
RH
1467 if (add_sections != NULL)
1468 {
1469 struct section_add *padd;
1470 struct section_list *pset;
1471
1472 for (padd = add_sections; padd != NULL; padd = padd->next)
1473 {
2593f09a
NC
1474 flagword flags;
1475
551b43fd
AM
1476 pset = find_section_list (padd->name, FALSE);
1477 if (pset != NULL)
1478 pset->used = TRUE;
1479
1480 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1481 if (pset != NULL && pset->set_flags)
1482 flags = pset->flags | SEC_HAS_CONTENTS;
1483
c8782eee
NC
1484 /* bfd_make_section_with_flags() does not return very helpful
1485 error codes, so check for the most likely user error first. */
1486 if (bfd_get_section_by_name (obfd, padd->name))
252b5132 1487 {
2db6cde7
NS
1488 bfd_nonfatal_message (NULL, obfd, NULL,
1489 _("can't add section '%s'"), padd->name);
950d48e7 1490 return FALSE;
252b5132 1491 }
c8782eee
NC
1492 else
1493 {
1494 padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
1495 if (padd->section == NULL)
1496 {
2db6cde7
NS
1497 bfd_nonfatal_message (NULL, obfd, NULL,
1498 _("can't create section `%s'"),
1499 padd->name);
c8782eee
NC
1500 return FALSE;
1501 }
1502 }
252b5132 1503
2593f09a 1504 if (! bfd_set_section_size (obfd, padd->section, padd->size))
950d48e7 1505 {
2db6cde7 1506 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1507 return FALSE;
1508 }
252b5132 1509
2593f09a
NC
1510 if (pset != NULL)
1511 {
1512 if (pset->change_vma != CHANGE_IGNORE)
84e2f313
NC
1513 if (! bfd_set_section_vma (obfd, padd->section,
1514 pset->vma_val))
950d48e7 1515 {
2db6cde7 1516 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1517 return FALSE;
1518 }
57938635 1519
2593f09a
NC
1520 if (pset->change_lma != CHANGE_IGNORE)
1521 {
1522 padd->section->lma = pset->lma_val;
950d48e7 1523
2593f09a
NC
1524 if (! bfd_set_section_alignment
1525 (obfd, padd->section,
1526 bfd_section_alignment (obfd, padd->section)))
950d48e7 1527 {
2db6cde7 1528 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1529 return FALSE;
1530 }
252b5132
RH
1531 }
1532 }
1533 }
1534 }
1535
2593f09a
NC
1536 if (gnu_debuglink_filename != NULL)
1537 {
84e2f313
NC
1538 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1539 (obfd, gnu_debuglink_filename);
e7c81c25
NC
1540
1541 if (gnu_debuglink_section == NULL)
950d48e7 1542 {
2db6cde7
NS
1543 bfd_nonfatal_message (NULL, obfd, NULL,
1544 _("cannot create debug link section `%s'"),
1545 gnu_debuglink_filename);
950d48e7
NC
1546 return FALSE;
1547 }
6e2c86ac
NC
1548
1549 /* Special processing for PE format files. We
1550 have no way to distinguish PE from COFF here. */
1551 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1552 {
1553 bfd_vma debuglink_vma;
1554 asection * highest_section;
1555 asection * sec;
1556
1557 /* The PE spec requires that all sections be adjacent and sorted
1558 in ascending order of VMA. It also specifies that debug
1559 sections should be last. This is despite the fact that debug
1560 sections are not loaded into memory and so in theory have no
1561 use for a VMA.
1562
1563 This means that the debuglink section must be given a non-zero
1564 VMA which makes it contiguous with other debug sections. So
1565 walk the current section list, find the section with the
1566 highest VMA and start the debuglink section after that one. */
1567 for (sec = obfd->sections, highest_section = NULL;
1568 sec != NULL;
1569 sec = sec->next)
1570 if (sec->vma > 0
1571 && (highest_section == NULL
1572 || sec->vma > highest_section->vma))
1573 highest_section = sec;
1574
1575 if (highest_section)
1576 debuglink_vma = BFD_ALIGN (highest_section->vma
1577 + highest_section->size,
1578 /* FIXME: We ought to be using
1579 COFF_PAGE_SIZE here or maybe
1580 bfd_get_section_alignment() (if it
1581 was set) but since this is for PE
1582 and we know the required alignment
1583 it is easier just to hard code it. */
1584 0x1000);
1585 else
1586 /* Umm, not sure what to do in this case. */
1587 debuglink_vma = 0x1000;
1588
1589 bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
1590 }
950d48e7
NC
1591 }
1592
1aa9ef63
L
1593 if (bfd_count_sections (obfd) != 0
1594 && (gap_fill_set || pad_to_set))
252b5132
RH
1595 {
1596 asection **set;
1597 unsigned int c, i;
1598
1599 /* We must fill in gaps between the sections and/or we must pad
1600 the last section to a specified address. We do this by
1601 grabbing a list of the sections, sorting them by VMA, and
1602 increasing the section sizes as required to fill the gaps.
1603 We write out the gap contents below. */
1604
1605 c = bfd_count_sections (obfd);
d3ba0551 1606 osections = xmalloc (c * sizeof (asection *));
252b5132 1607 set = osections;
d3ba0551 1608 bfd_map_over_sections (obfd, get_sections, &set);
252b5132
RH
1609
1610 qsort (osections, c, sizeof (asection *), compare_section_lma);
1611
d3ba0551 1612 gaps = xmalloc (c * sizeof (bfd_size_type));
252b5132
RH
1613 memset (gaps, 0, c * sizeof (bfd_size_type));
1614
1615 if (gap_fill_set)
1616 {
1617 for (i = 0; i < c - 1; i++)
1618 {
1619 flagword flags;
1620 bfd_size_type size;
1621 bfd_vma gap_start, gap_stop;
1622
1623 flags = bfd_get_section_flags (obfd, osections[i]);
1624 if ((flags & SEC_HAS_CONTENTS) == 0
1625 || (flags & SEC_LOAD) == 0)
1626 continue;
1627
1628 size = bfd_section_size (obfd, osections[i]);
1629 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1630 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1631 if (gap_start < gap_stop)
1632 {
1633 if (! bfd_set_section_size (obfd, osections[i],
1634 size + (gap_stop - gap_start)))
1635 {
2db6cde7
NS
1636 bfd_nonfatal_message (NULL, obfd, osections[i],
1637 _("Can't fill gap after section"));
252b5132
RH
1638 status = 1;
1639 break;
1640 }
1641 gaps[i] = gap_stop - gap_start;
1642 if (max_gap < gap_stop - gap_start)
1643 max_gap = gap_stop - gap_start;
1644 }
1645 }
1646 }
1647
1648 if (pad_to_set)
1649 {
1650 bfd_vma lma;
1651 bfd_size_type size;
1652
1653 lma = bfd_section_lma (obfd, osections[c - 1]);
1654 size = bfd_section_size (obfd, osections[c - 1]);
1655 if (lma + size < pad_to)
1656 {
1657 if (! bfd_set_section_size (obfd, osections[c - 1],
1658 pad_to - lma))
1659 {
2db6cde7
NS
1660 bfd_nonfatal_message (NULL, obfd, osections[c - 1],
1661 _("can't add padding"));
252b5132
RH
1662 status = 1;
1663 }
1664 else
1665 {
1666 gaps[c - 1] = pad_to - (lma + size);
1667 if (max_gap < pad_to - (lma + size))
1668 max_gap = pad_to - (lma + size);
1669 }
1670 }
1671 }
1672 }
1673
594ef5db
NC
1674 /* Symbol filtering must happen after the output sections
1675 have been created, but before their contents are set. */
252b5132 1676 dhandle = NULL;
252b5132 1677 if (convert_debugging)
b922d590 1678 dhandle = read_debugging_info (ibfd, isympp, symcount, FALSE);
57938635
AM
1679
1680 if (strip_symbols == STRIP_DEBUG
252b5132
RH
1681 || strip_symbols == STRIP_ALL
1682 || strip_symbols == STRIP_UNNEEDED
ed1653a7 1683 || strip_symbols == STRIP_NONDEBUG
252b5132 1684 || discard_locals != LOCALS_UNDEF
d58c2e3a 1685 || localize_hidden
047c9024
NC
1686 || htab_elements (strip_specific_htab) != 0
1687 || htab_elements (keep_specific_htab) != 0
1688 || htab_elements (localize_specific_htab) != 0
1689 || htab_elements (globalize_specific_htab) != 0
1690 || htab_elements (keepglobal_specific_htab) != 0
1691 || htab_elements (weaken_specific_htab) != 0
d7fb0dd2 1692 || prefix_symbols_string
252b5132 1693 || sections_removed
f91ea849 1694 || sections_copied
252b5132
RH
1695 || convert_debugging
1696 || change_leading_char
1697 || remove_leading_char
57938635 1698 || redefine_sym_list
252b5132
RH
1699 || weaken)
1700 {
1701 /* Mark symbols used in output relocations so that they
1702 are kept, even if they are local labels or static symbols.
57938635 1703
252b5132
RH
1704 Note we iterate over the input sections examining their
1705 relocations since the relocations for the output sections
1706 haven't been set yet. mark_symbols_used_in_relocations will
1707 ignore input sections which have no corresponding output
1708 section. */
1709 if (strip_symbols != STRIP_ALL)
1710 bfd_map_over_sections (ibfd,
1711 mark_symbols_used_in_relocations,
d3ba0551
AM
1712 isympp);
1713 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
252b5132
RH
1714 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1715 }
1716
1717 if (convert_debugging && dhandle != NULL)
1718 {
1719 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1720 {
1721 status = 1;
950d48e7 1722 return FALSE;
252b5132
RH
1723 }
1724 }
1725
1726 bfd_set_symtab (obfd, osympp, symcount);
1727
1728 /* This has to happen after the symbol table has been set. */
d3ba0551 1729 bfd_map_over_sections (ibfd, copy_section, obfd);
252b5132
RH
1730
1731 if (add_sections != NULL)
1732 {
1733 struct section_add *padd;
1734
1735 for (padd = add_sections; padd != NULL; padd = padd->next)
1736 {
d3ba0551
AM
1737 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1738 0, padd->size))
950d48e7 1739 {
2db6cde7 1740 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1741 return FALSE;
1742 }
252b5132
RH
1743 }
1744 }
1745
e7c81c25
NC
1746 if (gnu_debuglink_filename != NULL)
1747 {
1748 if (! bfd_fill_in_gnu_debuglink_section
1749 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
950d48e7 1750 {
2db6cde7
NS
1751 bfd_nonfatal_message (NULL, obfd, NULL,
1752 _("cannot fill debug link section `%s'"),
1753 gnu_debuglink_filename);
950d48e7
NC
1754 return FALSE;
1755 }
e7c81c25
NC
1756 }
1757
252b5132
RH
1758 if (gap_fill_set || pad_to_set)
1759 {
1760 bfd_byte *buf;
1761 int c, i;
1762
1763 /* Fill in the gaps. */
252b5132
RH
1764 if (max_gap > 8192)
1765 max_gap = 8192;
d3ba0551
AM
1766 buf = xmalloc (max_gap);
1767 memset (buf, gap_fill, max_gap);
252b5132
RH
1768
1769 c = bfd_count_sections (obfd);
1770 for (i = 0; i < c; i++)
1771 {
1772 if (gaps[i] != 0)
1773 {
1774 bfd_size_type left;
1775 file_ptr off;
1776
1777 left = gaps[i];
1778 off = bfd_section_size (obfd, osections[i]) - left;
594ef5db 1779
252b5132
RH
1780 while (left > 0)
1781 {
1782 bfd_size_type now;
1783
1784 if (left > 8192)
1785 now = 8192;
1786 else
1787 now = left;
1788
1789 if (! bfd_set_section_contents (obfd, osections[i], buf,
1790 off, now))
950d48e7 1791 {
2db6cde7 1792 bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
950d48e7
NC
1793 return FALSE;
1794 }
252b5132
RH
1795
1796 left -= now;
1797 off += now;
1798 }
1799 }
1800 }
1801 }
1802
d3e52d40
RS
1803 /* Do not copy backend data if --extract-symbol is passed; anything
1804 that needs to look at the section contents will fail. */
1805 if (extract_symbol)
1806 return TRUE;
1807
252b5132
RH
1808 /* Allow the BFD backend to copy any private data it understands
1809 from the input BFD to the output BFD. This is done last to
1810 permit the routine to look at the filtered symbol table, which is
1811 important for the ECOFF code at least. */
42bb2e33 1812 if (! bfd_copy_private_bfd_data (ibfd, obfd))
252b5132 1813 {
2db6cde7
NS
1814 bfd_nonfatal_message (NULL, obfd, NULL,
1815 _("error copying private BFD data"));
950d48e7 1816 return FALSE;
252b5132 1817 }
1ae8b3d2
AO
1818
1819 /* Switch to the alternate machine code. We have to do this at the
1820 very end, because we only initialize the header when we create
1821 the first section. */
f9d4ad2a
NC
1822 if (use_alt_mach_code != 0)
1823 {
1824 if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
1825 {
1826 non_fatal (_("this target does not support %lu alternative machine codes"),
1827 use_alt_mach_code);
1828 if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1829 {
1830 non_fatal (_("treating that number as an absolute e_machine value instead"));
1831 elf_elfheader (obfd)->e_machine = use_alt_mach_code;
1832 }
1833 else
1834 non_fatal (_("ignoring the alternative value"));
1835 }
1836 }
950d48e7
NC
1837
1838 return TRUE;
252b5132
RH
1839}
1840
1841/* Read each archive element in turn from IBFD, copy the
ee873e00
NC
1842 contents to temp file, and keep the temp file handle.
1843 If 'force_output_target' is TRUE then make sure that
1844 all elements in the new archive are of the type
1845 'output_target'. */
252b5132
RH
1846
1847static void
ee873e00
NC
1848copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
1849 bfd_boolean force_output_target)
252b5132
RH
1850{
1851 struct name_list
1852 {
1853 struct name_list *next;
4c168fa3 1854 const char *name;
252b5132
RH
1855 bfd *obfd;
1856 } *list, *l;
1857 bfd **ptr = &obfd->archive_head;
1858 bfd *this_element;
f9c026a8 1859 char * dir;
252b5132
RH
1860
1861 /* Make a temp directory to hold the contents. */
f9c026a8 1862 dir = make_tempdir (bfd_get_filename (obfd));
f9c026a8
NC
1863 if (dir == NULL)
1864 fatal (_("cannot create tempdir for archive copying (error: %s)"),
1865 strerror (errno));
84e2f313 1866
252b5132 1867 obfd->has_armap = ibfd->has_armap;
a8da6403 1868 obfd->is_thin_archive = ibfd->is_thin_archive;
252b5132
RH
1869
1870 list = NULL;
1871
1872 this_element = bfd_openr_next_archived_file (ibfd, NULL);
594ef5db 1873
b667df2e 1874 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
2db6cde7 1875 RETURN_NONFATAL (obfd);
b667df2e 1876
d3ba0551 1877 while (!status && this_element != NULL)
252b5132 1878 {
4c168fa3
AM
1879 char *output_name;
1880 bfd *output_bfd;
252b5132 1881 bfd *last_element;
8066d1a2
AS
1882 struct stat buf;
1883 int stat_status = 0;
950d48e7 1884 bfd_boolean delete = TRUE;
8066d1a2 1885
4c168fa3
AM
1886 /* Create an output file for this member. */
1887 output_name = concat (dir, "/",
1888 bfd_get_filename (this_element), (char *) 0);
1889
1890 /* If the file already exists, make another temp dir. */
1891 if (stat (output_name, &buf) >= 0)
1892 {
f9c026a8
NC
1893 output_name = make_tempdir (output_name);
1894 if (output_name == NULL)
485be063
AM
1895 fatal (_("cannot create tempdir for archive copying (error: %s)"),
1896 strerror (errno));
84e2f313 1897
d3ba0551 1898 l = xmalloc (sizeof (struct name_list));
4c168fa3
AM
1899 l->name = output_name;
1900 l->next = list;
1901 l->obfd = NULL;
1902 list = l;
1903 output_name = concat (output_name, "/",
1904 bfd_get_filename (this_element), (char *) 0);
1905 }
1906
8066d1a2
AS
1907 if (preserve_dates)
1908 {
1909 stat_status = bfd_stat_arch_elt (this_element, &buf);
594ef5db 1910
8066d1a2
AS
1911 if (stat_status != 0)
1912 non_fatal (_("internal stat error on %s"),
1913 bfd_get_filename (this_element));
1914 }
252b5132 1915
d3ba0551 1916 l = xmalloc (sizeof (struct name_list));
252b5132
RH
1917 l->name = output_name;
1918 l->next = list;
bee59fd2 1919 l->obfd = NULL;
252b5132
RH
1920 list = l;
1921
b34976b6 1922 if (bfd_check_format (this_element, bfd_object))
77f762d6 1923 {
ee873e00
NC
1924 /* PR binutils/3110: Cope with archives
1925 containing multiple target types. */
1926 if (force_output_target)
1927 output_bfd = bfd_openw (output_name, output_target);
1928 else
1929 output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
1930
1931 if (output_bfd == NULL)
2db6cde7
NS
1932 {
1933 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
1934 status = 1;
1935 return;
1936 }
ee873e00 1937
77f762d6 1938 delete = ! copy_object (this_element, output_bfd);
252b5132 1939
77f762d6
L
1940 if (! delete
1941 || bfd_get_arch (this_element) != bfd_arch_unknown)
1942 {
1943 if (!bfd_close (output_bfd))
1944 {
2db6cde7 1945 bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
77f762d6
L
1946 /* Error in new object file. Don't change archive. */
1947 status = 1;
1948 }
1949 }
1950 else
1951 goto copy_unknown_element;
1952 }
1953 else
252b5132 1954 {
2db6cde7
NS
1955 bfd_nonfatal_message (bfd_get_archive_filename (this_element),
1956 NULL, NULL,
1957 _("Unable to recognise the format of file"));
77f762d6 1958
ee873e00 1959 output_bfd = bfd_openw (output_name, output_target);
77f762d6
L
1960copy_unknown_element:
1961 delete = !copy_unknown_object (this_element, output_bfd);
1962 if (!bfd_close_all_done (output_bfd))
1963 {
2db6cde7 1964 bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
77f762d6
L
1965 /* Error in new object file. Don't change archive. */
1966 status = 1;
1967 }
252b5132
RH
1968 }
1969
950d48e7
NC
1970 if (delete)
1971 {
1972 unlink (output_name);
1973 status = 1;
1974 }
1975 else
1976 {
1977 if (preserve_dates && stat_status == 0)
1978 set_times (output_name, &buf);
8066d1a2 1979
950d48e7
NC
1980 /* Open the newly output file and attach to our list. */
1981 output_bfd = bfd_openr (output_name, output_target);
252b5132 1982
950d48e7 1983 l->obfd = output_bfd;
252b5132 1984
950d48e7 1985 *ptr = output_bfd;
cc481421 1986 ptr = &output_bfd->archive_next;
252b5132 1987
950d48e7 1988 last_element = this_element;
252b5132 1989
950d48e7 1990 this_element = bfd_openr_next_archived_file (ibfd, last_element);
252b5132 1991
950d48e7
NC
1992 bfd_close (last_element);
1993 }
252b5132 1994 }
d3ba0551 1995 *ptr = NULL;
252b5132
RH
1996
1997 if (!bfd_close (obfd))
2db6cde7 1998 RETURN_NONFATAL (obfd);
252b5132
RH
1999
2000 if (!bfd_close (ibfd))
2db6cde7 2001 RETURN_NONFATAL (obfd);
252b5132
RH
2002
2003 /* Delete all the files that we opened. */
2004 for (l = list; l != NULL; l = l->next)
2005 {
4c168fa3
AM
2006 if (l->obfd == NULL)
2007 rmdir (l->name);
2008 else
2009 {
2010 bfd_close (l->obfd);
2011 unlink (l->name);
2012 }
252b5132
RH
2013 }
2014 rmdir (dir);
2015}
2016
2017/* The top-level control. */
2018
2019static void
84e2f313
NC
2020copy_file (const char *input_filename, const char *output_filename,
2021 const char *input_target, const char *output_target)
252b5132
RH
2022{
2023 bfd *ibfd;
49c12576
AM
2024 char **obj_matching;
2025 char **core_matching;
252b5132 2026
f24ddbdd
NC
2027 if (get_file_size (input_filename) < 1)
2028 {
2029 status = 1;
2030 return;
2031 }
2032
252b5132
RH
2033 /* To allow us to do "strip *" without dying on the first
2034 non-object file, failures are nonfatal. */
252b5132
RH
2035 ibfd = bfd_openr (input_filename, input_target);
2036 if (ibfd == NULL)
2db6cde7
NS
2037 {
2038 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2039 status = 1;
2040 return;
2041 }
252b5132
RH
2042
2043 if (bfd_check_format (ibfd, bfd_archive))
2044 {
ee873e00 2045 bfd_boolean force_output_target;
252b5132
RH
2046 bfd *obfd;
2047
2048 /* bfd_get_target does not return the correct value until
2049 bfd_check_format succeeds. */
2050 if (output_target == NULL)
ee873e00
NC
2051 {
2052 output_target = bfd_get_target (ibfd);
2053 force_output_target = FALSE;
2054 }
2055 else
2056 force_output_target = TRUE;
252b5132
RH
2057
2058 obfd = bfd_openw (output_filename, output_target);
2059 if (obfd == NULL)
2db6cde7
NS
2060 {
2061 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2062 status = 1;
2063 return;
2064 }
252b5132 2065
ee873e00 2066 copy_archive (ibfd, obfd, output_target, force_output_target);
252b5132 2067 }
49c12576 2068 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
252b5132
RH
2069 {
2070 bfd *obfd;
49c12576 2071 do_copy:
950d48e7 2072
252b5132
RH
2073 /* bfd_get_target does not return the correct value until
2074 bfd_check_format succeeds. */
2075 if (output_target == NULL)
2076 output_target = bfd_get_target (ibfd);
2077
2078 obfd = bfd_openw (output_filename, output_target);
2079 if (obfd == NULL)
2db6cde7
NS
2080 {
2081 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2082 status = 1;
2083 return;
2084 }
252b5132 2085
a580b8e0
JB
2086 if (! copy_object (ibfd, obfd))
2087 status = 1;
252b5132
RH
2088
2089 if (!bfd_close (obfd))
2db6cde7 2090 RETURN_NONFATAL (obfd);
252b5132
RH
2091
2092 if (!bfd_close (ibfd))
2db6cde7 2093 RETURN_NONFATAL (ibfd);
252b5132
RH
2094 }
2095 else
2096 {
49c12576
AM
2097 bfd_error_type obj_error = bfd_get_error ();
2098 bfd_error_type core_error;
b34976b6 2099
49c12576
AM
2100 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
2101 {
2102 /* This probably can't happen.. */
2103 if (obj_error == bfd_error_file_ambiguously_recognized)
2104 free (obj_matching);
2105 goto do_copy;
2106 }
2107
2108 core_error = bfd_get_error ();
2109 /* Report the object error in preference to the core error. */
2110 if (obj_error != core_error)
2111 bfd_set_error (obj_error);
2112
2db6cde7 2113 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
57938635 2114
49c12576
AM
2115 if (obj_error == bfd_error_file_ambiguously_recognized)
2116 {
2117 list_matching_formats (obj_matching);
2118 free (obj_matching);
2119 }
2120 if (core_error == bfd_error_file_ambiguously_recognized)
252b5132 2121 {
49c12576
AM
2122 list_matching_formats (core_matching);
2123 free (core_matching);
252b5132 2124 }
57938635 2125
252b5132
RH
2126 status = 1;
2127 }
2128}
2129
594ef5db
NC
2130/* Add a name to the section renaming list. */
2131
2132static void
84e2f313
NC
2133add_section_rename (const char * old_name, const char * new_name,
2134 flagword flags)
594ef5db
NC
2135{
2136 section_rename * rename;
2137
2138 /* Check for conflicts first. */
2139 for (rename = section_rename_list; rename != NULL; rename = rename->next)
2140 if (strcmp (rename->old_name, old_name) == 0)
2141 {
2142 /* Silently ignore duplicate definitions. */
2143 if (strcmp (rename->new_name, new_name) == 0
2144 && rename->flags == flags)
2145 return;
0af11b59 2146
594ef5db
NC
2147 fatal (_("Multiple renames of section %s"), old_name);
2148 }
2149
d3ba0551 2150 rename = xmalloc (sizeof (* rename));
594ef5db
NC
2151
2152 rename->old_name = old_name;
2153 rename->new_name = new_name;
2154 rename->flags = flags;
2155 rename->next = section_rename_list;
0af11b59 2156
594ef5db
NC
2157 section_rename_list = rename;
2158}
2159
2160/* Check the section rename list for a new name of the input section
2161 ISECTION. Return the new name if one is found.
2162 Also set RETURNED_FLAGS to the flags to be used for this section. */
2163
2164static const char *
84e2f313
NC
2165find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
2166 flagword * returned_flags)
594ef5db
NC
2167{
2168 const char * old_name = bfd_section_name (ibfd, isection);
2169 section_rename * rename;
2170
2171 /* Default to using the flags of the input section. */
2172 * returned_flags = bfd_get_section_flags (ibfd, isection);
2173
2174 for (rename = section_rename_list; rename != NULL; rename = rename->next)
2175 if (strcmp (rename->old_name, old_name) == 0)
2176 {
2177 if (rename->flags != (flagword) -1)
2178 * returned_flags = rename->flags;
2179
2180 return rename->new_name;
2181 }
2182
2183 return old_name;
2184}
2185
80fccad2
BW
2186/* Once each of the sections is copied, we may still need to do some
2187 finalization work for private section headers. Do that here. */
2188
2189static void
2190setup_bfd_headers (bfd *ibfd, bfd *obfd)
2191{
80fccad2
BW
2192 /* Allow the BFD backend to copy any private data it understands
2193 from the input section to the output section. */
2194 if (! bfd_copy_private_header_data (ibfd, obfd))
2195 {
2db6cde7
NS
2196 status = 1;
2197 bfd_nonfatal_message (NULL, ibfd, NULL,
2198 _("error in private h eader data"));
2199 return;
80fccad2
BW
2200 }
2201
2202 /* All went well. */
2203 return;
80fccad2
BW
2204}
2205
594ef5db
NC
2206/* Create a section in OBFD with the same
2207 name and attributes as ISECTION in IBFD. */
252b5132
RH
2208
2209static void
84e2f313 2210setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 2211{
d3ba0551 2212 bfd *obfd = obfdarg;
252b5132
RH
2213 struct section_list *p;
2214 sec_ptr osection;
2215 bfd_size_type size;
2216 bfd_vma vma;
2217 bfd_vma lma;
2218 flagword flags;
1a89cc7d 2219 const char *err;
594ef5db 2220 const char * name;
d7fb0dd2 2221 char *prefix = NULL;
66125551 2222 bfd_boolean make_nobits;
0af11b59 2223
2593f09a 2224 if (is_strip_section (ibfd, isection))
252b5132
RH
2225 return;
2226
b34976b6 2227 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
252b5132 2228 if (p != NULL)
b34976b6 2229 p->used = TRUE;
252b5132 2230
594ef5db
NC
2231 /* Get the, possibly new, name of the output section. */
2232 name = find_section_rename (ibfd, isection, & flags);
0af11b59 2233
d7fb0dd2 2234 /* Prefix sections. */
84e2f313
NC
2235 if ((prefix_alloc_sections_string)
2236 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
d7fb0dd2
NC
2237 prefix = prefix_alloc_sections_string;
2238 else if (prefix_sections_string)
2239 prefix = prefix_sections_string;
2240
2241 if (prefix)
2242 {
2243 char *n;
2244
2245 n = xmalloc (strlen (prefix) + strlen (name) + 1);
2246 strcpy (n, prefix);
2247 strcat (n, name);
2248 name = n;
2249 }
66491ebc 2250
66125551 2251 make_nobits = FALSE;
551b43fd
AM
2252 if (p != NULL && p->set_flags)
2253 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
42bb2e33 2254 else if (strip_symbols == STRIP_NONDEBUG
66125551
AM
2255 && (flags & SEC_ALLOC) != 0
2256 && (ibfd->xvec->flavour != bfd_target_elf_flavour
2257 || elf_section_type (isection) != SHT_NOTE))
2258 {
2259 flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2260 if (obfd->xvec->flavour == bfd_target_elf_flavour)
2261 {
2262 make_nobits = TRUE;
2263
2264 /* Twiddle the input section flags so that it seems to
2265 elf.c:copy_private_bfd_data that section flags have not
2266 changed between input and output sections. This hack
2267 prevents wholesale rewriting of the program headers. */
2268 isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2269 }
2270 }
551b43fd
AM
2271
2272 osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
57938635 2273
252b5132
RH
2274 if (osection == NULL)
2275 {
2db6cde7 2276 err = _("failed to create output section");
252b5132
RH
2277 goto loser;
2278 }
2279
66125551 2280 if (make_nobits)
551b43fd
AM
2281 elf_section_type (osection) = SHT_NOBITS;
2282
252b5132
RH
2283 size = bfd_section_size (ibfd, isection);
2284 if (copy_byte >= 0)
2285 size = (size + interleave - 1) / interleave;
d3e52d40
RS
2286 else if (extract_symbol)
2287 size = 0;
252b5132
RH
2288 if (! bfd_set_section_size (obfd, osection, size))
2289 {
2db6cde7 2290 err = _("failed to set size");
252b5132
RH
2291 goto loser;
2292 }
57938635 2293
252b5132
RH
2294 vma = bfd_section_vma (ibfd, isection);
2295 if (p != NULL && p->change_vma == CHANGE_MODIFY)
2296 vma += p->vma_val;
2297 else if (p != NULL && p->change_vma == CHANGE_SET)
2298 vma = p->vma_val;
2299 else
2300 vma += change_section_address;
57938635 2301
237dcb53 2302 if (! bfd_set_section_vma (obfd, osection, vma))
252b5132 2303 {
2db6cde7 2304 err = _("failed to set vma");
252b5132
RH
2305 goto loser;
2306 }
2307
2308 lma = isection->lma;
2309 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2310 {
2311 if (p->change_lma == CHANGE_MODIFY)
2312 lma += p->lma_val;
2313 else if (p->change_lma == CHANGE_SET)
2314 lma = p->lma_val;
2315 else
2316 abort ();
2317 }
2318 else
2319 lma += change_section_address;
57938635 2320
237dcb53 2321 osection->lma = lma;
252b5132
RH
2322
2323 /* FIXME: This is probably not enough. If we change the LMA we
2324 may have to recompute the header for the file as well. */
b34976b6
AM
2325 if (!bfd_set_section_alignment (obfd,
2326 osection,
2327 bfd_section_alignment (ibfd, isection)))
252b5132 2328 {
2db6cde7 2329 err = _("failed to set alignment");
252b5132
RH
2330 goto loser;
2331 }
2332
bc408b8a
JJ
2333 /* Copy merge entity size. */
2334 osection->entsize = isection->entsize;
2335
252b5132
RH
2336 /* This used to be mangle_section; we do here to avoid using
2337 bfd_get_section_by_name since some formats allow multiple
2338 sections with the same name. */
2339 isection->output_section = osection;
237dcb53 2340 isection->output_offset = 0;
d3e52d40
RS
2341
2342 /* Do not copy backend data if --extract-symbol is passed; anything
2343 that needs to look at the section contents will fail. */
2344 if (extract_symbol)
2345 return;
252b5132
RH
2346
2347 /* Allow the BFD backend to copy any private data it understands
2348 from the input section to the output section. */
42bb2e33 2349 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
252b5132 2350 {
2db6cde7 2351 err = _("failed to copy private data");
252b5132
RH
2352 goto loser;
2353 }
30288845 2354 else if ((isection->flags & SEC_GROUP) != 0)
c39ada54 2355 {
30288845 2356 asymbol *gsym = group_signature (isection);
c39ada54 2357
30288845
AM
2358 if (gsym != NULL)
2359 gsym->flags |= BSF_KEEP;
c39ada54 2360 }
252b5132 2361
594ef5db 2362 /* All went well. */
252b5132
RH
2363 return;
2364
2365loser:
252b5132 2366 status = 1;
2db6cde7 2367 bfd_nonfatal_message (NULL, obfd, osection, err);
252b5132
RH
2368}
2369
2370/* Copy the data of input section ISECTION of IBFD
2371 to an output section with the same name in OBFD.
2372 If stripping then don't copy any relocation info. */
2373
2374static void
84e2f313 2375copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 2376{
d3ba0551 2377 bfd *obfd = obfdarg;
252b5132
RH
2378 struct section_list *p;
2379 arelent **relpp;
2380 long relcount;
2381 sec_ptr osection;
2382 bfd_size_type size;
2383 long relsize;
dc156bc0 2384 flagword flags;
252b5132 2385
594ef5db
NC
2386 /* If we have already failed earlier on,
2387 do not keep on generating complaints now. */
252b5132
RH
2388 if (status != 0)
2389 return;
57938635 2390
2593f09a 2391 if (is_strip_section (ibfd, isection))
e0c60db2 2392 return;
252b5132 2393
2593f09a 2394 flags = bfd_get_section_flags (ibfd, isection);
dc156bc0
AM
2395 if ((flags & SEC_GROUP) != 0)
2396 return;
2397
252b5132 2398 osection = isection->output_section;
135dfb4a 2399 size = bfd_get_section_size (isection);
252b5132
RH
2400
2401 if (size == 0 || osection == 0)
2402 return;
2403
237dcb53
AM
2404 if (extract_symbol)
2405 return;
2406
2593f09a
NC
2407 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2408
0af11b59 2409 /* Core files do not need to be relocated. */
4dd67f29
MS
2410 if (bfd_get_format (obfd) == bfd_core)
2411 relsize = 0;
2412 else
ed570f48
NC
2413 {
2414 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
4dd67f29 2415
ed570f48
NC
2416 if (relsize < 0)
2417 {
2418 /* Do not complain if the target does not support relocations. */
2419 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2420 relsize = 0;
2421 else
2db6cde7
NS
2422 {
2423 status = 1;
2424 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2425 return;
2426 }
ed570f48
NC
2427 }
2428 }
57938635 2429
252b5132 2430 if (relsize == 0)
d3ba0551 2431 bfd_set_reloc (obfd, osection, NULL, 0);
252b5132
RH
2432 else
2433 {
d3ba0551 2434 relpp = xmalloc (relsize);
252b5132
RH
2435 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2436 if (relcount < 0)
2db6cde7
NS
2437 {
2438 status = 1;
2439 bfd_nonfatal_message (NULL, ibfd, isection,
2440 _("relocation count is negative"));
2441 return;
2442 }
57938635 2443
252b5132
RH
2444 if (strip_symbols == STRIP_ALL)
2445 {
2446 /* Remove relocations which are not in
0af11b59 2447 keep_strip_specific_list. */
252b5132
RH
2448 arelent **temp_relpp;
2449 long temp_relcount = 0;
2450 long i;
57938635 2451
d3ba0551 2452 temp_relpp = xmalloc (relsize);
252b5132 2453 for (i = 0; i < relcount; i++)
d3ba0551 2454 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
047c9024 2455 keep_specific_htab))
252b5132
RH
2456 temp_relpp [temp_relcount++] = relpp [i];
2457 relcount = temp_relcount;
2458 free (relpp);
2459 relpp = temp_relpp;
2460 }
e0c60db2 2461
d3ba0551 2462 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
f0312d39
JJ
2463 if (relcount == 0)
2464 free (relpp);
252b5132 2465 }
57938635 2466
0af11b59 2467 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
4dd67f29 2468 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
252b5132 2469 {
d3ba0551 2470 void *memhunk = xmalloc (size);
252b5132 2471
d3ba0551 2472 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2db6cde7
NS
2473 {
2474 status = 1;
2475 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2476 return;
2477 }
252b5132 2478
9e48b4c6
NC
2479 if (reverse_bytes)
2480 {
2481 /* We don't handle leftover bytes (too many possible behaviors,
2482 and we don't know what the user wants). The section length
2483 must be a multiple of the number of bytes to swap. */
2484 if ((size % reverse_bytes) == 0)
2485 {
2486 unsigned long i, j;
2487 bfd_byte b;
2488
2489 for (i = 0; i < size; i += reverse_bytes)
2490 for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2491 {
2492 bfd_byte *m = (bfd_byte *) memhunk;
2493
2494 b = m[i + j];
2495 m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2496 m[(i + reverse_bytes) - (j + 1)] = b;
2497 }
2498 }
2499 else
2500 /* User must pad the section up in order to do this. */
2501 fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2502 bfd_section_name (ibfd, isection), reverse_bytes);
2503 }
2504
57938635 2505 if (copy_byte >= 0)
5e675b72
AM
2506 {
2507 /* Keep only every `copy_byte'th byte in MEMHUNK. */
2f01ffbf 2508 char *from = (char *) memhunk + copy_byte;
5e675b72 2509 char *to = memhunk;
2f01ffbf 2510 char *end = (char *) memhunk + size;
5e675b72
AM
2511
2512 for (; from < end; from += interleave)
2513 *to++ = *from;
2514
2515 size = (size + interleave - 1 - copy_byte) / interleave;
2516 osection->lma /= interleave;
2517 }
252b5132 2518
d3ba0551 2519 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2db6cde7
NS
2520 {
2521 status = 1;
2522 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2523 return;
2524 }
252b5132
RH
2525 free (memhunk);
2526 }
2527 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2528 {
d3ba0551 2529 void *memhunk = xmalloc (size);
252b5132
RH
2530
2531 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2532 flag--they can just remove the section entirely and add it
2533 back again. However, we do permit them to turn on the
2534 SEC_HAS_CONTENTS flag, and take it to mean that the section
2535 contents should be zeroed out. */
2536
2537 memset (memhunk, 0, size);
d3ba0551 2538 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2db6cde7
NS
2539 {
2540 status = 1;
2541 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2542 return;
2543 }
252b5132
RH
2544 free (memhunk);
2545 }
2546}
2547
2548/* Get all the sections. This is used when --gap-fill or --pad-to is
2549 used. */
2550
2551static void
84e2f313 2552get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
252b5132 2553{
d3ba0551 2554 asection ***secppp = secppparg;
252b5132
RH
2555
2556 **secppp = osection;
2557 ++(*secppp);
2558}
2559
2560/* Sort sections by VMA. This is called via qsort, and is used when
2561 --gap-fill or --pad-to is used. We force non loadable or empty
2562 sections to the front, where they are easier to ignore. */
2563
2564static int
84e2f313 2565compare_section_lma (const void *arg1, const void *arg2)
252b5132 2566{
d3ba0551
AM
2567 const asection *const *sec1 = arg1;
2568 const asection *const *sec2 = arg2;
252b5132
RH
2569 flagword flags1, flags2;
2570
2571 /* Sort non loadable sections to the front. */
2572 flags1 = (*sec1)->flags;
2573 flags2 = (*sec2)->flags;
2574 if ((flags1 & SEC_HAS_CONTENTS) == 0
2575 || (flags1 & SEC_LOAD) == 0)
2576 {
2577 if ((flags2 & SEC_HAS_CONTENTS) != 0
2578 && (flags2 & SEC_LOAD) != 0)
2579 return -1;
2580 }
2581 else
2582 {
2583 if ((flags2 & SEC_HAS_CONTENTS) == 0
2584 || (flags2 & SEC_LOAD) == 0)
2585 return 1;
2586 }
2587
2588 /* Sort sections by LMA. */
2589 if ((*sec1)->lma > (*sec2)->lma)
2590 return 1;
2591 else if ((*sec1)->lma < (*sec2)->lma)
2592 return -1;
2593
2594 /* Sort sections with the same LMA by size. */
135dfb4a 2595 if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
252b5132 2596 return 1;
135dfb4a 2597 else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
252b5132
RH
2598 return -1;
2599
2600 return 0;
2601}
2602
2603/* Mark all the symbols which will be used in output relocations with
2604 the BSF_KEEP flag so that those symbols will not be stripped.
2605
2606 Ignore relocations which will not appear in the output file. */
2607
2608static void
84e2f313 2609mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
252b5132 2610{
d3ba0551 2611 asymbol **symbols = symbolsarg;
252b5132
RH
2612 long relsize;
2613 arelent **relpp;
2614 long relcount, i;
2615
2616 /* Ignore an input section with no corresponding output section. */
2617 if (isection->output_section == NULL)
2618 return;
2619
2620 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2621 if (relsize < 0)
ed570f48
NC
2622 {
2623 /* Do not complain if the target does not support relocations. */
2624 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2625 return;
2626 bfd_fatal (bfd_get_filename (ibfd));
2627 }
252b5132
RH
2628
2629 if (relsize == 0)
2630 return;
2631
d3ba0551 2632 relpp = xmalloc (relsize);
252b5132
RH
2633 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2634 if (relcount < 0)
2635 bfd_fatal (bfd_get_filename (ibfd));
2636
ec5d57d5
NC
2637 /* Examine each symbol used in a relocation. If it's not one of the
2638 special bfd section symbols, then mark it with BSF_KEEP. */
252b5132
RH
2639 for (i = 0; i < relcount; i++)
2640 {
ec5d57d5
NC
2641 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2642 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2643 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2644 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
252b5132
RH
2645 }
2646
2647 if (relpp != NULL)
2648 free (relpp);
2649}
2650
2651/* Write out debugging information. */
2652
b34976b6 2653static bfd_boolean
84e2f313
NC
2654write_debugging_info (bfd *obfd, void *dhandle,
2655 long *symcountp ATTRIBUTE_UNUSED,
2656 asymbol ***symppp ATTRIBUTE_UNUSED)
252b5132
RH
2657{
2658 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2659 return write_ieee_debugging_info (obfd, dhandle);
2660
2661 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2662 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2663 {
2664 bfd_byte *syms, *strings;
2665 bfd_size_type symsize, stringsize;
2666 asection *stabsec, *stabstrsec;
551b43fd 2667 flagword flags;
252b5132
RH
2668
2669 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2670 &symsize, &strings,
2671 &stringsize))
b34976b6 2672 return FALSE;
252b5132 2673
551b43fd
AM
2674 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2675 stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2676 stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
252b5132
RH
2677 if (stabsec == NULL
2678 || stabstrsec == NULL
2679 || ! bfd_set_section_size (obfd, stabsec, symsize)
2680 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2681 || ! bfd_set_section_alignment (obfd, stabsec, 2)
551b43fd 2682 || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
252b5132 2683 {
2db6cde7
NS
2684 bfd_nonfatal_message (NULL, obfd, NULL,
2685 _("can't create debugging section"));
b34976b6 2686 return FALSE;
252b5132
RH
2687 }
2688
2689 /* We can get away with setting the section contents now because
2690 the next thing the caller is going to do is copy over the
2691 real sections. We may someday have to split the contents
2692 setting out of this function. */
d3ba0551
AM
2693 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2694 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2695 stringsize))
252b5132 2696 {
2db6cde7
NS
2697 bfd_nonfatal_message (NULL, obfd, NULL,
2698 _("can't set debugging section contents"));
b34976b6 2699 return FALSE;
252b5132
RH
2700 }
2701
b34976b6 2702 return TRUE;
252b5132
RH
2703 }
2704
2db6cde7
NS
2705 bfd_nonfatal_message (NULL, obfd, NULL,
2706 _("don't know how to write debugging information for %s"),
2707 bfd_get_target (obfd));
b34976b6 2708 return FALSE;
252b5132
RH
2709}
2710
2711static int
84e2f313 2712strip_main (int argc, char *argv[])
252b5132 2713{
7c29036b
NC
2714 char *input_target = NULL;
2715 char *output_target = NULL;
b34976b6 2716 bfd_boolean show_version = FALSE;
7c29036b
NC
2717 bfd_boolean formats_info = FALSE;
2718 int c;
2719 int i;
252b5132
RH
2720 struct section_list *p;
2721 char *output_file = NULL;
2722
5fe11841 2723 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
252b5132
RH
2724 strip_options, (int *) 0)) != EOF)
2725 {
2726 switch (c)
2727 {
2728 case 'I':
2729 input_target = optarg;
2730 break;
2731 case 'O':
2732 output_target = optarg;
2733 break;
2734 case 'F':
2735 input_target = output_target = optarg;
2736 break;
2737 case 'R':
b34976b6
AM
2738 p = find_section_list (optarg, TRUE);
2739 p->remove = TRUE;
2740 sections_removed = TRUE;
252b5132
RH
2741 break;
2742 case 's':
2743 strip_symbols = STRIP_ALL;
2744 break;
2745 case 'S':
2746 case 'g':
db4f6831 2747 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
252b5132
RH
2748 strip_symbols = STRIP_DEBUG;
2749 break;
2750 case OPTION_STRIP_UNNEEDED:
2751 strip_symbols = STRIP_UNNEEDED;
2752 break;
2753 case 'K':
047c9024 2754 add_specific_symbol (optarg, keep_specific_htab);
252b5132
RH
2755 break;
2756 case 'N':
047c9024 2757 add_specific_symbol (optarg, strip_specific_htab);
252b5132
RH
2758 break;
2759 case 'o':
2760 output_file = optarg;
2761 break;
2762 case 'p':
b34976b6 2763 preserve_dates = TRUE;
252b5132
RH
2764 break;
2765 case 'x':
2766 discard_locals = LOCALS_ALL;
2767 break;
2768 case 'X':
2769 discard_locals = LOCALS_START_L;
2770 break;
2771 case 'v':
b34976b6 2772 verbose = TRUE;
252b5132
RH
2773 break;
2774 case 'V':
b34976b6 2775 show_version = TRUE;
252b5132 2776 break;
7c29036b
NC
2777 case OPTION_FORMATS_INFO:
2778 formats_info = TRUE;
2779 break;
ed1653a7
NC
2780 case OPTION_ONLY_KEEP_DEBUG:
2781 strip_symbols = STRIP_NONDEBUG;
2782 break;
1637cd90
JB
2783 case OPTION_KEEP_FILE_SYMBOLS:
2784 keep_file_symbols = 1;
2785 break;
252b5132 2786 case 0:
594ef5db
NC
2787 /* We've been given a long option. */
2788 break;
5fe11841
NC
2789 case 'w':
2790 wildcard = TRUE;
2791 break;
8b53311e 2792 case 'H':
252b5132
RH
2793 case 'h':
2794 strip_usage (stdout, 0);
2795 default:
2796 strip_usage (stderr, 1);
2797 }
2798 }
2799
84e2f313
NC
2800 if (formats_info)
2801 {
2802 display_info ();
2803 return 0;
2804 }
c1c0eb9e 2805
252b5132
RH
2806 if (show_version)
2807 print_version ("strip");
2808
2809 /* Default is to strip all symbols. */
2810 if (strip_symbols == STRIP_UNDEF
2811 && discard_locals == LOCALS_UNDEF
047c9024 2812 && htab_elements (strip_specific_htab) == 0)
252b5132
RH
2813 strip_symbols = STRIP_ALL;
2814
d3ba0551 2815 if (output_target == NULL)
252b5132
RH
2816 output_target = input_target;
2817
2818 i = optind;
2819 if (i == argc
2820 || (output_file != NULL && (i + 1) < argc))
2821 strip_usage (stderr, 1);
2822
2823 for (; i < argc; i++)
2824 {
2825 int hold_status = status;
2826 struct stat statbuf;
2827 char *tmpname;
2828
f24ddbdd 2829 if (get_file_size (argv[i]) < 1)
d68c385b
NC
2830 {
2831 status = 1;
2832 continue;
2833 }
f24ddbdd 2834
252b5132 2835 if (preserve_dates)
f24ddbdd
NC
2836 /* No need to check the return value of stat().
2837 It has already been checked in get_file_size(). */
2838 stat (argv[i], &statbuf);
252b5132 2839
12f498a7 2840 if (output_file == NULL || strcmp (argv[i], output_file) == 0)
252b5132 2841 tmpname = make_tempname (argv[i]);
12f498a7
NS
2842 else
2843 tmpname = output_file;
252b5132 2844
f9c026a8
NC
2845 if (tmpname == NULL)
2846 {
2db6cde7
NS
2847 bfd_nonfatal_message (argv[i], NULL, NULL,
2848 _("could not create temporary file to hold stripped copy"));
f9c026a8
NC
2849 status = 1;
2850 continue;
2851 }
2852
d68c385b 2853 status = 0;
252b5132
RH
2854 copy_file (argv[i], tmpname, input_target, output_target);
2855 if (status == 0)
2856 {
2857 if (preserve_dates)
2858 set_times (tmpname, &statbuf);
12f498a7
NS
2859 if (output_file != tmpname)
2860 smart_rename (tmpname, output_file ? output_file : argv[i],
2861 preserve_dates);
252b5132
RH
2862 status = hold_status;
2863 }
2864 else
bb14f524 2865 unlink_if_ordinary (tmpname);
12f498a7 2866 if (output_file != tmpname)
252b5132
RH
2867 free (tmpname);
2868 }
2869
d68c385b 2870 return status;
252b5132
RH
2871}
2872
2873static int
84e2f313 2874copy_main (int argc, char *argv[])
252b5132 2875{
43a0748c 2876 char * binary_architecture = NULL;
7c29036b
NC
2877 char *input_filename = NULL;
2878 char *output_filename = NULL;
c1c0eb9e 2879 char *tmpname;
7c29036b
NC
2880 char *input_target = NULL;
2881 char *output_target = NULL;
b34976b6
AM
2882 bfd_boolean show_version = FALSE;
2883 bfd_boolean change_warn = TRUE;
7c29036b 2884 bfd_boolean formats_info = FALSE;
252b5132
RH
2885 int c;
2886 struct section_list *p;
2887 struct stat statbuf;
2888
5fe11841 2889 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
252b5132
RH
2890 copy_options, (int *) 0)) != EOF)
2891 {
2892 switch (c)
2893 {
2894 case 'b':
2895 copy_byte = atoi (optarg);
2896 if (copy_byte < 0)
2897 fatal (_("byte number must be non-negative"));
2898 break;
57938635 2899
0af11b59
KH
2900 case 'B':
2901 binary_architecture = optarg;
2902 break;
43a0748c 2903
252b5132
RH
2904 case 'i':
2905 interleave = atoi (optarg);
2906 if (interleave < 1)
2907 fatal (_("interleave must be positive"));
2908 break;
57938635 2909
252b5132
RH
2910 case 'I':
2911 case 's': /* "source" - 'I' is preferred */
2912 input_target = optarg;
2913 break;
57938635 2914
252b5132
RH
2915 case 'O':
2916 case 'd': /* "destination" - 'O' is preferred */
2917 output_target = optarg;
2918 break;
57938635 2919
252b5132
RH
2920 case 'F':
2921 input_target = output_target = optarg;
2922 break;
57938635 2923
f91ea849 2924 case 'j':
b34976b6 2925 p = find_section_list (optarg, TRUE);
f91ea849
ILT
2926 if (p->remove)
2927 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
2928 p->copy = TRUE;
2929 sections_copied = TRUE;
f91ea849 2930 break;
57938635 2931
252b5132 2932 case 'R':
b34976b6 2933 p = find_section_list (optarg, TRUE);
f91ea849
ILT
2934 if (p->copy)
2935 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
2936 p->remove = TRUE;
2937 sections_removed = TRUE;
252b5132 2938 break;
57938635 2939
252b5132
RH
2940 case 'S':
2941 strip_symbols = STRIP_ALL;
2942 break;
57938635 2943
252b5132
RH
2944 case 'g':
2945 strip_symbols = STRIP_DEBUG;
2946 break;
57938635 2947
252b5132
RH
2948 case OPTION_STRIP_UNNEEDED:
2949 strip_symbols = STRIP_UNNEEDED;
2950 break;
57938635 2951
ed1653a7
NC
2952 case OPTION_ONLY_KEEP_DEBUG:
2953 strip_symbols = STRIP_NONDEBUG;
2954 break;
2955
1637cd90
JB
2956 case OPTION_KEEP_FILE_SYMBOLS:
2957 keep_file_symbols = 1;
2958 break;
2959
2593f09a
NC
2960 case OPTION_ADD_GNU_DEBUGLINK:
2961 gnu_debuglink_filename = optarg;
2962 break;
2963
252b5132 2964 case 'K':
047c9024 2965 add_specific_symbol (optarg, keep_specific_htab);
252b5132 2966 break;
57938635 2967
252b5132 2968 case 'N':
047c9024 2969 add_specific_symbol (optarg, strip_specific_htab);
252b5132 2970 break;
57938635 2971
bcf32829 2972 case OPTION_STRIP_UNNEEDED_SYMBOL:
047c9024 2973 add_specific_symbol (optarg, strip_unneeded_htab);
bcf32829
JB
2974 break;
2975
252b5132 2976 case 'L':
047c9024 2977 add_specific_symbol (optarg, localize_specific_htab);
252b5132 2978 break;
57938635 2979
7b4a0685 2980 case OPTION_GLOBALIZE_SYMBOL:
047c9024 2981 add_specific_symbol (optarg, globalize_specific_htab);
7b4a0685
NC
2982 break;
2983
16b2b71c 2984 case 'G':
047c9024 2985 add_specific_symbol (optarg, keepglobal_specific_htab);
16b2b71c
NC
2986 break;
2987
252b5132 2988 case 'W':
047c9024 2989 add_specific_symbol (optarg, weaken_specific_htab);
252b5132 2990 break;
57938635 2991
252b5132 2992 case 'p':
b34976b6 2993 preserve_dates = TRUE;
252b5132 2994 break;
57938635 2995
5fe11841
NC
2996 case 'w':
2997 wildcard = TRUE;
2998 break;
2999
252b5132
RH
3000 case 'x':
3001 discard_locals = LOCALS_ALL;
3002 break;
57938635 3003
252b5132
RH
3004 case 'X':
3005 discard_locals = LOCALS_START_L;
3006 break;
57938635 3007
252b5132 3008 case 'v':
b34976b6 3009 verbose = TRUE;
252b5132 3010 break;
57938635 3011
252b5132 3012 case 'V':
b34976b6 3013 show_version = TRUE;
252b5132 3014 break;
57938635 3015
7c29036b
NC
3016 case OPTION_FORMATS_INFO:
3017 formats_info = TRUE;
3018 break;
3019
252b5132 3020 case OPTION_WEAKEN:
b34976b6 3021 weaken = TRUE;
252b5132 3022 break;
57938635 3023
252b5132
RH
3024 case OPTION_ADD_SECTION:
3025 {
3026 const char *s;
f24ddbdd 3027 off_t size;
252b5132
RH
3028 struct section_add *pa;
3029 int len;
3030 char *name;
3031 FILE *f;
3032
3033 s = strchr (optarg, '=');
57938635 3034
252b5132 3035 if (s == NULL)
57938635 3036 fatal (_("bad format for %s"), "--add-section");
252b5132 3037
f24ddbdd
NC
3038 size = get_file_size (s + 1);
3039 if (size < 1)
d68c385b
NC
3040 {
3041 status = 1;
3042 break;
3043 }
252b5132 3044
d3ba0551 3045 pa = xmalloc (sizeof (struct section_add));
252b5132
RH
3046
3047 len = s - optarg;
d3ba0551 3048 name = xmalloc (len + 1);
252b5132
RH
3049 strncpy (name, optarg, len);
3050 name[len] = '\0';
3051 pa->name = name;
3052
3053 pa->filename = s + 1;
f24ddbdd
NC
3054 pa->size = size;
3055 pa->contents = xmalloc (size);
252b5132 3056
252b5132 3057 f = fopen (pa->filename, FOPEN_RB);
57938635 3058
252b5132 3059 if (f == NULL)
84e2f313
NC
3060 fatal (_("cannot open: %s: %s"),
3061 pa->filename, strerror (errno));
57938635 3062
252b5132
RH
3063 if (fread (pa->contents, 1, pa->size, f) == 0
3064 || ferror (f))
3065 fatal (_("%s: fread failed"), pa->filename);
3066
3067 fclose (f);
3068
3069 pa->next = add_sections;
3070 add_sections = pa;
3071 }
3072 break;
57938635 3073
252b5132
RH
3074 case OPTION_CHANGE_START:
3075 change_start = parse_vma (optarg, "--change-start");
3076 break;
57938635 3077
252b5132
RH
3078 case OPTION_CHANGE_SECTION_ADDRESS:
3079 case OPTION_CHANGE_SECTION_LMA:
3080 case OPTION_CHANGE_SECTION_VMA:
3081 {
3082 const char *s;
3083 int len;
3084 char *name;
b4c96d0d 3085 char *option = NULL;
252b5132 3086 bfd_vma val;
b4c96d0d 3087 enum change_action what = CHANGE_IGNORE;
57938635 3088
252b5132
RH
3089 switch (c)
3090 {
b4c96d0d
ILT
3091 case OPTION_CHANGE_SECTION_ADDRESS:
3092 option = "--change-section-address";
3093 break;
3094 case OPTION_CHANGE_SECTION_LMA:
3095 option = "--change-section-lma";
3096 break;
3097 case OPTION_CHANGE_SECTION_VMA:
3098 option = "--change-section-vma";
3099 break;
252b5132 3100 }
57938635 3101
252b5132
RH
3102 s = strchr (optarg, '=');
3103 if (s == NULL)
3104 {
3105 s = strchr (optarg, '+');
3106 if (s == NULL)
3107 {
3108 s = strchr (optarg, '-');
3109 if (s == NULL)
3110 fatal (_("bad format for %s"), option);
3111 }
3112 }
3113
3114 len = s - optarg;
d3ba0551 3115 name = xmalloc (len + 1);
252b5132
RH
3116 strncpy (name, optarg, len);
3117 name[len] = '\0';
3118
b34976b6 3119 p = find_section_list (name, TRUE);
252b5132
RH
3120
3121 val = parse_vma (s + 1, option);
3122
3123 switch (*s)
3124 {
3125 case '=': what = CHANGE_SET; break;
3126 case '-': val = - val; /* Drop through. */
3127 case '+': what = CHANGE_MODIFY; break;
3128 }
57938635 3129
252b5132
RH
3130 switch (c)
3131 {
3132 case OPTION_CHANGE_SECTION_ADDRESS:
3133 p->change_vma = what;
3134 p->vma_val = val;
3135 /* Drop through. */
57938635 3136
252b5132
RH
3137 case OPTION_CHANGE_SECTION_LMA:
3138 p->change_lma = what;
3139 p->lma_val = val;
3140 break;
57938635 3141
252b5132
RH
3142 case OPTION_CHANGE_SECTION_VMA:
3143 p->change_vma = what;
3144 p->vma_val = val;
3145 break;
3146 }
3147 }
3148 break;
57938635 3149
252b5132
RH
3150 case OPTION_CHANGE_ADDRESSES:
3151 change_section_address = parse_vma (optarg, "--change-addresses");
3152 change_start = change_section_address;
3153 break;
57938635 3154
252b5132 3155 case OPTION_CHANGE_WARNINGS:
b34976b6 3156 change_warn = TRUE;
252b5132 3157 break;
57938635 3158
252b5132 3159 case OPTION_CHANGE_LEADING_CHAR:
b34976b6 3160 change_leading_char = TRUE;
252b5132 3161 break;
57938635 3162
252b5132 3163 case OPTION_DEBUGGING:
b34976b6 3164 convert_debugging = TRUE;
252b5132 3165 break;
57938635 3166
252b5132
RH
3167 case OPTION_GAP_FILL:
3168 {
3169 bfd_vma gap_fill_vma;
3170
3171 gap_fill_vma = parse_vma (optarg, "--gap-fill");
3172 gap_fill = (bfd_byte) gap_fill_vma;
3173 if ((bfd_vma) gap_fill != gap_fill_vma)
3174 {
3175 char buff[20];
57938635 3176
252b5132 3177 sprintf_vma (buff, gap_fill_vma);
57938635 3178
252b5132
RH
3179 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3180 buff, gap_fill);
3181 }
b34976b6 3182 gap_fill_set = TRUE;
252b5132
RH
3183 }
3184 break;
57938635 3185
252b5132 3186 case OPTION_NO_CHANGE_WARNINGS:
b34976b6 3187 change_warn = FALSE;
252b5132 3188 break;
57938635 3189
252b5132
RH
3190 case OPTION_PAD_TO:
3191 pad_to = parse_vma (optarg, "--pad-to");
b34976b6 3192 pad_to_set = TRUE;
252b5132 3193 break;
57938635 3194
252b5132 3195 case OPTION_REMOVE_LEADING_CHAR:
b34976b6 3196 remove_leading_char = TRUE;
252b5132 3197 break;
57938635
AM
3198
3199 case OPTION_REDEFINE_SYM:
3200 {
3201 /* Push this redefinition onto redefine_symbol_list. */
3202
3203 int len;
3204 const char *s;
3205 const char *nextarg;
3206 char *source, *target;
3207
3208 s = strchr (optarg, '=');
3209 if (s == NULL)
594ef5db 3210 fatal (_("bad format for %s"), "--redefine-sym");
57938635
AM
3211
3212 len = s - optarg;
d3ba0551 3213 source = xmalloc (len + 1);
57938635
AM
3214 strncpy (source, optarg, len);
3215 source[len] = '\0';
3216
3217 nextarg = s + 1;
3218 len = strlen (nextarg);
d3ba0551 3219 target = xmalloc (len + 1);
57938635
AM
3220 strcpy (target, nextarg);
3221
92991082 3222 redefine_list_append ("--redefine-sym", source, target);
57938635
AM
3223
3224 free (source);
3225 free (target);
3226 }
3227 break;
3228
92991082
JT
3229 case OPTION_REDEFINE_SYMS:
3230 add_redefine_syms_file (optarg);
3231 break;
3232
252b5132
RH
3233 case OPTION_SET_SECTION_FLAGS:
3234 {
3235 const char *s;
3236 int len;
3237 char *name;
3238
3239 s = strchr (optarg, '=');
3240 if (s == NULL)
57938635 3241 fatal (_("bad format for %s"), "--set-section-flags");
252b5132
RH
3242
3243 len = s - optarg;
d3ba0551 3244 name = xmalloc (len + 1);
252b5132
RH
3245 strncpy (name, optarg, len);
3246 name[len] = '\0';
3247
b34976b6 3248 p = find_section_list (name, TRUE);
252b5132 3249
b34976b6 3250 p->set_flags = TRUE;
252b5132
RH
3251 p->flags = parse_flags (s + 1);
3252 }
3253 break;
57938635 3254
594ef5db
NC
3255 case OPTION_RENAME_SECTION:
3256 {
3257 flagword flags;
3bcfb3e4
AM
3258 const char *eq, *fl;
3259 char *old_name;
3260 char *new_name;
594ef5db
NC
3261 unsigned int len;
3262
3bcfb3e4
AM
3263 eq = strchr (optarg, '=');
3264 if (eq == NULL)
594ef5db
NC
3265 fatal (_("bad format for %s"), "--rename-section");
3266
3bcfb3e4 3267 len = eq - optarg;
594ef5db 3268 if (len == 0)
3bcfb3e4 3269 fatal (_("bad format for %s"), "--rename-section");
594ef5db 3270
d3ba0551 3271 old_name = xmalloc (len + 1);
594ef5db
NC
3272 strncpy (old_name, optarg, len);
3273 old_name[len] = 0;
3274
3bcfb3e4
AM
3275 eq++;
3276 fl = strchr (eq, ',');
3277 if (fl)
594ef5db 3278 {
3bcfb3e4
AM
3279 flags = parse_flags (fl + 1);
3280 len = fl - eq;
594ef5db
NC
3281 }
3282 else
3283 {
594ef5db 3284 flags = -1;
3bcfb3e4 3285 len = strlen (eq);
594ef5db
NC
3286 }
3287
3bcfb3e4
AM
3288 if (len == 0)
3289 fatal (_("bad format for %s"), "--rename-section");
3290
d3ba0551 3291 new_name = xmalloc (len + 1);
3bcfb3e4
AM
3292 strncpy (new_name, eq, len);
3293 new_name[len] = 0;
3294
594ef5db
NC
3295 add_section_rename (old_name, new_name, flags);
3296 }
3297 break;
3298
252b5132
RH
3299 case OPTION_SET_START:
3300 set_start = parse_vma (optarg, "--set-start");
b34976b6 3301 set_start_set = TRUE;
252b5132 3302 break;
57938635 3303
0af11b59
KH
3304 case OPTION_SREC_LEN:
3305 Chunk = parse_vma (optarg, "--srec-len");
3306 break;
420496c1 3307
0af11b59 3308 case OPTION_SREC_FORCES3:
b34976b6 3309 S3Forced = TRUE;
0af11b59 3310 break;
420496c1 3311
16b2b71c 3312 case OPTION_STRIP_SYMBOLS:
047c9024 3313 add_specific_symbols (optarg, strip_specific_htab);
16b2b71c
NC
3314 break;
3315
bcf32829 3316 case OPTION_STRIP_UNNEEDED_SYMBOLS:
047c9024 3317 add_specific_symbols (optarg, strip_unneeded_htab);
bcf32829
JB
3318 break;
3319
16b2b71c 3320 case OPTION_KEEP_SYMBOLS:
047c9024 3321 add_specific_symbols (optarg, keep_specific_htab);
16b2b71c
NC
3322 break;
3323
d58c2e3a
RS
3324 case OPTION_LOCALIZE_HIDDEN:
3325 localize_hidden = TRUE;
3326 break;
3327
16b2b71c 3328 case OPTION_LOCALIZE_SYMBOLS:
047c9024 3329 add_specific_symbols (optarg, localize_specific_htab);
16b2b71c
NC
3330 break;
3331
7b4a0685 3332 case OPTION_GLOBALIZE_SYMBOLS:
047c9024 3333 add_specific_symbols (optarg, globalize_specific_htab);
7b4a0685
NC
3334 break;
3335
16b2b71c 3336 case OPTION_KEEPGLOBAL_SYMBOLS:
047c9024 3337 add_specific_symbols (optarg, keepglobal_specific_htab);
16b2b71c
NC
3338 break;
3339
3340 case OPTION_WEAKEN_SYMBOLS:
047c9024 3341 add_specific_symbols (optarg, weaken_specific_htab);
16b2b71c
NC
3342 break;
3343
1ae8b3d2 3344 case OPTION_ALT_MACH_CODE:
f9d4ad2a
NC
3345 use_alt_mach_code = strtoul (optarg, NULL, 0);
3346 if (use_alt_mach_code == 0)
3347 fatal (_("unable to parse alternative machine code"));
1ae8b3d2
AO
3348 break;
3349
d7fb0dd2
NC
3350 case OPTION_PREFIX_SYMBOLS:
3351 prefix_symbols_string = optarg;
3352 break;
3353
3354 case OPTION_PREFIX_SECTIONS:
3355 prefix_sections_string = optarg;
3356 break;
3357
3358 case OPTION_PREFIX_ALLOC_SECTIONS:
3359 prefix_alloc_sections_string = optarg;
3360 break;
3361
4087920c
MR
3362 case OPTION_READONLY_TEXT:
3363 bfd_flags_to_set |= WP_TEXT;
3364 bfd_flags_to_clear &= ~WP_TEXT;
3365 break;
3366
3367 case OPTION_WRITABLE_TEXT:
3368 bfd_flags_to_clear |= WP_TEXT;
3369 bfd_flags_to_set &= ~WP_TEXT;
3370 break;
3371
3372 case OPTION_PURE:
3373 bfd_flags_to_set |= D_PAGED;
3374 bfd_flags_to_clear &= ~D_PAGED;
3375 break;
3376
3377 case OPTION_IMPURE:
3378 bfd_flags_to_clear |= D_PAGED;
3379 bfd_flags_to_set &= ~D_PAGED;
3380 break;
3381
d3e52d40
RS
3382 case OPTION_EXTRACT_SYMBOL:
3383 extract_symbol = TRUE;
3384 break;
3385
9e48b4c6
NC
3386 case OPTION_REVERSE_BYTES:
3387 {
3388 int prev = reverse_bytes;
3389
3390 reverse_bytes = atoi (optarg);
3391 if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3392 fatal (_("number of bytes to reverse must be positive and even"));
3393
3394 if (prev && prev != reverse_bytes)
3395 non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3396 prev);
3397 break;
3398 }
3399
252b5132 3400 case 0:
2593f09a
NC
3401 /* We've been given a long option. */
3402 break;
57938635 3403
8b53311e 3404 case 'H':
252b5132
RH
3405 case 'h':
3406 copy_usage (stdout, 0);
57938635 3407
252b5132
RH
3408 default:
3409 copy_usage (stderr, 1);
3410 }
3411 }
3412
7c29036b
NC
3413 if (formats_info)
3414 {
3415 display_info ();
3416 return 0;
3417 }
c1c0eb9e 3418
252b5132
RH
3419 if (show_version)
3420 print_version ("objcopy");
3421
3422 if (copy_byte >= interleave)
3423 fatal (_("byte number must be less than interleave"));
3424
3425 if (optind == argc || optind + 2 < argc)
3426 copy_usage (stderr, 1);
3427
3428 input_filename = argv[optind];
3429 if (optind + 1 < argc)
3430 output_filename = argv[optind + 1];
3431
3432 /* Default is to strip no symbols. */
3433 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3434 strip_symbols = STRIP_NONE;
3435
d3ba0551 3436 if (output_target == NULL)
252b5132
RH
3437 output_target = input_target;
3438
d3ba0551 3439 if (binary_architecture != NULL)
252b5132 3440 {
43a0748c 3441 if (input_target && strcmp (input_target, "binary") == 0)
0af11b59
KH
3442 {
3443 const bfd_arch_info_type * temp_arch_info;
43a0748c
NC
3444
3445 temp_arch_info = bfd_scan_arch (binary_architecture);
3446
0af11b59 3447 if (temp_arch_info != NULL)
b749473b
NC
3448 {
3449 bfd_external_binary_architecture = temp_arch_info->arch;
3450 bfd_external_machine = temp_arch_info->mach;
3451 }
0af11b59
KH
3452 else
3453 fatal (_("architecture %s unknown"), binary_architecture);
3454 }
43a0748c
NC
3455 else
3456 {
3457 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
3458 non_fatal (_(" Argument %s ignored"), binary_architecture);
3459 }
252b5132
RH
3460 }
3461
43a0748c
NC
3462 if (preserve_dates)
3463 if (stat (input_filename, & statbuf) < 0)
f24ddbdd
NC
3464 fatal (_("warning: could not locate '%s'. System error message: %s"),
3465 input_filename, strerror (errno));
43a0748c 3466
0fcdcb91 3467 /* If there is no destination file, or the source and destination files
d3ba0551
AM
3468 are the same, then create a temp and rename the result into the input. */
3469 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
12f498a7 3470 tmpname = make_tempname (input_filename);
252b5132 3471 else
12f498a7 3472 tmpname = output_filename;
c1c0eb9e 3473
12f498a7
NS
3474 if (tmpname == NULL)
3475 fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3476 input_filename, strerror (errno));
594ef5db 3477
12f498a7
NS
3478 copy_file (input_filename, tmpname, input_target, output_target);
3479 if (status == 0)
3480 {
3481 if (preserve_dates)
3482 set_times (tmpname, &statbuf);
3483 if (tmpname != output_filename)
3484 smart_rename (tmpname, input_filename, preserve_dates);
252b5132 3485 }
12f498a7
NS
3486 else
3487 unlink_if_ordinary (tmpname);
252b5132
RH
3488
3489 if (change_warn)
3490 {
3491 for (p = change_sections; p != NULL; p = p->next)
3492 {
3493 if (! p->used)
3494 {
3495 if (p->change_vma != CHANGE_IGNORE)
3496 {
3497 char buff [20];
3498
3499 sprintf_vma (buff, p->vma_val);
57938635 3500
252b5132 3501 /* xgettext:c-format */
57938635
AM
3502 non_fatal (_("%s %s%c0x%s never used"),
3503 "--change-section-vma",
252b5132
RH
3504 p->name,
3505 p->change_vma == CHANGE_SET ? '=' : '+',
3506 buff);
3507 }
57938635 3508
252b5132
RH
3509 if (p->change_lma != CHANGE_IGNORE)
3510 {
3511 char buff [20];
3512
3513 sprintf_vma (buff, p->lma_val);
57938635 3514
252b5132 3515 /* xgettext:c-format */
57938635
AM
3516 non_fatal (_("%s %s%c0x%s never used"),
3517 "--change-section-lma",
252b5132
RH
3518 p->name,
3519 p->change_lma == CHANGE_SET ? '=' : '+',
3520 buff);
3521 }
3522 }
3523 }
3524 }
3525
3526 return 0;
3527}
3528
3529int
84e2f313 3530main (int argc, char *argv[])
252b5132
RH
3531{
3532#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3533 setlocale (LC_MESSAGES, "");
3882b010
L
3534#endif
3535#if defined (HAVE_SETLOCALE)
3536 setlocale (LC_CTYPE, "");
252b5132
RH
3537#endif
3538 bindtextdomain (PACKAGE, LOCALEDIR);
3539 textdomain (PACKAGE);
3540
3541 program_name = argv[0];
3542 xmalloc_set_program_name (program_name);
3543
3544 START_PROGRESS (program_name, 0);
3545
869b9d07
MM
3546 expandargv (&argc, &argv);
3547
252b5132
RH
3548 strip_symbols = STRIP_UNDEF;
3549 discard_locals = LOCALS_UNDEF;
3550
3551 bfd_init ();
3552 set_default_bfd_target ();
3553
3554 if (is_strip < 0)
3555 {
3556 int i = strlen (program_name);
5af11cab
AM
3557#ifdef HAVE_DOS_BASED_FILE_SYSTEM
3558 /* Drop the .exe suffix, if any. */
3559 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3560 {
3561 i -= 4;
3562 program_name[i] = '\0';
3563 }
3564#endif
3565 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
252b5132
RH
3566 }
3567
047c9024
NC
3568 create_symbol_htabs ();
3569
252b5132
RH
3570 if (is_strip)
3571 strip_main (argc, argv);
3572 else
3573 copy_main (argc, argv);
3574
3575 END_PROGRESS (program_name);
3576
3577 return status;
3578}