.
[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
5fe11841
NC
184/* Whether to permit wildcard in symbol comparasion. */
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)))
252b5132
RH
1141 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1142 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1143 bfd_get_mach (ibfd)));
57938635 1144
252b5132
RH
1145 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1146 RETURN_NONFATAL (bfd_get_filename (ibfd));
1147
1148 if (isympp)
1149 free (isympp);
57938635 1150
252b5132
RH
1151 if (osympp != isympp)
1152 free (osympp);
1153
1154 /* BFD mandates that all output sections be created and sizes set before
1155 any output is done. Thus, we traverse all sections multiple times. */
d3ba0551 1156 bfd_map_over_sections (ibfd, setup_section, obfd);
252b5132
RH
1157
1158 if (add_sections != NULL)
1159 {
1160 struct section_add *padd;
1161 struct section_list *pset;
1162
1163 for (padd = add_sections; padd != NULL; padd = padd->next)
1164 {
2593f09a
NC
1165 flagword flags;
1166
252b5132
RH
1167 padd->section = bfd_make_section (obfd, padd->name);
1168 if (padd->section == NULL)
1169 {
1170 non_fatal (_("can't create section `%s': %s"),
1171 padd->name, bfd_errmsg (bfd_get_error ()));
1172 status = 1;
1173 return;
1174 }
252b5132 1175
2593f09a
NC
1176 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1177 RETURN_NONFATAL (bfd_get_filename (obfd));
252b5132 1178
2593f09a
NC
1179 pset = find_section_list (padd->name, FALSE);
1180 if (pset != NULL)
1181 pset->used = TRUE;
57938635 1182
2593f09a
NC
1183 if (pset != NULL && pset->set_flags)
1184 flags = pset->flags | SEC_HAS_CONTENTS;
1185 else
1186 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
252b5132 1187
2593f09a
NC
1188 if (! bfd_set_section_flags (obfd, padd->section, flags))
1189 RETURN_NONFATAL (bfd_get_filename (obfd));
57938635 1190
2593f09a
NC
1191 if (pset != NULL)
1192 {
1193 if (pset->change_vma != CHANGE_IGNORE)
84e2f313
NC
1194 if (! bfd_set_section_vma (obfd, padd->section,
1195 pset->vma_val))
2593f09a 1196 RETURN_NONFATAL (bfd_get_filename (obfd));
57938635 1197
2593f09a
NC
1198 if (pset->change_lma != CHANGE_IGNORE)
1199 {
1200 padd->section->lma = pset->lma_val;
1201
1202 if (! bfd_set_section_alignment
1203 (obfd, padd->section,
1204 bfd_section_alignment (obfd, padd->section)))
1205 RETURN_NONFATAL (bfd_get_filename (obfd));
252b5132
RH
1206 }
1207 }
1208 }
1209 }
1210
2593f09a
NC
1211 if (gnu_debuglink_filename != NULL)
1212 {
84e2f313
NC
1213 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1214 (obfd, gnu_debuglink_filename);
e7c81c25
NC
1215
1216 if (gnu_debuglink_section == NULL)
2593f09a
NC
1217 RETURN_NONFATAL (gnu_debuglink_filename);
1218 }
1219
252b5132
RH
1220 if (gap_fill_set || pad_to_set)
1221 {
1222 asection **set;
1223 unsigned int c, i;
1224
1225 /* We must fill in gaps between the sections and/or we must pad
1226 the last section to a specified address. We do this by
1227 grabbing a list of the sections, sorting them by VMA, and
1228 increasing the section sizes as required to fill the gaps.
1229 We write out the gap contents below. */
1230
1231 c = bfd_count_sections (obfd);
d3ba0551 1232 osections = xmalloc (c * sizeof (asection *));
252b5132 1233 set = osections;
d3ba0551 1234 bfd_map_over_sections (obfd, get_sections, &set);
252b5132
RH
1235
1236 qsort (osections, c, sizeof (asection *), compare_section_lma);
1237
d3ba0551 1238 gaps = xmalloc (c * sizeof (bfd_size_type));
252b5132
RH
1239 memset (gaps, 0, c * sizeof (bfd_size_type));
1240
1241 if (gap_fill_set)
1242 {
1243 for (i = 0; i < c - 1; i++)
1244 {
1245 flagword flags;
1246 bfd_size_type size;
1247 bfd_vma gap_start, gap_stop;
1248
1249 flags = bfd_get_section_flags (obfd, osections[i]);
1250 if ((flags & SEC_HAS_CONTENTS) == 0
1251 || (flags & SEC_LOAD) == 0)
1252 continue;
1253
1254 size = bfd_section_size (obfd, osections[i]);
1255 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1256 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1257 if (gap_start < gap_stop)
1258 {
1259 if (! bfd_set_section_size (obfd, osections[i],
1260 size + (gap_stop - gap_start)))
1261 {
1262 non_fatal (_("Can't fill gap after %s: %s"),
0af11b59
KH
1263 bfd_get_section_name (obfd, osections[i]),
1264 bfd_errmsg (bfd_get_error ()));
252b5132
RH
1265 status = 1;
1266 break;
1267 }
1268 gaps[i] = gap_stop - gap_start;
1269 if (max_gap < gap_stop - gap_start)
1270 max_gap = gap_stop - gap_start;
1271 }
1272 }
1273 }
1274
1275 if (pad_to_set)
1276 {
1277 bfd_vma lma;
1278 bfd_size_type size;
1279
1280 lma = bfd_section_lma (obfd, osections[c - 1]);
1281 size = bfd_section_size (obfd, osections[c - 1]);
1282 if (lma + size < pad_to)
1283 {
1284 if (! bfd_set_section_size (obfd, osections[c - 1],
1285 pad_to - lma))
1286 {
1287 non_fatal (_("Can't add padding to %s: %s"),
0af11b59
KH
1288 bfd_get_section_name (obfd, osections[c - 1]),
1289 bfd_errmsg (bfd_get_error ()));
252b5132
RH
1290 status = 1;
1291 }
1292 else
1293 {
1294 gaps[c - 1] = pad_to - (lma + size);
1295 if (max_gap < pad_to - (lma + size))
1296 max_gap = pad_to - (lma + size);
1297 }
1298 }
1299 }
1300 }
1301
594ef5db
NC
1302 /* Symbol filtering must happen after the output sections
1303 have been created, but before their contents are set. */
252b5132
RH
1304 dhandle = NULL;
1305 symsize = bfd_get_symtab_upper_bound (ibfd);
1306 if (symsize < 0)
1307 RETURN_NONFATAL (bfd_get_filename (ibfd));
57938635 1308
d3ba0551 1309 osympp = isympp = xmalloc (symsize);
252b5132
RH
1310 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1311 if (symcount < 0)
1312 RETURN_NONFATAL (bfd_get_filename (ibfd));
57938635 1313
252b5132
RH
1314 if (convert_debugging)
1315 dhandle = read_debugging_info (ibfd, isympp, symcount);
57938635
AM
1316
1317 if (strip_symbols == STRIP_DEBUG
252b5132
RH
1318 || strip_symbols == STRIP_ALL
1319 || strip_symbols == STRIP_UNNEEDED
ed1653a7 1320 || strip_symbols == STRIP_NONDEBUG
252b5132
RH
1321 || discard_locals != LOCALS_UNDEF
1322 || strip_specific_list != NULL
1323 || keep_specific_list != NULL
1324 || localize_specific_list != NULL
16b2b71c 1325 || keepglobal_specific_list != NULL
252b5132 1326 || weaken_specific_list != NULL
d7fb0dd2 1327 || prefix_symbols_string
252b5132 1328 || sections_removed
f91ea849 1329 || sections_copied
252b5132
RH
1330 || convert_debugging
1331 || change_leading_char
1332 || remove_leading_char
57938635 1333 || redefine_sym_list
252b5132
RH
1334 || weaken)
1335 {
1336 /* Mark symbols used in output relocations so that they
1337 are kept, even if they are local labels or static symbols.
57938635 1338
252b5132
RH
1339 Note we iterate over the input sections examining their
1340 relocations since the relocations for the output sections
1341 haven't been set yet. mark_symbols_used_in_relocations will
1342 ignore input sections which have no corresponding output
1343 section. */
1344 if (strip_symbols != STRIP_ALL)
1345 bfd_map_over_sections (ibfd,
1346 mark_symbols_used_in_relocations,
d3ba0551
AM
1347 isympp);
1348 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
252b5132
RH
1349 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1350 }
1351
1352 if (convert_debugging && dhandle != NULL)
1353 {
1354 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1355 {
1356 status = 1;
1357 return;
1358 }
1359 }
1360
1361 bfd_set_symtab (obfd, osympp, symcount);
1362
1363 /* This has to happen after the symbol table has been set. */
d3ba0551 1364 bfd_map_over_sections (ibfd, copy_section, obfd);
252b5132
RH
1365
1366 if (add_sections != NULL)
1367 {
1368 struct section_add *padd;
1369
1370 for (padd = add_sections; padd != NULL; padd = padd->next)
1371 {
d3ba0551
AM
1372 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1373 0, padd->size))
252b5132
RH
1374 RETURN_NONFATAL (bfd_get_filename (obfd));
1375 }
1376 }
1377
e7c81c25
NC
1378 if (gnu_debuglink_filename != NULL)
1379 {
1380 if (! bfd_fill_in_gnu_debuglink_section
1381 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
84e2f313 1382 RETURN_NONFATAL (gnu_debuglink_filename);
e7c81c25
NC
1383 }
1384
252b5132
RH
1385 if (gap_fill_set || pad_to_set)
1386 {
1387 bfd_byte *buf;
1388 int c, i;
1389
1390 /* Fill in the gaps. */
252b5132
RH
1391 if (max_gap > 8192)
1392 max_gap = 8192;
d3ba0551
AM
1393 buf = xmalloc (max_gap);
1394 memset (buf, gap_fill, max_gap);
252b5132
RH
1395
1396 c = bfd_count_sections (obfd);
1397 for (i = 0; i < c; i++)
1398 {
1399 if (gaps[i] != 0)
1400 {
1401 bfd_size_type left;
1402 file_ptr off;
1403
1404 left = gaps[i];
1405 off = bfd_section_size (obfd, osections[i]) - left;
594ef5db 1406
252b5132
RH
1407 while (left > 0)
1408 {
1409 bfd_size_type now;
1410
1411 if (left > 8192)
1412 now = 8192;
1413 else
1414 now = left;
1415
1416 if (! bfd_set_section_contents (obfd, osections[i], buf,
1417 off, now))
1418 RETURN_NONFATAL (bfd_get_filename (obfd));
1419
1420 left -= now;
1421 off += now;
1422 }
1423 }
1424 }
1425 }
1426
1427 /* Allow the BFD backend to copy any private data it understands
1428 from the input BFD to the output BFD. This is done last to
1429 permit the routine to look at the filtered symbol table, which is
1430 important for the ECOFF code at least. */
ed1653a7
NC
1431 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1432 && strip_symbols == STRIP_NONDEBUG)
1433 /* Do not copy the private data when creating an ELF format
1434 debug info file. We do not want the program headers. */
1435 ;
1436 else if (! bfd_copy_private_bfd_data (ibfd, obfd))
252b5132
RH
1437 {
1438 non_fatal (_("%s: error copying private BFD data: %s"),
1439 bfd_get_filename (obfd),
1440 bfd_errmsg (bfd_get_error ()));
1441 status = 1;
1442 return;
1443 }
1ae8b3d2
AO
1444
1445 /* Switch to the alternate machine code. We have to do this at the
1446 very end, because we only initialize the header when we create
1447 the first section. */
1448 if (use_alt_mach_code != 0)
1449 {
1450 if (!bfd_alt_mach_code (obfd, use_alt_mach_code))
1451 non_fatal (_("unknown alternate machine code, ignored"));
1452 }
252b5132
RH
1453}
1454
4c168fa3
AM
1455#undef MKDIR
1456#if defined (_WIN32) && !defined (__CYGWIN32__)
1457#define MKDIR(DIR, MODE) mkdir (DIR)
1458#else
1459#define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1460#endif
1461
252b5132
RH
1462/* Read each archive element in turn from IBFD, copy the
1463 contents to temp file, and keep the temp file handle. */
1464
1465static void
84e2f313 1466copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
252b5132
RH
1467{
1468 struct name_list
1469 {
1470 struct name_list *next;
4c168fa3 1471 const char *name;
252b5132
RH
1472 bfd *obfd;
1473 } *list, *l;
1474 bfd **ptr = &obfd->archive_head;
1475 bfd *this_element;
1476 char *dir = make_tempname (bfd_get_filename (obfd));
1477
1478 /* Make a temp directory to hold the contents. */
4c168fa3 1479 if (MKDIR (dir, 0700) != 0)
84e2f313
NC
1480 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1481 dir, strerror (errno));
1482
252b5132
RH
1483 obfd->has_armap = ibfd->has_armap;
1484
1485 list = NULL;
1486
1487 this_element = bfd_openr_next_archived_file (ibfd, NULL);
594ef5db 1488
b667df2e
AM
1489 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1490 RETURN_NONFATAL (bfd_get_filename (obfd));
1491
d3ba0551 1492 while (!status && this_element != NULL)
252b5132 1493 {
4c168fa3
AM
1494 char *output_name;
1495 bfd *output_bfd;
252b5132 1496 bfd *last_element;
8066d1a2
AS
1497 struct stat buf;
1498 int stat_status = 0;
1499
4c168fa3
AM
1500 /* Create an output file for this member. */
1501 output_name = concat (dir, "/",
1502 bfd_get_filename (this_element), (char *) 0);
1503
1504 /* If the file already exists, make another temp dir. */
1505 if (stat (output_name, &buf) >= 0)
1506 {
1507 output_name = make_tempname (output_name);
1508 if (MKDIR (output_name, 0700) != 0)
84e2f313
NC
1509 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1510 output_name, strerror (errno));
1511
d3ba0551 1512 l = xmalloc (sizeof (struct name_list));
4c168fa3
AM
1513 l->name = output_name;
1514 l->next = list;
1515 l->obfd = NULL;
1516 list = l;
1517 output_name = concat (output_name, "/",
1518 bfd_get_filename (this_element), (char *) 0);
1519 }
1520
1521 output_bfd = bfd_openw (output_name, output_target);
8066d1a2
AS
1522 if (preserve_dates)
1523 {
1524 stat_status = bfd_stat_arch_elt (this_element, &buf);
594ef5db 1525
8066d1a2
AS
1526 if (stat_status != 0)
1527 non_fatal (_("internal stat error on %s"),
1528 bfd_get_filename (this_element));
1529 }
252b5132 1530
d3ba0551 1531 l = xmalloc (sizeof (struct name_list));
252b5132
RH
1532 l->name = output_name;
1533 l->next = list;
1534 list = l;
1535
d3ba0551 1536 if (output_bfd == NULL)
252b5132
RH
1537 RETURN_NONFATAL (output_name);
1538
b34976b6 1539 if (bfd_check_format (this_element, bfd_object))
252b5132
RH
1540 copy_object (this_element, output_bfd);
1541
1542 if (!bfd_close (output_bfd))
1543 {
1544 bfd_nonfatal (bfd_get_filename (output_bfd));
0af11b59 1545 /* Error in new object file. Don't change archive. */
252b5132
RH
1546 status = 1;
1547 }
1548
8066d1a2
AS
1549 if (preserve_dates && stat_status == 0)
1550 set_times (output_name, &buf);
1551
252b5132
RH
1552 /* Open the newly output file and attach to our list. */
1553 output_bfd = bfd_openr (output_name, output_target);
1554
1555 l->obfd = output_bfd;
1556
1557 *ptr = output_bfd;
1558 ptr = &output_bfd->next;
1559
1560 last_element = this_element;
1561
1562 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1563
1564 bfd_close (last_element);
1565 }
d3ba0551 1566 *ptr = NULL;
252b5132
RH
1567
1568 if (!bfd_close (obfd))
1569 RETURN_NONFATAL (bfd_get_filename (obfd));
1570
1571 if (!bfd_close (ibfd))
1572 RETURN_NONFATAL (bfd_get_filename (ibfd));
1573
1574 /* Delete all the files that we opened. */
1575 for (l = list; l != NULL; l = l->next)
1576 {
4c168fa3
AM
1577 if (l->obfd == NULL)
1578 rmdir (l->name);
1579 else
1580 {
1581 bfd_close (l->obfd);
1582 unlink (l->name);
1583 }
252b5132
RH
1584 }
1585 rmdir (dir);
1586}
1587
1588/* The top-level control. */
1589
1590static void
84e2f313
NC
1591copy_file (const char *input_filename, const char *output_filename,
1592 const char *input_target, const char *output_target)
252b5132
RH
1593{
1594 bfd *ibfd;
49c12576
AM
1595 char **obj_matching;
1596 char **core_matching;
252b5132 1597
f24ddbdd
NC
1598 if (get_file_size (input_filename) < 1)
1599 {
1600 status = 1;
1601 return;
1602 }
1603
252b5132
RH
1604 /* To allow us to do "strip *" without dying on the first
1605 non-object file, failures are nonfatal. */
252b5132
RH
1606 ibfd = bfd_openr (input_filename, input_target);
1607 if (ibfd == NULL)
1608 RETURN_NONFATAL (input_filename);
1609
1610 if (bfd_check_format (ibfd, bfd_archive))
1611 {
1612 bfd *obfd;
1613
1614 /* bfd_get_target does not return the correct value until
1615 bfd_check_format succeeds. */
1616 if (output_target == NULL)
1617 output_target = bfd_get_target (ibfd);
1618
1619 obfd = bfd_openw (output_filename, output_target);
1620 if (obfd == NULL)
1621 RETURN_NONFATAL (output_filename);
1622
1623 copy_archive (ibfd, obfd, output_target);
1624 }
49c12576 1625 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
252b5132
RH
1626 {
1627 bfd *obfd;
49c12576 1628 do_copy:
252b5132
RH
1629 /* bfd_get_target does not return the correct value until
1630 bfd_check_format succeeds. */
1631 if (output_target == NULL)
1632 output_target = bfd_get_target (ibfd);
1633
1634 obfd = bfd_openw (output_filename, output_target);
1635 if (obfd == NULL)
1636 RETURN_NONFATAL (output_filename);
1637
1638 copy_object (ibfd, obfd);
1639
1640 if (!bfd_close (obfd))
1641 RETURN_NONFATAL (output_filename);
1642
1643 if (!bfd_close (ibfd))
1644 RETURN_NONFATAL (input_filename);
1645 }
1646 else
1647 {
49c12576
AM
1648 bfd_error_type obj_error = bfd_get_error ();
1649 bfd_error_type core_error;
b34976b6 1650
49c12576
AM
1651 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
1652 {
1653 /* This probably can't happen.. */
1654 if (obj_error == bfd_error_file_ambiguously_recognized)
1655 free (obj_matching);
1656 goto do_copy;
1657 }
1658
1659 core_error = bfd_get_error ();
1660 /* Report the object error in preference to the core error. */
1661 if (obj_error != core_error)
1662 bfd_set_error (obj_error);
1663
252b5132 1664 bfd_nonfatal (input_filename);
57938635 1665
49c12576
AM
1666 if (obj_error == bfd_error_file_ambiguously_recognized)
1667 {
1668 list_matching_formats (obj_matching);
1669 free (obj_matching);
1670 }
1671 if (core_error == bfd_error_file_ambiguously_recognized)
252b5132 1672 {
49c12576
AM
1673 list_matching_formats (core_matching);
1674 free (core_matching);
252b5132 1675 }
57938635 1676
252b5132
RH
1677 status = 1;
1678 }
1679}
1680
594ef5db
NC
1681/* Add a name to the section renaming list. */
1682
1683static void
84e2f313
NC
1684add_section_rename (const char * old_name, const char * new_name,
1685 flagword flags)
594ef5db
NC
1686{
1687 section_rename * rename;
1688
1689 /* Check for conflicts first. */
1690 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1691 if (strcmp (rename->old_name, old_name) == 0)
1692 {
1693 /* Silently ignore duplicate definitions. */
1694 if (strcmp (rename->new_name, new_name) == 0
1695 && rename->flags == flags)
1696 return;
0af11b59 1697
594ef5db
NC
1698 fatal (_("Multiple renames of section %s"), old_name);
1699 }
1700
d3ba0551 1701 rename = xmalloc (sizeof (* rename));
594ef5db
NC
1702
1703 rename->old_name = old_name;
1704 rename->new_name = new_name;
1705 rename->flags = flags;
1706 rename->next = section_rename_list;
0af11b59 1707
594ef5db
NC
1708 section_rename_list = rename;
1709}
1710
1711/* Check the section rename list for a new name of the input section
1712 ISECTION. Return the new name if one is found.
1713 Also set RETURNED_FLAGS to the flags to be used for this section. */
1714
1715static const char *
84e2f313
NC
1716find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
1717 flagword * returned_flags)
594ef5db
NC
1718{
1719 const char * old_name = bfd_section_name (ibfd, isection);
1720 section_rename * rename;
1721
1722 /* Default to using the flags of the input section. */
1723 * returned_flags = bfd_get_section_flags (ibfd, isection);
1724
1725 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1726 if (strcmp (rename->old_name, old_name) == 0)
1727 {
1728 if (rename->flags != (flagword) -1)
1729 * returned_flags = rename->flags;
1730
1731 return rename->new_name;
1732 }
1733
1734 return old_name;
1735}
1736
1737/* Create a section in OBFD with the same
1738 name and attributes as ISECTION in IBFD. */
252b5132
RH
1739
1740static void
84e2f313 1741setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 1742{
d3ba0551 1743 bfd *obfd = obfdarg;
252b5132
RH
1744 struct section_list *p;
1745 sec_ptr osection;
1746 bfd_size_type size;
1747 bfd_vma vma;
1748 bfd_vma lma;
1749 flagword flags;
1a89cc7d 1750 const char *err;
594ef5db 1751 const char * name;
d7fb0dd2 1752 char *prefix = NULL;
0af11b59 1753
2593f09a 1754 if (is_strip_section (ibfd, isection))
252b5132
RH
1755 return;
1756
b34976b6 1757 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
252b5132 1758 if (p != NULL)
b34976b6 1759 p->used = TRUE;
252b5132 1760
594ef5db
NC
1761 /* Get the, possibly new, name of the output section. */
1762 name = find_section_rename (ibfd, isection, & flags);
0af11b59 1763
d7fb0dd2 1764 /* Prefix sections. */
84e2f313
NC
1765 if ((prefix_alloc_sections_string)
1766 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
d7fb0dd2
NC
1767 prefix = prefix_alloc_sections_string;
1768 else if (prefix_sections_string)
1769 prefix = prefix_sections_string;
1770
1771 if (prefix)
1772 {
1773 char *n;
1774
1775 n = xmalloc (strlen (prefix) + strlen (name) + 1);
1776 strcpy (n, prefix);
1777 strcat (n, name);
1778 name = n;
1779 }
66491ebc 1780
594ef5db 1781 osection = bfd_make_section_anyway (obfd, name);
57938635 1782
252b5132
RH
1783 if (osection == NULL)
1784 {
1a89cc7d 1785 err = _("making");
252b5132
RH
1786 goto loser;
1787 }
1788
1789 size = bfd_section_size (ibfd, isection);
1790 if (copy_byte >= 0)
1791 size = (size + interleave - 1) / interleave;
1792 if (! bfd_set_section_size (obfd, osection, size))
1793 {
1a89cc7d 1794 err = _("size");
252b5132
RH
1795 goto loser;
1796 }
57938635 1797
252b5132
RH
1798 vma = bfd_section_vma (ibfd, isection);
1799 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1800 vma += p->vma_val;
1801 else if (p != NULL && p->change_vma == CHANGE_SET)
1802 vma = p->vma_val;
1803 else
1804 vma += change_section_address;
57938635 1805
252b5132
RH
1806 if (! bfd_set_section_vma (obfd, osection, vma))
1807 {
1a89cc7d 1808 err = _("vma");
252b5132
RH
1809 goto loser;
1810 }
1811
1812 lma = isection->lma;
1813 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1814 {
1815 if (p->change_lma == CHANGE_MODIFY)
1816 lma += p->lma_val;
1817 else if (p->change_lma == CHANGE_SET)
1818 lma = p->lma_val;
1819 else
1820 abort ();
1821 }
1822 else
1823 lma += change_section_address;
57938635 1824
252b5132
RH
1825 osection->lma = lma;
1826
1827 /* FIXME: This is probably not enough. If we change the LMA we
1828 may have to recompute the header for the file as well. */
b34976b6
AM
1829 if (!bfd_set_section_alignment (obfd,
1830 osection,
1831 bfd_section_alignment (ibfd, isection)))
252b5132 1832 {
1a89cc7d 1833 err = _("alignment");
252b5132
RH
1834 goto loser;
1835 }
1836
252b5132 1837 if (p != NULL && p->set_flags)
17978339 1838 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
252b5132
RH
1839 if (!bfd_set_section_flags (obfd, osection, flags))
1840 {
1a89cc7d 1841 err = _("flags");
252b5132
RH
1842 goto loser;
1843 }
1844
bc408b8a
JJ
1845 /* Copy merge entity size. */
1846 osection->entsize = isection->entsize;
1847
252b5132
RH
1848 /* This used to be mangle_section; we do here to avoid using
1849 bfd_get_section_by_name since some formats allow multiple
1850 sections with the same name. */
1851 isection->output_section = osection;
1852 isection->output_offset = 0;
1853
1854 /* Allow the BFD backend to copy any private data it understands
1855 from the input section to the output section. */
ed1653a7
NC
1856 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1857 && strip_symbols == STRIP_NONDEBUG)
1858 /* Do not copy the private data when creating an ELF format
1859 debug info file. We do not want the program headers. */
1860 ;
1861 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
252b5132 1862 {
1a89cc7d 1863 err = _("private data");
252b5132
RH
1864 goto loser;
1865 }
1866
594ef5db 1867 /* All went well. */
252b5132
RH
1868 return;
1869
1870loser:
1871 non_fatal (_("%s: section `%s': error in %s: %s"),
1872 bfd_get_filename (ibfd),
1873 bfd_section_name (ibfd, isection),
1874 err, bfd_errmsg (bfd_get_error ()));
1875 status = 1;
1876}
1877
1878/* Copy the data of input section ISECTION of IBFD
1879 to an output section with the same name in OBFD.
1880 If stripping then don't copy any relocation info. */
1881
1882static void
84e2f313 1883copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 1884{
d3ba0551 1885 bfd *obfd = obfdarg;
252b5132
RH
1886 struct section_list *p;
1887 arelent **relpp;
1888 long relcount;
1889 sec_ptr osection;
1890 bfd_size_type size;
1891 long relsize;
dc156bc0 1892 flagword flags;
252b5132 1893
594ef5db
NC
1894 /* If we have already failed earlier on,
1895 do not keep on generating complaints now. */
252b5132
RH
1896 if (status != 0)
1897 return;
57938635 1898
2593f09a 1899 if (is_strip_section (ibfd, isection))
e0c60db2 1900 return;
252b5132 1901
2593f09a 1902 flags = bfd_get_section_flags (ibfd, isection);
dc156bc0
AM
1903 if ((flags & SEC_GROUP) != 0)
1904 return;
1905
252b5132
RH
1906 osection = isection->output_section;
1907 size = bfd_get_section_size_before_reloc (isection);
1908
1909 if (size == 0 || osection == 0)
1910 return;
1911
2593f09a
NC
1912 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
1913
0af11b59 1914 /* Core files do not need to be relocated. */
4dd67f29
MS
1915 if (bfd_get_format (obfd) == bfd_core)
1916 relsize = 0;
1917 else
ed570f48
NC
1918 {
1919 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
4dd67f29 1920
ed570f48
NC
1921 if (relsize < 0)
1922 {
1923 /* Do not complain if the target does not support relocations. */
1924 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
1925 relsize = 0;
1926 else
1927 RETURN_NONFATAL (bfd_get_filename (ibfd));
1928 }
1929 }
57938635 1930
252b5132 1931 if (relsize == 0)
d3ba0551 1932 bfd_set_reloc (obfd, osection, NULL, 0);
252b5132
RH
1933 else
1934 {
d3ba0551 1935 relpp = xmalloc (relsize);
252b5132
RH
1936 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1937 if (relcount < 0)
1938 RETURN_NONFATAL (bfd_get_filename (ibfd));
57938635 1939
252b5132
RH
1940 if (strip_symbols == STRIP_ALL)
1941 {
1942 /* Remove relocations which are not in
0af11b59 1943 keep_strip_specific_list. */
252b5132
RH
1944 arelent **temp_relpp;
1945 long temp_relcount = 0;
1946 long i;
57938635 1947
d3ba0551 1948 temp_relpp = xmalloc (relsize);
252b5132 1949 for (i = 0; i < relcount; i++)
d3ba0551
AM
1950 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
1951 keep_specific_list))
252b5132
RH
1952 temp_relpp [temp_relcount++] = relpp [i];
1953 relcount = temp_relcount;
1954 free (relpp);
1955 relpp = temp_relpp;
1956 }
e0c60db2 1957
d3ba0551 1958 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
252b5132 1959 }
57938635 1960
252b5132 1961 isection->_cooked_size = isection->_raw_size;
b34976b6 1962 isection->reloc_done = TRUE;
252b5132 1963
0af11b59 1964 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
4dd67f29 1965 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
252b5132 1966 {
d3ba0551 1967 void *memhunk = xmalloc (size);
252b5132 1968
d3ba0551 1969 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
252b5132
RH
1970 RETURN_NONFATAL (bfd_get_filename (ibfd));
1971
57938635 1972 if (copy_byte >= 0)
252b5132
RH
1973 filter_bytes (memhunk, &size);
1974
d3ba0551 1975 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
252b5132
RH
1976 RETURN_NONFATAL (bfd_get_filename (obfd));
1977
1978 free (memhunk);
1979 }
1980 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1981 {
d3ba0551 1982 void *memhunk = xmalloc (size);
252b5132
RH
1983
1984 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1985 flag--they can just remove the section entirely and add it
1986 back again. However, we do permit them to turn on the
1987 SEC_HAS_CONTENTS flag, and take it to mean that the section
1988 contents should be zeroed out. */
1989
1990 memset (memhunk, 0, size);
d3ba0551 1991 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
252b5132
RH
1992 RETURN_NONFATAL (bfd_get_filename (obfd));
1993 free (memhunk);
1994 }
1995}
1996
1997/* Get all the sections. This is used when --gap-fill or --pad-to is
1998 used. */
1999
2000static void
84e2f313 2001get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
252b5132 2002{
d3ba0551 2003 asection ***secppp = secppparg;
252b5132
RH
2004
2005 **secppp = osection;
2006 ++(*secppp);
2007}
2008
2009/* Sort sections by VMA. This is called via qsort, and is used when
2010 --gap-fill or --pad-to is used. We force non loadable or empty
2011 sections to the front, where they are easier to ignore. */
2012
2013static int
84e2f313 2014compare_section_lma (const void *arg1, const void *arg2)
252b5132 2015{
d3ba0551
AM
2016 const asection *const *sec1 = arg1;
2017 const asection *const *sec2 = arg2;
252b5132
RH
2018 flagword flags1, flags2;
2019
2020 /* Sort non loadable sections to the front. */
2021 flags1 = (*sec1)->flags;
2022 flags2 = (*sec2)->flags;
2023 if ((flags1 & SEC_HAS_CONTENTS) == 0
2024 || (flags1 & SEC_LOAD) == 0)
2025 {
2026 if ((flags2 & SEC_HAS_CONTENTS) != 0
2027 && (flags2 & SEC_LOAD) != 0)
2028 return -1;
2029 }
2030 else
2031 {
2032 if ((flags2 & SEC_HAS_CONTENTS) == 0
2033 || (flags2 & SEC_LOAD) == 0)
2034 return 1;
2035 }
2036
2037 /* Sort sections by LMA. */
2038 if ((*sec1)->lma > (*sec2)->lma)
2039 return 1;
2040 else if ((*sec1)->lma < (*sec2)->lma)
2041 return -1;
2042
2043 /* Sort sections with the same LMA by size. */
2044 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
2045 return 1;
2046 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
2047 return -1;
2048
2049 return 0;
2050}
2051
2052/* Mark all the symbols which will be used in output relocations with
2053 the BSF_KEEP flag so that those symbols will not be stripped.
2054
2055 Ignore relocations which will not appear in the output file. */
2056
2057static void
84e2f313 2058mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
252b5132 2059{
d3ba0551 2060 asymbol **symbols = symbolsarg;
252b5132
RH
2061 long relsize;
2062 arelent **relpp;
2063 long relcount, i;
2064
2065 /* Ignore an input section with no corresponding output section. */
2066 if (isection->output_section == NULL)
2067 return;
2068
2069 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2070 if (relsize < 0)
ed570f48
NC
2071 {
2072 /* Do not complain if the target does not support relocations. */
2073 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2074 return;
2075 bfd_fatal (bfd_get_filename (ibfd));
2076 }
252b5132
RH
2077
2078 if (relsize == 0)
2079 return;
2080
d3ba0551 2081 relpp = xmalloc (relsize);
252b5132
RH
2082 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2083 if (relcount < 0)
2084 bfd_fatal (bfd_get_filename (ibfd));
2085
ec5d57d5
NC
2086 /* Examine each symbol used in a relocation. If it's not one of the
2087 special bfd section symbols, then mark it with BSF_KEEP. */
252b5132
RH
2088 for (i = 0; i < relcount; i++)
2089 {
ec5d57d5
NC
2090 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2091 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2092 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2093 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
252b5132
RH
2094 }
2095
2096 if (relpp != NULL)
2097 free (relpp);
2098}
2099
2100/* Write out debugging information. */
2101
b34976b6 2102static bfd_boolean
84e2f313
NC
2103write_debugging_info (bfd *obfd, void *dhandle,
2104 long *symcountp ATTRIBUTE_UNUSED,
2105 asymbol ***symppp ATTRIBUTE_UNUSED)
252b5132
RH
2106{
2107 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2108 return write_ieee_debugging_info (obfd, dhandle);
2109
2110 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2111 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2112 {
2113 bfd_byte *syms, *strings;
2114 bfd_size_type symsize, stringsize;
2115 asection *stabsec, *stabstrsec;
2116
2117 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2118 &symsize, &strings,
2119 &stringsize))
b34976b6 2120 return FALSE;
252b5132
RH
2121
2122 stabsec = bfd_make_section (obfd, ".stab");
2123 stabstrsec = bfd_make_section (obfd, ".stabstr");
2124 if (stabsec == NULL
2125 || stabstrsec == NULL
2126 || ! bfd_set_section_size (obfd, stabsec, symsize)
2127 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2128 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2129 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
2130 || ! bfd_set_section_flags (obfd, stabsec,
2131 (SEC_HAS_CONTENTS
2132 | SEC_READONLY
2133 | SEC_DEBUGGING))
2134 || ! bfd_set_section_flags (obfd, stabstrsec,
2135 (SEC_HAS_CONTENTS
2136 | SEC_READONLY
2137 | SEC_DEBUGGING)))
2138 {
2139 non_fatal (_("%s: can't create debugging section: %s"),
2140 bfd_get_filename (obfd),
2141 bfd_errmsg (bfd_get_error ()));
b34976b6 2142 return FALSE;
252b5132
RH
2143 }
2144
2145 /* We can get away with setting the section contents now because
2146 the next thing the caller is going to do is copy over the
2147 real sections. We may someday have to split the contents
2148 setting out of this function. */
d3ba0551
AM
2149 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2150 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2151 stringsize))
252b5132
RH
2152 {
2153 non_fatal (_("%s: can't set debugging section contents: %s"),
2154 bfd_get_filename (obfd),
2155 bfd_errmsg (bfd_get_error ()));
b34976b6 2156 return FALSE;
252b5132
RH
2157 }
2158
b34976b6 2159 return TRUE;
252b5132
RH
2160 }
2161
2162 non_fatal (_("%s: don't know how to write debugging information for %s"),
2163 bfd_get_filename (obfd), bfd_get_target (obfd));
b34976b6 2164 return FALSE;
252b5132
RH
2165}
2166
2167static int
84e2f313 2168strip_main (int argc, char *argv[])
252b5132 2169{
7c29036b
NC
2170 char *input_target = NULL;
2171 char *output_target = NULL;
b34976b6 2172 bfd_boolean show_version = FALSE;
7c29036b
NC
2173 bfd_boolean formats_info = FALSE;
2174 int c;
2175 int i;
252b5132
RH
2176 struct section_list *p;
2177 char *output_file = NULL;
2178
5fe11841 2179 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
252b5132
RH
2180 strip_options, (int *) 0)) != EOF)
2181 {
2182 switch (c)
2183 {
2184 case 'I':
2185 input_target = optarg;
2186 break;
2187 case 'O':
2188 output_target = optarg;
2189 break;
2190 case 'F':
2191 input_target = output_target = optarg;
2192 break;
2193 case 'R':
b34976b6
AM
2194 p = find_section_list (optarg, TRUE);
2195 p->remove = TRUE;
2196 sections_removed = TRUE;
252b5132
RH
2197 break;
2198 case 's':
2199 strip_symbols = STRIP_ALL;
2200 break;
2201 case 'S':
2202 case 'g':
db4f6831 2203 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
252b5132
RH
2204 strip_symbols = STRIP_DEBUG;
2205 break;
2206 case OPTION_STRIP_UNNEEDED:
2207 strip_symbols = STRIP_UNNEEDED;
2208 break;
2209 case 'K':
2210 add_specific_symbol (optarg, &keep_specific_list);
2211 break;
2212 case 'N':
2213 add_specific_symbol (optarg, &strip_specific_list);
2214 break;
2215 case 'o':
2216 output_file = optarg;
2217 break;
2218 case 'p':
b34976b6 2219 preserve_dates = TRUE;
252b5132
RH
2220 break;
2221 case 'x':
2222 discard_locals = LOCALS_ALL;
2223 break;
2224 case 'X':
2225 discard_locals = LOCALS_START_L;
2226 break;
2227 case 'v':
b34976b6 2228 verbose = TRUE;
252b5132
RH
2229 break;
2230 case 'V':
b34976b6 2231 show_version = TRUE;
252b5132 2232 break;
7c29036b
NC
2233 case OPTION_FORMATS_INFO:
2234 formats_info = TRUE;
2235 break;
ed1653a7
NC
2236 case OPTION_ONLY_KEEP_DEBUG:
2237 strip_symbols = STRIP_NONDEBUG;
2238 break;
252b5132 2239 case 0:
594ef5db
NC
2240 /* We've been given a long option. */
2241 break;
5fe11841
NC
2242 case 'w':
2243 wildcard = TRUE;
2244 break;
8b53311e 2245 case 'H':
252b5132
RH
2246 case 'h':
2247 strip_usage (stdout, 0);
2248 default:
2249 strip_usage (stderr, 1);
2250 }
2251 }
2252
84e2f313
NC
2253 if (formats_info)
2254 {
2255 display_info ();
2256 return 0;
2257 }
7c29036b 2258
252b5132
RH
2259 if (show_version)
2260 print_version ("strip");
2261
2262 /* Default is to strip all symbols. */
2263 if (strip_symbols == STRIP_UNDEF
2264 && discard_locals == LOCALS_UNDEF
2265 && strip_specific_list == NULL)
2266 strip_symbols = STRIP_ALL;
2267
d3ba0551 2268 if (output_target == NULL)
252b5132
RH
2269 output_target = input_target;
2270
2271 i = optind;
2272 if (i == argc
2273 || (output_file != NULL && (i + 1) < argc))
2274 strip_usage (stderr, 1);
2275
2276 for (; i < argc; i++)
2277 {
2278 int hold_status = status;
2279 struct stat statbuf;
2280 char *tmpname;
2281
f24ddbdd
NC
2282 if (get_file_size (argv[i]) < 1)
2283 continue;
2284
252b5132 2285 if (preserve_dates)
f24ddbdd
NC
2286 /* No need to check the return value of stat().
2287 It has already been checked in get_file_size(). */
2288 stat (argv[i], &statbuf);
252b5132
RH
2289
2290 if (output_file != NULL)
2291 tmpname = output_file;
2292 else
2293 tmpname = make_tempname (argv[i]);
2294 status = 0;
2295
2296 copy_file (argv[i], tmpname, input_target, output_target);
2297 if (status == 0)
2298 {
2299 if (preserve_dates)
2300 set_times (tmpname, &statbuf);
2301 if (output_file == NULL)
2302 smart_rename (tmpname, argv[i], preserve_dates);
2303 status = hold_status;
2304 }
2305 else
2306 unlink (tmpname);
2307 if (output_file == NULL)
2308 free (tmpname);
2309 }
2310
2311 return 0;
2312}
2313
2314static int
84e2f313 2315copy_main (int argc, char *argv[])
252b5132 2316{
43a0748c 2317 char * binary_architecture = NULL;
7c29036b
NC
2318 char *input_filename = NULL;
2319 char *output_filename = NULL;
2320 char *input_target = NULL;
2321 char *output_target = NULL;
b34976b6
AM
2322 bfd_boolean show_version = FALSE;
2323 bfd_boolean change_warn = TRUE;
7c29036b 2324 bfd_boolean formats_info = FALSE;
252b5132
RH
2325 int c;
2326 struct section_list *p;
2327 struct stat statbuf;
2328
5fe11841 2329 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
252b5132
RH
2330 copy_options, (int *) 0)) != EOF)
2331 {
2332 switch (c)
2333 {
2334 case 'b':
2335 copy_byte = atoi (optarg);
2336 if (copy_byte < 0)
2337 fatal (_("byte number must be non-negative"));
2338 break;
57938635 2339
0af11b59
KH
2340 case 'B':
2341 binary_architecture = optarg;
2342 break;
43a0748c 2343
252b5132
RH
2344 case 'i':
2345 interleave = atoi (optarg);
2346 if (interleave < 1)
2347 fatal (_("interleave must be positive"));
2348 break;
57938635 2349
252b5132
RH
2350 case 'I':
2351 case 's': /* "source" - 'I' is preferred */
2352 input_target = optarg;
2353 break;
57938635 2354
252b5132
RH
2355 case 'O':
2356 case 'd': /* "destination" - 'O' is preferred */
2357 output_target = optarg;
2358 break;
57938635 2359
252b5132
RH
2360 case 'F':
2361 input_target = output_target = optarg;
2362 break;
57938635 2363
f91ea849 2364 case 'j':
b34976b6 2365 p = find_section_list (optarg, TRUE);
f91ea849
ILT
2366 if (p->remove)
2367 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
2368 p->copy = TRUE;
2369 sections_copied = TRUE;
f91ea849 2370 break;
57938635 2371
252b5132 2372 case 'R':
b34976b6 2373 p = find_section_list (optarg, TRUE);
f91ea849
ILT
2374 if (p->copy)
2375 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
2376 p->remove = TRUE;
2377 sections_removed = TRUE;
252b5132 2378 break;
57938635 2379
252b5132
RH
2380 case 'S':
2381 strip_symbols = STRIP_ALL;
2382 break;
57938635 2383
252b5132
RH
2384 case 'g':
2385 strip_symbols = STRIP_DEBUG;
2386 break;
57938635 2387
252b5132
RH
2388 case OPTION_STRIP_UNNEEDED:
2389 strip_symbols = STRIP_UNNEEDED;
2390 break;
57938635 2391
ed1653a7
NC
2392 case OPTION_ONLY_KEEP_DEBUG:
2393 strip_symbols = STRIP_NONDEBUG;
2394 break;
2395
2593f09a
NC
2396 case OPTION_ADD_GNU_DEBUGLINK:
2397 gnu_debuglink_filename = optarg;
2398 break;
2399
252b5132
RH
2400 case 'K':
2401 add_specific_symbol (optarg, &keep_specific_list);
2402 break;
57938635 2403
252b5132
RH
2404 case 'N':
2405 add_specific_symbol (optarg, &strip_specific_list);
2406 break;
57938635 2407
252b5132
RH
2408 case 'L':
2409 add_specific_symbol (optarg, &localize_specific_list);
2410 break;
57938635 2411
16b2b71c
NC
2412 case 'G':
2413 add_specific_symbol (optarg, &keepglobal_specific_list);
2414 break;
2415
252b5132
RH
2416 case 'W':
2417 add_specific_symbol (optarg, &weaken_specific_list);
2418 break;
57938635 2419
252b5132 2420 case 'p':
b34976b6 2421 preserve_dates = TRUE;
252b5132 2422 break;
57938635 2423
5fe11841
NC
2424 case 'w':
2425 wildcard = TRUE;
2426 break;
2427
252b5132
RH
2428 case 'x':
2429 discard_locals = LOCALS_ALL;
2430 break;
57938635 2431
252b5132
RH
2432 case 'X':
2433 discard_locals = LOCALS_START_L;
2434 break;
57938635 2435
252b5132 2436 case 'v':
b34976b6 2437 verbose = TRUE;
252b5132 2438 break;
57938635 2439
252b5132 2440 case 'V':
b34976b6 2441 show_version = TRUE;
252b5132 2442 break;
57938635 2443
7c29036b
NC
2444 case OPTION_FORMATS_INFO:
2445 formats_info = TRUE;
2446 break;
2447
252b5132 2448 case OPTION_WEAKEN:
b34976b6 2449 weaken = TRUE;
252b5132 2450 break;
57938635 2451
252b5132
RH
2452 case OPTION_ADD_SECTION:
2453 {
2454 const char *s;
f24ddbdd 2455 off_t size;
252b5132
RH
2456 struct section_add *pa;
2457 int len;
2458 char *name;
2459 FILE *f;
2460
2461 s = strchr (optarg, '=');
57938635 2462
252b5132 2463 if (s == NULL)
57938635 2464 fatal (_("bad format for %s"), "--add-section");
252b5132 2465
f24ddbdd
NC
2466 size = get_file_size (s + 1);
2467 if (size < 1)
2468 break;
252b5132 2469
d3ba0551 2470 pa = xmalloc (sizeof (struct section_add));
252b5132
RH
2471
2472 len = s - optarg;
d3ba0551 2473 name = xmalloc (len + 1);
252b5132
RH
2474 strncpy (name, optarg, len);
2475 name[len] = '\0';
2476 pa->name = name;
2477
2478 pa->filename = s + 1;
f24ddbdd
NC
2479 pa->size = size;
2480 pa->contents = xmalloc (size);
252b5132 2481
252b5132 2482 f = fopen (pa->filename, FOPEN_RB);
57938635 2483
252b5132 2484 if (f == NULL)
84e2f313
NC
2485 fatal (_("cannot open: %s: %s"),
2486 pa->filename, strerror (errno));
57938635 2487
252b5132
RH
2488 if (fread (pa->contents, 1, pa->size, f) == 0
2489 || ferror (f))
2490 fatal (_("%s: fread failed"), pa->filename);
2491
2492 fclose (f);
2493
2494 pa->next = add_sections;
2495 add_sections = pa;
2496 }
2497 break;
57938635 2498
252b5132
RH
2499 case OPTION_CHANGE_START:
2500 change_start = parse_vma (optarg, "--change-start");
2501 break;
57938635 2502
252b5132
RH
2503 case OPTION_CHANGE_SECTION_ADDRESS:
2504 case OPTION_CHANGE_SECTION_LMA:
2505 case OPTION_CHANGE_SECTION_VMA:
2506 {
2507 const char *s;
2508 int len;
2509 char *name;
b4c96d0d 2510 char *option = NULL;
252b5132 2511 bfd_vma val;
b4c96d0d 2512 enum change_action what = CHANGE_IGNORE;
57938635 2513
252b5132
RH
2514 switch (c)
2515 {
b4c96d0d
ILT
2516 case OPTION_CHANGE_SECTION_ADDRESS:
2517 option = "--change-section-address";
2518 break;
2519 case OPTION_CHANGE_SECTION_LMA:
2520 option = "--change-section-lma";
2521 break;
2522 case OPTION_CHANGE_SECTION_VMA:
2523 option = "--change-section-vma";
2524 break;
252b5132 2525 }
57938635 2526
252b5132
RH
2527 s = strchr (optarg, '=');
2528 if (s == NULL)
2529 {
2530 s = strchr (optarg, '+');
2531 if (s == NULL)
2532 {
2533 s = strchr (optarg, '-');
2534 if (s == NULL)
2535 fatal (_("bad format for %s"), option);
2536 }
2537 }
2538
2539 len = s - optarg;
d3ba0551 2540 name = xmalloc (len + 1);
252b5132
RH
2541 strncpy (name, optarg, len);
2542 name[len] = '\0';
2543
b34976b6 2544 p = find_section_list (name, TRUE);
252b5132
RH
2545
2546 val = parse_vma (s + 1, option);
2547
2548 switch (*s)
2549 {
2550 case '=': what = CHANGE_SET; break;
2551 case '-': val = - val; /* Drop through. */
2552 case '+': what = CHANGE_MODIFY; break;
2553 }
57938635 2554
252b5132
RH
2555 switch (c)
2556 {
2557 case OPTION_CHANGE_SECTION_ADDRESS:
2558 p->change_vma = what;
2559 p->vma_val = val;
2560 /* Drop through. */
57938635 2561
252b5132
RH
2562 case OPTION_CHANGE_SECTION_LMA:
2563 p->change_lma = what;
2564 p->lma_val = val;
2565 break;
57938635 2566
252b5132
RH
2567 case OPTION_CHANGE_SECTION_VMA:
2568 p->change_vma = what;
2569 p->vma_val = val;
2570 break;
2571 }
2572 }
2573 break;
57938635 2574
252b5132
RH
2575 case OPTION_CHANGE_ADDRESSES:
2576 change_section_address = parse_vma (optarg, "--change-addresses");
2577 change_start = change_section_address;
2578 break;
57938635 2579
252b5132 2580 case OPTION_CHANGE_WARNINGS:
b34976b6 2581 change_warn = TRUE;
252b5132 2582 break;
57938635 2583
252b5132 2584 case OPTION_CHANGE_LEADING_CHAR:
b34976b6 2585 change_leading_char = TRUE;
252b5132 2586 break;
57938635 2587
252b5132 2588 case OPTION_DEBUGGING:
b34976b6 2589 convert_debugging = TRUE;
252b5132 2590 break;
57938635 2591
252b5132
RH
2592 case OPTION_GAP_FILL:
2593 {
2594 bfd_vma gap_fill_vma;
2595
2596 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2597 gap_fill = (bfd_byte) gap_fill_vma;
2598 if ((bfd_vma) gap_fill != gap_fill_vma)
2599 {
2600 char buff[20];
57938635 2601
252b5132 2602 sprintf_vma (buff, gap_fill_vma);
57938635 2603
252b5132
RH
2604 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2605 buff, gap_fill);
2606 }
b34976b6 2607 gap_fill_set = TRUE;
252b5132
RH
2608 }
2609 break;
57938635 2610
252b5132 2611 case OPTION_NO_CHANGE_WARNINGS:
b34976b6 2612 change_warn = FALSE;
252b5132 2613 break;
57938635 2614
252b5132
RH
2615 case OPTION_PAD_TO:
2616 pad_to = parse_vma (optarg, "--pad-to");
b34976b6 2617 pad_to_set = TRUE;
252b5132 2618 break;
57938635 2619
252b5132 2620 case OPTION_REMOVE_LEADING_CHAR:
b34976b6 2621 remove_leading_char = TRUE;
252b5132 2622 break;
57938635
AM
2623
2624 case OPTION_REDEFINE_SYM:
2625 {
2626 /* Push this redefinition onto redefine_symbol_list. */
2627
2628 int len;
2629 const char *s;
2630 const char *nextarg;
2631 char *source, *target;
2632
2633 s = strchr (optarg, '=');
2634 if (s == NULL)
594ef5db 2635 fatal (_("bad format for %s"), "--redefine-sym");
57938635
AM
2636
2637 len = s - optarg;
d3ba0551 2638 source = xmalloc (len + 1);
57938635
AM
2639 strncpy (source, optarg, len);
2640 source[len] = '\0';
2641
2642 nextarg = s + 1;
2643 len = strlen (nextarg);
d3ba0551 2644 target = xmalloc (len + 1);
57938635
AM
2645 strcpy (target, nextarg);
2646
92991082 2647 redefine_list_append ("--redefine-sym", source, target);
57938635
AM
2648
2649 free (source);
2650 free (target);
2651 }
2652 break;
2653
92991082
JT
2654 case OPTION_REDEFINE_SYMS:
2655 add_redefine_syms_file (optarg);
2656 break;
2657
252b5132
RH
2658 case OPTION_SET_SECTION_FLAGS:
2659 {
2660 const char *s;
2661 int len;
2662 char *name;
2663
2664 s = strchr (optarg, '=');
2665 if (s == NULL)
57938635 2666 fatal (_("bad format for %s"), "--set-section-flags");
252b5132
RH
2667
2668 len = s - optarg;
d3ba0551 2669 name = xmalloc (len + 1);
252b5132
RH
2670 strncpy (name, optarg, len);
2671 name[len] = '\0';
2672
b34976b6 2673 p = find_section_list (name, TRUE);
252b5132 2674
b34976b6 2675 p->set_flags = TRUE;
252b5132
RH
2676 p->flags = parse_flags (s + 1);
2677 }
2678 break;
57938635 2679
594ef5db
NC
2680 case OPTION_RENAME_SECTION:
2681 {
2682 flagword flags;
3bcfb3e4
AM
2683 const char *eq, *fl;
2684 char *old_name;
2685 char *new_name;
594ef5db
NC
2686 unsigned int len;
2687
3bcfb3e4
AM
2688 eq = strchr (optarg, '=');
2689 if (eq == NULL)
594ef5db
NC
2690 fatal (_("bad format for %s"), "--rename-section");
2691
3bcfb3e4 2692 len = eq - optarg;
594ef5db 2693 if (len == 0)
3bcfb3e4 2694 fatal (_("bad format for %s"), "--rename-section");
594ef5db 2695
d3ba0551 2696 old_name = xmalloc (len + 1);
594ef5db
NC
2697 strncpy (old_name, optarg, len);
2698 old_name[len] = 0;
2699
3bcfb3e4
AM
2700 eq++;
2701 fl = strchr (eq, ',');
2702 if (fl)
594ef5db 2703 {
3bcfb3e4
AM
2704 flags = parse_flags (fl + 1);
2705 len = fl - eq;
594ef5db
NC
2706 }
2707 else
2708 {
594ef5db 2709 flags = -1;
3bcfb3e4 2710 len = strlen (eq);
594ef5db
NC
2711 }
2712
3bcfb3e4
AM
2713 if (len == 0)
2714 fatal (_("bad format for %s"), "--rename-section");
2715
d3ba0551 2716 new_name = xmalloc (len + 1);
3bcfb3e4
AM
2717 strncpy (new_name, eq, len);
2718 new_name[len] = 0;
2719
594ef5db
NC
2720 add_section_rename (old_name, new_name, flags);
2721 }
2722 break;
2723
252b5132
RH
2724 case OPTION_SET_START:
2725 set_start = parse_vma (optarg, "--set-start");
b34976b6 2726 set_start_set = TRUE;
252b5132 2727 break;
57938635 2728
0af11b59
KH
2729 case OPTION_SREC_LEN:
2730 Chunk = parse_vma (optarg, "--srec-len");
2731 break;
420496c1 2732
0af11b59 2733 case OPTION_SREC_FORCES3:
b34976b6 2734 S3Forced = TRUE;
0af11b59 2735 break;
420496c1 2736
16b2b71c
NC
2737 case OPTION_STRIP_SYMBOLS:
2738 add_specific_symbols (optarg, &strip_specific_list);
2739 break;
2740
2741 case OPTION_KEEP_SYMBOLS:
2742 add_specific_symbols (optarg, &keep_specific_list);
2743 break;
2744
2745 case OPTION_LOCALIZE_SYMBOLS:
2746 add_specific_symbols (optarg, &localize_specific_list);
2747 break;
2748
2749 case OPTION_KEEPGLOBAL_SYMBOLS:
2750 add_specific_symbols (optarg, &keepglobal_specific_list);
2751 break;
2752
2753 case OPTION_WEAKEN_SYMBOLS:
2754 add_specific_symbols (optarg, &weaken_specific_list);
2755 break;
2756
1ae8b3d2
AO
2757 case OPTION_ALT_MACH_CODE:
2758 use_alt_mach_code = atoi (optarg);
2759 if (use_alt_mach_code <= 0)
2760 fatal (_("alternate machine code index must be positive"));
2761 break;
2762
d7fb0dd2
NC
2763 case OPTION_PREFIX_SYMBOLS:
2764 prefix_symbols_string = optarg;
2765 break;
2766
2767 case OPTION_PREFIX_SECTIONS:
2768 prefix_sections_string = optarg;
2769 break;
2770
2771 case OPTION_PREFIX_ALLOC_SECTIONS:
2772 prefix_alloc_sections_string = optarg;
2773 break;
2774
252b5132 2775 case 0:
2593f09a
NC
2776 /* We've been given a long option. */
2777 break;
57938635 2778
8b53311e 2779 case 'H':
252b5132
RH
2780 case 'h':
2781 copy_usage (stdout, 0);
57938635 2782
252b5132
RH
2783 default:
2784 copy_usage (stderr, 1);
2785 }
2786 }
2787
7c29036b
NC
2788 if (formats_info)
2789 {
2790 display_info ();
2791 return 0;
2792 }
2793
252b5132
RH
2794 if (show_version)
2795 print_version ("objcopy");
2796
2797 if (copy_byte >= interleave)
2798 fatal (_("byte number must be less than interleave"));
2799
2800 if (optind == argc || optind + 2 < argc)
2801 copy_usage (stderr, 1);
2802
2803 input_filename = argv[optind];
2804 if (optind + 1 < argc)
2805 output_filename = argv[optind + 1];
2806
2807 /* Default is to strip no symbols. */
2808 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2809 strip_symbols = STRIP_NONE;
2810
d3ba0551 2811 if (output_target == NULL)
252b5132
RH
2812 output_target = input_target;
2813
d3ba0551 2814 if (binary_architecture != NULL)
252b5132 2815 {
43a0748c 2816 if (input_target && strcmp (input_target, "binary") == 0)
0af11b59
KH
2817 {
2818 const bfd_arch_info_type * temp_arch_info;
43a0748c
NC
2819
2820 temp_arch_info = bfd_scan_arch (binary_architecture);
2821
0af11b59 2822 if (temp_arch_info != NULL)
b749473b
NC
2823 {
2824 bfd_external_binary_architecture = temp_arch_info->arch;
2825 bfd_external_machine = temp_arch_info->mach;
2826 }
0af11b59
KH
2827 else
2828 fatal (_("architecture %s unknown"), binary_architecture);
2829 }
43a0748c
NC
2830 else
2831 {
2832 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2833 non_fatal (_(" Argument %s ignored"), binary_architecture);
2834 }
252b5132
RH
2835 }
2836
43a0748c
NC
2837 if (preserve_dates)
2838 if (stat (input_filename, & statbuf) < 0)
f24ddbdd
NC
2839 fatal (_("warning: could not locate '%s'. System error message: %s"),
2840 input_filename, strerror (errno));
43a0748c 2841
0fcdcb91 2842 /* If there is no destination file, or the source and destination files
d3ba0551
AM
2843 are the same, then create a temp and rename the result into the input. */
2844 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
252b5132
RH
2845 {
2846 char *tmpname = make_tempname (input_filename);
2847
2848 copy_file (input_filename, tmpname, input_target, output_target);
2849 if (status == 0)
57938635 2850 {
252b5132
RH
2851 if (preserve_dates)
2852 set_times (tmpname, &statbuf);
2853 smart_rename (tmpname, input_filename, preserve_dates);
2854 }
2855 else
2856 unlink (tmpname);
2857 }
2858 else
2859 {
2860 copy_file (input_filename, output_filename, input_target, output_target);
594ef5db 2861
252b5132
RH
2862 if (status == 0 && preserve_dates)
2863 set_times (output_filename, &statbuf);
2864 }
2865
2866 if (change_warn)
2867 {
2868 for (p = change_sections; p != NULL; p = p->next)
2869 {
2870 if (! p->used)
2871 {
2872 if (p->change_vma != CHANGE_IGNORE)
2873 {
2874 char buff [20];
2875
2876 sprintf_vma (buff, p->vma_val);
57938635 2877
252b5132 2878 /* xgettext:c-format */
57938635
AM
2879 non_fatal (_("%s %s%c0x%s never used"),
2880 "--change-section-vma",
252b5132
RH
2881 p->name,
2882 p->change_vma == CHANGE_SET ? '=' : '+',
2883 buff);
2884 }
57938635 2885
252b5132
RH
2886 if (p->change_lma != CHANGE_IGNORE)
2887 {
2888 char buff [20];
2889
2890 sprintf_vma (buff, p->lma_val);
57938635 2891
252b5132 2892 /* xgettext:c-format */
57938635
AM
2893 non_fatal (_("%s %s%c0x%s never used"),
2894 "--change-section-lma",
252b5132
RH
2895 p->name,
2896 p->change_lma == CHANGE_SET ? '=' : '+',
2897 buff);
2898 }
2899 }
2900 }
2901 }
2902
2903 return 0;
2904}
2905
2906int
84e2f313 2907main (int argc, char *argv[])
252b5132
RH
2908{
2909#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2910 setlocale (LC_MESSAGES, "");
3882b010
L
2911#endif
2912#if defined (HAVE_SETLOCALE)
2913 setlocale (LC_CTYPE, "");
252b5132
RH
2914#endif
2915 bindtextdomain (PACKAGE, LOCALEDIR);
2916 textdomain (PACKAGE);
2917
2918 program_name = argv[0];
2919 xmalloc_set_program_name (program_name);
2920
2921 START_PROGRESS (program_name, 0);
2922
2923 strip_symbols = STRIP_UNDEF;
2924 discard_locals = LOCALS_UNDEF;
2925
2926 bfd_init ();
2927 set_default_bfd_target ();
2928
2929 if (is_strip < 0)
2930 {
2931 int i = strlen (program_name);
5af11cab
AM
2932#ifdef HAVE_DOS_BASED_FILE_SYSTEM
2933 /* Drop the .exe suffix, if any. */
2934 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2935 {
2936 i -= 4;
2937 program_name[i] = '\0';
2938 }
2939#endif
2940 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
252b5132
RH
2941 }
2942
2943 if (is_strip)
2944 strip_main (argc, argv);
2945 else
2946 copy_main (argc, argv);
2947
2948 END_PROGRESS (program_name);
2949
2950 return status;
2951}
This page took 0.386043 seconds and 4 git commands to generate.