Wed Jul 12 10:40:23 1995 H.J. Lu <hjl@nynexst.com>
[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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 bfd *obfd;
824 } *list, *l;
825 bfd **ptr = &obfd->archive_head;
826 bfd *this_element;
827 char *dir = make_tempname (bfd_get_filename (obfd));
828
829 /* Make a temp directory to hold the contents. */
830 if (mkdir (dir, 0700) != 0)
831 {
832 fatal ("cannot mkdir %s for archive copying (error: %s)",
833 dir, strerror (errno));
834 }
835 obfd->has_armap = ibfd->has_armap;
836
837 list = NULL;
838
839 this_element = bfd_openr_next_archived_file (ibfd, NULL);
840 while (this_element != (bfd *) NULL)
841 {
842 /* Create an output file for this member. */
843 char *output_name = cat (dir, "/", bfd_get_filename(this_element));
844 bfd *output_bfd = bfd_openw (output_name, output_target);
845 bfd *last_element;
846
847 l = (struct name_list *) xmalloc (sizeof (struct name_list));
848 l->name = output_name;
849 l->next = list;
850 list = l;
851
852 if (output_bfd == (bfd *) NULL)
853 {
854 nonfatal (output_name);
855 }
856 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
857 {
858 nonfatal (bfd_get_filename (obfd));
859 }
860
861 if (bfd_check_format (this_element, bfd_object) == true)
862 {
863 copy_object (this_element, output_bfd);
864 }
865
866 bfd_close (output_bfd);
867
868 /* Open the newly output file and attach to our list. */
869 output_bfd = bfd_openr (output_name, output_target);
870
871 l->obfd = output_bfd;
872
873 *ptr = output_bfd;
874 ptr = &output_bfd->next;
875
876 last_element = this_element;
877
878 this_element = bfd_openr_next_archived_file (ibfd, last_element);
879
880 bfd_close (last_element);
881 }
882 *ptr = (bfd *) NULL;
883
884 if (!bfd_close (obfd))
885 {
886 nonfatal (bfd_get_filename (obfd));
887 }
888
889 if (!bfd_close (ibfd))
890 {
891 nonfatal (bfd_get_filename (ibfd));
892 }
893
894 /* Delete all the files that we opened. */
895 for (l = list; l != NULL; l = l->next)
896 {
897 bfd_close (l->obfd);
898 unlink (l->name);
899 }
900 rmdir (dir);
901 }
902
903 /* The top-level control. */
904
905 static void
906 copy_file (input_filename, output_filename, input_target, output_target)
907 char *input_filename;
908 char *output_filename;
909 char *input_target;
910 char *output_target;
911 {
912 bfd *ibfd;
913 char **matching;
914
915 /* To allow us to do "strip *" without dying on the first
916 non-object file, failures are nonfatal. */
917
918 ibfd = bfd_openr (input_filename, input_target);
919 if (ibfd == NULL)
920 {
921 nonfatal (input_filename);
922 }
923
924 if (bfd_check_format (ibfd, bfd_archive))
925 {
926 bfd *obfd;
927
928 /* bfd_get_target does not return the correct value until
929 bfd_check_format succeeds. */
930 if (output_target == NULL)
931 output_target = bfd_get_target (ibfd);
932
933 obfd = bfd_openw (output_filename, output_target);
934 if (obfd == NULL)
935 {
936 nonfatal (output_filename);
937 }
938 copy_archive (ibfd, obfd, output_target);
939 }
940 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
941 {
942 bfd *obfd;
943
944 /* bfd_get_target does not return the correct value until
945 bfd_check_format succeeds. */
946 if (output_target == NULL)
947 output_target = bfd_get_target (ibfd);
948
949 obfd = bfd_openw (output_filename, output_target);
950 if (obfd == NULL)
951 {
952 nonfatal (output_filename);
953 }
954
955 copy_object (ibfd, obfd);
956
957 if (!bfd_close (obfd))
958 {
959 nonfatal (output_filename);
960 }
961
962 if (!bfd_close (ibfd))
963 {
964 nonfatal (input_filename);
965 }
966 }
967 else
968 {
969 bfd_nonfatal (input_filename);
970 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
971 {
972 list_matching_formats (matching);
973 free (matching);
974 }
975 status = 1;
976 }
977 }
978
979 /* Create a section in OBFD with the same name and attributes
980 as ISECTION in IBFD. */
981
982 static void
983 setup_section (ibfd, isection, obfdarg)
984 bfd *ibfd;
985 sec_ptr isection;
986 PTR obfdarg;
987 {
988 bfd *obfd = (bfd *) obfdarg;
989 struct section_list *p;
990 sec_ptr osection;
991 bfd_vma vma;
992 flagword flags;
993 char *err;
994
995 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
996 && (strip_symbols == strip_debug
997 || strip_symbols == strip_unneeded
998 || strip_symbols == strip_all
999 || discard_locals == locals_all))
1000 return;
1001
1002 p = find_section_list (bfd_section_name (ibfd, isection), false);
1003 if (p != NULL)
1004 p->used = true;
1005
1006 if (p != NULL && p->remove)
1007 return;
1008
1009 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1010 if (osection == NULL)
1011 {
1012 err = "making";
1013 goto loser;
1014 }
1015
1016 if (!bfd_set_section_size (obfd,
1017 osection,
1018 bfd_section_size (ibfd, isection)))
1019 {
1020 err = "size";
1021 goto loser;
1022 }
1023
1024 vma = bfd_section_vma (ibfd, isection);
1025 if (p != NULL && p->adjust == adjust_vma)
1026 vma += p->val;
1027 else if (p != NULL && p->adjust == set_vma)
1028 vma = p->val;
1029 else
1030 vma += adjust_section_vma;
1031 if (! bfd_set_section_vma (obfd, osection, vma))
1032 {
1033 err = "vma";
1034 goto loser;
1035 }
1036
1037 if (bfd_set_section_alignment (obfd,
1038 osection,
1039 bfd_section_alignment (ibfd, isection))
1040 == false)
1041 {
1042 err = "alignment";
1043 goto loser;
1044 }
1045
1046 flags = bfd_get_section_flags (ibfd, isection);
1047 if (p != NULL && p->set_flags)
1048 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1049 if (!bfd_set_section_flags (obfd, osection, flags))
1050 {
1051 err = "flags";
1052 goto loser;
1053 }
1054
1055 /* This used to be mangle_section; we do here to avoid using
1056 bfd_get_section_by_name since some formats allow multiple
1057 sections with the same name. */
1058 isection->output_section = osection;
1059 isection->output_offset = 0;
1060
1061 /* Allow the BFD backend to copy any private data it understands
1062 from the input section to the output section. */
1063 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1064 {
1065 err = "private data";
1066 goto loser;
1067 }
1068
1069 /* All went well */
1070 return;
1071
1072 loser:
1073 fprintf (stderr, "%s: %s: section `%s': error in %s: %s\n",
1074 program_name,
1075 bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
1076 err, bfd_errmsg (bfd_get_error ()));
1077 status = 1;
1078 }
1079
1080 /* Copy the data of input section ISECTION of IBFD
1081 to an output section with the same name in OBFD.
1082 If stripping then don't copy any relocation info. */
1083
1084 static void
1085 copy_section (ibfd, isection, obfdarg)
1086 bfd *ibfd;
1087 sec_ptr isection;
1088 PTR obfdarg;
1089 {
1090 bfd *obfd = (bfd *) obfdarg;
1091 struct section_list *p;
1092 arelent **relpp;
1093 long relcount;
1094 sec_ptr osection;
1095 bfd_size_type size;
1096
1097 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1098 && (strip_symbols == strip_debug
1099 || strip_symbols == strip_unneeded
1100 || strip_symbols == strip_all
1101 || discard_locals == locals_all))
1102 {
1103 return;
1104 }
1105
1106 p = find_section_list (bfd_section_name (ibfd, isection), false);
1107
1108 if (p != NULL && p->remove)
1109 return;
1110
1111 osection = isection->output_section;
1112 size = bfd_get_section_size_before_reloc (isection);
1113
1114 if (size == 0 || osection == 0)
1115 return;
1116
1117 if (strip_symbols == strip_all)
1118 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1119 else
1120 {
1121 long relsize;
1122
1123 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1124 if (relsize < 0)
1125 {
1126 nonfatal (bfd_get_filename (ibfd));
1127 }
1128 if (relsize == 0)
1129 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1130 else
1131 {
1132 relpp = (arelent **) xmalloc (relsize);
1133 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1134 if (relcount < 0)
1135 {
1136 nonfatal (bfd_get_filename (ibfd));
1137 }
1138 bfd_set_reloc (obfd, osection, relpp, relcount);
1139 }
1140 }
1141
1142 isection->_cooked_size = isection->_raw_size;
1143 isection->reloc_done = true;
1144
1145 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1146 {
1147 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1148
1149 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1150 size))
1151 {
1152 nonfatal (bfd_get_filename (ibfd));
1153 }
1154
1155 if (copy_byte >= 0)
1156 {
1157 filter_bytes (memhunk, &size);
1158 /* The section has gotten smaller. */
1159 if (!bfd_set_section_size (obfd, osection, size))
1160 nonfatal (bfd_get_filename (obfd));
1161 }
1162
1163 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1164 size))
1165 {
1166 nonfatal (bfd_get_filename (obfd));
1167 }
1168 free (memhunk);
1169 }
1170 }
1171
1172 /* Get all the sections. This is used when --gap-fill or --pad-to is
1173 used. */
1174
1175 static void
1176 get_sections (obfd, osection, secppparg)
1177 bfd *obfd;
1178 asection *osection;
1179 PTR secppparg;
1180 {
1181 asection ***secppp = (asection ***) secppparg;
1182
1183 **secppp = osection;
1184 ++(*secppp);
1185 }
1186
1187 /* Sort sections by VMA. This is called via qsort, and is used when
1188 --gap-fill or --pad-to is used. We force non loadable or empty
1189 sections to the front, where they are easier to ignore. */
1190
1191 static int
1192 compare_section_vma (arg1, arg2)
1193 const PTR arg1;
1194 const PTR arg2;
1195 {
1196 const asection **sec1 = (const asection **) arg1;
1197 const asection **sec2 = (const asection **) arg2;
1198 flagword flags1, flags2;
1199
1200 /* Sort non loadable sections to the front. */
1201 flags1 = (*sec1)->flags;
1202 flags2 = (*sec2)->flags;
1203 if ((flags1 & SEC_HAS_CONTENTS) == 0
1204 || (flags1 & SEC_LOAD) == 0)
1205 {
1206 if ((flags2 & SEC_HAS_CONTENTS) != 0
1207 && (flags2 & SEC_LOAD) != 0)
1208 return -1;
1209 }
1210 else
1211 {
1212 if ((flags2 & SEC_HAS_CONTENTS) == 0
1213 || (flags2 & SEC_LOAD) == 0)
1214 return 1;
1215 }
1216
1217 /* Sort sections by VMA. */
1218 if ((*sec1)->vma > (*sec2)->vma)
1219 return 1;
1220 else if ((*sec1)->vma < (*sec2)->vma)
1221 return -1;
1222
1223 /* Sort sections with the same VMA by size. */
1224 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1225 return 1;
1226 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1227 return -1;
1228
1229 return 0;
1230 }
1231
1232 /* Mark all the symbols which will be used in output relocations with
1233 the BSF_KEEP flag so that those symbols will not be stripped.
1234
1235 Ignore relocations which will not appear in the output file. */
1236
1237 static void
1238 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1239 bfd *ibfd;
1240 sec_ptr isection;
1241 PTR symbolsarg;
1242 {
1243 asymbol **symbols = (asymbol **) symbolsarg;
1244 long relsize;
1245 arelent **relpp;
1246 long relcount, i;
1247
1248 /* Ignore an input section with no corresponding output section. */
1249 if (isection->output_section == NULL)
1250 return;
1251
1252 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1253 if (relsize < 0)
1254 bfd_fatal (bfd_get_filename (ibfd));
1255
1256 relpp = (arelent **) xmalloc (relsize);
1257 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1258 if (relcount < 0)
1259 bfd_fatal (bfd_get_filename (ibfd));
1260
1261 /* Examine each symbol used in a relocation. If it's not one of the
1262 special bfd section symbols, then mark it with BSF_KEEP. */
1263 for (i = 0; i < relcount; i++)
1264 {
1265 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1266 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1267 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1268 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1269 }
1270
1271 if (relpp != NULL)
1272 free (relpp);
1273 }
1274
1275 /* The number of bytes to copy at once. */
1276 #define COPY_BUF 8192
1277
1278 /* Copy file FROM to file TO, performing no translations.
1279 Return 0 if ok, -1 if error. */
1280
1281 static int
1282 simple_copy (from, to)
1283 char *from, *to;
1284 {
1285 int fromfd, tofd, nread;
1286 int saved;
1287 char buf[COPY_BUF];
1288
1289 fromfd = open (from, O_RDONLY);
1290 if (fromfd < 0)
1291 return -1;
1292 tofd = open (to, O_WRONLY | O_CREAT | O_TRUNC);
1293 if (tofd < 0)
1294 {
1295 saved = errno;
1296 close (fromfd);
1297 errno = saved;
1298 return -1;
1299 }
1300 while ((nread = read (fromfd, buf, sizeof buf)) > 0)
1301 {
1302 if (write (tofd, buf, nread) != nread)
1303 {
1304 saved = errno;
1305 close (fromfd);
1306 close (tofd);
1307 errno = saved;
1308 return -1;
1309 }
1310 }
1311 saved = errno;
1312 close (fromfd);
1313 close (tofd);
1314 if (nread < 0)
1315 {
1316 errno = saved;
1317 return -1;
1318 }
1319 return 0;
1320 }
1321
1322 #ifndef S_ISLNK
1323 #ifdef S_IFLNK
1324 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1325 #else
1326 #define S_ISLNK(m) 0
1327 #define lstat stat
1328 #endif
1329 #endif
1330
1331 /* Rename FROM to TO, copying if TO is a link.
1332 Assumes that TO already exists, because FROM is a temp file.
1333 Return 0 if ok, -1 if error. */
1334
1335 static int
1336 smart_rename (from, to)
1337 char *from, *to;
1338 {
1339 struct stat s;
1340 int ret = 0;
1341
1342 if (lstat (to, &s))
1343 return -1;
1344
1345 /* Use rename only if TO is not a symbolic link and has
1346 only one hard link. */
1347 if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
1348 {
1349 ret = rename (from, to);
1350 if (ret == 0)
1351 {
1352 /* Try to preserve the permission bits and ownership of TO. */
1353 chmod (to, s.st_mode & 07777);
1354 chown (to, s.st_uid, s.st_gid);
1355 }
1356 else
1357 {
1358 /* We have to clean up here. */
1359 int saved = errno;
1360 fprintf (stderr, "%s: %s: ", program_name, to);
1361 errno = saved;
1362 perror ("rename");
1363 unlink (from);
1364 }
1365 }
1366 else
1367 {
1368 ret = simple_copy (from, to);
1369 if (ret != 0)
1370 {
1371 int saved = errno;
1372 fprintf (stderr, "%s: %s: ", program_name, to);
1373 errno = saved;
1374 perror ("simple_copy");
1375 }
1376 unlink (from);
1377 }
1378 return ret;
1379 }
1380
1381 static int
1382 strip_main (argc, argv)
1383 int argc;
1384 char *argv[];
1385 {
1386 char *input_target = NULL, *output_target = NULL;
1387 boolean show_version = false;
1388 int c, i;
1389 struct section_list *p;
1390
1391 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:sSgxXVv",
1392 strip_options, (int *) 0)) != EOF)
1393 {
1394 switch (c)
1395 {
1396 case 'I':
1397 input_target = optarg;
1398 break;
1399 case 'O':
1400 output_target = optarg;
1401 break;
1402 case 'F':
1403 input_target = output_target = optarg;
1404 break;
1405 case 'R':
1406 p = find_section_list (optarg, true);
1407 p->remove = true;
1408 sections_removed = true;
1409 break;
1410 case 's':
1411 strip_symbols = strip_all;
1412 break;
1413 case 'S':
1414 case 'g':
1415 strip_symbols = strip_debug;
1416 break;
1417 case OPTION_STRIP_UNNEEDED:
1418 strip_symbols = strip_unneeded;
1419 break;
1420 case 'K':
1421 if (! keep_symbols && strip_specific_list != NULL)
1422 {
1423 fprintf (stderr, "%s: Can not specify both -K and -N\n",
1424 program_name);
1425 strip_usage (stderr, 1);
1426 }
1427 keep_symbols = true;
1428 add_strip_symbol (optarg);
1429 break;
1430 case 'N':
1431 if (keep_symbols)
1432 {
1433 fprintf (stderr, "%s: Can not specify both -K and -N\n",
1434 program_name);
1435 strip_usage (stderr, 1);
1436 }
1437 add_strip_symbol (optarg);
1438 break;
1439 case 'x':
1440 discard_locals = locals_all;
1441 break;
1442 case 'X':
1443 discard_locals = locals_start_L;
1444 break;
1445 case 'v':
1446 verbose = true;
1447 break;
1448 case 'V':
1449 show_version = true;
1450 break;
1451 case 0:
1452 break; /* we've been given a long option */
1453 case 'h':
1454 strip_usage (stdout, 0);
1455 default:
1456 strip_usage (stderr, 1);
1457 }
1458 }
1459
1460 if (show_version)
1461 {
1462 printf ("GNU %s version %s\n", program_name, program_version);
1463 exit (0);
1464 }
1465
1466 /* Default is to strip all symbols. */
1467 if (strip_symbols == strip_undef
1468 && discard_locals == locals_undef
1469 && strip_specific_list == NULL)
1470 strip_symbols = strip_all;
1471
1472 if (output_target == (char *) NULL)
1473 output_target = input_target;
1474
1475 i = optind;
1476 if (i == argc)
1477 strip_usage (stderr, 1);
1478
1479 for (; i < argc; i++)
1480 {
1481 int hold_status = status;
1482
1483 char *tmpname = make_tempname (argv[i]);
1484 status = 0;
1485 copy_file (argv[i], tmpname, input_target, output_target);
1486 if (status == 0)
1487 {
1488 smart_rename (tmpname, argv[i]);
1489 status = hold_status;
1490 }
1491 else
1492 unlink (tmpname);
1493 free (tmpname);
1494 }
1495
1496 return 0;
1497 }
1498
1499 static int
1500 copy_main (argc, argv)
1501 int argc;
1502 char *argv[];
1503 {
1504 char *input_filename = NULL, *output_filename = NULL;
1505 char *input_target = NULL, *output_target = NULL;
1506 boolean show_version = false;
1507 boolean adjust_warn = true;
1508 int c;
1509 struct section_list *p;
1510
1511 while ((c = getopt_long (argc, argv, "b:i:I:K:N:s:O:d:F:R:SgxXVv",
1512 copy_options, (int *) 0)) != EOF)
1513 {
1514 switch (c)
1515 {
1516 case 'b':
1517 copy_byte = atoi(optarg);
1518 if (copy_byte < 0)
1519 {
1520 fprintf (stderr, "%s: byte number must be non-negative\n",
1521 program_name);
1522 exit (1);
1523 }
1524 break;
1525 case 'i':
1526 interleave = atoi(optarg);
1527 if (interleave < 1)
1528 {
1529 fprintf(stderr, "%s: interleave must be positive\n",
1530 program_name);
1531 exit (1);
1532 }
1533 break;
1534 case 'I':
1535 case 's': /* "source" - 'I' is preferred */
1536 input_target = optarg;
1537 break;
1538 case 'O':
1539 case 'd': /* "destination" - 'O' is preferred */
1540 output_target = optarg;
1541 break;
1542 case 'F':
1543 input_target = output_target = optarg;
1544 break;
1545 case 'R':
1546 p = find_section_list (optarg, true);
1547 p->remove = true;
1548 sections_removed = true;
1549 break;
1550 case 'S':
1551 strip_symbols = strip_all;
1552 break;
1553 case 'g':
1554 strip_symbols = strip_debug;
1555 break;
1556 case OPTION_STRIP_UNNEEDED:
1557 strip_symbols = strip_unneeded;
1558 break;
1559 case 'K':
1560 if (! keep_symbols && strip_specific_list != NULL)
1561 {
1562 fprintf (stderr, "%s: Can not specify both -K and -N\n",
1563 program_name);
1564 strip_usage (stderr, 1);
1565 }
1566 keep_symbols = true;
1567 add_strip_symbol (optarg);
1568 break;
1569 case 'N':
1570 if (keep_symbols)
1571 {
1572 fprintf (stderr, "%s: Can not specify both -K and -N\n",
1573 program_name);
1574 strip_usage (stderr, 1);
1575 }
1576 add_strip_symbol (optarg);
1577 break;
1578 case 'x':
1579 discard_locals = locals_all;
1580 break;
1581 case 'X':
1582 discard_locals = locals_start_L;
1583 break;
1584 case 'v':
1585 verbose = true;
1586 break;
1587 case 'V':
1588 show_version = true;
1589 break;
1590 case OPTION_ADD_SECTION:
1591 {
1592 const char *s;
1593 struct stat st;
1594 struct section_add *pa;
1595 int len;
1596 char *name;
1597 FILE *f;
1598
1599 s = strchr (optarg, '=');
1600 if (s == NULL)
1601 {
1602 fprintf (stderr,
1603 "%s: bad format for --add-section NAME=FILENAME\n",
1604 program_name);
1605 exit (1);
1606 }
1607
1608 if (stat (s + 1, &st) < 0)
1609 {
1610 fprintf (stderr, "%s: ", program_name);
1611 perror (s + 1);
1612 exit (1);
1613 }
1614
1615 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1616
1617 len = s - optarg;
1618 name = (char *) xmalloc (len + 1);
1619 strncpy (name, optarg, len);
1620 name[len] = '\0';
1621 pa->name = name;
1622
1623 pa->filename = s + 1;
1624
1625 pa->size = st.st_size;
1626
1627 pa->contents = (bfd_byte *) xmalloc (pa->size);
1628 f = fopen (pa->filename, FOPEN_RB);
1629 if (f == NULL)
1630 {
1631 fprintf (stderr, "%s: ", program_name);
1632 perror (pa->filename);
1633 exit (1);
1634 }
1635 if (fread (pa->contents, 1, pa->size, f) == 0
1636 || ferror (f))
1637 {
1638 fprintf (stderr, "%s: %s: fread failed\n",
1639 program_name, pa->filename);
1640 exit (1);
1641 }
1642 fclose (f);
1643
1644 pa->next = add_sections;
1645 add_sections = pa;
1646 }
1647 break;
1648 case OPTION_ADJUST_START:
1649 adjust_start = parse_vma (optarg, "--adjust-start");
1650 break;
1651 case OPTION_ADJUST_SECTION_VMA:
1652 {
1653 const char *s;
1654 int len;
1655 char *name;
1656
1657 s = strchr (optarg, '=');
1658 if (s == NULL)
1659 {
1660 s = strchr (optarg, '+');
1661 if (s == NULL)
1662 {
1663 s = strchr (optarg, '-');
1664 if (s == NULL)
1665 {
1666 fprintf (stderr,
1667 "%s: bad format for --adjust-section-vma\n",
1668 program_name);
1669 exit (1);
1670 }
1671 }
1672 }
1673
1674 len = s - optarg;
1675 name = (char *) xmalloc (len + 1);
1676 strncpy (name, optarg, len);
1677 name[len] = '\0';
1678
1679 p = find_section_list (name, true);
1680
1681 p->val = parse_vma (s + 1, "--adjust-section-vma");
1682
1683 if (*s == '=')
1684 p->adjust = set_vma;
1685 else
1686 {
1687 p->adjust = adjust_vma;
1688 if (*s == '-')
1689 p->val = - p->val;
1690 }
1691 }
1692 break;
1693 case OPTION_ADJUST_VMA:
1694 adjust_section_vma = parse_vma (optarg, "--adjust-vma");
1695 adjust_start = adjust_section_vma;
1696 break;
1697 case OPTION_ADJUST_WARNINGS:
1698 adjust_warn = true;
1699 break;
1700 case OPTION_GAP_FILL:
1701 {
1702 bfd_vma gap_fill_vma;
1703
1704 gap_fill_vma = parse_vma (optarg, "--gap-fill");
1705 gap_fill = (bfd_byte) gap_fill_vma;
1706 if ((bfd_vma) gap_fill != gap_fill_vma)
1707 {
1708 fprintf (stderr, "%s: warning: truncating gap-fill from 0x",
1709 program_name);
1710 fprintf_vma (stderr, gap_fill_vma);
1711 fprintf (stderr, "to 0x%x\n", (unsigned int) gap_fill);
1712 }
1713 gap_fill_set = true;
1714 }
1715 break;
1716 case OPTION_NO_ADJUST_WARNINGS:
1717 adjust_warn = false;
1718 break;
1719 case OPTION_PAD_TO:
1720 pad_to = parse_vma (optarg, "--pad-to");
1721 pad_to_set = true;
1722 break;
1723 case OPTION_SET_SECTION_FLAGS:
1724 {
1725 const char *s;
1726 int len;
1727 char *name;
1728
1729 s = strchr (optarg, '=');
1730 if (s == NULL)
1731 {
1732 fprintf (stderr, "%s: bad format for --set-section-flags\n",
1733 program_name);
1734 exit (1);
1735 }
1736
1737 len = s - optarg;
1738 name = (char *) xmalloc (len + 1);
1739 strncpy (name, optarg, len);
1740 name[len] = '\0';
1741
1742 p = find_section_list (name, true);
1743
1744 p->set_flags = true;
1745 p->flags = parse_flags (s + 1);
1746 }
1747 break;
1748 case OPTION_SET_START:
1749 set_start = parse_vma (optarg, "--set-start");
1750 set_start_set = true;
1751 break;
1752 case 0:
1753 break; /* we've been given a long option */
1754 case 'h':
1755 copy_usage (stdout, 0);
1756 default:
1757 copy_usage (stderr, 1);
1758 }
1759 }
1760
1761 if (show_version)
1762 {
1763 printf ("GNU %s version %s\n", program_name, program_version);
1764 exit (0);
1765 }
1766
1767 if (copy_byte >= interleave)
1768 {
1769 fprintf (stderr, "%s: byte number must be less than interleave\n",
1770 program_name);
1771 exit (1);
1772 }
1773
1774 if (optind == argc || optind + 2 < argc)
1775 copy_usage (stderr, 1);
1776
1777 input_filename = argv[optind];
1778 if (optind + 1 < argc)
1779 output_filename = argv[optind + 1];
1780
1781 /* Default is to strip no symbols. */
1782 if (strip_symbols == strip_undef && discard_locals == locals_undef)
1783 strip_symbols = strip_none;
1784
1785 if (output_target == (char *) NULL)
1786 output_target = input_target;
1787
1788 /* If there is no destination file then create a temp and rename
1789 the result into the input. */
1790
1791 if (output_filename == (char *) NULL)
1792 {
1793 char *tmpname = make_tempname (input_filename);
1794 copy_file (input_filename, tmpname, input_target, output_target);
1795 if (status == 0)
1796 smart_rename (tmpname, input_filename);
1797 else
1798 unlink (tmpname);
1799 }
1800 else
1801 {
1802 copy_file (input_filename, output_filename, input_target, output_target);
1803 }
1804
1805 if (adjust_warn)
1806 {
1807 for (p = adjust_sections; p != NULL; p = p->next)
1808 {
1809 if (! p->used && p->adjust != ignore_vma)
1810 {
1811 fprintf (stderr, "%s: warning: --adjust-section-vma %s%c0x",
1812 program_name, p->name,
1813 p->adjust == set_vma ? '=' : '+');
1814 fprintf_vma (stderr, p->val);
1815 fprintf (stderr, " never used\n");
1816 }
1817 }
1818 }
1819
1820 return 0;
1821 }
1822
1823 int
1824 main (argc, argv)
1825 int argc;
1826 char *argv[];
1827 {
1828 program_name = argv[0];
1829 xmalloc_set_program_name (program_name);
1830
1831 START_PROGRESS (program_name, 0);
1832
1833 strip_symbols = strip_undef;
1834 discard_locals = locals_undef;
1835
1836 bfd_init ();
1837
1838 if (is_strip < 0)
1839 {
1840 int i = strlen (program_name);
1841 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0);
1842 }
1843
1844 if (is_strip)
1845 strip_main (argc, argv);
1846 else
1847 copy_main (argc, argv);
1848
1849 END_PROGRESS (program_name);
1850
1851 return status;
1852 }
This page took 0.069354 seconds and 5 git commands to generate.