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