Add --redefine-sym to objcopy.
[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, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21 \f
22 #include "bfd.h"
23 #include "progress.h"
24 #include "bucomm.h"
25 #include "getopt.h"
26 #include "libiberty.h"
27 #include "budbg.h"
28 #include <sys/stat.h>
29
30 /* A list of symbols to explicitly strip out, or to keep. A linked
31 list is good enough for a small number from the command line, but
32 this will slow things down a lot if many symbols are being
33 deleted. */
34
35 struct symlist
36 {
37 const char *name;
38 struct symlist *next;
39 };
40
41 /* A list to support redefine_sym. */
42 struct redefine_node
43 {
44 char *source;
45 char *target;
46 struct redefine_node *next;
47 };
48
49 static void copy_usage PARAMS ((FILE *, int));
50 static void strip_usage PARAMS ((FILE *, int));
51 static flagword parse_flags PARAMS ((const char *));
52 static struct section_list *find_section_list PARAMS ((const char *, boolean));
53 static void setup_section PARAMS ((bfd *, asection *, PTR));
54 static void copy_section PARAMS ((bfd *, asection *, PTR));
55 static void get_sections PARAMS ((bfd *, asection *, PTR));
56 static int compare_section_lma PARAMS ((const PTR, const PTR));
57 static void add_specific_symbol PARAMS ((const char *, struct symlist **));
58 static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
59 static boolean is_strip_section PARAMS ((bfd *, asection *));
60 static unsigned int filter_symbols
61 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
62 static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
63 static void filter_bytes PARAMS ((char *, bfd_size_type *));
64 static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
65 static void copy_object PARAMS ((bfd *, bfd *));
66 static void copy_archive PARAMS ((bfd *, bfd *, const char *));
67 static void copy_file
68 PARAMS ((const char *, const char *, const char *, const char *));
69 static int strip_main PARAMS ((int, char **));
70 static int copy_main PARAMS ((int, char **));
71 static const char *lookup_sym_redefinition PARAMS((const char *));
72 static void redefine_list_append PARAMS ((const char *, const char *));
73
74 #define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
75
76 static asymbol **isympp = NULL; /* Input symbols */
77 static asymbol **osympp = NULL; /* Output symbols that survive stripping */
78
79 /* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
80 static int copy_byte = -1;
81 static int interleave = 4;
82
83 static boolean verbose; /* Print file and target names. */
84 static boolean preserve_dates; /* Preserve input file timestamp. */
85 static int status = 0; /* Exit status. */
86
87 enum strip_action
88 {
89 STRIP_UNDEF,
90 STRIP_NONE, /* don't strip */
91 STRIP_DEBUG, /* strip all debugger symbols */
92 STRIP_UNNEEDED, /* strip unnecessary symbols */
93 STRIP_ALL /* strip all symbols */
94 };
95
96 /* Which symbols to remove. */
97 static enum strip_action strip_symbols;
98
99 enum locals_action
100 {
101 LOCALS_UNDEF,
102 LOCALS_START_L, /* discard locals starting with L */
103 LOCALS_ALL /* discard all locals */
104 };
105
106 /* Which local symbols to remove. Overrides STRIP_ALL. */
107 static enum locals_action discard_locals;
108
109 /* What kind of change to perform. */
110 enum change_action
111 {
112 CHANGE_IGNORE,
113 CHANGE_MODIFY,
114 CHANGE_SET
115 };
116
117 /* Structure used to hold lists of sections and actions to take. */
118 struct section_list
119 {
120 struct section_list * next; /* Next section to change. */
121 const char * name; /* Section name. */
122 boolean used; /* Whether this entry was used. */
123 boolean remove; /* Whether to remove this section. */
124 boolean copy; /* Whether to copy this section. */
125 enum change_action change_vma;/* Whether to change or set VMA. */
126 bfd_vma vma_val; /* Amount to change by or set to. */
127 enum change_action change_lma;/* Whether to change or set LMA. */
128 bfd_vma lma_val; /* Amount to change by or set to. */
129 boolean set_flags; /* Whether to set the section flags. */
130 flagword flags; /* What to set the section flags to. */
131 };
132
133 static struct section_list *change_sections;
134 static boolean sections_removed;
135 static boolean sections_copied;
136
137 /* Changes to the start address. */
138 static bfd_vma change_start = 0;
139 static boolean set_start_set = false;
140 static bfd_vma set_start;
141
142 /* Changes to section addresses. */
143 static bfd_vma change_section_address = 0;
144
145 /* Filling gaps between sections. */
146 static boolean gap_fill_set = false;
147 static bfd_byte gap_fill = 0;
148
149 /* Pad to a given address. */
150 static boolean pad_to_set = false;
151 static bfd_vma pad_to;
152
153 /* List of sections to add. */
154
155 struct section_add
156 {
157 /* Next section to add. */
158 struct section_add *next;
159 /* Name of section to add. */
160 const char *name;
161 /* Name of file holding section contents. */
162 const char *filename;
163 /* Size of file. */
164 size_t size;
165 /* Contents of file. */
166 bfd_byte *contents;
167 /* BFD section, after it has been added. */
168 asection *section;
169 };
170
171 static struct section_add *add_sections;
172
173 /* Whether to convert debugging information. */
174
175 static boolean convert_debugging = false;
176
177 /* Whether to change the leading character in symbol names. */
178
179 static boolean change_leading_char = false;
180
181 /* Whether to remove the leading character from global symbol names. */
182
183 static boolean remove_leading_char = false;
184
185 /* List of symbols to strip, keep, localize, weaken, or redefine. */
186
187 static struct symlist *strip_specific_list = NULL;
188 static struct symlist *keep_specific_list = NULL;
189 static struct symlist *localize_specific_list = NULL;
190 static struct symlist *weaken_specific_list = NULL;
191 static struct redefine_node *redefine_sym_list = NULL;
192
193 /* If this is true, we weaken global symbols (set BSF_WEAK). */
194
195 static boolean weaken = false;
196
197 /* 150 isn't special; it's just an arbitrary non-ASCII char value. */
198
199 #define OPTION_ADD_SECTION 150
200 #define OPTION_CHANGE_ADDRESSES (OPTION_ADD_SECTION + 1)
201 #define OPTION_CHANGE_LEADING_CHAR (OPTION_CHANGE_ADDRESSES + 1)
202 #define OPTION_CHANGE_START (OPTION_CHANGE_LEADING_CHAR + 1)
203 #define OPTION_CHANGE_SECTION_ADDRESS (OPTION_CHANGE_START + 1)
204 #define OPTION_CHANGE_SECTION_LMA (OPTION_CHANGE_SECTION_ADDRESS + 1)
205 #define OPTION_CHANGE_SECTION_VMA (OPTION_CHANGE_SECTION_LMA + 1)
206 #define OPTION_CHANGE_WARNINGS (OPTION_CHANGE_SECTION_VMA + 1)
207 #define OPTION_DEBUGGING (OPTION_CHANGE_WARNINGS + 1)
208 #define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
209 #define OPTION_NO_CHANGE_WARNINGS (OPTION_GAP_FILL + 1)
210 #define OPTION_PAD_TO (OPTION_NO_CHANGE_WARNINGS + 1)
211 #define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
212 #define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
213 #define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
214 #define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
215 #define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
216 #define OPTION_REDEFINE_SYM (OPTION_WEAKEN + 1)
217
218 /* Options to handle if running as "strip". */
219
220 static struct option strip_options[] =
221 {
222 {"discard-all", no_argument, 0, 'x'},
223 {"discard-locals", no_argument, 0, 'X'},
224 {"format", required_argument, 0, 'F'}, /* Obsolete */
225 {"help", no_argument, 0, 'h'},
226 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
227 {"input-target", required_argument, 0, 'I'},
228 {"keep-symbol", required_argument, 0, 'K'},
229 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
230 {"output-target", required_argument, 0, 'O'},
231 {"preserve-dates", no_argument, 0, 'p'},
232 {"remove-section", required_argument, 0, 'R'},
233 {"strip-all", no_argument, 0, 's'},
234 {"strip-debug", no_argument, 0, 'S'},
235 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
236 {"strip-symbol", required_argument, 0, 'N'},
237 {"target", required_argument, 0, 'F'},
238 {"verbose", no_argument, 0, 'v'},
239 {"version", no_argument, 0, 'V'},
240 {0, no_argument, 0, 0}
241 };
242
243 /* Options to handle if running as "objcopy". */
244
245 static struct option copy_options[] =
246 {
247 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
248 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
249 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
250 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
251 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
252 {"byte", required_argument, 0, 'b'},
253 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
254 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
255 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
256 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
257 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
258 {"change-start", required_argument, 0, OPTION_CHANGE_START},
259 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
260 {"debugging", no_argument, 0, OPTION_DEBUGGING},
261 {"discard-all", no_argument, 0, 'x'},
262 {"discard-locals", no_argument, 0, 'X'},
263 {"only-section", required_argument, 0, 'j'},
264 {"format", required_argument, 0, 'F'}, /* Obsolete */
265 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
266 {"help", no_argument, 0, 'h'},
267 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
268 {"input-target", required_argument, 0, 'I'},
269 {"interleave", required_argument, 0, 'i'},
270 {"keep-symbol", required_argument, 0, 'K'},
271 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
272 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
273 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
274 {"output-target", required_argument, 0, 'O'},
275 {"pad-to", required_argument, 0, OPTION_PAD_TO},
276 {"preserve-dates", no_argument, 0, 'p'},
277 {"localize-symbol", required_argument, 0, 'L'},
278 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
279 {"remove-section", required_argument, 0, 'R'},
280 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
281 {"set-start", required_argument, 0, OPTION_SET_START},
282 {"strip-all", no_argument, 0, 'S'},
283 {"strip-debug", no_argument, 0, 'g'},
284 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
285 {"strip-symbol", required_argument, 0, 'N'},
286 {"target", required_argument, 0, 'F'},
287 {"verbose", no_argument, 0, 'v'},
288 {"version", no_argument, 0, 'V'},
289 {"weaken", no_argument, 0, OPTION_WEAKEN},
290 {"weaken-symbol", required_argument, 0, 'W'},
291 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
292 {0, no_argument, 0, 0}
293 };
294
295 /* IMPORTS */
296 extern char *program_name;
297
298 /* This flag distinguishes between strip and objcopy:
299 1 means this is 'strip'; 0 means this is 'objcopy'.
300 -1 means if we should use argv[0] to decide. */
301 extern int is_strip;
302
303
304 static void
305 copy_usage (stream, exit_status)
306 FILE *stream;
307 int exit_status;
308 {
309 fprintf (stream, _("Usage: %s <switches> in-file [out-file]\n"), program_name);
310 fprintf (stream, _(" The switches are:\n"));
311 fprintf (stream, _("\
312 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
313 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
314 -F --target <bfdname> Set both input and output format to <bfdname>\n\
315 --debugging Convert debugging information, if possible\n\
316 -p --preserve-dates Copy modified/access timestamps to the output\n\
317 -j --only-section <name> Only copy section <name> into the output\n\
318 -R --remove-section <name> Remove section <name> from the output\n\
319 -S --strip-all Remove all symbol and relocation information\n\
320 -g --strip-debug Remove all debugging symbols\n\
321 --strip-unneeded Remove all symbols not needed by relocations\n\
322 -N --strip-symbol <name> Do not copy symbol <name>\n\
323 -K --keep-symbol <name> Only copy symbol <name>\n\
324 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
325 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
326 --weaken Force all global symbols to be marked as weak\n\
327 -x --discard-all Remove all non-global symbols\n\
328 -X --discard-locals Remove any compiler-generated symbols\n\
329 -i --interleave <number> Only copy one out of every <number> bytes\n\
330 -b --byte <num> Select byte <num> in every interleaved block\n\
331 --gap-fill <val> Fill gaps between sections with <val>\n\
332 --pad-to <addr> Pad the last section up to address <addr>\n\
333 --set-start <addr> Set the start address to <addr>\n\
334 {--change-start|--adjust-start} <incr>\n\
335 Add <incr> to the start address\n\
336 {--change-addresses|--adjust-vma} <incr>\n\
337 Add <incr> to LMA, VMA and start addresses\n\
338 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
339 Change LMA and VMA of section <name> by <val>\n\
340 --change-section-lma <name>{=|+|-}<val>\n\
341 Change the LMA of section <name> by <val>\n\
342 --change-section-vma <name>{=|+|-}<val>\n\
343 Change the VMA of section <name> by <val>\n\
344 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
345 Warn if a named section does not exist\n\
346 --set-section-flags <name>=<flags>\n\
347 Set section <name>'s properties to <flags>\n\
348 --add-section <name>=<file> Add section <name> found in <file> to output\n\
349 --change-leading-char Force output format's leading character style\n\
350 --remove-leading-char Remove leading character from global symbols\n\
351 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
352 -v --verbose List all object files modified\n\
353 -V --version Display this program's version number\n\
354 -h --help Display this output\n\
355 "));
356 list_supported_targets (program_name, stream);
357 if (exit_status == 0)
358 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
359 exit (exit_status);
360 }
361
362 static void
363 strip_usage (stream, exit_status)
364 FILE *stream;
365 int exit_status;
366 {
367 fprintf (stream, _("Usage: %s <switches> in-file(s)\n"), program_name);
368 fprintf (stream, _(" The switches are:\n"));
369 fprintf (stream, _("\
370 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
371 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
372 -F --target <bfdname> Set both input and output format to <bfdname>\n\
373 -p --preserve-dates Copy modified/access timestamps to the output\n\
374 -R --remove-section <name> Remove section <name> from the output\n\
375 -s --strip-all Remove all symbol and relocation information\n\
376 -g -S --strip-debug Remove all debugging symbols\n\
377 --strip-unneeded Remove all symbols not needed by relocations\n\
378 -N --strip-symbol <name> Do not copy symbol <name>\n\
379 -K --keep-symbol <name> Only copy symbol <name>\n\
380 -x --discard-all Remove all non-global symbols\n\
381 -X --discard-locals Remove any compiler-generated symbols\n\
382 -v --verbose List all object files modified\n\
383 -V --version Display this program's version number\n\
384 -h --help Display this output\n\
385 -o <file> Place stripped output into <file>\n\
386 "));
387
388 list_supported_targets (program_name, stream);
389 if (exit_status == 0)
390 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
391 exit (exit_status);
392 }
393
394 /* Parse section flags into a flagword, with a fatal error if the
395 string can't be parsed. */
396
397 static flagword
398 parse_flags (s)
399 const char *s;
400 {
401 flagword ret;
402 const char *snext;
403 int len;
404
405 ret = SEC_NO_FLAGS;
406
407 do
408 {
409 snext = strchr (s, ',');
410 if (snext == NULL)
411 len = strlen (s);
412 else
413 {
414 len = snext - s;
415 ++snext;
416 }
417
418 if (0) ;
419 #define PARSE_FLAG(fname,fval) \
420 else if (strncasecmp (fname, s, len) == 0) ret |= fval
421 PARSE_FLAG ("alloc", SEC_ALLOC);
422 PARSE_FLAG ("load", SEC_LOAD);
423 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
424 PARSE_FLAG ("readonly", SEC_READONLY);
425 PARSE_FLAG ("debug", SEC_DEBUGGING);
426 PARSE_FLAG ("code", SEC_CODE);
427 PARSE_FLAG ("data", SEC_DATA);
428 PARSE_FLAG ("rom", SEC_ROM);
429 PARSE_FLAG ("share", SEC_SHARED);
430 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
431 #undef PARSE_FLAG
432 else
433 {
434 char *copy;
435
436 copy = xmalloc (len + 1);
437 strncpy (copy, s, len);
438 copy[len] = '\0';
439 non_fatal (_("unrecognized section flag `%s'"), copy);
440 fatal (_("supported flags: %s"),
441 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
442 }
443
444 s = snext;
445 }
446 while (s != NULL);
447
448 return ret;
449 }
450
451 /* Find and optionally add an entry in the change_sections list. */
452
453 static struct section_list *
454 find_section_list (name, add)
455 const char *name;
456 boolean add;
457 {
458 register struct section_list *p;
459
460 for (p = change_sections; p != NULL; p = p->next)
461 if (strcmp (p->name, name) == 0)
462 return p;
463
464 if (! add)
465 return NULL;
466
467 p = (struct section_list *) xmalloc (sizeof (struct section_list));
468 p->name = name;
469 p->used = false;
470 p->remove = false;
471 p->copy = false;
472 p->change_vma = CHANGE_IGNORE;
473 p->change_lma = CHANGE_IGNORE;
474 p->vma_val = 0;
475 p->lma_val = 0;
476 p->set_flags = false;
477 p->flags = 0;
478
479 p->next = change_sections;
480 change_sections = p;
481
482 return p;
483 }
484
485 /* Add a symbol to strip_specific_list. */
486
487 static void
488 add_specific_symbol (name, list)
489 const char *name;
490 struct symlist **list;
491 {
492 struct symlist *tmp_list;
493
494 tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
495 tmp_list->name = name;
496 tmp_list->next = *list;
497 *list = tmp_list;
498 }
499
500 /* See whether a symbol should be stripped or kept based on
501 strip_specific_list and keep_symbols. */
502
503 static boolean
504 is_specified_symbol (name, list)
505 const char *name;
506 struct symlist *list;
507 {
508 struct symlist *tmp_list;
509
510 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
511 {
512 if (strcmp (name, tmp_list->name) == 0)
513 return true;
514 }
515 return false;
516 }
517
518 /* See if a section is being removed. */
519
520 static boolean
521 is_strip_section (abfd, sec)
522 bfd *abfd ATTRIBUTE_UNUSED;
523 asection *sec;
524 {
525 struct section_list *p;
526
527 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
528 && (strip_symbols == STRIP_DEBUG
529 || strip_symbols == STRIP_UNNEEDED
530 || strip_symbols == STRIP_ALL
531 || discard_locals == LOCALS_ALL
532 || convert_debugging))
533 return true;
534
535 if (! sections_removed && ! sections_copied)
536 return false;
537
538 p = find_section_list (bfd_get_section_name (abfd, sec), false);
539 if (sections_removed && p != NULL && p->remove)
540 return true;
541 if (sections_copied && (p == NULL || ! p->copy))
542 return true;
543 return false;
544 }
545
546 /* Choose which symbol entries to copy; put the result in OSYMS.
547 We don't copy in place, because that confuses the relocs.
548 Return the number of symbols to print. */
549
550 static unsigned int
551 filter_symbols (abfd, obfd, osyms, isyms, symcount)
552 bfd *abfd;
553 bfd *obfd;
554 asymbol **osyms, **isyms;
555 long symcount;
556 {
557 register asymbol **from = isyms, **to = osyms;
558 long src_count = 0, dst_count = 0;
559
560 for (; src_count < symcount; src_count++)
561 {
562 asymbol *sym = from[src_count];
563 flagword flags = sym->flags;
564 const char *name = bfd_asymbol_name (sym);
565 int keep;
566
567 if (redefine_sym_list)
568 {
569 const char *old_name, *new_name;
570
571 old_name = bfd_asymbol_name (sym);
572 new_name = lookup_sym_redefinition (old_name);
573 name = bfd_asymbol_name (sym) = new_name;
574 }
575
576 if (change_leading_char
577 && (bfd_get_symbol_leading_char (abfd)
578 != bfd_get_symbol_leading_char (obfd))
579 && (bfd_get_symbol_leading_char (abfd) == '\0'
580 || (name[0] == bfd_get_symbol_leading_char (abfd))))
581 {
582 if (bfd_get_symbol_leading_char (obfd) == '\0')
583 name = bfd_asymbol_name (sym) = name + 1;
584 else
585 {
586 char *n;
587
588 n = xmalloc (strlen (name) + 2);
589 n[0] = bfd_get_symbol_leading_char (obfd);
590 if (bfd_get_symbol_leading_char (abfd) == '\0')
591 strcpy (n + 1, name);
592 else
593 strcpy (n + 1, name + 1);
594 name = bfd_asymbol_name (sym) = n;
595 }
596 }
597
598 if (remove_leading_char
599 && ((flags & BSF_GLOBAL) != 0
600 || (flags & BSF_WEAK) != 0
601 || bfd_is_und_section (bfd_get_section (sym))
602 || bfd_is_com_section (bfd_get_section (sym)))
603 && name[0] == bfd_get_symbol_leading_char (abfd))
604 name = bfd_asymbol_name (sym) = name + 1;
605
606 if (strip_symbols == STRIP_ALL)
607 keep = 0;
608 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
609 || ((flags & BSF_SECTION_SYM) != 0
610 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
611 & BSF_KEEP) != 0))
612 keep = 1;
613 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
614 || (flags & BSF_WEAK) != 0
615 || bfd_is_und_section (bfd_get_section (sym))
616 || bfd_is_com_section (bfd_get_section (sym)))
617 keep = strip_symbols != STRIP_UNNEEDED;
618 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
619 keep = (strip_symbols != STRIP_DEBUG
620 && strip_symbols != STRIP_UNNEEDED
621 && ! convert_debugging);
622 else /* Local symbol. */
623 keep = (strip_symbols != STRIP_UNNEEDED
624 && (discard_locals != LOCALS_ALL
625 && (discard_locals != LOCALS_START_L
626 || ! bfd_is_local_label (abfd, sym))));
627
628 if (keep && is_specified_symbol (name, strip_specific_list))
629 keep = 0;
630 if (!keep && is_specified_symbol (name, keep_specific_list))
631 keep = 1;
632 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
633 keep = 0;
634
635 if (keep && (flags & BSF_GLOBAL) != 0
636 && (weaken || is_specified_symbol (name, weaken_specific_list)))
637 {
638 sym->flags &=~ BSF_GLOBAL;
639 sym->flags |= BSF_WEAK;
640 }
641 if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
642 && is_specified_symbol (name, localize_specific_list))
643 {
644 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
645 sym->flags |= BSF_LOCAL;
646 }
647
648 if (keep)
649 to[dst_count++] = sym;
650 }
651
652 to[dst_count] = NULL;
653
654 return dst_count;
655 }
656
657 static const char *
658 lookup_sym_redefinition (source)
659 const char *source;
660 {
661 const char *result;
662 struct redefine_node *list;
663
664 result = source;
665
666 for (list = redefine_sym_list; list != NULL; list = list->next)
667 {
668 if (strcmp (source, list->source) == 0)
669 {
670 result = list->target;
671 break;
672 }
673 }
674 return result;
675 }
676
677 /* Add a node to a symbol redefine list */
678
679 static void
680 redefine_list_append (source, target)
681 const char *source;
682 const char *target;
683 {
684 struct redefine_node **p;
685 struct redefine_node *list;
686 struct redefine_node *new_node;
687
688 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
689 {
690 if (strcmp (source, list->source) == 0)
691 {
692 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
693 "--redefine-sym",
694 source);
695 }
696
697 if (strcmp (target, list->target) == 0)
698 {
699 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
700 "--redefine-sym",
701 target);
702 }
703 }
704
705 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
706
707 new_node->source = strdup (source);
708 new_node->target = strdup (target);
709 new_node->next = NULL;
710
711 *p = new_node;
712 }
713
714
715 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
716 Adjust *SIZE. */
717
718 static void
719 filter_bytes (memhunk, size)
720 char *memhunk;
721 bfd_size_type *size;
722 {
723 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
724
725 for (; from < end; from += interleave)
726 *to++ = *from;
727 if (*size % interleave > (bfd_size_type) copy_byte)
728 *size = (*size / interleave) + 1;
729 else
730 *size /= interleave;
731 }
732
733 /* Copy object file IBFD onto OBFD. */
734
735 static void
736 copy_object (ibfd, obfd)
737 bfd *ibfd;
738 bfd *obfd;
739 {
740 bfd_vma start;
741 long symcount;
742 asection **osections = NULL;
743 bfd_size_type *gaps = NULL;
744 bfd_size_type max_gap = 0;
745 long symsize;
746 PTR dhandle;
747
748
749 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
750 RETURN_NONFATAL (bfd_get_filename (obfd));
751
752 if (verbose)
753 printf (_("copy from %s(%s) to %s(%s)\n"),
754 bfd_get_filename (ibfd), bfd_get_target (ibfd),
755 bfd_get_filename (obfd), bfd_get_target (obfd));
756
757 if (set_start_set)
758 start = set_start;
759 else
760 start = bfd_get_start_address (ibfd);
761 start += change_start;
762
763 if (!bfd_set_start_address (obfd, start)
764 || !bfd_set_file_flags (obfd,
765 (bfd_get_file_flags (ibfd)
766 & bfd_applicable_file_flags (obfd))))
767 RETURN_NONFATAL (bfd_get_filename (ibfd));
768
769 /* Copy architecture of input file to output file */
770 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
771 bfd_get_mach (ibfd)))
772 non_fatal (_("Warning: Output file cannot represent architecture %s"),
773 bfd_printable_arch_mach (bfd_get_arch (ibfd),
774 bfd_get_mach (ibfd)));
775
776 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
777 RETURN_NONFATAL (bfd_get_filename (ibfd));
778
779 if (isympp)
780 free (isympp);
781
782 if (osympp != isympp)
783 free (osympp);
784
785 /* BFD mandates that all output sections be created and sizes set before
786 any output is done. Thus, we traverse all sections multiple times. */
787 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
788
789 if (add_sections != NULL)
790 {
791 struct section_add *padd;
792 struct section_list *pset;
793
794 for (padd = add_sections; padd != NULL; padd = padd->next)
795 {
796 padd->section = bfd_make_section (obfd, padd->name);
797 if (padd->section == NULL)
798 {
799 non_fatal (_("can't create section `%s': %s"),
800 padd->name, bfd_errmsg (bfd_get_error ()));
801 status = 1;
802 return;
803 }
804 else
805 {
806 flagword flags;
807
808 if (! bfd_set_section_size (obfd, padd->section, padd->size))
809 RETURN_NONFATAL (bfd_get_filename (obfd));
810
811 pset = find_section_list (padd->name, false);
812 if (pset != NULL)
813 pset->used = true;
814
815 if (pset != NULL && pset->set_flags)
816 flags = pset->flags | SEC_HAS_CONTENTS;
817 else
818 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
819
820 if (! bfd_set_section_flags (obfd, padd->section, flags))
821 RETURN_NONFATAL (bfd_get_filename (obfd));
822
823 if (pset != NULL)
824 {
825 if (pset->change_vma != CHANGE_IGNORE)
826 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
827 RETURN_NONFATAL (bfd_get_filename (obfd));
828
829 if (pset->change_lma != CHANGE_IGNORE)
830 {
831 padd->section->lma = pset->lma_val;
832
833 if (! bfd_set_section_alignment
834 (obfd, padd->section,
835 bfd_section_alignment (obfd, padd->section)))
836 RETURN_NONFATAL (bfd_get_filename (obfd));
837 }
838 }
839 }
840 }
841 }
842
843 if (gap_fill_set || pad_to_set)
844 {
845 asection **set;
846 unsigned int c, i;
847
848 /* We must fill in gaps between the sections and/or we must pad
849 the last section to a specified address. We do this by
850 grabbing a list of the sections, sorting them by VMA, and
851 increasing the section sizes as required to fill the gaps.
852 We write out the gap contents below. */
853
854 c = bfd_count_sections (obfd);
855 osections = (asection **) xmalloc (c * sizeof (asection *));
856 set = osections;
857 bfd_map_over_sections (obfd, get_sections, (void *) &set);
858
859 qsort (osections, c, sizeof (asection *), compare_section_lma);
860
861 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
862 memset (gaps, 0, c * sizeof (bfd_size_type));
863
864 if (gap_fill_set)
865 {
866 for (i = 0; i < c - 1; i++)
867 {
868 flagword flags;
869 bfd_size_type size;
870 bfd_vma gap_start, gap_stop;
871
872 flags = bfd_get_section_flags (obfd, osections[i]);
873 if ((flags & SEC_HAS_CONTENTS) == 0
874 || (flags & SEC_LOAD) == 0)
875 continue;
876
877 size = bfd_section_size (obfd, osections[i]);
878 gap_start = bfd_section_lma (obfd, osections[i]) + size;
879 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
880 if (gap_start < gap_stop)
881 {
882 if (! bfd_set_section_size (obfd, osections[i],
883 size + (gap_stop - gap_start)))
884 {
885 non_fatal (_("Can't fill gap after %s: %s"),
886 bfd_get_section_name (obfd, osections[i]),
887 bfd_errmsg (bfd_get_error ()));
888 status = 1;
889 break;
890 }
891 gaps[i] = gap_stop - gap_start;
892 if (max_gap < gap_stop - gap_start)
893 max_gap = gap_stop - gap_start;
894 }
895 }
896 }
897
898 if (pad_to_set)
899 {
900 bfd_vma lma;
901 bfd_size_type size;
902
903 lma = bfd_section_lma (obfd, osections[c - 1]);
904 size = bfd_section_size (obfd, osections[c - 1]);
905 if (lma + size < pad_to)
906 {
907 if (! bfd_set_section_size (obfd, osections[c - 1],
908 pad_to - lma))
909 {
910 non_fatal (_("Can't add padding to %s: %s"),
911 bfd_get_section_name (obfd, osections[c - 1]),
912 bfd_errmsg (bfd_get_error ()));
913 status = 1;
914 }
915 else
916 {
917 gaps[c - 1] = pad_to - (lma + size);
918 if (max_gap < pad_to - (lma + size))
919 max_gap = pad_to - (lma + size);
920 }
921 }
922 }
923 }
924
925 /* Symbol filtering must happen after the output sections have
926 been created, but before their contents are set. */
927 dhandle = NULL;
928 symsize = bfd_get_symtab_upper_bound (ibfd);
929 if (symsize < 0)
930 RETURN_NONFATAL (bfd_get_filename (ibfd));
931
932 osympp = isympp = (asymbol **) xmalloc (symsize);
933 symcount = bfd_canonicalize_symtab (ibfd, isympp);
934 if (symcount < 0)
935 RETURN_NONFATAL (bfd_get_filename (ibfd));
936
937 if (convert_debugging)
938 dhandle = read_debugging_info (ibfd, isympp, symcount);
939
940 if (strip_symbols == STRIP_DEBUG
941 || strip_symbols == STRIP_ALL
942 || strip_symbols == STRIP_UNNEEDED
943 || discard_locals != LOCALS_UNDEF
944 || strip_specific_list != NULL
945 || keep_specific_list != NULL
946 || localize_specific_list != NULL
947 || weaken_specific_list != NULL
948 || sections_removed
949 || sections_copied
950 || convert_debugging
951 || change_leading_char
952 || remove_leading_char
953 || redefine_sym_list
954 || weaken)
955 {
956 /* Mark symbols used in output relocations so that they
957 are kept, even if they are local labels or static symbols.
958
959 Note we iterate over the input sections examining their
960 relocations since the relocations for the output sections
961 haven't been set yet. mark_symbols_used_in_relocations will
962 ignore input sections which have no corresponding output
963 section. */
964 if (strip_symbols != STRIP_ALL)
965 bfd_map_over_sections (ibfd,
966 mark_symbols_used_in_relocations,
967 (PTR)isympp);
968 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
969 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
970 }
971
972 if (convert_debugging && dhandle != NULL)
973 {
974 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
975 {
976 status = 1;
977 return;
978 }
979 }
980
981 bfd_set_symtab (obfd, osympp, symcount);
982
983 /* This has to happen after the symbol table has been set. */
984 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
985
986 if (add_sections != NULL)
987 {
988 struct section_add *padd;
989
990 for (padd = add_sections; padd != NULL; padd = padd->next)
991 {
992 if (! bfd_set_section_contents (obfd, padd->section,
993 (PTR) padd->contents,
994 (file_ptr) 0,
995 (bfd_size_type) padd->size))
996 RETURN_NONFATAL (bfd_get_filename (obfd));
997 }
998 }
999
1000 if (gap_fill_set || pad_to_set)
1001 {
1002 bfd_byte *buf;
1003 int c, i;
1004
1005 /* Fill in the gaps. */
1006
1007 if (max_gap > 8192)
1008 max_gap = 8192;
1009 buf = (bfd_byte *) xmalloc (max_gap);
1010 memset (buf, gap_fill, (size_t) max_gap);
1011
1012 c = bfd_count_sections (obfd);
1013 for (i = 0; i < c; i++)
1014 {
1015 if (gaps[i] != 0)
1016 {
1017 bfd_size_type left;
1018 file_ptr off;
1019
1020 left = gaps[i];
1021 off = bfd_section_size (obfd, osections[i]) - left;
1022 while (left > 0)
1023 {
1024 bfd_size_type now;
1025
1026 if (left > 8192)
1027 now = 8192;
1028 else
1029 now = left;
1030
1031 if (! bfd_set_section_contents (obfd, osections[i], buf,
1032 off, now))
1033 RETURN_NONFATAL (bfd_get_filename (obfd));
1034
1035 left -= now;
1036 off += now;
1037 }
1038 }
1039 }
1040 }
1041
1042 /* Allow the BFD backend to copy any private data it understands
1043 from the input BFD to the output BFD. This is done last to
1044 permit the routine to look at the filtered symbol table, which is
1045 important for the ECOFF code at least. */
1046 if (!bfd_copy_private_bfd_data (ibfd, obfd))
1047 {
1048 non_fatal (_("%s: error copying private BFD data: %s"),
1049 bfd_get_filename (obfd),
1050 bfd_errmsg (bfd_get_error ()));
1051 status = 1;
1052 return;
1053 }
1054 }
1055
1056 /* Read each archive element in turn from IBFD, copy the
1057 contents to temp file, and keep the temp file handle. */
1058
1059 static void
1060 copy_archive (ibfd, obfd, output_target)
1061 bfd *ibfd;
1062 bfd *obfd;
1063 const char *output_target;
1064 {
1065 struct name_list
1066 {
1067 struct name_list *next;
1068 char *name;
1069 bfd *obfd;
1070 } *list, *l;
1071 bfd **ptr = &obfd->archive_head;
1072 bfd *this_element;
1073 char *dir = make_tempname (bfd_get_filename (obfd));
1074
1075 /* Make a temp directory to hold the contents. */
1076 #if defined (_WIN32) && !defined (__CYGWIN32__)
1077 if (mkdir (dir) != 0)
1078 #else
1079 if (mkdir (dir, 0700) != 0)
1080 #endif
1081 {
1082 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1083 dir, strerror (errno));
1084 }
1085 obfd->has_armap = ibfd->has_armap;
1086
1087 list = NULL;
1088
1089 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1090 while (!status && this_element != (bfd *) NULL)
1091 {
1092 /* Create an output file for this member. */
1093 char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1094 (char *) NULL);
1095 bfd *output_bfd = bfd_openw (output_name, output_target);
1096 bfd *last_element;
1097 struct stat buf;
1098 int stat_status = 0;
1099
1100 if (preserve_dates)
1101 {
1102 stat_status = bfd_stat_arch_elt (this_element, &buf);
1103 if (stat_status != 0)
1104 non_fatal (_("internal stat error on %s"),
1105 bfd_get_filename (this_element));
1106 }
1107
1108 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1109 l->name = output_name;
1110 l->next = list;
1111 list = l;
1112
1113 if (output_bfd == (bfd *) NULL)
1114 RETURN_NONFATAL (output_name);
1115
1116 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1117 RETURN_NONFATAL (bfd_get_filename (obfd));
1118
1119 if (bfd_check_format (this_element, bfd_object) == true)
1120 copy_object (this_element, output_bfd);
1121
1122 if (!bfd_close (output_bfd))
1123 {
1124 bfd_nonfatal (bfd_get_filename (output_bfd));
1125 /* Error in new object file. Don't change archive. */
1126 status = 1;
1127 }
1128
1129 if (preserve_dates && stat_status == 0)
1130 set_times (output_name, &buf);
1131
1132 /* Open the newly output file and attach to our list. */
1133 output_bfd = bfd_openr (output_name, output_target);
1134
1135 l->obfd = output_bfd;
1136
1137 *ptr = output_bfd;
1138 ptr = &output_bfd->next;
1139
1140 last_element = this_element;
1141
1142 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1143
1144 bfd_close (last_element);
1145 }
1146 *ptr = (bfd *) NULL;
1147
1148 if (!bfd_close (obfd))
1149 RETURN_NONFATAL (bfd_get_filename (obfd));
1150
1151 if (!bfd_close (ibfd))
1152 RETURN_NONFATAL (bfd_get_filename (ibfd));
1153
1154 /* Delete all the files that we opened. */
1155 for (l = list; l != NULL; l = l->next)
1156 {
1157 bfd_close (l->obfd);
1158 unlink (l->name);
1159 }
1160 rmdir (dir);
1161 }
1162
1163 /* The top-level control. */
1164
1165 static void
1166 copy_file (input_filename, output_filename, input_target, output_target)
1167 const char *input_filename;
1168 const char *output_filename;
1169 const char *input_target;
1170 const char *output_target;
1171 {
1172 bfd *ibfd;
1173 char **matching;
1174
1175 /* To allow us to do "strip *" without dying on the first
1176 non-object file, failures are nonfatal. */
1177
1178 ibfd = bfd_openr (input_filename, input_target);
1179 if (ibfd == NULL)
1180 RETURN_NONFATAL (input_filename);
1181
1182 if (bfd_check_format (ibfd, bfd_archive))
1183 {
1184 bfd *obfd;
1185
1186 /* bfd_get_target does not return the correct value until
1187 bfd_check_format succeeds. */
1188 if (output_target == NULL)
1189 output_target = bfd_get_target (ibfd);
1190
1191 obfd = bfd_openw (output_filename, output_target);
1192 if (obfd == NULL)
1193 RETURN_NONFATAL (output_filename);
1194
1195 copy_archive (ibfd, obfd, output_target);
1196 }
1197 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1198 {
1199 bfd *obfd;
1200
1201 /* bfd_get_target does not return the correct value until
1202 bfd_check_format succeeds. */
1203 if (output_target == NULL)
1204 output_target = bfd_get_target (ibfd);
1205
1206 obfd = bfd_openw (output_filename, output_target);
1207 if (obfd == NULL)
1208 RETURN_NONFATAL (output_filename);
1209
1210 copy_object (ibfd, obfd);
1211
1212 if (!bfd_close (obfd))
1213 RETURN_NONFATAL (output_filename);
1214
1215 if (!bfd_close (ibfd))
1216 RETURN_NONFATAL (input_filename);
1217 }
1218 else
1219 {
1220 bfd_nonfatal (input_filename);
1221
1222 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1223 {
1224 list_matching_formats (matching);
1225 free (matching);
1226 }
1227
1228 status = 1;
1229 }
1230 }
1231
1232 /* Create a section in OBFD with the same name and attributes
1233 as ISECTION in IBFD. */
1234
1235 static void
1236 setup_section (ibfd, isection, obfdarg)
1237 bfd *ibfd;
1238 sec_ptr isection;
1239 PTR obfdarg;
1240 {
1241 bfd *obfd = (bfd *) obfdarg;
1242 struct section_list *p;
1243 sec_ptr osection;
1244 bfd_size_type size;
1245 bfd_vma vma;
1246 bfd_vma lma;
1247 flagword flags;
1248 char *err;
1249
1250 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1251 && (strip_symbols == STRIP_DEBUG
1252 || strip_symbols == STRIP_UNNEEDED
1253 || strip_symbols == STRIP_ALL
1254 || discard_locals == LOCALS_ALL
1255 || convert_debugging))
1256 return;
1257
1258 p = find_section_list (bfd_section_name (ibfd, isection), false);
1259 if (p != NULL)
1260 p->used = true;
1261
1262 if (sections_removed && p != NULL && p->remove)
1263 return;
1264 if (sections_copied && (p == NULL || ! p->copy))
1265 return;
1266
1267 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1268
1269 if (osection == NULL)
1270 {
1271 err = "making";
1272 goto loser;
1273 }
1274
1275 size = bfd_section_size (ibfd, isection);
1276 if (copy_byte >= 0)
1277 size = (size + interleave - 1) / interleave;
1278 if (! bfd_set_section_size (obfd, osection, size))
1279 {
1280 err = "size";
1281 goto loser;
1282 }
1283
1284 vma = bfd_section_vma (ibfd, isection);
1285 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1286 vma += p->vma_val;
1287 else if (p != NULL && p->change_vma == CHANGE_SET)
1288 vma = p->vma_val;
1289 else
1290 vma += change_section_address;
1291
1292 if (! bfd_set_section_vma (obfd, osection, vma))
1293 {
1294 err = "vma";
1295 goto loser;
1296 }
1297
1298 lma = isection->lma;
1299 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1300 {
1301 if (p->change_lma == CHANGE_MODIFY)
1302 lma += p->lma_val;
1303 else if (p->change_lma == CHANGE_SET)
1304 lma = p->lma_val;
1305 else
1306 abort ();
1307 }
1308 else
1309 lma += change_section_address;
1310
1311 osection->lma = lma;
1312
1313 /* FIXME: This is probably not enough. If we change the LMA we
1314 may have to recompute the header for the file as well. */
1315 if (bfd_set_section_alignment (obfd,
1316 osection,
1317 bfd_section_alignment (ibfd, isection))
1318 == false)
1319 {
1320 err = "alignment";
1321 goto loser;
1322 }
1323
1324 flags = bfd_get_section_flags (ibfd, isection);
1325 if (p != NULL && p->set_flags)
1326 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1327 if (!bfd_set_section_flags (obfd, osection, flags))
1328 {
1329 err = "flags";
1330 goto loser;
1331 }
1332
1333 /* This used to be mangle_section; we do here to avoid using
1334 bfd_get_section_by_name since some formats allow multiple
1335 sections with the same name. */
1336 isection->output_section = osection;
1337 isection->output_offset = 0;
1338
1339 /* Allow the BFD backend to copy any private data it understands
1340 from the input section to the output section. */
1341 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1342 {
1343 err = "private data";
1344 goto loser;
1345 }
1346
1347 /* All went well */
1348 return;
1349
1350 loser:
1351 non_fatal (_("%s: section `%s': error in %s: %s"),
1352 bfd_get_filename (ibfd),
1353 bfd_section_name (ibfd, isection),
1354 err, bfd_errmsg (bfd_get_error ()));
1355 status = 1;
1356 }
1357
1358 /* Copy the data of input section ISECTION of IBFD
1359 to an output section with the same name in OBFD.
1360 If stripping then don't copy any relocation info. */
1361
1362 static void
1363 copy_section (ibfd, isection, obfdarg)
1364 bfd *ibfd;
1365 sec_ptr isection;
1366 PTR obfdarg;
1367 {
1368 bfd *obfd = (bfd *) obfdarg;
1369 struct section_list *p;
1370 arelent **relpp;
1371 long relcount;
1372 sec_ptr osection;
1373 bfd_size_type size;
1374 long relsize;
1375
1376 /* If we have already failed earlier on, do not keep on generating
1377 complaints now. */
1378 if (status != 0)
1379 return;
1380
1381 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1382 && (strip_symbols == STRIP_DEBUG
1383 || strip_symbols == STRIP_UNNEEDED
1384 || strip_symbols == STRIP_ALL
1385 || discard_locals == LOCALS_ALL
1386 || convert_debugging))
1387 {
1388 return;
1389 }
1390
1391 p = find_section_list (bfd_section_name (ibfd, isection), false);
1392
1393 if (sections_removed && p != NULL && p->remove)
1394 return;
1395 if (sections_copied && (p == NULL || ! p->copy))
1396 return;
1397
1398 osection = isection->output_section;
1399 size = bfd_get_section_size_before_reloc (isection);
1400
1401 if (size == 0 || osection == 0)
1402 return;
1403
1404
1405 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1406 if (relsize < 0)
1407 RETURN_NONFATAL (bfd_get_filename (ibfd));
1408
1409 if (relsize == 0)
1410 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1411 else
1412 {
1413 relpp = (arelent **) xmalloc (relsize);
1414 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1415 if (relcount < 0)
1416 RETURN_NONFATAL (bfd_get_filename (ibfd));
1417
1418 if (strip_symbols == STRIP_ALL)
1419 {
1420 /* Remove relocations which are not in
1421 keep_strip_specific_list. */
1422 arelent **temp_relpp;
1423 long temp_relcount = 0;
1424 long i;
1425
1426 temp_relpp = (arelent **) xmalloc (relsize);
1427 for (i = 0; i < relcount; i++)
1428 if (is_specified_symbol
1429 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
1430 keep_specific_list))
1431 temp_relpp [temp_relcount++] = relpp [i];
1432 relcount = temp_relcount;
1433 free (relpp);
1434 relpp = temp_relpp;
1435 }
1436 bfd_set_reloc (obfd, osection,
1437 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1438 }
1439
1440 isection->_cooked_size = isection->_raw_size;
1441 isection->reloc_done = true;
1442
1443 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1444 {
1445 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1446
1447 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1448 size))
1449 RETURN_NONFATAL (bfd_get_filename (ibfd));
1450
1451 if (copy_byte >= 0)
1452 filter_bytes (memhunk, &size);
1453
1454 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1455 size))
1456 RETURN_NONFATAL (bfd_get_filename (obfd));
1457
1458 free (memhunk);
1459 }
1460 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1461 {
1462 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1463
1464 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1465 flag--they can just remove the section entirely and add it
1466 back again. However, we do permit them to turn on the
1467 SEC_HAS_CONTENTS flag, and take it to mean that the section
1468 contents should be zeroed out. */
1469
1470 memset (memhunk, 0, size);
1471 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1472 size))
1473 RETURN_NONFATAL (bfd_get_filename (obfd));
1474 free (memhunk);
1475 }
1476 }
1477
1478 /* Get all the sections. This is used when --gap-fill or --pad-to is
1479 used. */
1480
1481 static void
1482 get_sections (obfd, osection, secppparg)
1483 bfd *obfd ATTRIBUTE_UNUSED;
1484 asection *osection;
1485 PTR secppparg;
1486 {
1487 asection ***secppp = (asection ***) secppparg;
1488
1489 **secppp = osection;
1490 ++(*secppp);
1491 }
1492
1493 /* Sort sections by VMA. This is called via qsort, and is used when
1494 --gap-fill or --pad-to is used. We force non loadable or empty
1495 sections to the front, where they are easier to ignore. */
1496
1497 static int
1498 compare_section_lma (arg1, arg2)
1499 const PTR arg1;
1500 const PTR arg2;
1501 {
1502 const asection **sec1 = (const asection **) arg1;
1503 const asection **sec2 = (const asection **) arg2;
1504 flagword flags1, flags2;
1505
1506 /* Sort non loadable sections to the front. */
1507 flags1 = (*sec1)->flags;
1508 flags2 = (*sec2)->flags;
1509 if ((flags1 & SEC_HAS_CONTENTS) == 0
1510 || (flags1 & SEC_LOAD) == 0)
1511 {
1512 if ((flags2 & SEC_HAS_CONTENTS) != 0
1513 && (flags2 & SEC_LOAD) != 0)
1514 return -1;
1515 }
1516 else
1517 {
1518 if ((flags2 & SEC_HAS_CONTENTS) == 0
1519 || (flags2 & SEC_LOAD) == 0)
1520 return 1;
1521 }
1522
1523 /* Sort sections by LMA. */
1524 if ((*sec1)->lma > (*sec2)->lma)
1525 return 1;
1526 else if ((*sec1)->lma < (*sec2)->lma)
1527 return -1;
1528
1529 /* Sort sections with the same LMA by size. */
1530 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1531 return 1;
1532 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1533 return -1;
1534
1535 return 0;
1536 }
1537
1538 /* Mark all the symbols which will be used in output relocations with
1539 the BSF_KEEP flag so that those symbols will not be stripped.
1540
1541 Ignore relocations which will not appear in the output file. */
1542
1543 static void
1544 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1545 bfd *ibfd;
1546 sec_ptr isection;
1547 PTR symbolsarg;
1548 {
1549 asymbol **symbols = (asymbol **) symbolsarg;
1550 long relsize;
1551 arelent **relpp;
1552 long relcount, i;
1553
1554 /* Ignore an input section with no corresponding output section. */
1555 if (isection->output_section == NULL)
1556 return;
1557
1558 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1559 if (relsize < 0)
1560 bfd_fatal (bfd_get_filename (ibfd));
1561
1562 if (relsize == 0)
1563 return;
1564
1565 relpp = (arelent **) xmalloc (relsize);
1566 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1567 if (relcount < 0)
1568 bfd_fatal (bfd_get_filename (ibfd));
1569
1570 /* Examine each symbol used in a relocation. If it's not one of the
1571 special bfd section symbols, then mark it with BSF_KEEP. */
1572 for (i = 0; i < relcount; i++)
1573 {
1574 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1575 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1576 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1577 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1578 }
1579
1580 if (relpp != NULL)
1581 free (relpp);
1582 }
1583
1584 /* Write out debugging information. */
1585
1586 static boolean
1587 write_debugging_info (obfd, dhandle, symcountp, symppp)
1588 bfd *obfd;
1589 PTR dhandle;
1590 long *symcountp ATTRIBUTE_UNUSED;
1591 asymbol ***symppp ATTRIBUTE_UNUSED;
1592 {
1593 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1594 return write_ieee_debugging_info (obfd, dhandle);
1595
1596 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1597 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1598 {
1599 bfd_byte *syms, *strings;
1600 bfd_size_type symsize, stringsize;
1601 asection *stabsec, *stabstrsec;
1602
1603 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1604 &symsize, &strings,
1605 &stringsize))
1606 return false;
1607
1608 stabsec = bfd_make_section (obfd, ".stab");
1609 stabstrsec = bfd_make_section (obfd, ".stabstr");
1610 if (stabsec == NULL
1611 || stabstrsec == NULL
1612 || ! bfd_set_section_size (obfd, stabsec, symsize)
1613 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1614 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1615 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1616 || ! bfd_set_section_flags (obfd, stabsec,
1617 (SEC_HAS_CONTENTS
1618 | SEC_READONLY
1619 | SEC_DEBUGGING))
1620 || ! bfd_set_section_flags (obfd, stabstrsec,
1621 (SEC_HAS_CONTENTS
1622 | SEC_READONLY
1623 | SEC_DEBUGGING)))
1624 {
1625 non_fatal (_("%s: can't create debugging section: %s"),
1626 bfd_get_filename (obfd),
1627 bfd_errmsg (bfd_get_error ()));
1628 return false;
1629 }
1630
1631 /* We can get away with setting the section contents now because
1632 the next thing the caller is going to do is copy over the
1633 real sections. We may someday have to split the contents
1634 setting out of this function. */
1635 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1636 symsize)
1637 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1638 (file_ptr) 0, stringsize))
1639 {
1640 non_fatal (_("%s: can't set debugging section contents: %s"),
1641 bfd_get_filename (obfd),
1642 bfd_errmsg (bfd_get_error ()));
1643 return false;
1644 }
1645
1646 return true;
1647 }
1648
1649 non_fatal (_("%s: don't know how to write debugging information for %s"),
1650 bfd_get_filename (obfd), bfd_get_target (obfd));
1651 return false;
1652 }
1653
1654 static int
1655 strip_main (argc, argv)
1656 int argc;
1657 char *argv[];
1658 {
1659 char *input_target = NULL, *output_target = NULL;
1660 boolean show_version = false;
1661 int c, i;
1662 struct section_list *p;
1663 char *output_file = NULL;
1664
1665 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpgxXVv",
1666 strip_options, (int *) 0)) != EOF)
1667 {
1668 switch (c)
1669 {
1670 case 'I':
1671 input_target = optarg;
1672 break;
1673 case 'O':
1674 output_target = optarg;
1675 break;
1676 case 'F':
1677 input_target = output_target = optarg;
1678 break;
1679 case 'R':
1680 p = find_section_list (optarg, true);
1681 p->remove = true;
1682 sections_removed = true;
1683 break;
1684 case 's':
1685 strip_symbols = STRIP_ALL;
1686 break;
1687 case 'S':
1688 case 'g':
1689 strip_symbols = STRIP_DEBUG;
1690 break;
1691 case OPTION_STRIP_UNNEEDED:
1692 strip_symbols = STRIP_UNNEEDED;
1693 break;
1694 case 'K':
1695 add_specific_symbol (optarg, &keep_specific_list);
1696 break;
1697 case 'N':
1698 add_specific_symbol (optarg, &strip_specific_list);
1699 break;
1700 case 'o':
1701 output_file = optarg;
1702 break;
1703 case 'p':
1704 preserve_dates = true;
1705 break;
1706 case 'x':
1707 discard_locals = LOCALS_ALL;
1708 break;
1709 case 'X':
1710 discard_locals = LOCALS_START_L;
1711 break;
1712 case 'v':
1713 verbose = true;
1714 break;
1715 case 'V':
1716 show_version = true;
1717 break;
1718 case 0:
1719 break; /* we've been given a long option */
1720 case 'h':
1721 strip_usage (stdout, 0);
1722 default:
1723 strip_usage (stderr, 1);
1724 }
1725 }
1726
1727 if (show_version)
1728 print_version ("strip");
1729
1730 /* Default is to strip all symbols. */
1731 if (strip_symbols == STRIP_UNDEF
1732 && discard_locals == LOCALS_UNDEF
1733 && strip_specific_list == NULL)
1734 strip_symbols = STRIP_ALL;
1735
1736 if (output_target == (char *) NULL)
1737 output_target = input_target;
1738
1739 i = optind;
1740 if (i == argc
1741 || (output_file != NULL && (i + 1) < argc))
1742 strip_usage (stderr, 1);
1743
1744 for (; i < argc; i++)
1745 {
1746 int hold_status = status;
1747 struct stat statbuf;
1748 char *tmpname;
1749
1750 if (preserve_dates)
1751 {
1752 if (stat (argv[i], &statbuf) < 0)
1753 {
1754 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1755 continue;
1756 }
1757 }
1758
1759 if (output_file != NULL)
1760 tmpname = output_file;
1761 else
1762 tmpname = make_tempname (argv[i]);
1763 status = 0;
1764
1765 copy_file (argv[i], tmpname, input_target, output_target);
1766 if (status == 0)
1767 {
1768 if (preserve_dates)
1769 set_times (tmpname, &statbuf);
1770 if (output_file == NULL)
1771 smart_rename (tmpname, argv[i], preserve_dates);
1772 status = hold_status;
1773 }
1774 else
1775 unlink (tmpname);
1776 if (output_file == NULL)
1777 free (tmpname);
1778 }
1779
1780 return 0;
1781 }
1782
1783 static int
1784 copy_main (argc, argv)
1785 int argc;
1786 char *argv[];
1787 {
1788 char *input_filename = NULL, *output_filename = NULL;
1789 char *input_target = NULL, *output_target = NULL;
1790 boolean show_version = false;
1791 boolean change_warn = true;
1792 int c;
1793 struct section_list *p;
1794 struct stat statbuf;
1795
1796 while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
1797 copy_options, (int *) 0)) != EOF)
1798 {
1799 switch (c)
1800 {
1801 case 'b':
1802 copy_byte = atoi (optarg);
1803 if (copy_byte < 0)
1804 fatal (_("byte number must be non-negative"));
1805 break;
1806
1807 case 'i':
1808 interleave = atoi (optarg);
1809 if (interleave < 1)
1810 fatal (_("interleave must be positive"));
1811 break;
1812
1813 case 'I':
1814 case 's': /* "source" - 'I' is preferred */
1815 input_target = optarg;
1816 break;
1817
1818 case 'O':
1819 case 'd': /* "destination" - 'O' is preferred */
1820 output_target = optarg;
1821 break;
1822
1823 case 'F':
1824 input_target = output_target = optarg;
1825 break;
1826
1827 case 'j':
1828 p = find_section_list (optarg, true);
1829 if (p->remove)
1830 fatal (_("%s both copied and removed"), optarg);
1831 p->copy = true;
1832 sections_copied = true;
1833 break;
1834
1835 case 'R':
1836 p = find_section_list (optarg, true);
1837 if (p->copy)
1838 fatal (_("%s both copied and removed"), optarg);
1839 p->remove = true;
1840 sections_removed = true;
1841 break;
1842
1843 case 'S':
1844 strip_symbols = STRIP_ALL;
1845 break;
1846
1847 case 'g':
1848 strip_symbols = STRIP_DEBUG;
1849 break;
1850
1851 case OPTION_STRIP_UNNEEDED:
1852 strip_symbols = STRIP_UNNEEDED;
1853 break;
1854
1855 case 'K':
1856 add_specific_symbol (optarg, &keep_specific_list);
1857 break;
1858
1859 case 'N':
1860 add_specific_symbol (optarg, &strip_specific_list);
1861 break;
1862
1863 case 'L':
1864 add_specific_symbol (optarg, &localize_specific_list);
1865 break;
1866
1867 case 'W':
1868 add_specific_symbol (optarg, &weaken_specific_list);
1869 break;
1870
1871 case 'p':
1872 preserve_dates = true;
1873 break;
1874
1875 case 'x':
1876 discard_locals = LOCALS_ALL;
1877 break;
1878
1879 case 'X':
1880 discard_locals = LOCALS_START_L;
1881 break;
1882
1883 case 'v':
1884 verbose = true;
1885 break;
1886
1887 case 'V':
1888 show_version = true;
1889 break;
1890
1891 case OPTION_WEAKEN:
1892 weaken = true;
1893 break;
1894
1895 case OPTION_ADD_SECTION:
1896 {
1897 const char *s;
1898 struct stat st;
1899 struct section_add *pa;
1900 int len;
1901 char *name;
1902 FILE *f;
1903
1904 s = strchr (optarg, '=');
1905
1906 if (s == NULL)
1907 fatal (_("bad format for %s"), "--add-section");
1908
1909 if (stat (s + 1, & st) < 0)
1910 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
1911
1912 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1913
1914 len = s - optarg;
1915 name = (char *) xmalloc (len + 1);
1916 strncpy (name, optarg, len);
1917 name[len] = '\0';
1918 pa->name = name;
1919
1920 pa->filename = s + 1;
1921
1922 pa->size = st.st_size;
1923
1924 pa->contents = (bfd_byte *) xmalloc (pa->size);
1925 f = fopen (pa->filename, FOPEN_RB);
1926
1927 if (f == NULL)
1928 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
1929
1930 if (fread (pa->contents, 1, pa->size, f) == 0
1931 || ferror (f))
1932 fatal (_("%s: fread failed"), pa->filename);
1933
1934 fclose (f);
1935
1936 pa->next = add_sections;
1937 add_sections = pa;
1938 }
1939 break;
1940
1941 case OPTION_CHANGE_START:
1942 change_start = parse_vma (optarg, "--change-start");
1943 break;
1944
1945 case OPTION_CHANGE_SECTION_ADDRESS:
1946 case OPTION_CHANGE_SECTION_LMA:
1947 case OPTION_CHANGE_SECTION_VMA:
1948 {
1949 const char *s;
1950 int len;
1951 char *name;
1952 char *option = NULL;
1953 bfd_vma val;
1954 enum change_action what = CHANGE_IGNORE;
1955
1956 switch (c)
1957 {
1958 case OPTION_CHANGE_SECTION_ADDRESS:
1959 option = "--change-section-address";
1960 break;
1961 case OPTION_CHANGE_SECTION_LMA:
1962 option = "--change-section-lma";
1963 break;
1964 case OPTION_CHANGE_SECTION_VMA:
1965 option = "--change-section-vma";
1966 break;
1967 }
1968
1969 s = strchr (optarg, '=');
1970 if (s == NULL)
1971 {
1972 s = strchr (optarg, '+');
1973 if (s == NULL)
1974 {
1975 s = strchr (optarg, '-');
1976 if (s == NULL)
1977 fatal (_("bad format for %s"), option);
1978 }
1979 }
1980
1981 len = s - optarg;
1982 name = (char *) xmalloc (len + 1);
1983 strncpy (name, optarg, len);
1984 name[len] = '\0';
1985
1986 p = find_section_list (name, true);
1987
1988 val = parse_vma (s + 1, option);
1989
1990 switch (*s)
1991 {
1992 case '=': what = CHANGE_SET; break;
1993 case '-': val = - val; /* Drop through. */
1994 case '+': what = CHANGE_MODIFY; break;
1995 }
1996
1997 switch (c)
1998 {
1999 case OPTION_CHANGE_SECTION_ADDRESS:
2000 p->change_vma = what;
2001 p->vma_val = val;
2002 /* Drop through. */
2003
2004 case OPTION_CHANGE_SECTION_LMA:
2005 p->change_lma = what;
2006 p->lma_val = val;
2007 break;
2008
2009 case OPTION_CHANGE_SECTION_VMA:
2010 p->change_vma = what;
2011 p->vma_val = val;
2012 break;
2013 }
2014 }
2015 break;
2016
2017 case OPTION_CHANGE_ADDRESSES:
2018 change_section_address = parse_vma (optarg, "--change-addresses");
2019 change_start = change_section_address;
2020 break;
2021
2022 case OPTION_CHANGE_WARNINGS:
2023 change_warn = true;
2024 break;
2025
2026 case OPTION_CHANGE_LEADING_CHAR:
2027 change_leading_char = true;
2028 break;
2029
2030 case OPTION_DEBUGGING:
2031 convert_debugging = true;
2032 break;
2033
2034 case OPTION_GAP_FILL:
2035 {
2036 bfd_vma gap_fill_vma;
2037
2038 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2039 gap_fill = (bfd_byte) gap_fill_vma;
2040 if ((bfd_vma) gap_fill != gap_fill_vma)
2041 {
2042 char buff[20];
2043
2044 sprintf_vma (buff, gap_fill_vma);
2045
2046 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2047 buff, gap_fill);
2048 }
2049 gap_fill_set = true;
2050 }
2051 break;
2052
2053 case OPTION_NO_CHANGE_WARNINGS:
2054 change_warn = false;
2055 break;
2056
2057 case OPTION_PAD_TO:
2058 pad_to = parse_vma (optarg, "--pad-to");
2059 pad_to_set = true;
2060 break;
2061
2062 case OPTION_REMOVE_LEADING_CHAR:
2063 remove_leading_char = true;
2064 break;
2065
2066 case OPTION_REDEFINE_SYM:
2067 {
2068 /* Push this redefinition onto redefine_symbol_list. */
2069
2070 int len;
2071 const char *s;
2072 const char *nextarg;
2073 char *source, *target;
2074
2075 s = strchr (optarg, '=');
2076 if (s == NULL)
2077 {
2078 fatal (_("bad format for %s"), "--redefine-sym");
2079 }
2080
2081 len = s - optarg;
2082 source = (char *) xmalloc (len + 1);
2083 strncpy (source, optarg, len);
2084 source[len] = '\0';
2085
2086 nextarg = s + 1;
2087 len = strlen (nextarg);
2088 target = (char *) xmalloc (len + 1);
2089 strcpy (target, nextarg);
2090
2091 redefine_list_append (source, target);
2092
2093 free (source);
2094 free (target);
2095 }
2096 break;
2097
2098 case OPTION_SET_SECTION_FLAGS:
2099 {
2100 const char *s;
2101 int len;
2102 char *name;
2103
2104 s = strchr (optarg, '=');
2105 if (s == NULL)
2106 fatal (_("bad format for %s"), "--set-section-flags");
2107
2108 len = s - optarg;
2109 name = (char *) xmalloc (len + 1);
2110 strncpy (name, optarg, len);
2111 name[len] = '\0';
2112
2113 p = find_section_list (name, true);
2114
2115 p->set_flags = true;
2116 p->flags = parse_flags (s + 1);
2117 }
2118 break;
2119
2120 case OPTION_SET_START:
2121 set_start = parse_vma (optarg, "--set-start");
2122 set_start_set = true;
2123 break;
2124
2125 case 0:
2126 break; /* we've been given a long option */
2127
2128 case 'h':
2129 copy_usage (stdout, 0);
2130
2131 default:
2132 copy_usage (stderr, 1);
2133 }
2134 }
2135
2136 if (show_version)
2137 print_version ("objcopy");
2138
2139 if (copy_byte >= interleave)
2140 fatal (_("byte number must be less than interleave"));
2141
2142 if (optind == argc || optind + 2 < argc)
2143 copy_usage (stderr, 1);
2144
2145 input_filename = argv[optind];
2146 if (optind + 1 < argc)
2147 output_filename = argv[optind + 1];
2148
2149 /* Default is to strip no symbols. */
2150 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2151 strip_symbols = STRIP_NONE;
2152
2153 if (output_target == (char *) NULL)
2154 output_target = input_target;
2155
2156 if (preserve_dates)
2157 {
2158 if (stat (input_filename, &statbuf) < 0)
2159 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2160 }
2161
2162 /* If there is no destination file then create a temp and rename
2163 the result into the input. */
2164
2165 if (output_filename == (char *) NULL)
2166 {
2167 char *tmpname = make_tempname (input_filename);
2168
2169 copy_file (input_filename, tmpname, input_target, output_target);
2170 if (status == 0)
2171 {
2172 if (preserve_dates)
2173 set_times (tmpname, &statbuf);
2174 smart_rename (tmpname, input_filename, preserve_dates);
2175 }
2176 else
2177 unlink (tmpname);
2178 }
2179 else
2180 {
2181 copy_file (input_filename, output_filename, input_target, output_target);
2182 if (status == 0 && preserve_dates)
2183 set_times (output_filename, &statbuf);
2184 }
2185
2186 if (change_warn)
2187 {
2188 for (p = change_sections; p != NULL; p = p->next)
2189 {
2190 if (! p->used)
2191 {
2192 if (p->change_vma != CHANGE_IGNORE)
2193 {
2194 char buff [20];
2195
2196 sprintf_vma (buff, p->vma_val);
2197
2198 /* xgettext:c-format */
2199 non_fatal (_("%s %s%c0x%s never used"),
2200 "--change-section-vma",
2201 p->name,
2202 p->change_vma == CHANGE_SET ? '=' : '+',
2203 buff);
2204 }
2205
2206 if (p->change_lma != CHANGE_IGNORE)
2207 {
2208 char buff [20];
2209
2210 sprintf_vma (buff, p->lma_val);
2211
2212 /* xgettext:c-format */
2213 non_fatal (_("%s %s%c0x%s never used"),
2214 "--change-section-lma",
2215 p->name,
2216 p->change_lma == CHANGE_SET ? '=' : '+',
2217 buff);
2218 }
2219 }
2220 }
2221 }
2222
2223 return 0;
2224 }
2225
2226 int
2227 main (argc, argv)
2228 int argc;
2229 char *argv[];
2230 {
2231 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2232 setlocale (LC_MESSAGES, "");
2233 #endif
2234 bindtextdomain (PACKAGE, LOCALEDIR);
2235 textdomain (PACKAGE);
2236
2237 program_name = argv[0];
2238 xmalloc_set_program_name (program_name);
2239
2240 START_PROGRESS (program_name, 0);
2241
2242 strip_symbols = STRIP_UNDEF;
2243 discard_locals = LOCALS_UNDEF;
2244
2245 bfd_init ();
2246 set_default_bfd_target ();
2247
2248 if (is_strip < 0)
2249 {
2250 int i = strlen (program_name);
2251 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0);
2252 }
2253
2254 if (is_strip)
2255 strip_main (argc, argv);
2256 else
2257 copy_main (argc, argv);
2258
2259 END_PROGRESS (program_name);
2260
2261 return status;
2262 }
This page took 0.102418 seconds and 5 git commands to generate.