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