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