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