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