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