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