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