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