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