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