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