objcopy.c revision 60484
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
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
41/* A list to support redefine_sym.  */
42struct redefine_node
43{
44  char *source;
45  char *target;
46  struct redefine_node *next;
47};
48
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 **));
71static const char *lookup_sym_redefinition PARAMS((const char *));
72static void redefine_list_append PARAMS ((const char *, const char *));
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.  */
124  boolean		copy;      /* Whether to copy this section.  */
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;
135static boolean sections_copied;
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
185/* List of symbols to strip, keep, localize, weaken, or redefine.  */
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;
191static struct redefine_node *redefine_sym_list = NULL;
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)
216#define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
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'},
263  {"only-section", required_argument, 0, 'j'},
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'},
291  {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
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{
309  fprintf (stream, _("Usage: %s <switches> in-file [out-file]\n"), program_name);
310  fprintf (stream, _(" The switches are:\n"));
311  fprintf (stream, _("\
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\
351     --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
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"));
356  list_supported_targets (program_name, stream);
357  if (exit_status == 0)
358    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
359  exit (exit_status);
360}
361
362static void
363strip_usage (stream, exit_status)
364     FILE *stream;
365     int exit_status;
366{
367  fprintf (stream, _("Usage: %s <switches> in-file(s)\n"), program_name);
368  fprintf (stream, _(" The switches are:\n"));
369  fprintf (stream, _("\
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
388  list_supported_targets (program_name, stream);
389  if (exit_status == 0)
390    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
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);
423      PARSE_FLAG ("noload", SEC_NEVER_LOAD);
424      PARSE_FLAG ("readonly", SEC_READONLY);
425      PARSE_FLAG ("debug", SEC_DEBUGGING);
426      PARSE_FLAG ("code", SEC_CODE);
427      PARSE_FLAG ("data", SEC_DATA);
428      PARSE_FLAG ("rom", SEC_ROM);
429      PARSE_FLAG ("share", SEC_SHARED);
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);
440	  fatal (_("supported flags: %s"),
441		 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
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;
471  p->copy = false;
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
487static void
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)
522     bfd *abfd ATTRIBUTE_UNUSED;
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
535  if (! sections_removed && ! sections_copied)
536    return false;
537
538  p = find_section_list (bfd_get_section_name (abfd, sec), false);
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;
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
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
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
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
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;
727  if (*size % interleave > (bfd_size_type) copy_byte)
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)));
775
776  if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
777    RETURN_NONFATAL (bfd_get_filename (ibfd));
778
779  if (isympp)
780    free (isympp);
781
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;
807
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;
819
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));
828
829		  if (pset->change_lma != CHANGE_IGNORE)
830		    {
831		      padd->section->lma = pset->lma_val;
832
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));
931
932  osympp = isympp = (asymbol **) xmalloc (symsize);
933  symcount = bfd_canonicalize_symtab (ibfd, isympp);
934  if (symcount < 0)
935    RETURN_NONFATAL (bfd_get_filename (ibfd));
936
937  if (convert_debugging)
938    dhandle = read_debugging_info (ibfd, isympp, symcount);
939
940  if (strip_symbols == STRIP_DEBUG
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
949      || sections_copied
950      || convert_debugging
951      || change_leading_char
952      || remove_leading_char
953      || redefine_sym_list
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.
958
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;
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	}
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
1129      if (preserve_dates && stat_status == 0)
1130	set_times (output_name, &buf);
1131
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);
1221
1222      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1223	{
1224	  list_matching_formats (matching);
1225	  free (matching);
1226	}
1227
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;
1248  char *err;
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
1262  if (sections_removed && p != NULL && p->remove)
1263    return;
1264  if (sections_copied && (p == NULL || ! p->copy))
1265    return;
1266
1267  osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1268
1269  if (osection == NULL)
1270    {
1271      err = "making";
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    {
1280      err = "size";
1281      goto loser;
1282    }
1283
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;
1291
1292  if (! bfd_set_section_vma (obfd, osection, vma))
1293    {
1294      err = "vma";
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;
1310
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    {
1320      err = "alignment";
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    {
1329      err = "flags";
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    {
1343      err = "private data";
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;
1380
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
1393  if (sections_removed && p != NULL && p->remove)
1394    return;
1395  if (sections_copied && (p == NULL || ! p->copy))
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));
1408
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));
1417
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;
1425
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    }
1439
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
1451      if (copy_byte >= 0)
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)
1483     bfd *obfd ATTRIBUTE_UNUSED;
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;
1590     long *symcountp ATTRIBUTE_UNUSED;
1591     asymbol ***symppp ATTRIBUTE_UNUSED;
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
1796  while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
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;
1806
1807	case 'i':
1808	  interleave = atoi (optarg);
1809	  if (interleave < 1)
1810	    fatal (_("interleave must be positive"));
1811	  break;
1812
1813	case 'I':
1814	case 's':		/* "source" - 'I' is preferred */
1815	  input_target = optarg;
1816	  break;
1817
1818	case 'O':
1819	case 'd':		/* "destination" - 'O' is preferred */
1820	  output_target = optarg;
1821	  break;
1822
1823	case 'F':
1824	  input_target = output_target = optarg;
1825	  break;
1826
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;
1834
1835	case 'R':
1836	  p = find_section_list (optarg, true);
1837	  if (p->copy)
1838	    fatal (_("%s both copied and removed"), optarg);
1839	  p->remove = true;
1840	  sections_removed = true;
1841	  break;
1842
1843	case 'S':
1844	  strip_symbols = STRIP_ALL;
1845	  break;
1846
1847	case 'g':
1848	  strip_symbols = STRIP_DEBUG;
1849	  break;
1850
1851	case OPTION_STRIP_UNNEEDED:
1852	  strip_symbols = STRIP_UNNEEDED;
1853	  break;
1854
1855	case 'K':
1856	  add_specific_symbol (optarg, &keep_specific_list);
1857	  break;
1858
1859	case 'N':
1860	  add_specific_symbol (optarg, &strip_specific_list);
1861	  break;
1862
1863	case 'L':
1864	  add_specific_symbol (optarg, &localize_specific_list);
1865	  break;
1866
1867	case 'W':
1868	  add_specific_symbol (optarg, &weaken_specific_list);
1869	  break;
1870
1871	case 'p':
1872	  preserve_dates = true;
1873	  break;
1874
1875	case 'x':
1876	  discard_locals = LOCALS_ALL;
1877	  break;
1878
1879	case 'X':
1880	  discard_locals = LOCALS_START_L;
1881	  break;
1882
1883	case 'v':
1884	  verbose = true;
1885	  break;
1886
1887	case 'V':
1888	  show_version = true;
1889	  break;
1890
1891	case OPTION_WEAKEN:
1892	  weaken = true;
1893	  break;
1894
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, '=');
1905
1906	    if (s == NULL)
1907	      fatal (_("bad format for %s"), "--add-section");
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);
1926
1927	    if (f == NULL)
1928	      fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
1929
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;
1940
1941	case OPTION_CHANGE_START:
1942	  change_start = parse_vma (optarg, "--change-start");
1943	  break;
1944
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;
1952	    char *option = NULL;
1953	    bfd_vma val;
1954	    enum change_action what = CHANGE_IGNORE;
1955
1956	    switch (c)
1957	      {
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;
1967	      }
1968
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	      }
1996
1997	    switch (c)
1998	      {
1999	      case OPTION_CHANGE_SECTION_ADDRESS:
2000		p->change_vma = what;
2001		p->vma_val    = val;
2002		/* Drop through.  */
2003
2004	      case OPTION_CHANGE_SECTION_LMA:
2005		p->change_lma = what;
2006		p->lma_val    = val;
2007		break;
2008
2009	      case OPTION_CHANGE_SECTION_VMA:
2010		p->change_vma = what;
2011		p->vma_val    = val;
2012		break;
2013	      }
2014	  }
2015	  break;
2016
2017	case OPTION_CHANGE_ADDRESSES:
2018	  change_section_address = parse_vma (optarg, "--change-addresses");
2019	  change_start = change_section_address;
2020	  break;
2021
2022	case OPTION_CHANGE_WARNINGS:
2023	  change_warn = true;
2024	  break;
2025
2026	case OPTION_CHANGE_LEADING_CHAR:
2027	  change_leading_char = true;
2028	  break;
2029
2030	case OPTION_DEBUGGING:
2031	  convert_debugging = true;
2032	  break;
2033
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];
2043
2044		sprintf_vma (buff, gap_fill_vma);
2045
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;
2052
2053	case OPTION_NO_CHANGE_WARNINGS:
2054	  change_warn = false;
2055	  break;
2056
2057	case OPTION_PAD_TO:
2058	  pad_to = parse_vma (optarg, "--pad-to");
2059	  pad_to_set = true;
2060	  break;
2061
2062	case OPTION_REMOVE_LEADING_CHAR:
2063	  remove_leading_char = true;
2064	  break;
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
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)
2106	      fatal (_("bad format for %s"), "--set-section-flags");
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;
2119
2120	case OPTION_SET_START:
2121	  set_start = parse_vma (optarg, "--set-start");
2122	  set_start_set = true;
2123	  break;
2124
2125	case 0:
2126	  break;		/* we've been given a long option */
2127
2128	case 'h':
2129	  copy_usage (stdout, 0);
2130
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)
2171	{
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);
2197
2198		  /* xgettext:c-format */
2199		  non_fatal (_("%s %s%c0x%s never used"),
2200			     "--change-section-vma",
2201			     p->name,
2202			     p->change_vma == CHANGE_SET ? '=' : '+',
2203			     buff);
2204		}
2205
2206	      if (p->change_lma != CHANGE_IGNORE)
2207		{
2208		  char buff [20];
2209
2210		  sprintf_vma (buff, p->lma_val);
2211
2212		  /* xgettext:c-format */
2213		  non_fatal (_("%s %s%c0x%s never used"),
2214			     "--change-section-lma",
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}
2263