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