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