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