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