]> Git Repo - binutils.git/blob - binutils/objcopy.c
* binutils-all/objdump.exp (cpus_expected): New variable, taken from objdump -i
[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                       status = 1;
588                     }
589                   left -= now;
590                   off += now;
591                 }
592             }
593         }
594     }
595
596   /* Allow the BFD backend to copy any private data it understands
597      from the input BFD to the output BFD.  This is done last to
598      permit the routine to look at the filtered symbol table, which is
599      important for the ECOFF code at least.  */
600   if (!bfd_copy_private_bfd_data (ibfd, obfd))
601     {
602       fprintf (stderr, "%s: %s: error copying private BFD data: %s\n",
603                program_name, bfd_get_filename (obfd),
604                bfd_errmsg (bfd_get_error ()));
605       status = 1;
606       return;
607     }
608 }
609
610 static char *
611 cat (a, b, c)
612      char *a;
613      char *b;
614      char *c;
615 {
616   size_t size = strlen (a) + strlen (b) + strlen (c);
617   char *r = xmalloc (size + 1);
618
619   strcpy (r, a);
620   strcat (r, b);
621   strcat (r, c);
622   return r;
623 }
624
625 /* Read each archive element in turn from IBFD, copy the
626    contents to temp file, and keep the temp file handle.  */
627
628 static void
629 copy_archive (ibfd, obfd, output_target)
630      bfd *ibfd;
631      bfd *obfd;
632      char *output_target;
633 {
634   struct name_list
635     {
636       struct name_list *next;
637       char *name;
638     } *list, *l;
639   bfd **ptr = &obfd->archive_head;
640   bfd *this_element;
641   char *dir = make_tempname (bfd_get_filename (obfd));
642
643   /* Make a temp directory to hold the contents.  */
644   mkdir (dir, 0700);
645   obfd->has_armap = ibfd->has_armap;
646
647   list = NULL;
648
649   this_element = bfd_openr_next_archived_file (ibfd, NULL);
650   while (this_element != (bfd *) NULL)
651     {
652       /* Create an output file for this member.  */
653       char *output_name = cat (dir, "/", bfd_get_filename(this_element));
654       bfd *output_bfd = bfd_openw (output_name, output_target);
655       bfd *last_element;
656
657       l = (struct name_list *) xmalloc (sizeof (struct name_list));
658       l->name = output_name;
659       l->next = list;
660       list = l;
661
662       if (output_bfd == (bfd *) NULL)
663         {
664           nonfatal (output_name);
665         }
666       if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
667         {
668           nonfatal (bfd_get_filename (obfd));
669         }
670
671       if (bfd_check_format (this_element, bfd_object) == true)
672         {
673           copy_object (this_element, output_bfd);
674         }
675
676       bfd_close (output_bfd);
677
678       /* Open the newly output file and attach to our list.  */
679       output_bfd = bfd_openr (output_name, output_target);
680
681       *ptr = output_bfd;
682       ptr = &output_bfd->next;
683
684       last_element = this_element;
685
686       this_element = bfd_openr_next_archived_file (ibfd, last_element);
687
688       bfd_close (last_element);
689     }
690   *ptr = (bfd *) NULL;
691
692   if (!bfd_close (obfd))
693     {
694       nonfatal (bfd_get_filename (obfd));
695     }
696
697   /* Delete all the files that we opened.  */
698   for (l = list; l != NULL; l = l->next)
699     unlink (l->name);
700   rmdir (dir);
701
702   if (!bfd_close (ibfd))
703     {
704       nonfatal (bfd_get_filename (ibfd));
705     }
706 }
707
708 /* The top-level control.  */
709
710 static void
711 copy_file (input_filename, output_filename, input_target, output_target)
712      char *input_filename;
713      char *output_filename;
714      char *input_target;
715      char *output_target;
716 {
717   bfd *ibfd;
718   char **matching;
719
720   /* To allow us to do "strip *" without dying on the first
721      non-object file, failures are nonfatal.  */
722
723   ibfd = bfd_openr (input_filename, input_target);
724   if (ibfd == NULL)
725     {
726       nonfatal (input_filename);
727     }
728
729   if (bfd_check_format (ibfd, bfd_archive))
730     {
731       bfd *obfd;
732
733       /* bfd_get_target does not return the correct value until
734          bfd_check_format succeeds.  */
735       if (output_target == NULL)
736         output_target = bfd_get_target (ibfd);
737
738       obfd = bfd_openw (output_filename, output_target);
739       if (obfd == NULL)
740         {
741           nonfatal (output_filename);
742         }
743       copy_archive (ibfd, obfd, output_target);
744     }
745   else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
746     {
747       bfd *obfd;
748
749       /* bfd_get_target does not return the correct value until
750          bfd_check_format succeeds.  */
751       if (output_target == NULL)
752         output_target = bfd_get_target (ibfd);
753
754       obfd = bfd_openw (output_filename, output_target);
755       if (obfd == NULL)
756         {
757           nonfatal (output_filename);
758         }
759
760       copy_object (ibfd, obfd);
761
762       if (!bfd_close (obfd))
763         {
764           nonfatal (output_filename);
765         }
766
767       if (!bfd_close (ibfd))
768         {
769           nonfatal (input_filename);
770         }
771     }
772   else
773     {
774       bfd_nonfatal (input_filename);
775       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
776         {
777           list_matching_formats (matching);
778           free (matching);
779         }
780       status = 1;
781     }
782 }
783
784 /* Create a section in OBFD with the same name and attributes
785    as ISECTION in IBFD.  */
786
787 static void
788 setup_section (ibfd, isection, obfdarg)
789      bfd *ibfd;
790      sec_ptr isection;
791      PTR obfdarg;
792 {
793   bfd *obfd = (bfd *) obfdarg;
794   struct section_list *p;
795   sec_ptr osection;
796   bfd_vma vma;
797   char *err;
798
799   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
800       && (strip_symbols == strip_debug
801           || strip_symbols == strip_all
802           || discard_locals == locals_all))
803     return;
804
805   for (p = remove_sections; p != NULL; p = p->next)
806     {
807       if (strcmp (p->name, bfd_section_name (ibfd, isection)) == 0)
808         {
809           p->used = true;
810           return;
811         }
812     }
813
814   osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
815   if (osection == NULL)
816     {
817       err = "making";
818       goto loser;
819     }
820
821   if (!bfd_set_section_size (obfd,
822                              osection,
823                              bfd_section_size (ibfd, isection)))
824     {
825       err = "size";
826       goto loser;
827     }
828
829   vma = bfd_section_vma (ibfd, isection);
830   for (p = adjust_sections; p != NULL; p = p->next)
831     {
832       if (strcmp (p->name, bfd_section_name (ibfd, isection)) == 0)
833         {
834           if (p->adjust)
835             vma += p->val;
836           else
837             vma = p->val;
838           p->used = true;
839           break;
840         }
841     }
842   if (p == NULL)
843     vma += adjust_section_vma;
844
845   if (! bfd_set_section_vma (obfd, osection, vma))
846     {
847       err = "vma";
848       goto loser;
849     }
850
851   if (bfd_set_section_alignment (obfd,
852                                  osection,
853                                  bfd_section_alignment (ibfd, isection))
854       == false)
855     {
856       err = "alignment";
857       goto loser;
858     }
859
860   if (!bfd_set_section_flags (obfd, osection,
861                               bfd_get_section_flags (ibfd, isection)))
862     {
863       err = "flags";
864       goto loser;
865     }
866
867   /* This used to be mangle_section; we do here to avoid using
868      bfd_get_section_by_name since some formats allow multiple
869      sections with the same name.  */
870   isection->output_section = osection;
871   isection->output_offset = 0;
872
873   /* Allow the BFD backend to copy any private data it understands
874      from the input section to the output section.  */
875   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
876     {
877       err = "private data";
878       goto loser;
879     }
880
881   /* All went well */
882   return;
883
884 loser:
885   fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
886            program_name,
887            bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
888            err, bfd_errmsg (bfd_get_error ()));
889   status = 1;
890 }
891
892 /* Copy the data of input section ISECTION of IBFD
893    to an output section with the same name in OBFD.
894    If stripping then don't copy any relocation info.  */
895
896 static void
897 copy_section (ibfd, isection, obfdarg)
898      bfd *ibfd;
899      sec_ptr isection;
900      PTR obfdarg;
901 {
902   bfd *obfd = (bfd *) obfdarg;
903   struct section_list *p;
904   arelent **relpp;
905   long relcount;
906   sec_ptr osection;
907   bfd_size_type size;
908
909   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
910       && (strip_symbols == strip_debug
911           || strip_symbols == strip_all
912           || discard_locals == locals_all))
913     {
914       return;
915     }
916
917   for (p = remove_sections; p != NULL; p = p->next)
918     if (strcmp (p->name, bfd_section_name (ibfd, isection)) == 0)
919       return;
920
921   osection = isection->output_section;
922   size = bfd_get_section_size_before_reloc (isection);
923
924   if (size == 0 || osection == 0)
925     return;
926
927   if (strip_symbols == strip_all)
928     bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
929   else
930     {
931       long relsize;
932
933       relsize = bfd_get_reloc_upper_bound (ibfd, isection);
934       if (relsize < 0)
935         {
936           nonfatal (bfd_get_filename (ibfd));
937         }
938       if (relsize == 0)
939         bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
940       else
941         {
942           relpp = (arelent **) xmalloc (relsize);
943           relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
944           if (relcount < 0)
945             {
946               nonfatal (bfd_get_filename (ibfd));
947             }
948           bfd_set_reloc (obfd, osection, relpp, relcount);
949         }
950     }
951
952   isection->_cooked_size = isection->_raw_size;
953   isection->reloc_done = true;
954
955   if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
956     {
957       PTR memhunk = (PTR) xmalloc ((unsigned) size);
958
959       if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
960                                      size))
961         {
962           nonfatal (bfd_get_filename (ibfd));
963         }
964
965       if (copy_byte >= 0) 
966         {
967           filter_bytes (memhunk, &size);
968               /* The section has gotten smaller. */
969           if (!bfd_set_section_size (obfd, osection, size))
970             nonfatal (bfd_get_filename (obfd));
971         }
972
973       if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
974                                      size))
975         {
976           nonfatal (bfd_get_filename (obfd));
977         }
978       free (memhunk);
979     }
980 }
981
982 /* Get all the sections.  This is used when --gap-fill or --pad-to is
983    used.  */
984
985 static void
986 get_sections (obfd, osection, secppparg)
987      bfd *obfd;
988      asection *osection;
989      PTR secppparg;
990 {
991   asection ***secppp = (asection ***) secppparg;
992
993   **secppp = osection;
994   ++(*secppp);
995 }
996
997 /* Sort sections by VMA.  This is called via qsort, and is used when
998    --gap-fill or --pad-to is used.  We force non loadable or empty
999    sections to the front, where they are easier to ignore.  */
1000
1001 static int
1002 compare_section_vma (arg1, arg2)
1003      const PTR arg1;
1004      const PTR arg2;
1005 {
1006   const asection **sec1 = (const asection **) arg1;
1007   const asection **sec2 = (const asection **) arg2;
1008   flagword flags1, flags2;
1009
1010   /* Sort non loadable sections to the front.  */
1011   flags1 = (*sec1)->flags;
1012   flags2 = (*sec2)->flags;
1013   if ((flags1 & SEC_HAS_CONTENTS) == 0
1014       || (flags1 & SEC_LOAD) == 0)
1015     {
1016       if ((flags2 & SEC_HAS_CONTENTS) != 0
1017           && (flags2 & SEC_LOAD) != 0)
1018         return -1;
1019     }
1020   else
1021     {
1022       if ((flags2 & SEC_HAS_CONTENTS) == 0
1023           || (flags2 & SEC_LOAD) == 0)
1024         return 1;
1025     }
1026
1027   /* Sort sections by VMA.  */
1028   if ((*sec1)->vma > (*sec2)->vma)
1029     return 1;
1030   else if ((*sec1)->vma < (*sec2)->vma)
1031     return -1;
1032
1033   /* Sort sections with the same VMA by size.  */
1034   if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1035     return 1;
1036   else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1037     return -1;
1038
1039   return 0;
1040 }
1041
1042 /* Mark all the symbols which will be used in output relocations with
1043    the BSF_KEEP flag so that those symbols will not be stripped.
1044
1045    Ignore relocations which will not appear in the output file.  */
1046
1047 static void
1048 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1049      bfd *ibfd;
1050      sec_ptr isection;
1051      PTR symbolsarg;
1052 {
1053   asymbol **symbols = (asymbol **) symbolsarg;
1054   long relsize;
1055   arelent **relpp;
1056   long relcount, i;
1057
1058   /* Ignore an input section with no corresponding output section.  */
1059   if (isection->output_section == NULL)
1060     return;
1061
1062   relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1063   if (relsize < 0)
1064     bfd_fatal (bfd_get_filename (ibfd));
1065
1066   relpp = (arelent **) xmalloc (relsize);
1067   relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1068   if (relcount < 0)
1069     bfd_fatal (bfd_get_filename (ibfd));
1070
1071   /* Examine each symbol used in a relocation.  If it's not one of the
1072      special bfd section symbols, then mark it with BSF_KEEP.  */
1073   for (i = 0; i < relcount; i++)
1074     {
1075       if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1076           && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1077           && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1078         (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1079     }
1080
1081   if (relpp != NULL)
1082     free (relpp);
1083 }
1084
1085 /* The number of bytes to copy at once.  */
1086 #define COPY_BUF 8192
1087
1088 /* Copy file FROM to file TO, performing no translations.
1089    Return 0 if ok, -1 if error.  */
1090
1091 static int
1092 simple_copy (from, to)
1093      char *from, *to;
1094 {
1095   int fromfd, tofd, nread;
1096   char buf[COPY_BUF];
1097
1098   fromfd = open (from, O_RDONLY);
1099   if (fromfd < 0)
1100     return -1;
1101   tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
1102   if (tofd < 0)
1103     {
1104       close (fromfd);
1105       return -1;
1106     }
1107   while ((nread = read (fromfd, buf, sizeof buf)) > 0)
1108     {
1109       if (write (tofd, buf, nread) != nread)
1110         {
1111           close (fromfd);
1112           close (tofd);
1113           return -1;
1114         }
1115     }
1116   close (fromfd);
1117   close (tofd);
1118   if (nread < 0)
1119     return -1;
1120   return 0;
1121 }
1122
1123 #ifndef S_ISLNK
1124 #ifdef S_IFLNK
1125 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1126 #else
1127 #define S_ISLNK(m) 0
1128 #define lstat stat
1129 #endif
1130 #endif
1131
1132 /* Rename FROM to TO, copying if TO is a link.
1133    Assumes that TO already exists, because FROM is a temp file.
1134    Return 0 if ok, -1 if error.  */
1135
1136 static int
1137 smart_rename (from, to)
1138      char *from, *to;
1139 {
1140   struct stat s;
1141   int ret = 0;
1142
1143   if (lstat (to, &s))
1144     return -1;
1145
1146   /* Use rename only if TO is not a symbolic link and has
1147      only one hard link.  */
1148   if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
1149     {
1150       ret = rename (from, to);
1151       if (ret == 0)
1152         {
1153           /* Try to preserve the permission bits and ownership of TO.  */
1154           chmod (to, s.st_mode & 07777);
1155           chown (to, s.st_uid, s.st_gid);
1156         }
1157     }
1158   else
1159     {
1160       ret = simple_copy (from, to);
1161       if (ret == 0)
1162         unlink (from);
1163     }
1164   return ret;
1165 }
1166
1167 static int
1168 strip_main (argc, argv)
1169      int argc;
1170      char *argv[];
1171 {
1172   char *input_target = NULL, *output_target = NULL;
1173   boolean show_version = false;
1174   int c, i;
1175
1176   while ((c = getopt_long (argc, argv, "I:O:F:R:sSgxXVvN:",
1177                            strip_options, (int *) 0)) != EOF)
1178     {
1179       switch (c)
1180         {
1181         case 'I':
1182           input_target = optarg;
1183           break;
1184         case 'O':
1185           output_target = optarg;
1186           break;
1187         case 'F':
1188           input_target = output_target = optarg;
1189           break;
1190         case 'R':
1191           {
1192             struct section_list *n;
1193
1194             n = (struct section_list *) xmalloc (sizeof (struct section_list));
1195             n->name = optarg;
1196             n->used = false;
1197             n->next = remove_sections;
1198             remove_sections = n;
1199           }
1200           break;
1201         case 's':
1202           strip_symbols = strip_all;
1203           break;
1204         case 'S':
1205         case 'g':
1206           strip_symbols = strip_debug;
1207           break;
1208         case 'N':
1209           add_strip_symbol (optarg);
1210           break;
1211         case 'x':
1212           discard_locals = locals_all;
1213           break;
1214         case 'X':
1215           discard_locals = locals_start_L;
1216           break;
1217         case 'v':
1218           verbose = true;
1219           break;
1220         case 'V':
1221           show_version = true;
1222           break;
1223         case 0:
1224           break;                /* we've been given a long option */
1225         case 'h':
1226           strip_usage (stdout, 0);
1227         default:
1228           strip_usage (stderr, 1);
1229         }
1230     }
1231
1232   if (show_version)
1233     {
1234       printf ("GNU %s version %s\n", program_name, program_version);
1235       exit (0);
1236     }
1237
1238   /* Default is to strip all symbols.  */
1239   if (strip_symbols == strip_undef
1240       && discard_locals == locals_undef
1241       && strip_specific_list == NULL)
1242     strip_symbols = strip_all;
1243
1244   if (output_target == (char *) NULL)
1245     output_target = input_target;
1246
1247   i = optind;
1248   if (i == argc)
1249     strip_usage (stderr, 1);
1250
1251   for (; i < argc; i++)
1252     {
1253       int hold_status = status;
1254
1255       char *tmpname = make_tempname (argv[i]);
1256       status = 0;
1257       copy_file (argv[i], tmpname, input_target, output_target);
1258       if (status == 0)
1259         {
1260           smart_rename (tmpname, argv[i]);
1261           status = hold_status;
1262         }
1263       else
1264         unlink (tmpname);
1265       free (tmpname);
1266     }
1267
1268   return 0;
1269 }
1270
1271 static int
1272 copy_main (argc, argv)
1273      int argc;
1274      char *argv[];
1275 {
1276   char *input_filename = NULL, *output_filename = NULL;
1277   char *input_target = NULL, *output_target = NULL;
1278   boolean show_version = false;
1279   boolean adjust_warn = true;
1280   int c;
1281   struct section_list *p;
1282
1283   while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:R:SgxXVvN:",
1284                            copy_options, (int *) 0)) != EOF)
1285     {
1286       switch (c)
1287         {
1288         case 'b':
1289           copy_byte = atoi(optarg);
1290           if (copy_byte < 0)
1291             {
1292               fprintf (stderr, "%s: byte number must be non-negative\n",
1293                        program_name);
1294               exit (1);
1295             }
1296           break;
1297         case 'i':
1298           interleave = atoi(optarg);
1299           if (interleave < 1)
1300             {
1301               fprintf(stderr, "%s: interleave must be positive\n",
1302                       program_name);
1303               exit (1);
1304             }
1305           break;
1306         case 'I':
1307         case 's':               /* "source" - 'I' is preferred */
1308           input_target = optarg;
1309           break;
1310         case 'O':
1311         case 'd':               /* "destination" - 'O' is preferred */
1312           output_target = optarg;
1313           break;
1314         case 'F':
1315           input_target = output_target = optarg;
1316           break;
1317         case 'R':
1318           p = (struct section_list *) xmalloc (sizeof (struct section_list));
1319           p->name = optarg;
1320           p->used = false;
1321           p->next = remove_sections;
1322           remove_sections = p;
1323           break;
1324         case 'S':
1325           strip_symbols = strip_all;
1326           break;
1327         case 'g':
1328           strip_symbols = strip_debug;
1329           break;
1330         case 'N':
1331           add_strip_symbol (optarg);
1332           break;
1333         case 'x':
1334           discard_locals = locals_all;
1335           break;
1336         case 'X':
1337           discard_locals = locals_start_L;
1338           break;
1339         case 'v':
1340           verbose = true;
1341           break;
1342         case 'V':
1343           show_version = true;
1344           break;
1345         case OPTION_ADJUST_START:
1346           adjust_start = parse_vma (optarg, "--adjust-start");
1347           break;
1348         case OPTION_ADJUST_SECTION_VMA:
1349           {
1350             const char *s;
1351             int len;
1352             char *name;
1353
1354             p = (struct section_list *) xmalloc (sizeof (struct section_list));
1355             s = strchr (optarg, '=');
1356             if (s != NULL)
1357               {
1358                 p->adjust = false;
1359                 p->val = parse_vma (s + 1, "--adjust-section-vma");
1360               }
1361             else
1362               {
1363                 s = strchr (optarg, '+');
1364                 if (s == NULL)
1365                   {
1366                     s = strchr (optarg, '-');
1367                     if (s == NULL)
1368                       {
1369                         fprintf (stderr,
1370                                  "%s: bad format for --adjust-section-vma\n",
1371                                  program_name);
1372                         exit (1);
1373                       }
1374                   }
1375                 p->adjust = true;
1376                 p->val = parse_vma (s + 1, "--adjust-section-vma");
1377                 if (*s == '-')
1378                   p->val = - p->val;
1379               }
1380
1381             len = s - optarg;
1382             name = (char *) xmalloc (len + 1);
1383             strncpy (name, optarg, len);
1384             name[len] = '\0';
1385             p->name = name;
1386
1387             p->used = false;
1388
1389             p->next = adjust_sections;
1390             adjust_sections = p;
1391           }
1392           break;
1393         case OPTION_ADJUST_VMA:
1394           adjust_section_vma = parse_vma (optarg, "--adjust-vma");
1395           adjust_start = adjust_section_vma;
1396           break;
1397         case OPTION_ADJUST_WARNINGS:
1398           adjust_warn = true;
1399           break;
1400         case OPTION_GAP_FILL:
1401           {
1402             bfd_vma gap_fill_vma;
1403
1404             gap_fill_vma = parse_vma (optarg, "--gap-fill");
1405             gap_fill = (bfd_byte) gap_fill_vma;
1406             if ((bfd_vma) gap_fill != gap_fill_vma)
1407               {
1408                 fprintf (stderr, "%s: warning: truncating gap-fill from 0x",
1409                          program_name);
1410                 fprintf_vma (stderr, gap_fill_vma);
1411                 fprintf (stderr, "to 0x%x\n", (unsigned int) gap_fill);
1412               }
1413             gap_fill_set = true;
1414           }
1415           break;
1416         case OPTION_NO_ADJUST_WARNINGS:
1417           adjust_warn = false;
1418           break;
1419         case OPTION_PAD_TO:
1420           pad_to = parse_vma (optarg, "--pad-to");
1421           pad_to_set = true;
1422           break;
1423         case OPTION_SET_START:
1424           set_start = parse_vma (optarg, "--set-start");
1425           set_start_set = true;
1426           break;
1427         case 0:
1428           break;                /* we've been given a long option */
1429         case 'h':
1430           copy_usage (stdout, 0);
1431         default:
1432           copy_usage (stderr, 1);
1433         }
1434     }
1435
1436   if (show_version)
1437     {
1438       printf ("GNU %s version %s\n", program_name, program_version);
1439       exit (0);
1440     }
1441
1442   if (copy_byte >= interleave)
1443     {
1444       fprintf (stderr, "%s: byte number must be less than interleave\n",
1445                program_name);
1446       exit (1);
1447     }
1448
1449   if (optind == argc || optind + 2 < argc)
1450     copy_usage (stderr, 1);
1451
1452   input_filename = argv[optind];
1453   if (optind + 1 < argc)
1454     output_filename = argv[optind + 1];
1455
1456   /* Default is to strip no symbols.  */
1457   if (strip_symbols == strip_undef && discard_locals == locals_undef)
1458     strip_symbols = strip_none;
1459
1460   if (output_target == (char *) NULL)
1461     output_target = input_target;
1462
1463   /* If there is no destination file then create a temp and rename
1464      the result into the input.  */
1465
1466   if (output_filename == (char *) NULL)
1467     {
1468       char *tmpname = make_tempname (input_filename);
1469       copy_file (input_filename, tmpname, input_target, output_target);
1470       if (status == 0)
1471         smart_rename (tmpname, input_filename);
1472       else
1473         unlink (tmpname);
1474     }
1475   else
1476     {
1477       copy_file (input_filename, output_filename, input_target, output_target);
1478     }
1479
1480   if (adjust_warn)
1481     {
1482       for (p = adjust_sections; p != NULL; p = p->next)
1483         {
1484           if (! p->used)
1485             {
1486               fprintf (stderr, "%s: warning: --adjust-section-vma %s%c0x",
1487                        program_name, p->name,
1488                        p->adjust ? '=' : '+');
1489               fprintf_vma (stderr, p->val);
1490               fprintf (stderr, " never used\n");
1491             }
1492         }
1493     }
1494
1495   /* We could issue similar warnings for remove_sections, but I don't
1496      think that would be as useful.  */
1497
1498   return 0;
1499 }
1500
1501 int
1502 main (argc, argv)
1503      int argc;
1504      char *argv[];
1505 {
1506   program_name = argv[0];
1507   xmalloc_set_program_name (program_name);
1508   strip_symbols = strip_undef;
1509   discard_locals = locals_undef;
1510
1511   bfd_init ();
1512
1513   if (is_strip < 0)
1514     {
1515       int i = strlen (program_name);
1516       is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0);
1517     }
1518
1519   if (is_strip)
1520     strip_main (argc, argv);
1521   else
1522     copy_main (argc, argv);
1523
1524   return status;
1525 }
This page took 0.114341 seconds and 4 git commands to generate.