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