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