]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/objcopy.c
Add --srec-len and --srec-forceS3 switches to objcopy
[thirdparty/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
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
769 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
770 RETURN_NONFATAL (bfd_get_filename (obfd));
771
772 if (verbose)
773 printf (_("copy from %s(%s) to %s(%s)\n"),
774 bfd_get_filename (ibfd), bfd_get_target (ibfd),
775 bfd_get_filename (obfd), bfd_get_target (obfd));
776
777 if (set_start_set)
778 start = set_start;
779 else
780 start = bfd_get_start_address (ibfd);
781 start += change_start;
782
783 if (!bfd_set_start_address (obfd, start)
784 || !bfd_set_file_flags (obfd,
785 (bfd_get_file_flags (ibfd)
786 & bfd_applicable_file_flags (obfd))))
787 RETURN_NONFATAL (bfd_get_filename (ibfd));
788
789 /* Copy architecture of input file to output file */
790 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
791 bfd_get_mach (ibfd)))
792 non_fatal (_("Warning: Output file cannot represent architecture %s"),
793 bfd_printable_arch_mach (bfd_get_arch (ibfd),
794 bfd_get_mach (ibfd)));
795
796 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
797 RETURN_NONFATAL (bfd_get_filename (ibfd));
798
799 if (isympp)
800 free (isympp);
801
802 if (osympp != isympp)
803 free (osympp);
804
805 /* BFD mandates that all output sections be created and sizes set before
806 any output is done. Thus, we traverse all sections multiple times. */
807 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
808
809 if (add_sections != NULL)
810 {
811 struct section_add *padd;
812 struct section_list *pset;
813
814 for (padd = add_sections; padd != NULL; padd = padd->next)
815 {
816 padd->section = bfd_make_section (obfd, padd->name);
817 if (padd->section == NULL)
818 {
819 non_fatal (_("can't create section `%s': %s"),
820 padd->name, bfd_errmsg (bfd_get_error ()));
821 status = 1;
822 return;
823 }
824 else
825 {
826 flagword flags;
827
828 if (! bfd_set_section_size (obfd, padd->section, padd->size))
829 RETURN_NONFATAL (bfd_get_filename (obfd));
830
831 pset = find_section_list (padd->name, false);
832 if (pset != NULL)
833 pset->used = true;
834
835 if (pset != NULL && pset->set_flags)
836 flags = pset->flags | SEC_HAS_CONTENTS;
837 else
838 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
839
840 if (! bfd_set_section_flags (obfd, padd->section, flags))
841 RETURN_NONFATAL (bfd_get_filename (obfd));
842
843 if (pset != NULL)
844 {
845 if (pset->change_vma != CHANGE_IGNORE)
846 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
847 RETURN_NONFATAL (bfd_get_filename (obfd));
848
849 if (pset->change_lma != CHANGE_IGNORE)
850 {
851 padd->section->lma = pset->lma_val;
852
853 if (! bfd_set_section_alignment
854 (obfd, padd->section,
855 bfd_section_alignment (obfd, padd->section)))
856 RETURN_NONFATAL (bfd_get_filename (obfd));
857 }
858 }
859 }
860 }
861 }
862
863 if (gap_fill_set || pad_to_set)
864 {
865 asection **set;
866 unsigned int c, i;
867
868 /* We must fill in gaps between the sections and/or we must pad
869 the last section to a specified address. We do this by
870 grabbing a list of the sections, sorting them by VMA, and
871 increasing the section sizes as required to fill the gaps.
872 We write out the gap contents below. */
873
874 c = bfd_count_sections (obfd);
875 osections = (asection **) xmalloc (c * sizeof (asection *));
876 set = osections;
877 bfd_map_over_sections (obfd, get_sections, (void *) &set);
878
879 qsort (osections, c, sizeof (asection *), compare_section_lma);
880
881 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
882 memset (gaps, 0, c * sizeof (bfd_size_type));
883
884 if (gap_fill_set)
885 {
886 for (i = 0; i < c - 1; i++)
887 {
888 flagword flags;
889 bfd_size_type size;
890 bfd_vma gap_start, gap_stop;
891
892 flags = bfd_get_section_flags (obfd, osections[i]);
893 if ((flags & SEC_HAS_CONTENTS) == 0
894 || (flags & SEC_LOAD) == 0)
895 continue;
896
897 size = bfd_section_size (obfd, osections[i]);
898 gap_start = bfd_section_lma (obfd, osections[i]) + size;
899 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
900 if (gap_start < gap_stop)
901 {
902 if (! bfd_set_section_size (obfd, osections[i],
903 size + (gap_stop - gap_start)))
904 {
905 non_fatal (_("Can't fill gap after %s: %s"),
906 bfd_get_section_name (obfd, osections[i]),
907 bfd_errmsg (bfd_get_error ()));
908 status = 1;
909 break;
910 }
911 gaps[i] = gap_stop - gap_start;
912 if (max_gap < gap_stop - gap_start)
913 max_gap = gap_stop - gap_start;
914 }
915 }
916 }
917
918 if (pad_to_set)
919 {
920 bfd_vma lma;
921 bfd_size_type size;
922
923 lma = bfd_section_lma (obfd, osections[c - 1]);
924 size = bfd_section_size (obfd, osections[c - 1]);
925 if (lma + size < pad_to)
926 {
927 if (! bfd_set_section_size (obfd, osections[c - 1],
928 pad_to - lma))
929 {
930 non_fatal (_("Can't add padding to %s: %s"),
931 bfd_get_section_name (obfd, osections[c - 1]),
932 bfd_errmsg (bfd_get_error ()));
933 status = 1;
934 }
935 else
936 {
937 gaps[c - 1] = pad_to - (lma + size);
938 if (max_gap < pad_to - (lma + size))
939 max_gap = pad_to - (lma + size);
940 }
941 }
942 }
943 }
944
945 /* Symbol filtering must happen after the output sections have
946 been created, but before their contents are set. */
947 dhandle = NULL;
948 symsize = bfd_get_symtab_upper_bound (ibfd);
949 if (symsize < 0)
950 RETURN_NONFATAL (bfd_get_filename (ibfd));
951
952 osympp = isympp = (asymbol **) xmalloc (symsize);
953 symcount = bfd_canonicalize_symtab (ibfd, isympp);
954 if (symcount < 0)
955 RETURN_NONFATAL (bfd_get_filename (ibfd));
956
957 if (convert_debugging)
958 dhandle = read_debugging_info (ibfd, isympp, symcount);
959
960 if (strip_symbols == STRIP_DEBUG
961 || strip_symbols == STRIP_ALL
962 || strip_symbols == STRIP_UNNEEDED
963 || discard_locals != LOCALS_UNDEF
964 || strip_specific_list != NULL
965 || keep_specific_list != NULL
966 || localize_specific_list != NULL
967 || weaken_specific_list != NULL
968 || sections_removed
969 || sections_copied
970 || convert_debugging
971 || change_leading_char
972 || remove_leading_char
973 || redefine_sym_list
974 || weaken)
975 {
976 /* Mark symbols used in output relocations so that they
977 are kept, even if they are local labels or static symbols.
978
979 Note we iterate over the input sections examining their
980 relocations since the relocations for the output sections
981 haven't been set yet. mark_symbols_used_in_relocations will
982 ignore input sections which have no corresponding output
983 section. */
984 if (strip_symbols != STRIP_ALL)
985 bfd_map_over_sections (ibfd,
986 mark_symbols_used_in_relocations,
987 (PTR)isympp);
988 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
989 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
990 }
991
992 if (convert_debugging && dhandle != NULL)
993 {
994 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
995 {
996 status = 1;
997 return;
998 }
999 }
1000
1001 bfd_set_symtab (obfd, osympp, symcount);
1002
1003 /* This has to happen after the symbol table has been set. */
1004 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1005
1006 if (add_sections != NULL)
1007 {
1008 struct section_add *padd;
1009
1010 for (padd = add_sections; padd != NULL; padd = padd->next)
1011 {
1012 if (! bfd_set_section_contents (obfd, padd->section,
1013 (PTR) padd->contents,
1014 (file_ptr) 0,
1015 (bfd_size_type) padd->size))
1016 RETURN_NONFATAL (bfd_get_filename (obfd));
1017 }
1018 }
1019
1020 if (gap_fill_set || pad_to_set)
1021 {
1022 bfd_byte *buf;
1023 int c, i;
1024
1025 /* Fill in the gaps. */
1026
1027 if (max_gap > 8192)
1028 max_gap = 8192;
1029 buf = (bfd_byte *) xmalloc (max_gap);
1030 memset (buf, gap_fill, (size_t) max_gap);
1031
1032 c = bfd_count_sections (obfd);
1033 for (i = 0; i < c; i++)
1034 {
1035 if (gaps[i] != 0)
1036 {
1037 bfd_size_type left;
1038 file_ptr off;
1039
1040 left = gaps[i];
1041 off = bfd_section_size (obfd, osections[i]) - left;
1042 while (left > 0)
1043 {
1044 bfd_size_type now;
1045
1046 if (left > 8192)
1047 now = 8192;
1048 else
1049 now = left;
1050
1051 if (! bfd_set_section_contents (obfd, osections[i], buf,
1052 off, now))
1053 RETURN_NONFATAL (bfd_get_filename (obfd));
1054
1055 left -= now;
1056 off += now;
1057 }
1058 }
1059 }
1060 }
1061
1062 /* Allow the BFD backend to copy any private data it understands
1063 from the input BFD to the output BFD. This is done last to
1064 permit the routine to look at the filtered symbol table, which is
1065 important for the ECOFF code at least. */
1066 if (!bfd_copy_private_bfd_data (ibfd, obfd))
1067 {
1068 non_fatal (_("%s: error copying private BFD data: %s"),
1069 bfd_get_filename (obfd),
1070 bfd_errmsg (bfd_get_error ()));
1071 status = 1;
1072 return;
1073 }
1074 }
1075
1076 /* Read each archive element in turn from IBFD, copy the
1077 contents to temp file, and keep the temp file handle. */
1078
1079 static void
1080 copy_archive (ibfd, obfd, output_target)
1081 bfd *ibfd;
1082 bfd *obfd;
1083 const char *output_target;
1084 {
1085 struct name_list
1086 {
1087 struct name_list *next;
1088 char *name;
1089 bfd *obfd;
1090 } *list, *l;
1091 bfd **ptr = &obfd->archive_head;
1092 bfd *this_element;
1093 char *dir = make_tempname (bfd_get_filename (obfd));
1094
1095 /* Make a temp directory to hold the contents. */
1096 #if defined (_WIN32) && !defined (__CYGWIN32__)
1097 if (mkdir (dir) != 0)
1098 #else
1099 if (mkdir (dir, 0700) != 0)
1100 #endif
1101 {
1102 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1103 dir, strerror (errno));
1104 }
1105 obfd->has_armap = ibfd->has_armap;
1106
1107 list = NULL;
1108
1109 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1110 while (!status && this_element != (bfd *) NULL)
1111 {
1112 /* Create an output file for this member. */
1113 char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1114 (char *) NULL);
1115 bfd *output_bfd = bfd_openw (output_name, output_target);
1116 bfd *last_element;
1117 struct stat buf;
1118 int stat_status = 0;
1119
1120 if (preserve_dates)
1121 {
1122 stat_status = bfd_stat_arch_elt (this_element, &buf);
1123 if (stat_status != 0)
1124 non_fatal (_("internal stat error on %s"),
1125 bfd_get_filename (this_element));
1126 }
1127
1128 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1129 l->name = output_name;
1130 l->next = list;
1131 list = l;
1132
1133 if (output_bfd == (bfd *) NULL)
1134 RETURN_NONFATAL (output_name);
1135
1136 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1137 RETURN_NONFATAL (bfd_get_filename (obfd));
1138
1139 if (bfd_check_format (this_element, bfd_object) == true)
1140 copy_object (this_element, output_bfd);
1141
1142 if (!bfd_close (output_bfd))
1143 {
1144 bfd_nonfatal (bfd_get_filename (output_bfd));
1145 /* Error in new object file. Don't change archive. */
1146 status = 1;
1147 }
1148
1149 if (preserve_dates && stat_status == 0)
1150 set_times (output_name, &buf);
1151
1152 /* Open the newly output file and attach to our list. */
1153 output_bfd = bfd_openr (output_name, output_target);
1154
1155 l->obfd = output_bfd;
1156
1157 *ptr = output_bfd;
1158 ptr = &output_bfd->next;
1159
1160 last_element = this_element;
1161
1162 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1163
1164 bfd_close (last_element);
1165 }
1166 *ptr = (bfd *) NULL;
1167
1168 if (!bfd_close (obfd))
1169 RETURN_NONFATAL (bfd_get_filename (obfd));
1170
1171 if (!bfd_close (ibfd))
1172 RETURN_NONFATAL (bfd_get_filename (ibfd));
1173
1174 /* Delete all the files that we opened. */
1175 for (l = list; l != NULL; l = l->next)
1176 {
1177 bfd_close (l->obfd);
1178 unlink (l->name);
1179 }
1180 rmdir (dir);
1181 }
1182
1183 /* The top-level control. */
1184
1185 static void
1186 copy_file (input_filename, output_filename, input_target, output_target)
1187 const char *input_filename;
1188 const char *output_filename;
1189 const char *input_target;
1190 const char *output_target;
1191 {
1192 bfd *ibfd;
1193 char **matching;
1194
1195 /* To allow us to do "strip *" without dying on the first
1196 non-object file, failures are nonfatal. */
1197
1198 ibfd = bfd_openr (input_filename, input_target);
1199 if (ibfd == NULL)
1200 RETURN_NONFATAL (input_filename);
1201
1202 if (bfd_check_format (ibfd, bfd_archive))
1203 {
1204 bfd *obfd;
1205
1206 /* bfd_get_target does not return the correct value until
1207 bfd_check_format succeeds. */
1208 if (output_target == NULL)
1209 output_target = bfd_get_target (ibfd);
1210
1211 obfd = bfd_openw (output_filename, output_target);
1212 if (obfd == NULL)
1213 RETURN_NONFATAL (output_filename);
1214
1215 copy_archive (ibfd, obfd, output_target);
1216 }
1217 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1218 {
1219 bfd *obfd;
1220
1221 /* bfd_get_target does not return the correct value until
1222 bfd_check_format succeeds. */
1223 if (output_target == NULL)
1224 output_target = bfd_get_target (ibfd);
1225
1226 obfd = bfd_openw (output_filename, output_target);
1227 if (obfd == NULL)
1228 RETURN_NONFATAL (output_filename);
1229
1230 copy_object (ibfd, obfd);
1231
1232 if (!bfd_close (obfd))
1233 RETURN_NONFATAL (output_filename);
1234
1235 if (!bfd_close (ibfd))
1236 RETURN_NONFATAL (input_filename);
1237 }
1238 else
1239 {
1240 bfd_nonfatal (input_filename);
1241
1242 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1243 {
1244 list_matching_formats (matching);
1245 free (matching);
1246 }
1247
1248 status = 1;
1249 }
1250 }
1251
1252 /* Create a section in OBFD with the same name and attributes
1253 as ISECTION in IBFD. */
1254
1255 static void
1256 setup_section (ibfd, isection, obfdarg)
1257 bfd *ibfd;
1258 sec_ptr isection;
1259 PTR obfdarg;
1260 {
1261 bfd *obfd = (bfd *) obfdarg;
1262 struct section_list *p;
1263 sec_ptr osection;
1264 bfd_size_type size;
1265 bfd_vma vma;
1266 bfd_vma lma;
1267 flagword flags;
1268 const char *err;
1269
1270 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1271 && (strip_symbols == STRIP_DEBUG
1272 || strip_symbols == STRIP_UNNEEDED
1273 || strip_symbols == STRIP_ALL
1274 || discard_locals == LOCALS_ALL
1275 || convert_debugging))
1276 return;
1277
1278 p = find_section_list (bfd_section_name (ibfd, isection), false);
1279 if (p != NULL)
1280 p->used = true;
1281
1282 if (sections_removed && p != NULL && p->remove)
1283 return;
1284 if (sections_copied && (p == NULL || ! p->copy))
1285 return;
1286
1287 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1288
1289 if (osection == NULL)
1290 {
1291 err = _("making");
1292 goto loser;
1293 }
1294
1295 size = bfd_section_size (ibfd, isection);
1296 if (copy_byte >= 0)
1297 size = (size + interleave - 1) / interleave;
1298 if (! bfd_set_section_size (obfd, osection, size))
1299 {
1300 err = _("size");
1301 goto loser;
1302 }
1303
1304 vma = bfd_section_vma (ibfd, isection);
1305 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1306 vma += p->vma_val;
1307 else if (p != NULL && p->change_vma == CHANGE_SET)
1308 vma = p->vma_val;
1309 else
1310 vma += change_section_address;
1311
1312 if (! bfd_set_section_vma (obfd, osection, vma))
1313 {
1314 err = _("vma");
1315 goto loser;
1316 }
1317
1318 lma = isection->lma;
1319 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1320 {
1321 if (p->change_lma == CHANGE_MODIFY)
1322 lma += p->lma_val;
1323 else if (p->change_lma == CHANGE_SET)
1324 lma = p->lma_val;
1325 else
1326 abort ();
1327 }
1328 else
1329 lma += change_section_address;
1330
1331 osection->lma = lma;
1332
1333 /* FIXME: This is probably not enough. If we change the LMA we
1334 may have to recompute the header for the file as well. */
1335 if (bfd_set_section_alignment (obfd,
1336 osection,
1337 bfd_section_alignment (ibfd, isection))
1338 == false)
1339 {
1340 err = _("alignment");
1341 goto loser;
1342 }
1343
1344 flags = bfd_get_section_flags (ibfd, isection);
1345 if (p != NULL && p->set_flags)
1346 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1347 if (!bfd_set_section_flags (obfd, osection, flags))
1348 {
1349 err = _("flags");
1350 goto loser;
1351 }
1352
1353 /* This used to be mangle_section; we do here to avoid using
1354 bfd_get_section_by_name since some formats allow multiple
1355 sections with the same name. */
1356 isection->output_section = osection;
1357 isection->output_offset = 0;
1358
1359 /* Allow the BFD backend to copy any private data it understands
1360 from the input section to the output section. */
1361 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1362 {
1363 err = _("private data");
1364 goto loser;
1365 }
1366
1367 /* All went well */
1368 return;
1369
1370 loser:
1371 non_fatal (_("%s: section `%s': error in %s: %s"),
1372 bfd_get_filename (ibfd),
1373 bfd_section_name (ibfd, isection),
1374 err, bfd_errmsg (bfd_get_error ()));
1375 status = 1;
1376 }
1377
1378 /* Copy the data of input section ISECTION of IBFD
1379 to an output section with the same name in OBFD.
1380 If stripping then don't copy any relocation info. */
1381
1382 static void
1383 copy_section (ibfd, isection, obfdarg)
1384 bfd *ibfd;
1385 sec_ptr isection;
1386 PTR obfdarg;
1387 {
1388 bfd *obfd = (bfd *) obfdarg;
1389 struct section_list *p;
1390 arelent **relpp;
1391 long relcount;
1392 sec_ptr osection;
1393 bfd_size_type size;
1394 long relsize;
1395
1396 /* If we have already failed earlier on, do not keep on generating
1397 complaints now. */
1398 if (status != 0)
1399 return;
1400
1401 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1402 && (strip_symbols == STRIP_DEBUG
1403 || strip_symbols == STRIP_UNNEEDED
1404 || strip_symbols == STRIP_ALL
1405 || discard_locals == LOCALS_ALL
1406 || convert_debugging))
1407 {
1408 return;
1409 }
1410
1411 p = find_section_list (bfd_section_name (ibfd, isection), false);
1412
1413 if (sections_removed && p != NULL && p->remove)
1414 return;
1415 if (sections_copied && (p == NULL || ! p->copy))
1416 return;
1417
1418 osection = isection->output_section;
1419 size = bfd_get_section_size_before_reloc (isection);
1420
1421 if (size == 0 || osection == 0)
1422 return;
1423
1424
1425 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1426 if (relsize < 0)
1427 RETURN_NONFATAL (bfd_get_filename (ibfd));
1428
1429 if (relsize == 0)
1430 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1431 else
1432 {
1433 relpp = (arelent **) xmalloc (relsize);
1434 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1435 if (relcount < 0)
1436 RETURN_NONFATAL (bfd_get_filename (ibfd));
1437
1438 if (strip_symbols == STRIP_ALL)
1439 {
1440 /* Remove relocations which are not in
1441 keep_strip_specific_list. */
1442 arelent **temp_relpp;
1443 long temp_relcount = 0;
1444 long i;
1445
1446 temp_relpp = (arelent **) xmalloc (relsize);
1447 for (i = 0; i < relcount; i++)
1448 if (is_specified_symbol
1449 (bfd_asymbol_name (*relpp [i]->sym_ptr_ptr),
1450 keep_specific_list))
1451 temp_relpp [temp_relcount++] = relpp [i];
1452 relcount = temp_relcount;
1453 free (relpp);
1454 relpp = temp_relpp;
1455 }
1456 bfd_set_reloc (obfd, osection,
1457 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1458 }
1459
1460 isection->_cooked_size = isection->_raw_size;
1461 isection->reloc_done = true;
1462
1463 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1464 {
1465 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1466
1467 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1468 size))
1469 RETURN_NONFATAL (bfd_get_filename (ibfd));
1470
1471 if (copy_byte >= 0)
1472 filter_bytes (memhunk, &size);
1473
1474 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1475 size))
1476 RETURN_NONFATAL (bfd_get_filename (obfd));
1477
1478 free (memhunk);
1479 }
1480 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1481 {
1482 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1483
1484 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1485 flag--they can just remove the section entirely and add it
1486 back again. However, we do permit them to turn on the
1487 SEC_HAS_CONTENTS flag, and take it to mean that the section
1488 contents should be zeroed out. */
1489
1490 memset (memhunk, 0, size);
1491 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1492 size))
1493 RETURN_NONFATAL (bfd_get_filename (obfd));
1494 free (memhunk);
1495 }
1496 }
1497
1498 /* Get all the sections. This is used when --gap-fill or --pad-to is
1499 used. */
1500
1501 static void
1502 get_sections (obfd, osection, secppparg)
1503 bfd *obfd ATTRIBUTE_UNUSED;
1504 asection *osection;
1505 PTR secppparg;
1506 {
1507 asection ***secppp = (asection ***) secppparg;
1508
1509 **secppp = osection;
1510 ++(*secppp);
1511 }
1512
1513 /* Sort sections by VMA. This is called via qsort, and is used when
1514 --gap-fill or --pad-to is used. We force non loadable or empty
1515 sections to the front, where they are easier to ignore. */
1516
1517 static int
1518 compare_section_lma (arg1, arg2)
1519 const PTR arg1;
1520 const PTR arg2;
1521 {
1522 const asection **sec1 = (const asection **) arg1;
1523 const asection **sec2 = (const asection **) arg2;
1524 flagword flags1, flags2;
1525
1526 /* Sort non loadable sections to the front. */
1527 flags1 = (*sec1)->flags;
1528 flags2 = (*sec2)->flags;
1529 if ((flags1 & SEC_HAS_CONTENTS) == 0
1530 || (flags1 & SEC_LOAD) == 0)
1531 {
1532 if ((flags2 & SEC_HAS_CONTENTS) != 0
1533 && (flags2 & SEC_LOAD) != 0)
1534 return -1;
1535 }
1536 else
1537 {
1538 if ((flags2 & SEC_HAS_CONTENTS) == 0
1539 || (flags2 & SEC_LOAD) == 0)
1540 return 1;
1541 }
1542
1543 /* Sort sections by LMA. */
1544 if ((*sec1)->lma > (*sec2)->lma)
1545 return 1;
1546 else if ((*sec1)->lma < (*sec2)->lma)
1547 return -1;
1548
1549 /* Sort sections with the same LMA by size. */
1550 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1551 return 1;
1552 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1553 return -1;
1554
1555 return 0;
1556 }
1557
1558 /* Mark all the symbols which will be used in output relocations with
1559 the BSF_KEEP flag so that those symbols will not be stripped.
1560
1561 Ignore relocations which will not appear in the output file. */
1562
1563 static void
1564 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1565 bfd *ibfd;
1566 sec_ptr isection;
1567 PTR symbolsarg;
1568 {
1569 asymbol **symbols = (asymbol **) symbolsarg;
1570 long relsize;
1571 arelent **relpp;
1572 long relcount, i;
1573
1574 /* Ignore an input section with no corresponding output section. */
1575 if (isection->output_section == NULL)
1576 return;
1577
1578 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1579 if (relsize < 0)
1580 bfd_fatal (bfd_get_filename (ibfd));
1581
1582 if (relsize == 0)
1583 return;
1584
1585 relpp = (arelent **) xmalloc (relsize);
1586 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1587 if (relcount < 0)
1588 bfd_fatal (bfd_get_filename (ibfd));
1589
1590 /* Examine each symbol used in a relocation. If it's not one of the
1591 special bfd section symbols, then mark it with BSF_KEEP. */
1592 for (i = 0; i < relcount; i++)
1593 {
1594 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1595 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1596 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1597 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1598 }
1599
1600 if (relpp != NULL)
1601 free (relpp);
1602 }
1603
1604 /* Write out debugging information. */
1605
1606 static boolean
1607 write_debugging_info (obfd, dhandle, symcountp, symppp)
1608 bfd *obfd;
1609 PTR dhandle;
1610 long *symcountp ATTRIBUTE_UNUSED;
1611 asymbol ***symppp ATTRIBUTE_UNUSED;
1612 {
1613 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1614 return write_ieee_debugging_info (obfd, dhandle);
1615
1616 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1617 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1618 {
1619 bfd_byte *syms, *strings;
1620 bfd_size_type symsize, stringsize;
1621 asection *stabsec, *stabstrsec;
1622
1623 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1624 &symsize, &strings,
1625 &stringsize))
1626 return false;
1627
1628 stabsec = bfd_make_section (obfd, ".stab");
1629 stabstrsec = bfd_make_section (obfd, ".stabstr");
1630 if (stabsec == NULL
1631 || stabstrsec == NULL
1632 || ! bfd_set_section_size (obfd, stabsec, symsize)
1633 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1634 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1635 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1636 || ! bfd_set_section_flags (obfd, stabsec,
1637 (SEC_HAS_CONTENTS
1638 | SEC_READONLY
1639 | SEC_DEBUGGING))
1640 || ! bfd_set_section_flags (obfd, stabstrsec,
1641 (SEC_HAS_CONTENTS
1642 | SEC_READONLY
1643 | SEC_DEBUGGING)))
1644 {
1645 non_fatal (_("%s: can't create debugging section: %s"),
1646 bfd_get_filename (obfd),
1647 bfd_errmsg (bfd_get_error ()));
1648 return false;
1649 }
1650
1651 /* We can get away with setting the section contents now because
1652 the next thing the caller is going to do is copy over the
1653 real sections. We may someday have to split the contents
1654 setting out of this function. */
1655 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1656 symsize)
1657 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1658 (file_ptr) 0, stringsize))
1659 {
1660 non_fatal (_("%s: can't set debugging section contents: %s"),
1661 bfd_get_filename (obfd),
1662 bfd_errmsg (bfd_get_error ()));
1663 return false;
1664 }
1665
1666 return true;
1667 }
1668
1669 non_fatal (_("%s: don't know how to write debugging information for %s"),
1670 bfd_get_filename (obfd), bfd_get_target (obfd));
1671 return false;
1672 }
1673
1674 static int
1675 strip_main (argc, argv)
1676 int argc;
1677 char *argv[];
1678 {
1679 char *input_target = NULL, *output_target = NULL;
1680 boolean show_version = false;
1681 int c, i;
1682 struct section_list *p;
1683 char *output_file = NULL;
1684
1685 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1686 strip_options, (int *) 0)) != EOF)
1687 {
1688 switch (c)
1689 {
1690 case 'I':
1691 input_target = optarg;
1692 break;
1693 case 'O':
1694 output_target = optarg;
1695 break;
1696 case 'F':
1697 input_target = output_target = optarg;
1698 break;
1699 case 'R':
1700 p = find_section_list (optarg, true);
1701 p->remove = true;
1702 sections_removed = true;
1703 break;
1704 case 's':
1705 strip_symbols = STRIP_ALL;
1706 break;
1707 case 'S':
1708 case 'g':
1709 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1710 strip_symbols = STRIP_DEBUG;
1711 break;
1712 case OPTION_STRIP_UNNEEDED:
1713 strip_symbols = STRIP_UNNEEDED;
1714 break;
1715 case 'K':
1716 add_specific_symbol (optarg, &keep_specific_list);
1717 break;
1718 case 'N':
1719 add_specific_symbol (optarg, &strip_specific_list);
1720 break;
1721 case 'o':
1722 output_file = optarg;
1723 break;
1724 case 'p':
1725 preserve_dates = true;
1726 break;
1727 case 'x':
1728 discard_locals = LOCALS_ALL;
1729 break;
1730 case 'X':
1731 discard_locals = LOCALS_START_L;
1732 break;
1733 case 'v':
1734 verbose = true;
1735 break;
1736 case 'V':
1737 show_version = true;
1738 break;
1739 case 0:
1740 break; /* we've been given a long option */
1741 case 'h':
1742 strip_usage (stdout, 0);
1743 default:
1744 strip_usage (stderr, 1);
1745 }
1746 }
1747
1748 if (show_version)
1749 print_version ("strip");
1750
1751 /* Default is to strip all symbols. */
1752 if (strip_symbols == STRIP_UNDEF
1753 && discard_locals == LOCALS_UNDEF
1754 && strip_specific_list == NULL)
1755 strip_symbols = STRIP_ALL;
1756
1757 if (output_target == (char *) NULL)
1758 output_target = input_target;
1759
1760 i = optind;
1761 if (i == argc
1762 || (output_file != NULL && (i + 1) < argc))
1763 strip_usage (stderr, 1);
1764
1765 for (; i < argc; i++)
1766 {
1767 int hold_status = status;
1768 struct stat statbuf;
1769 char *tmpname;
1770
1771 if (preserve_dates)
1772 {
1773 if (stat (argv[i], &statbuf) < 0)
1774 {
1775 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1776 continue;
1777 }
1778 }
1779
1780 if (output_file != NULL)
1781 tmpname = output_file;
1782 else
1783 tmpname = make_tempname (argv[i]);
1784 status = 0;
1785
1786 copy_file (argv[i], tmpname, input_target, output_target);
1787 if (status == 0)
1788 {
1789 if (preserve_dates)
1790 set_times (tmpname, &statbuf);
1791 if (output_file == NULL)
1792 smart_rename (tmpname, argv[i], preserve_dates);
1793 status = hold_status;
1794 }
1795 else
1796 unlink (tmpname);
1797 if (output_file == NULL)
1798 free (tmpname);
1799 }
1800
1801 return 0;
1802 }
1803
1804 static int
1805 copy_main (argc, argv)
1806 int argc;
1807 char *argv[];
1808 {
1809 char *input_filename = NULL, *output_filename = NULL;
1810 char *input_target = NULL, *output_target = NULL;
1811 boolean show_version = false;
1812 boolean change_warn = true;
1813 int c;
1814 struct section_list *p;
1815 struct stat statbuf;
1816
1817 while ((c = getopt_long (argc, argv, "b:i:I:j:K:N:s:O:d:F:L:R:SpgxXVvW:",
1818 copy_options, (int *) 0)) != EOF)
1819 {
1820 switch (c)
1821 {
1822 case 'b':
1823 copy_byte = atoi (optarg);
1824 if (copy_byte < 0)
1825 fatal (_("byte number must be non-negative"));
1826 break;
1827
1828 case 'i':
1829 interleave = atoi (optarg);
1830 if (interleave < 1)
1831 fatal (_("interleave must be positive"));
1832 break;
1833
1834 case 'I':
1835 case 's': /* "source" - 'I' is preferred */
1836 input_target = optarg;
1837 break;
1838
1839 case 'O':
1840 case 'd': /* "destination" - 'O' is preferred */
1841 output_target = optarg;
1842 break;
1843
1844 case 'F':
1845 input_target = output_target = optarg;
1846 break;
1847
1848 case 'j':
1849 p = find_section_list (optarg, true);
1850 if (p->remove)
1851 fatal (_("%s both copied and removed"), optarg);
1852 p->copy = true;
1853 sections_copied = true;
1854 break;
1855
1856 case 'R':
1857 p = find_section_list (optarg, true);
1858 if (p->copy)
1859 fatal (_("%s both copied and removed"), optarg);
1860 p->remove = true;
1861 sections_removed = true;
1862 break;
1863
1864 case 'S':
1865 strip_symbols = STRIP_ALL;
1866 break;
1867
1868 case 'g':
1869 strip_symbols = STRIP_DEBUG;
1870 break;
1871
1872 case OPTION_STRIP_UNNEEDED:
1873 strip_symbols = STRIP_UNNEEDED;
1874 break;
1875
1876 case 'K':
1877 add_specific_symbol (optarg, &keep_specific_list);
1878 break;
1879
1880 case 'N':
1881 add_specific_symbol (optarg, &strip_specific_list);
1882 break;
1883
1884 case 'L':
1885 add_specific_symbol (optarg, &localize_specific_list);
1886 break;
1887
1888 case 'W':
1889 add_specific_symbol (optarg, &weaken_specific_list);
1890 break;
1891
1892 case 'p':
1893 preserve_dates = true;
1894 break;
1895
1896 case 'x':
1897 discard_locals = LOCALS_ALL;
1898 break;
1899
1900 case 'X':
1901 discard_locals = LOCALS_START_L;
1902 break;
1903
1904 case 'v':
1905 verbose = true;
1906 break;
1907
1908 case 'V':
1909 show_version = true;
1910 break;
1911
1912 case OPTION_WEAKEN:
1913 weaken = true;
1914 break;
1915
1916 case OPTION_ADD_SECTION:
1917 {
1918 const char *s;
1919 struct stat st;
1920 struct section_add *pa;
1921 int len;
1922 char *name;
1923 FILE *f;
1924
1925 s = strchr (optarg, '=');
1926
1927 if (s == NULL)
1928 fatal (_("bad format for %s"), "--add-section");
1929
1930 if (stat (s + 1, & st) < 0)
1931 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
1932
1933 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1934
1935 len = s - optarg;
1936 name = (char *) xmalloc (len + 1);
1937 strncpy (name, optarg, len);
1938 name[len] = '\0';
1939 pa->name = name;
1940
1941 pa->filename = s + 1;
1942
1943 pa->size = st.st_size;
1944
1945 pa->contents = (bfd_byte *) xmalloc (pa->size);
1946 f = fopen (pa->filename, FOPEN_RB);
1947
1948 if (f == NULL)
1949 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
1950
1951 if (fread (pa->contents, 1, pa->size, f) == 0
1952 || ferror (f))
1953 fatal (_("%s: fread failed"), pa->filename);
1954
1955 fclose (f);
1956
1957 pa->next = add_sections;
1958 add_sections = pa;
1959 }
1960 break;
1961
1962 case OPTION_CHANGE_START:
1963 change_start = parse_vma (optarg, "--change-start");
1964 break;
1965
1966 case OPTION_CHANGE_SECTION_ADDRESS:
1967 case OPTION_CHANGE_SECTION_LMA:
1968 case OPTION_CHANGE_SECTION_VMA:
1969 {
1970 const char *s;
1971 int len;
1972 char *name;
1973 char *option = NULL;
1974 bfd_vma val;
1975 enum change_action what = CHANGE_IGNORE;
1976
1977 switch (c)
1978 {
1979 case OPTION_CHANGE_SECTION_ADDRESS:
1980 option = "--change-section-address";
1981 break;
1982 case OPTION_CHANGE_SECTION_LMA:
1983 option = "--change-section-lma";
1984 break;
1985 case OPTION_CHANGE_SECTION_VMA:
1986 option = "--change-section-vma";
1987 break;
1988 }
1989
1990 s = strchr (optarg, '=');
1991 if (s == NULL)
1992 {
1993 s = strchr (optarg, '+');
1994 if (s == NULL)
1995 {
1996 s = strchr (optarg, '-');
1997 if (s == NULL)
1998 fatal (_("bad format for %s"), option);
1999 }
2000 }
2001
2002 len = s - optarg;
2003 name = (char *) xmalloc (len + 1);
2004 strncpy (name, optarg, len);
2005 name[len] = '\0';
2006
2007 p = find_section_list (name, true);
2008
2009 val = parse_vma (s + 1, option);
2010
2011 switch (*s)
2012 {
2013 case '=': what = CHANGE_SET; break;
2014 case '-': val = - val; /* Drop through. */
2015 case '+': what = CHANGE_MODIFY; break;
2016 }
2017
2018 switch (c)
2019 {
2020 case OPTION_CHANGE_SECTION_ADDRESS:
2021 p->change_vma = what;
2022 p->vma_val = val;
2023 /* Drop through. */
2024
2025 case OPTION_CHANGE_SECTION_LMA:
2026 p->change_lma = what;
2027 p->lma_val = val;
2028 break;
2029
2030 case OPTION_CHANGE_SECTION_VMA:
2031 p->change_vma = what;
2032 p->vma_val = val;
2033 break;
2034 }
2035 }
2036 break;
2037
2038 case OPTION_CHANGE_ADDRESSES:
2039 change_section_address = parse_vma (optarg, "--change-addresses");
2040 change_start = change_section_address;
2041 break;
2042
2043 case OPTION_CHANGE_WARNINGS:
2044 change_warn = true;
2045 break;
2046
2047 case OPTION_CHANGE_LEADING_CHAR:
2048 change_leading_char = true;
2049 break;
2050
2051 case OPTION_DEBUGGING:
2052 convert_debugging = true;
2053 break;
2054
2055 case OPTION_GAP_FILL:
2056 {
2057 bfd_vma gap_fill_vma;
2058
2059 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2060 gap_fill = (bfd_byte) gap_fill_vma;
2061 if ((bfd_vma) gap_fill != gap_fill_vma)
2062 {
2063 char buff[20];
2064
2065 sprintf_vma (buff, gap_fill_vma);
2066
2067 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2068 buff, gap_fill);
2069 }
2070 gap_fill_set = true;
2071 }
2072 break;
2073
2074 case OPTION_NO_CHANGE_WARNINGS:
2075 change_warn = false;
2076 break;
2077
2078 case OPTION_PAD_TO:
2079 pad_to = parse_vma (optarg, "--pad-to");
2080 pad_to_set = true;
2081 break;
2082
2083 case OPTION_REMOVE_LEADING_CHAR:
2084 remove_leading_char = true;
2085 break;
2086
2087 case OPTION_REDEFINE_SYM:
2088 {
2089 /* Push this redefinition onto redefine_symbol_list. */
2090
2091 int len;
2092 const char *s;
2093 const char *nextarg;
2094 char *source, *target;
2095
2096 s = strchr (optarg, '=');
2097 if (s == NULL)
2098 {
2099 fatal (_("bad format for %s"), "--redefine-sym");
2100 }
2101
2102 len = s - optarg;
2103 source = (char *) xmalloc (len + 1);
2104 strncpy (source, optarg, len);
2105 source[len] = '\0';
2106
2107 nextarg = s + 1;
2108 len = strlen (nextarg);
2109 target = (char *) xmalloc (len + 1);
2110 strcpy (target, nextarg);
2111
2112 redefine_list_append (source, target);
2113
2114 free (source);
2115 free (target);
2116 }
2117 break;
2118
2119 case OPTION_SET_SECTION_FLAGS:
2120 {
2121 const char *s;
2122 int len;
2123 char *name;
2124
2125 s = strchr (optarg, '=');
2126 if (s == NULL)
2127 fatal (_("bad format for %s"), "--set-section-flags");
2128
2129 len = s - optarg;
2130 name = (char *) xmalloc (len + 1);
2131 strncpy (name, optarg, len);
2132 name[len] = '\0';
2133
2134 p = find_section_list (name, true);
2135
2136 p->set_flags = true;
2137 p->flags = parse_flags (s + 1);
2138 }
2139 break;
2140
2141 case OPTION_SET_START:
2142 set_start = parse_vma (optarg, "--set-start");
2143 set_start_set = true;
2144 break;
2145
2146 case OPTION_SREC_LEN:
2147 Chunk = parse_vma (optarg, "--srec-len");
2148 break;
2149
2150 case OPTION_SREC_FORCES3:
2151 S3Forced = true;
2152 break;
2153
2154 case 0:
2155 break; /* we've been given a long option */
2156
2157 case 'h':
2158 copy_usage (stdout, 0);
2159
2160 default:
2161 copy_usage (stderr, 1);
2162 }
2163 }
2164
2165 if (show_version)
2166 print_version ("objcopy");
2167
2168 if (copy_byte >= interleave)
2169 fatal (_("byte number must be less than interleave"));
2170
2171 if (optind == argc || optind + 2 < argc)
2172 copy_usage (stderr, 1);
2173
2174 input_filename = argv[optind];
2175 if (optind + 1 < argc)
2176 output_filename = argv[optind + 1];
2177
2178 /* Default is to strip no symbols. */
2179 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2180 strip_symbols = STRIP_NONE;
2181
2182 if (output_target == (char *) NULL)
2183 output_target = input_target;
2184
2185 if (preserve_dates)
2186 {
2187 if (stat (input_filename, &statbuf) < 0)
2188 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2189 }
2190
2191 /* If there is no destination file then create a temp and rename
2192 the result into the input. */
2193
2194 if (output_filename == (char *) NULL)
2195 {
2196 char *tmpname = make_tempname (input_filename);
2197
2198 copy_file (input_filename, tmpname, input_target, output_target);
2199 if (status == 0)
2200 {
2201 if (preserve_dates)
2202 set_times (tmpname, &statbuf);
2203 smart_rename (tmpname, input_filename, preserve_dates);
2204 }
2205 else
2206 unlink (tmpname);
2207 }
2208 else
2209 {
2210 copy_file (input_filename, output_filename, input_target, output_target);
2211 if (status == 0 && preserve_dates)
2212 set_times (output_filename, &statbuf);
2213 }
2214
2215 if (change_warn)
2216 {
2217 for (p = change_sections; p != NULL; p = p->next)
2218 {
2219 if (! p->used)
2220 {
2221 if (p->change_vma != CHANGE_IGNORE)
2222 {
2223 char buff [20];
2224
2225 sprintf_vma (buff, p->vma_val);
2226
2227 /* xgettext:c-format */
2228 non_fatal (_("%s %s%c0x%s never used"),
2229 "--change-section-vma",
2230 p->name,
2231 p->change_vma == CHANGE_SET ? '=' : '+',
2232 buff);
2233 }
2234
2235 if (p->change_lma != CHANGE_IGNORE)
2236 {
2237 char buff [20];
2238
2239 sprintf_vma (buff, p->lma_val);
2240
2241 /* xgettext:c-format */
2242 non_fatal (_("%s %s%c0x%s never used"),
2243 "--change-section-lma",
2244 p->name,
2245 p->change_lma == CHANGE_SET ? '=' : '+',
2246 buff);
2247 }
2248 }
2249 }
2250 }
2251
2252 return 0;
2253 }
2254
2255 int
2256 main (argc, argv)
2257 int argc;
2258 char *argv[];
2259 {
2260 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2261 setlocale (LC_MESSAGES, "");
2262 #endif
2263 bindtextdomain (PACKAGE, LOCALEDIR);
2264 textdomain (PACKAGE);
2265
2266 program_name = argv[0];
2267 xmalloc_set_program_name (program_name);
2268
2269 START_PROGRESS (program_name, 0);
2270
2271 strip_symbols = STRIP_UNDEF;
2272 discard_locals = LOCALS_UNDEF;
2273
2274 bfd_init ();
2275 set_default_bfd_target ();
2276
2277 if (is_strip < 0)
2278 {
2279 int i = strlen (program_name);
2280 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2281 /* Drop the .exe suffix, if any. */
2282 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2283 {
2284 i -= 4;
2285 program_name[i] = '\0';
2286 }
2287 #endif
2288 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2289 }
2290
2291 if (is_strip)
2292 strip_main (argc, argv);
2293 else
2294 copy_main (argc, argv);
2295
2296 END_PROGRESS (program_name);
2297
2298 return status;
2299 }