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