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