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