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