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