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