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