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