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