* arc.h (ARC_MACH_{BASE,HOST,GRAPHICS,AUDIO}): Define.
[deliverable/binutils-gdb.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.112426 seconds and 4 git commands to generate.