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