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