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