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