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