*** empty log message ***
[deliverable/binutils-gdb.git] / binutils / objcopy.c
... / ...
CommitLineData
1/* objcopy.c -- copy object file from input to output, optionally massaging it.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003
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"
29#include "filenames.h"
30#include "fnmatch.h"
31#include <sys/stat.h>
32
33/* A list of symbols to explicitly strip out, or to keep. A linked
34 list is good enough for a small number from the command line, but
35 this will slow things down a lot if many symbols are being
36 deleted. */
37
38struct symlist
39{
40 const char *name;
41 struct symlist *next;
42};
43
44/* A list to support redefine_sym. */
45struct redefine_node
46{
47 char *source;
48 char *target;
49 struct redefine_node *next;
50};
51
52typedef struct section_rename
53{
54 const char * old_name;
55 const char * new_name;
56 flagword flags;
57 struct section_rename * next;
58}
59section_rename;
60
61/* List of sections to be renamed. */
62static section_rename *section_rename_list;
63
64#define RETURN_NONFATAL(s) {bfd_nonfatal (s); status = 1; return;}
65
66static asymbol **isympp = NULL; /* Input symbols. */
67static asymbol **osympp = NULL; /* Output symbols that survive stripping. */
68
69/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
70static int copy_byte = -1;
71static int interleave = 4;
72
73static bfd_boolean verbose; /* Print file and target names. */
74static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
75static int status = 0; /* Exit status. */
76
77enum strip_action
78 {
79 STRIP_UNDEF,
80 STRIP_NONE, /* Don't strip. */
81 STRIP_DEBUG, /* Strip all debugger symbols. */
82 STRIP_UNNEEDED, /* Strip unnecessary symbols. */
83 STRIP_NONDEBUG, /* Strip everything but debug info. */
84 STRIP_ALL /* Strip all symbols. */
85 };
86
87/* Which symbols to remove. */
88static enum strip_action strip_symbols;
89
90enum locals_action
91 {
92 LOCALS_UNDEF,
93 LOCALS_START_L, /* Discard locals starting with L. */
94 LOCALS_ALL /* Discard all locals. */
95 };
96
97/* Which local symbols to remove. Overrides STRIP_ALL. */
98static enum locals_action discard_locals;
99
100/* What kind of change to perform. */
101enum change_action
102{
103 CHANGE_IGNORE,
104 CHANGE_MODIFY,
105 CHANGE_SET
106};
107
108/* Structure used to hold lists of sections and actions to take. */
109struct section_list
110{
111 struct section_list * next; /* Next section to change. */
112 const char * name; /* Section name. */
113 bfd_boolean used; /* Whether this entry was used. */
114 bfd_boolean remove; /* Whether to remove this section. */
115 bfd_boolean copy; /* Whether to copy this section. */
116 enum change_action change_vma;/* Whether to change or set VMA. */
117 bfd_vma vma_val; /* Amount to change by or set to. */
118 enum change_action change_lma;/* Whether to change or set LMA. */
119 bfd_vma lma_val; /* Amount to change by or set to. */
120 bfd_boolean set_flags; /* Whether to set the section flags. */
121 flagword flags; /* What to set the section flags to. */
122};
123
124static struct section_list *change_sections;
125
126/* TRUE if some sections are to be removed. */
127static bfd_boolean sections_removed;
128
129/* TRUE if only some sections are to be copied. */
130static bfd_boolean sections_copied;
131
132/* Changes to the start address. */
133static bfd_vma change_start = 0;
134static bfd_boolean set_start_set = FALSE;
135static bfd_vma set_start;
136
137/* Changes to section addresses. */
138static bfd_vma change_section_address = 0;
139
140/* Filling gaps between sections. */
141static bfd_boolean gap_fill_set = FALSE;
142static bfd_byte gap_fill = 0;
143
144/* Pad to a given address. */
145static bfd_boolean pad_to_set = FALSE;
146static bfd_vma pad_to;
147
148/* Use alternate machine code? */
149static int use_alt_mach_code = 0;
150
151/* List of sections to add. */
152struct section_add
153{
154 /* Next section to add. */
155 struct section_add *next;
156 /* Name of section to add. */
157 const char *name;
158 /* Name of file holding section contents. */
159 const char *filename;
160 /* Size of file. */
161 size_t size;
162 /* Contents of file. */
163 bfd_byte *contents;
164 /* BFD section, after it has been added. */
165 asection *section;
166};
167
168/* List of sections to add to the output BFD. */
169static struct section_add *add_sections;
170
171/* If non-NULL the argument to --add-gnu-debuglink.
172 This should be the filename to store in the .gnu_debuglink section. */
173static const char * gnu_debuglink_filename = NULL;
174
175/* Whether to convert debugging information. */
176static bfd_boolean convert_debugging = FALSE;
177
178/* Whether to change the leading character in symbol names. */
179static bfd_boolean change_leading_char = FALSE;
180
181/* Whether to remove the leading character from global symbol names. */
182static bfd_boolean remove_leading_char = FALSE;
183
184/* Whether to permit wildcard in symbol comparison. */
185static bfd_boolean wildcard = FALSE;
186
187/* List of symbols to strip, keep, localize, keep-global, weaken,
188 or redefine. */
189static struct symlist *strip_specific_list = NULL;
190static struct symlist *keep_specific_list = NULL;
191static struct symlist *localize_specific_list = NULL;
192static struct symlist *keepglobal_specific_list = NULL;
193static struct symlist *weaken_specific_list = NULL;
194static struct redefine_node *redefine_sym_list = NULL;
195
196/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
197static bfd_boolean weaken = FALSE;
198
199/* Prefix symbols/sections. */
200static char *prefix_symbols_string = 0;
201static char *prefix_sections_string = 0;
202static char *prefix_alloc_sections_string = 0;
203
204/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
205enum command_line_switch
206 {
207 OPTION_ADD_SECTION=150,
208 OPTION_CHANGE_ADDRESSES,
209 OPTION_CHANGE_LEADING_CHAR,
210 OPTION_CHANGE_START,
211 OPTION_CHANGE_SECTION_ADDRESS,
212 OPTION_CHANGE_SECTION_LMA,
213 OPTION_CHANGE_SECTION_VMA,
214 OPTION_CHANGE_WARNINGS,
215 OPTION_DEBUGGING,
216 OPTION_GAP_FILL,
217 OPTION_NO_CHANGE_WARNINGS,
218 OPTION_PAD_TO,
219 OPTION_REMOVE_LEADING_CHAR,
220 OPTION_SET_SECTION_FLAGS,
221 OPTION_SET_START,
222 OPTION_STRIP_UNNEEDED,
223 OPTION_WEAKEN,
224 OPTION_REDEFINE_SYM,
225 OPTION_REDEFINE_SYMS,
226 OPTION_SREC_LEN,
227 OPTION_SREC_FORCES3,
228 OPTION_STRIP_SYMBOLS,
229 OPTION_KEEP_SYMBOLS,
230 OPTION_LOCALIZE_SYMBOLS,
231 OPTION_KEEPGLOBAL_SYMBOLS,
232 OPTION_WEAKEN_SYMBOLS,
233 OPTION_RENAME_SECTION,
234 OPTION_ALT_MACH_CODE,
235 OPTION_PREFIX_SYMBOLS,
236 OPTION_PREFIX_SECTIONS,
237 OPTION_PREFIX_ALLOC_SECTIONS,
238 OPTION_FORMATS_INFO,
239 OPTION_ADD_GNU_DEBUGLINK,
240 OPTION_ONLY_KEEP_DEBUG
241 };
242
243/* Options to handle if running as "strip". */
244
245static struct option strip_options[] =
246{
247 {"discard-all", no_argument, 0, 'x'},
248 {"discard-locals", no_argument, 0, 'X'},
249 {"format", required_argument, 0, 'F'}, /* Obsolete */
250 {"help", no_argument, 0, 'h'},
251 {"info", no_argument, 0, OPTION_FORMATS_INFO},
252 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
253 {"input-target", required_argument, 0, 'I'},
254 {"keep-symbol", required_argument, 0, 'K'},
255 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
256 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
257 {"output-target", required_argument, 0, 'O'},
258 {"output-file", required_argument, 0, 'o'},
259 {"preserve-dates", no_argument, 0, 'p'},
260 {"remove-section", required_argument, 0, 'R'},
261 {"strip-all", no_argument, 0, 's'},
262 {"strip-debug", no_argument, 0, 'S'},
263 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
264 {"strip-symbol", required_argument, 0, 'N'},
265 {"target", required_argument, 0, 'F'},
266 {"verbose", no_argument, 0, 'v'},
267 {"version", no_argument, 0, 'V'},
268 {"wildcard", no_argument, 0, 'w'},
269 {0, no_argument, 0, 0}
270};
271
272/* Options to handle if running as "objcopy". */
273
274static struct option copy_options[] =
275{
276 {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
277 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
278 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
279 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
280 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
281 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
282 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
283 {"binary-architecture", required_argument, 0, 'B'},
284 {"byte", required_argument, 0, 'b'},
285 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
286 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
287 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
288 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
289 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
290 {"change-start", required_argument, 0, OPTION_CHANGE_START},
291 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
292 {"debugging", no_argument, 0, OPTION_DEBUGGING},
293 {"discard-all", no_argument, 0, 'x'},
294 {"discard-locals", no_argument, 0, 'X'},
295 {"format", required_argument, 0, 'F'}, /* Obsolete */
296 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
297 {"help", no_argument, 0, 'h'},
298 {"info", no_argument, 0, OPTION_FORMATS_INFO},
299 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
300 {"input-target", required_argument, 0, 'I'},
301 {"interleave", required_argument, 0, 'i'},
302 {"keep-global-symbol", required_argument, 0, 'G'},
303 {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
304 {"keep-symbol", required_argument, 0, 'K'},
305 {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
306 {"localize-symbol", required_argument, 0, 'L'},
307 {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
308 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
309 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
310 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
311 {"only-section", required_argument, 0, 'j'},
312 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
313 {"output-target", required_argument, 0, 'O'},
314 {"pad-to", required_argument, 0, OPTION_PAD_TO},
315 {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
316 {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
317 {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
318 {"preserve-dates", no_argument, 0, 'p'},
319 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
320 {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
321 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
322 {"remove-section", required_argument, 0, 'R'},
323 {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
324 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
325 {"set-start", required_argument, 0, OPTION_SET_START},
326 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
327 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
328 {"strip-all", no_argument, 0, 'S'},
329 {"strip-debug", no_argument, 0, 'g'},
330 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
331 {"strip-symbol", required_argument, 0, 'N'},
332 {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
333 {"target", required_argument, 0, 'F'},
334 {"verbose", no_argument, 0, 'v'},
335 {"version", no_argument, 0, 'V'},
336 {"weaken", no_argument, 0, OPTION_WEAKEN},
337 {"weaken-symbol", required_argument, 0, 'W'},
338 {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
339 {"wildcard", no_argument, 0, 'w'},
340 {0, no_argument, 0, 0}
341};
342
343/* IMPORTS */
344extern char *program_name;
345
346/* This flag distinguishes between strip and objcopy:
347 1 means this is 'strip'; 0 means this is 'objcopy'.
348 -1 means if we should use argv[0] to decide. */
349extern int is_strip;
350
351/* The maximum length of an S record. This variable is declared in srec.c
352 and can be modified by the --srec-len parameter. */
353extern unsigned int Chunk;
354
355/* Restrict the generation of Srecords to type S3 only.
356 This variable is declare in bfd/srec.c and can be toggled
357 on by the --srec-forceS3 command line switch. */
358extern bfd_boolean S3Forced;
359
360/* Defined in bfd/binary.c. Used to set architecture and machine of input
361 binary files. */
362extern enum bfd_architecture bfd_external_binary_architecture;
363extern unsigned long bfd_external_machine;
364
365/* Forward declarations. */
366static void setup_section (bfd *, asection *, void *);
367static void copy_section (bfd *, asection *, void *);
368static void get_sections (bfd *, asection *, void *);
369static int compare_section_lma (const void *, const void *);
370static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
371static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
372static const char *lookup_sym_redefinition (const char *);
373\f
374static void
375copy_usage (FILE *stream, int exit_status)
376{
377 fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
378 fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
379 fprintf (stream, _(" The options are:\n"));
380 fprintf (stream, _("\
381 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
382 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
383 -B --binary-architecture <arch> Set arch of output file, when input is binary\n\
384 -F --target <bfdname> Set both input and output format to <bfdname>\n\
385 --debugging Convert debugging information, if possible\n\
386 -p --preserve-dates Copy modified/access timestamps to the output\n\
387 -j --only-section <name> Only copy section <name> into the output\n\
388 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
389 -R --remove-section <name> Remove section <name> from the output\n\
390 -S --strip-all Remove all symbol and relocation information\n\
391 -g --strip-debug Remove all debugging symbols & sections\n\
392 --strip-unneeded Remove all symbols not needed by relocations\n\
393 -N --strip-symbol <name> Do not copy symbol <name>\n\
394 --only-keep-debug Strip everything but the debug information\n\
395 -K --keep-symbol <name> Only copy symbol <name>\n\
396 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
397 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
398 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
399 --weaken Force all global symbols to be marked as weak\n\
400 -w --wildcard Permit wildcard in symbol comparasion\n\
401 -x --discard-all Remove all non-global symbols\n\
402 -X --discard-locals Remove any compiler-generated symbols\n\
403 -i --interleave <number> Only copy one out of every <number> bytes\n\
404 -b --byte <num> Select byte <num> in every interleaved block\n\
405 --gap-fill <val> Fill gaps between sections with <val>\n\
406 --pad-to <addr> Pad the last section up to address <addr>\n\
407 --set-start <addr> Set the start address to <addr>\n\
408 {--change-start|--adjust-start} <incr>\n\
409 Add <incr> to the start address\n\
410 {--change-addresses|--adjust-vma} <incr>\n\
411 Add <incr> to LMA, VMA and start addresses\n\
412 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
413 Change LMA and VMA of section <name> by <val>\n\
414 --change-section-lma <name>{=|+|-}<val>\n\
415 Change the LMA of section <name> by <val>\n\
416 --change-section-vma <name>{=|+|-}<val>\n\
417 Change the VMA of section <name> by <val>\n\
418 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
419 Warn if a named section does not exist\n\
420 --set-section-flags <name>=<flags>\n\
421 Set section <name>'s properties to <flags>\n\
422 --add-section <name>=<file> Add section <name> found in <file> to output\n\
423 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
424 --change-leading-char Force output format's leading character style\n\
425 --remove-leading-char Remove leading character from global symbols\n\
426 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
427 --redefine-syms <file> --redefine-sym for all symbol pairs \n\
428 listed in <file>\n\
429 --srec-len <number> Restrict the length of generated Srecords\n\
430 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
431 --strip-symbols <file> -N for all symbols listed in <file>\n\
432 --keep-symbols <file> -K for all symbols listed in <file>\n\
433 --localize-symbols <file> -L for all symbols listed in <file>\n\
434 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
435 --weaken-symbols <file> -W for all symbols listed in <file>\n\
436 --alt-machine-code <index> Use alternate machine code for output\n\
437 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\
438 --prefix-sections <prefix> Add <prefix> to start of every section name\n\
439 --prefix-alloc-sections <prefix>\n\
440 Add <prefix> to start of every allocatable\n\
441 section name\n\
442 -v --verbose List all object files modified\n\
443 -V --version Display this program's version number\n\
444 -h --help Display this output\n\
445 --info List object formats & architectures supported\n\
446"));
447 list_supported_targets (program_name, stream);
448 if (exit_status == 0)
449 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
450 exit (exit_status);
451}
452
453static void
454strip_usage (FILE *stream, int exit_status)
455{
456 fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
457 fprintf (stream, _(" Removes symbols and sections from files\n"));
458 fprintf (stream, _(" The options are:\n"));
459 fprintf (stream, _("\
460 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\
461 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\
462 -F --target=<bfdname> Set both input and output format to <bfdname>\n\
463 -p --preserve-dates Copy modified/access timestamps to the output\n\
464 -R --remove-section=<name> Remove section <name> from the output\n\
465 -s --strip-all Remove all symbol and relocation information\n\
466 -g -S -d --strip-debug Remove all debugging symbols & sections\n\
467 --strip-unneeded Remove all symbols not needed by relocations\n\
468 --only-keep-debug Strip everything but the debug information\n\
469 -N --strip-symbol=<name> Do not copy symbol <name>\n\
470 -K --keep-symbol=<name> Only copy symbol <name>\n\
471 -w --wildcard Permit wildcard in symbol comparasion\n\
472 -x --discard-all Remove all non-global symbols\n\
473 -X --discard-locals Remove any compiler-generated symbols\n\
474 -v --verbose List all object files modified\n\
475 -V --version Display this program's version number\n\
476 -h --help Display this output\n\
477 --info List object formats & architectures supported\n\
478 -o <file> Place stripped output into <file>\n\
479"));
480
481 list_supported_targets (program_name, stream);
482 if (exit_status == 0)
483 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
484 exit (exit_status);
485}
486
487/* Parse section flags into a flagword, with a fatal error if the
488 string can't be parsed. */
489
490static flagword
491parse_flags (const char *s)
492{
493 flagword ret;
494 const char *snext;
495 int len;
496
497 ret = SEC_NO_FLAGS;
498
499 do
500 {
501 snext = strchr (s, ',');
502 if (snext == NULL)
503 len = strlen (s);
504 else
505 {
506 len = snext - s;
507 ++snext;
508 }
509
510 if (0) ;
511#define PARSE_FLAG(fname,fval) \
512 else if (strncasecmp (fname, s, len) == 0) ret |= fval
513 PARSE_FLAG ("alloc", SEC_ALLOC);
514 PARSE_FLAG ("load", SEC_LOAD);
515 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
516 PARSE_FLAG ("readonly", SEC_READONLY);
517 PARSE_FLAG ("debug", SEC_DEBUGGING);
518 PARSE_FLAG ("code", SEC_CODE);
519 PARSE_FLAG ("data", SEC_DATA);
520 PARSE_FLAG ("rom", SEC_ROM);
521 PARSE_FLAG ("share", SEC_SHARED);
522 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
523#undef PARSE_FLAG
524 else
525 {
526 char *copy;
527
528 copy = xmalloc (len + 1);
529 strncpy (copy, s, len);
530 copy[len] = '\0';
531 non_fatal (_("unrecognized section flag `%s'"), copy);
532 fatal (_("supported flags: %s"),
533 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
534 }
535
536 s = snext;
537 }
538 while (s != NULL);
539
540 return ret;
541}
542
543/* Find and optionally add an entry in the change_sections list. */
544
545static struct section_list *
546find_section_list (const char *name, bfd_boolean add)
547{
548 struct section_list *p;
549
550 for (p = change_sections; p != NULL; p = p->next)
551 if (strcmp (p->name, name) == 0)
552 return p;
553
554 if (! add)
555 return NULL;
556
557 p = xmalloc (sizeof (struct section_list));
558 p->name = name;
559 p->used = FALSE;
560 p->remove = FALSE;
561 p->copy = FALSE;
562 p->change_vma = CHANGE_IGNORE;
563 p->change_lma = CHANGE_IGNORE;
564 p->vma_val = 0;
565 p->lma_val = 0;
566 p->set_flags = FALSE;
567 p->flags = 0;
568
569 p->next = change_sections;
570 change_sections = p;
571
572 return p;
573}
574
575/* Add a symbol to strip_specific_list. */
576
577static void
578add_specific_symbol (const char *name, struct symlist **list)
579{
580 struct symlist *tmp_list;
581
582 tmp_list = xmalloc (sizeof (struct symlist));
583 tmp_list->name = name;
584 tmp_list->next = *list;
585 *list = tmp_list;
586}
587
588/* Add symbols listed in `filename' to strip_specific_list. */
589
590#define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
591#define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
592
593static void
594add_specific_symbols (const char *filename, struct symlist **list)
595{
596 off_t size;
597 FILE * f;
598 char * line;
599 char * buffer;
600 unsigned int line_count;
601
602 size = get_file_size (filename);
603 if (size == 0)
604 return;
605
606 buffer = xmalloc (size + 2);
607 f = fopen (filename, FOPEN_RT);
608 if (f == NULL)
609 fatal (_("cannot open '%s': %s"), filename, strerror (errno));
610
611 if (fread (buffer, 1, size, f) == 0 || ferror (f))
612 fatal (_("%s: fread failed"), filename);
613
614 fclose (f);
615 buffer [size] = '\n';
616 buffer [size + 1] = '\0';
617
618 line_count = 1;
619
620 for (line = buffer; * line != '\0'; line ++)
621 {
622 char * eol;
623 char * name;
624 char * name_end;
625 int finished = FALSE;
626
627 for (eol = line;; eol ++)
628 {
629 switch (* eol)
630 {
631 case '\n':
632 * eol = '\0';
633 /* Cope with \n\r. */
634 if (eol[1] == '\r')
635 ++ eol;
636 finished = TRUE;
637 break;
638
639 case '\r':
640 * eol = '\0';
641 /* Cope with \r\n. */
642 if (eol[1] == '\n')
643 ++ eol;
644 finished = TRUE;
645 break;
646
647 case 0:
648 finished = TRUE;
649 break;
650
651 case '#':
652 /* Line comment, Terminate the line here, in case a
653 name is present and then allow the rest of the
654 loop to find the real end of the line. */
655 * eol = '\0';
656 break;
657
658 default:
659 break;
660 }
661
662 if (finished)
663 break;
664 }
665
666 /* A name may now exist somewhere between 'line' and 'eol'.
667 Strip off leading whitespace and trailing whitespace,
668 then add it to the list. */
669 for (name = line; IS_WHITESPACE (* name); name ++)
670 ;
671 for (name_end = name;
672 (! IS_WHITESPACE (* name_end))
673 && (! IS_LINE_TERMINATOR (* name_end));
674 name_end ++)
675 ;
676
677 if (! IS_LINE_TERMINATOR (* name_end))
678 {
679 char * extra;
680
681 for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
682 ;
683
684 if (! IS_LINE_TERMINATOR (* extra))
685 non_fatal (_("Ignoring rubbish found on line %d of %s"),
686 line_count, filename);
687 }
688
689 * name_end = '\0';
690
691 if (name_end > name)
692 add_specific_symbol (name, list);
693
694 /* Advance line pointer to end of line. The 'eol ++' in the for
695 loop above will then advance us to the start of the next line. */
696 line = eol;
697 line_count ++;
698 }
699}
700
701/* See whether a symbol should be stripped or kept based on
702 strip_specific_list and keep_symbols. */
703
704static bfd_boolean
705is_specified_symbol (const char *name, struct symlist *list)
706{
707 struct symlist *tmp_list;
708
709 if (wildcard)
710 {
711 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
712 if (*(tmp_list->name) != '!')
713 {
714 if (!fnmatch (tmp_list->name, name, 0))
715 return TRUE;
716 }
717 else
718 {
719 if (fnmatch (tmp_list->name + 1, name, 0))
720 return TRUE;
721 }
722 }
723 else
724 {
725 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
726 if (strcmp (name, tmp_list->name) == 0)
727 return TRUE;
728 }
729
730 return FALSE;
731}
732
733/* See if a section is being removed. */
734
735static bfd_boolean
736is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
737{
738 if (sections_removed || sections_copied)
739 {
740 struct section_list *p;
741
742 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
743
744 if (sections_removed && p != NULL && p->remove)
745 return TRUE;
746 if (sections_copied && (p == NULL || ! p->copy))
747 return TRUE;
748 }
749
750 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
751 {
752 if (strip_symbols == STRIP_DEBUG
753 || strip_symbols == STRIP_UNNEEDED
754 || strip_symbols == STRIP_ALL
755 || discard_locals == LOCALS_ALL
756 || convert_debugging)
757 return TRUE;
758
759 if (strip_symbols == STRIP_NONDEBUG)
760 return FALSE;
761 }
762
763 return strip_symbols == STRIP_NONDEBUG ? TRUE : FALSE;
764}
765
766/* Choose which symbol entries to copy; put the result in OSYMS.
767 We don't copy in place, because that confuses the relocs.
768 Return the number of symbols to print. */
769
770static unsigned int
771filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
772 asymbol **isyms, long symcount)
773{
774 asymbol **from = isyms, **to = osyms;
775 long src_count = 0, dst_count = 0;
776 int relocatable = (abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
777 == HAS_RELOC;
778
779 for (; src_count < symcount; src_count++)
780 {
781 asymbol *sym = from[src_count];
782 flagword flags = sym->flags;
783 char *name = (char *) bfd_asymbol_name (sym);
784 int keep;
785 bfd_boolean undefined;
786 bfd_boolean rem_leading_char;
787 bfd_boolean add_leading_char;
788
789 undefined = bfd_is_und_section (bfd_get_section (sym));
790
791 if (redefine_sym_list)
792 {
793 char *old_name, *new_name;
794
795 old_name = (char *) bfd_asymbol_name (sym);
796 new_name = (char *) lookup_sym_redefinition (old_name);
797 bfd_asymbol_name (sym) = new_name;
798 name = new_name;
799 }
800
801 /* Check if we will remove the current leading character. */
802 rem_leading_char =
803 (name[0] == bfd_get_symbol_leading_char (abfd))
804 && (change_leading_char
805 || (remove_leading_char
806 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
807 || undefined
808 || bfd_is_com_section (bfd_get_section (sym)))));
809
810 /* Check if we will add a new leading character. */
811 add_leading_char =
812 change_leading_char
813 && (bfd_get_symbol_leading_char (obfd) != '\0')
814 && (bfd_get_symbol_leading_char (abfd) == '\0'
815 || (name[0] == bfd_get_symbol_leading_char (abfd)));
816
817 /* Short circuit for change_leading_char if we can do it in-place. */
818 if (rem_leading_char && add_leading_char && !prefix_symbols_string)
819 {
820 name[0] = bfd_get_symbol_leading_char (obfd);
821 bfd_asymbol_name (sym) = name;
822 rem_leading_char = FALSE;
823 add_leading_char = FALSE;
824 }
825
826 /* Remove leading char. */
827 if (rem_leading_char)
828 bfd_asymbol_name (sym) = ++name;
829
830 /* Add new leading char and/or prefix. */
831 if (add_leading_char || prefix_symbols_string)
832 {
833 char *n, *ptr;
834
835 ptr = n = xmalloc (1 + strlen (prefix_symbols_string)
836 + strlen (name) + 1);
837 if (add_leading_char)
838 *ptr++ = bfd_get_symbol_leading_char (obfd);
839
840 if (prefix_symbols_string)
841 {
842 strcpy (ptr, prefix_symbols_string);
843 ptr += strlen (prefix_symbols_string);
844 }
845
846 strcpy (ptr, name);
847 bfd_asymbol_name (sym) = n;
848 name = n;
849 }
850
851 if (strip_symbols == STRIP_ALL)
852 keep = 0;
853 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
854 || ((flags & BSF_SECTION_SYM) != 0
855 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
856 & BSF_KEEP) != 0))
857 keep = 1;
858 else if (relocatable /* Relocatable file. */
859 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
860 keep = 1;
861 else if (bfd_decode_symclass (sym) == 'I')
862 /* Global symbols in $idata sections need to be retained
863 even if relocatable is FALSE. External users of the
864 library containing the $idata section may reference these
865 symbols. */
866 keep = 1;
867 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
868 || (flags & BSF_WEAK) != 0
869 || undefined
870 || bfd_is_com_section (bfd_get_section (sym)))
871 keep = strip_symbols != STRIP_UNNEEDED;
872 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
873 keep = (strip_symbols != STRIP_DEBUG
874 && strip_symbols != STRIP_UNNEEDED
875 && ! convert_debugging);
876 else if (bfd_get_section (sym)->comdat)
877 /* COMDAT sections store special information in local
878 symbols, so we cannot risk stripping any of them. */
879 keep = 1;
880 else /* Local symbol. */
881 keep = (strip_symbols != STRIP_UNNEEDED
882 && (discard_locals != LOCALS_ALL
883 && (discard_locals != LOCALS_START_L
884 || ! bfd_is_local_label (abfd, sym))));
885
886 if (keep && is_specified_symbol (name, strip_specific_list))
887 keep = 0;
888 if (!keep && is_specified_symbol (name, keep_specific_list))
889 keep = 1;
890 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
891 keep = 0;
892
893 if (keep && (flags & BSF_GLOBAL) != 0
894 && (weaken || is_specified_symbol (name, weaken_specific_list)))
895 {
896 sym->flags &=~ BSF_GLOBAL;
897 sym->flags |= BSF_WEAK;
898 }
899 if (keep && !undefined && (flags & (BSF_GLOBAL | BSF_WEAK))
900 && (is_specified_symbol (name, localize_specific_list)
901 || (keepglobal_specific_list != NULL
902 && ! is_specified_symbol (name, keepglobal_specific_list))))
903 {
904 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
905 sym->flags |= BSF_LOCAL;
906 }
907
908 if (keep)
909 to[dst_count++] = sym;
910 }
911
912 to[dst_count] = NULL;
913
914 return dst_count;
915}
916
917/* Find the redefined name of symbol SOURCE. */
918
919static const char *
920lookup_sym_redefinition (const char *source)
921{
922 struct redefine_node *list;
923
924 for (list = redefine_sym_list; list != NULL; list = list->next)
925 if (strcmp (source, list->source) == 0)
926 return list->target;
927
928 return source;
929}
930
931/* Add a node to a symbol redefine list. */
932
933static void
934redefine_list_append (const char *cause, const char *source, const char *target)
935{
936 struct redefine_node **p;
937 struct redefine_node *list;
938 struct redefine_node *new_node;
939
940 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
941 {
942 if (strcmp (source, list->source) == 0)
943 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
944 cause, source);
945
946 if (strcmp (target, list->target) == 0)
947 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
948 cause, target);
949 }
950
951 new_node = xmalloc (sizeof (struct redefine_node));
952
953 new_node->source = strdup (source);
954 new_node->target = strdup (target);
955 new_node->next = NULL;
956
957 *p = new_node;
958}
959
960/* Handle the --redefine-syms option. Read lines containing "old new"
961 from the file, and add them to the symbol redefine list. */
962
963static void
964add_redefine_syms_file (const char *filename)
965{
966 FILE *file;
967 char *buf;
968 size_t bufsize;
969 size_t len;
970 size_t outsym_off;
971 int c, lineno;
972
973 file = fopen (filename, "r");
974 if (file == NULL)
975 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
976 filename, strerror (errno));
977
978 bufsize = 100;
979 buf = xmalloc (bufsize);
980
981 lineno = 1;
982 c = getc (file);
983 len = 0;
984 outsym_off = 0;
985 while (c != EOF)
986 {
987 /* Collect the input symbol name. */
988 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
989 {
990 if (c == '#')
991 goto comment;
992 buf[len++] = c;
993 if (len >= bufsize)
994 {
995 bufsize *= 2;
996 buf = xrealloc (buf, bufsize);
997 }
998 c = getc (file);
999 }
1000 buf[len++] = '\0';
1001 if (c == EOF)
1002 break;
1003
1004 /* Eat white space between the symbol names. */
1005 while (IS_WHITESPACE (c))
1006 c = getc (file);
1007 if (c == '#' || IS_LINE_TERMINATOR (c))
1008 goto comment;
1009 if (c == EOF)
1010 break;
1011
1012 /* Collect the output symbol name. */
1013 outsym_off = len;
1014 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1015 {
1016 if (c == '#')
1017 goto comment;
1018 buf[len++] = c;
1019 if (len >= bufsize)
1020 {
1021 bufsize *= 2;
1022 buf = xrealloc (buf, bufsize);
1023 }
1024 c = getc (file);
1025 }
1026 buf[len++] = '\0';
1027 if (c == EOF)
1028 break;
1029
1030 /* Eat white space at end of line. */
1031 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1032 c = getc (file);
1033 if (c == '#')
1034 goto comment;
1035 /* Handle \r\n. */
1036 if ((c == '\r' && (c = getc (file)) == '\n')
1037 || c == '\n' || c == EOF)
1038 {
1039 end_of_line:
1040 /* Append the redefinition to the list. */
1041 if (buf[0] != '\0')
1042 redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1043
1044 lineno++;
1045 len = 0;
1046 outsym_off = 0;
1047 if (c == EOF)
1048 break;
1049 c = getc (file);
1050 continue;
1051 }
1052 else
1053 fatal (_("%s: garbage at end of line %d"), filename, lineno);
1054 comment:
1055 if (len != 0 && (outsym_off == 0 || outsym_off == len))
1056 fatal (_("%s: missing new symbol name at line %d"), filename, lineno);
1057 buf[len++] = '\0';
1058
1059 /* Eat the rest of the line and finish it. */
1060 while (c != '\n' && c != EOF)
1061 c = getc (file);
1062 goto end_of_line;
1063 }
1064
1065 if (len != 0)
1066 fatal (_("%s: premature end of file at line %d"), filename, lineno);
1067
1068 free (buf);
1069}
1070
1071/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
1072 Adjust *SIZE. */
1073
1074static void
1075filter_bytes (char *memhunk, bfd_size_type *size)
1076{
1077 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
1078
1079 for (; from < end; from += interleave)
1080 *to++ = *from;
1081
1082 if (*size % interleave > (bfd_size_type) copy_byte)
1083 *size = (*size / interleave) + 1;
1084 else
1085 *size /= interleave;
1086}
1087
1088/* Copy object file IBFD onto OBFD. */
1089
1090static void
1091copy_object (bfd *ibfd, bfd *obfd)
1092{
1093 bfd_vma start;
1094 long symcount;
1095 asection **osections = NULL;
1096 asection *gnu_debuglink_section = NULL;
1097 bfd_size_type *gaps = NULL;
1098 bfd_size_type max_gap = 0;
1099 long symsize;
1100 void *dhandle;
1101 enum bfd_architecture iarch;
1102 unsigned int imach;
1103
1104 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1105 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1106 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1107 {
1108 fatal (_("Unable to change endianness of input file(s)"));
1109 return;
1110 }
1111
1112 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1113 RETURN_NONFATAL (bfd_get_filename (obfd));
1114
1115 if (verbose)
1116 printf (_("copy from %s(%s) to %s(%s)\n"),
1117 bfd_get_filename (ibfd), bfd_get_target (ibfd),
1118 bfd_get_filename (obfd), bfd_get_target (obfd));
1119
1120 if (set_start_set)
1121 start = set_start;
1122 else
1123 start = bfd_get_start_address (ibfd);
1124 start += change_start;
1125
1126 /* Neither the start address nor the flags
1127 need to be set for a core file. */
1128 if (bfd_get_format (obfd) != bfd_core)
1129 {
1130 if (!bfd_set_start_address (obfd, start)
1131 || !bfd_set_file_flags (obfd,
1132 (bfd_get_file_flags (ibfd)
1133 & bfd_applicable_file_flags (obfd))))
1134 RETURN_NONFATAL (bfd_get_filename (ibfd));
1135 }
1136
1137 /* Copy architecture of input file to output file. */
1138 iarch = bfd_get_arch (ibfd);
1139 imach = bfd_get_mach (ibfd);
1140 if (!bfd_set_arch_mach (obfd, iarch, imach)
1141 && (ibfd->target_defaulted
1142 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
1143 {
1144 if (bfd_get_arch (ibfd) == bfd_arch_unknown)
1145 fatal (_("Unable to recognise the format of the input file %s"),
1146 bfd_get_filename (ibfd));
1147 else
1148 {
1149 non_fatal (_("Warning: Output file cannot represent architecture %s"),
1150 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1151 bfd_get_mach (ibfd)));
1152 status = 1;
1153 return;
1154 }
1155 }
1156
1157 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1158 RETURN_NONFATAL (bfd_get_filename (ibfd));
1159
1160 if (isympp)
1161 free (isympp);
1162
1163 if (osympp != isympp)
1164 free (osympp);
1165
1166 /* BFD mandates that all output sections be created and sizes set before
1167 any output is done. Thus, we traverse all sections multiple times. */
1168 bfd_map_over_sections (ibfd, setup_section, obfd);
1169
1170 if (add_sections != NULL)
1171 {
1172 struct section_add *padd;
1173 struct section_list *pset;
1174
1175 for (padd = add_sections; padd != NULL; padd = padd->next)
1176 {
1177 flagword flags;
1178
1179 padd->section = bfd_make_section (obfd, padd->name);
1180 if (padd->section == NULL)
1181 {
1182 non_fatal (_("can't create section `%s': %s"),
1183 padd->name, bfd_errmsg (bfd_get_error ()));
1184 status = 1;
1185 return;
1186 }
1187
1188 if (! bfd_set_section_size (obfd, padd->section, padd->size))
1189 RETURN_NONFATAL (bfd_get_filename (obfd));
1190
1191 pset = find_section_list (padd->name, FALSE);
1192 if (pset != NULL)
1193 pset->used = TRUE;
1194
1195 if (pset != NULL && pset->set_flags)
1196 flags = pset->flags | SEC_HAS_CONTENTS;
1197 else
1198 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1199
1200 if (! bfd_set_section_flags (obfd, padd->section, flags))
1201 RETURN_NONFATAL (bfd_get_filename (obfd));
1202
1203 if (pset != NULL)
1204 {
1205 if (pset->change_vma != CHANGE_IGNORE)
1206 if (! bfd_set_section_vma (obfd, padd->section,
1207 pset->vma_val))
1208 RETURN_NONFATAL (bfd_get_filename (obfd));
1209
1210 if (pset->change_lma != CHANGE_IGNORE)
1211 {
1212 padd->section->lma = pset->lma_val;
1213
1214 if (! bfd_set_section_alignment
1215 (obfd, padd->section,
1216 bfd_section_alignment (obfd, padd->section)))
1217 RETURN_NONFATAL (bfd_get_filename (obfd));
1218 }
1219 }
1220 }
1221 }
1222
1223 if (gnu_debuglink_filename != NULL)
1224 {
1225 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1226 (obfd, gnu_debuglink_filename);
1227
1228 if (gnu_debuglink_section == NULL)
1229 RETURN_NONFATAL (gnu_debuglink_filename);
1230 }
1231
1232 if (gap_fill_set || pad_to_set)
1233 {
1234 asection **set;
1235 unsigned int c, i;
1236
1237 /* We must fill in gaps between the sections and/or we must pad
1238 the last section to a specified address. We do this by
1239 grabbing a list of the sections, sorting them by VMA, and
1240 increasing the section sizes as required to fill the gaps.
1241 We write out the gap contents below. */
1242
1243 c = bfd_count_sections (obfd);
1244 osections = xmalloc (c * sizeof (asection *));
1245 set = osections;
1246 bfd_map_over_sections (obfd, get_sections, &set);
1247
1248 qsort (osections, c, sizeof (asection *), compare_section_lma);
1249
1250 gaps = xmalloc (c * sizeof (bfd_size_type));
1251 memset (gaps, 0, c * sizeof (bfd_size_type));
1252
1253 if (gap_fill_set)
1254 {
1255 for (i = 0; i < c - 1; i++)
1256 {
1257 flagword flags;
1258 bfd_size_type size;
1259 bfd_vma gap_start, gap_stop;
1260
1261 flags = bfd_get_section_flags (obfd, osections[i]);
1262 if ((flags & SEC_HAS_CONTENTS) == 0
1263 || (flags & SEC_LOAD) == 0)
1264 continue;
1265
1266 size = bfd_section_size (obfd, osections[i]);
1267 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1268 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1269 if (gap_start < gap_stop)
1270 {
1271 if (! bfd_set_section_size (obfd, osections[i],
1272 size + (gap_stop - gap_start)))
1273 {
1274 non_fatal (_("Can't fill gap after %s: %s"),
1275 bfd_get_section_name (obfd, osections[i]),
1276 bfd_errmsg (bfd_get_error ()));
1277 status = 1;
1278 break;
1279 }
1280 gaps[i] = gap_stop - gap_start;
1281 if (max_gap < gap_stop - gap_start)
1282 max_gap = gap_stop - gap_start;
1283 }
1284 }
1285 }
1286
1287 if (pad_to_set)
1288 {
1289 bfd_vma lma;
1290 bfd_size_type size;
1291
1292 lma = bfd_section_lma (obfd, osections[c - 1]);
1293 size = bfd_section_size (obfd, osections[c - 1]);
1294 if (lma + size < pad_to)
1295 {
1296 if (! bfd_set_section_size (obfd, osections[c - 1],
1297 pad_to - lma))
1298 {
1299 non_fatal (_("Can't add padding to %s: %s"),
1300 bfd_get_section_name (obfd, osections[c - 1]),
1301 bfd_errmsg (bfd_get_error ()));
1302 status = 1;
1303 }
1304 else
1305 {
1306 gaps[c - 1] = pad_to - (lma + size);
1307 if (max_gap < pad_to - (lma + size))
1308 max_gap = pad_to - (lma + size);
1309 }
1310 }
1311 }
1312 }
1313
1314 /* Symbol filtering must happen after the output sections
1315 have been created, but before their contents are set. */
1316 dhandle = NULL;
1317 symsize = bfd_get_symtab_upper_bound (ibfd);
1318 if (symsize < 0)
1319 RETURN_NONFATAL (bfd_get_filename (ibfd));
1320
1321 osympp = isympp = xmalloc (symsize);
1322 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1323 if (symcount < 0)
1324 RETURN_NONFATAL (bfd_get_filename (ibfd));
1325
1326 if (convert_debugging)
1327 dhandle = read_debugging_info (ibfd, isympp, symcount);
1328
1329 if (strip_symbols == STRIP_DEBUG
1330 || strip_symbols == STRIP_ALL
1331 || strip_symbols == STRIP_UNNEEDED
1332 || strip_symbols == STRIP_NONDEBUG
1333 || discard_locals != LOCALS_UNDEF
1334 || strip_specific_list != NULL
1335 || keep_specific_list != NULL
1336 || localize_specific_list != NULL
1337 || keepglobal_specific_list != NULL
1338 || weaken_specific_list != NULL
1339 || prefix_symbols_string
1340 || sections_removed
1341 || sections_copied
1342 || convert_debugging
1343 || change_leading_char
1344 || remove_leading_char
1345 || redefine_sym_list
1346 || weaken)
1347 {
1348 /* Mark symbols used in output relocations so that they
1349 are kept, even if they are local labels or static symbols.
1350
1351 Note we iterate over the input sections examining their
1352 relocations since the relocations for the output sections
1353 haven't been set yet. mark_symbols_used_in_relocations will
1354 ignore input sections which have no corresponding output
1355 section. */
1356 if (strip_symbols != STRIP_ALL)
1357 bfd_map_over_sections (ibfd,
1358 mark_symbols_used_in_relocations,
1359 isympp);
1360 osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1361 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1362 }
1363
1364 if (convert_debugging && dhandle != NULL)
1365 {
1366 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1367 {
1368 status = 1;
1369 return;
1370 }
1371 }
1372
1373 bfd_set_symtab (obfd, osympp, symcount);
1374
1375 /* This has to happen after the symbol table has been set. */
1376 bfd_map_over_sections (ibfd, copy_section, obfd);
1377
1378 if (add_sections != NULL)
1379 {
1380 struct section_add *padd;
1381
1382 for (padd = add_sections; padd != NULL; padd = padd->next)
1383 {
1384 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1385 0, padd->size))
1386 RETURN_NONFATAL (bfd_get_filename (obfd));
1387 }
1388 }
1389
1390 if (gnu_debuglink_filename != NULL)
1391 {
1392 if (! bfd_fill_in_gnu_debuglink_section
1393 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1394 RETURN_NONFATAL (gnu_debuglink_filename);
1395 }
1396
1397 if (gap_fill_set || pad_to_set)
1398 {
1399 bfd_byte *buf;
1400 int c, i;
1401
1402 /* Fill in the gaps. */
1403 if (max_gap > 8192)
1404 max_gap = 8192;
1405 buf = xmalloc (max_gap);
1406 memset (buf, gap_fill, max_gap);
1407
1408 c = bfd_count_sections (obfd);
1409 for (i = 0; i < c; i++)
1410 {
1411 if (gaps[i] != 0)
1412 {
1413 bfd_size_type left;
1414 file_ptr off;
1415
1416 left = gaps[i];
1417 off = bfd_section_size (obfd, osections[i]) - left;
1418
1419 while (left > 0)
1420 {
1421 bfd_size_type now;
1422
1423 if (left > 8192)
1424 now = 8192;
1425 else
1426 now = left;
1427
1428 if (! bfd_set_section_contents (obfd, osections[i], buf,
1429 off, now))
1430 RETURN_NONFATAL (bfd_get_filename (obfd));
1431
1432 left -= now;
1433 off += now;
1434 }
1435 }
1436 }
1437 }
1438
1439 /* Allow the BFD backend to copy any private data it understands
1440 from the input BFD to the output BFD. This is done last to
1441 permit the routine to look at the filtered symbol table, which is
1442 important for the ECOFF code at least. */
1443 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1444 && strip_symbols == STRIP_NONDEBUG)
1445 /* Do not copy the private data when creating an ELF format
1446 debug info file. We do not want the program headers. */
1447 ;
1448 else if (! bfd_copy_private_bfd_data (ibfd, obfd))
1449 {
1450 non_fatal (_("%s: error copying private BFD data: %s"),
1451 bfd_get_filename (obfd),
1452 bfd_errmsg (bfd_get_error ()));
1453 status = 1;
1454 return;
1455 }
1456
1457 /* Switch to the alternate machine code. We have to do this at the
1458 very end, because we only initialize the header when we create
1459 the first section. */
1460 if (use_alt_mach_code != 0)
1461 {
1462 if (!bfd_alt_mach_code (obfd, use_alt_mach_code))
1463 non_fatal (_("unknown alternate machine code, ignored"));
1464 }
1465}
1466
1467#undef MKDIR
1468#if defined (_WIN32) && !defined (__CYGWIN32__)
1469#define MKDIR(DIR, MODE) mkdir (DIR)
1470#else
1471#define MKDIR(DIR, MODE) mkdir (DIR, MODE)
1472#endif
1473
1474/* Read each archive element in turn from IBFD, copy the
1475 contents to temp file, and keep the temp file handle. */
1476
1477static void
1478copy_archive (bfd *ibfd, bfd *obfd, const char *output_target)
1479{
1480 struct name_list
1481 {
1482 struct name_list *next;
1483 const char *name;
1484 bfd *obfd;
1485 } *list, *l;
1486 bfd **ptr = &obfd->archive_head;
1487 bfd *this_element;
1488 char *dir = make_tempname (bfd_get_filename (obfd));
1489
1490 /* Make a temp directory to hold the contents. */
1491 if (MKDIR (dir, 0700) != 0)
1492 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1493 dir, strerror (errno));
1494
1495 obfd->has_armap = ibfd->has_armap;
1496
1497 list = NULL;
1498
1499 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1500
1501 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1502 RETURN_NONFATAL (bfd_get_filename (obfd));
1503
1504 while (!status && this_element != NULL)
1505 {
1506 char *output_name;
1507 bfd *output_bfd;
1508 bfd *last_element;
1509 struct stat buf;
1510 int stat_status = 0;
1511
1512 /* Create an output file for this member. */
1513 output_name = concat (dir, "/",
1514 bfd_get_filename (this_element), (char *) 0);
1515
1516 /* If the file already exists, make another temp dir. */
1517 if (stat (output_name, &buf) >= 0)
1518 {
1519 output_name = make_tempname (output_name);
1520 if (MKDIR (output_name, 0700) != 0)
1521 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1522 output_name, strerror (errno));
1523
1524 l = xmalloc (sizeof (struct name_list));
1525 l->name = output_name;
1526 l->next = list;
1527 l->obfd = NULL;
1528 list = l;
1529 output_name = concat (output_name, "/",
1530 bfd_get_filename (this_element), (char *) 0);
1531 }
1532
1533 output_bfd = bfd_openw (output_name, output_target);
1534 if (preserve_dates)
1535 {
1536 stat_status = bfd_stat_arch_elt (this_element, &buf);
1537
1538 if (stat_status != 0)
1539 non_fatal (_("internal stat error on %s"),
1540 bfd_get_filename (this_element));
1541 }
1542
1543 l = xmalloc (sizeof (struct name_list));
1544 l->name = output_name;
1545 l->next = list;
1546 list = l;
1547
1548 if (output_bfd == NULL)
1549 RETURN_NONFATAL (output_name);
1550
1551 if (bfd_check_format (this_element, bfd_object))
1552 copy_object (this_element, output_bfd);
1553
1554 if (!bfd_close (output_bfd))
1555 {
1556 bfd_nonfatal (bfd_get_filename (output_bfd));
1557 /* Error in new object file. Don't change archive. */
1558 status = 1;
1559 }
1560
1561 if (preserve_dates && stat_status == 0)
1562 set_times (output_name, &buf);
1563
1564 /* Open the newly output file and attach to our list. */
1565 output_bfd = bfd_openr (output_name, output_target);
1566
1567 l->obfd = output_bfd;
1568
1569 *ptr = output_bfd;
1570 ptr = &output_bfd->next;
1571
1572 last_element = this_element;
1573
1574 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1575
1576 bfd_close (last_element);
1577 }
1578 *ptr = NULL;
1579
1580 if (!bfd_close (obfd))
1581 RETURN_NONFATAL (bfd_get_filename (obfd));
1582
1583 if (!bfd_close (ibfd))
1584 RETURN_NONFATAL (bfd_get_filename (ibfd));
1585
1586 /* Delete all the files that we opened. */
1587 for (l = list; l != NULL; l = l->next)
1588 {
1589 if (l->obfd == NULL)
1590 rmdir (l->name);
1591 else
1592 {
1593 bfd_close (l->obfd);
1594 unlink (l->name);
1595 }
1596 }
1597 rmdir (dir);
1598}
1599
1600/* The top-level control. */
1601
1602static void
1603copy_file (const char *input_filename, const char *output_filename,
1604 const char *input_target, const char *output_target)
1605{
1606 bfd *ibfd;
1607 char **obj_matching;
1608 char **core_matching;
1609
1610 if (get_file_size (input_filename) < 1)
1611 {
1612 status = 1;
1613 return;
1614 }
1615
1616 /* To allow us to do "strip *" without dying on the first
1617 non-object file, failures are nonfatal. */
1618 ibfd = bfd_openr (input_filename, input_target);
1619 if (ibfd == NULL)
1620 RETURN_NONFATAL (input_filename);
1621
1622 if (bfd_check_format (ibfd, bfd_archive))
1623 {
1624 bfd *obfd;
1625
1626 /* bfd_get_target does not return the correct value until
1627 bfd_check_format succeeds. */
1628 if (output_target == NULL)
1629 output_target = bfd_get_target (ibfd);
1630
1631 obfd = bfd_openw (output_filename, output_target);
1632 if (obfd == NULL)
1633 RETURN_NONFATAL (output_filename);
1634
1635 copy_archive (ibfd, obfd, output_target);
1636 }
1637 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
1638 {
1639 bfd *obfd;
1640 do_copy:
1641 /* bfd_get_target does not return the correct value until
1642 bfd_check_format succeeds. */
1643 if (output_target == NULL)
1644 output_target = bfd_get_target (ibfd);
1645
1646 obfd = bfd_openw (output_filename, output_target);
1647 if (obfd == NULL)
1648 RETURN_NONFATAL (output_filename);
1649
1650 copy_object (ibfd, obfd);
1651
1652 if (!bfd_close (obfd))
1653 RETURN_NONFATAL (output_filename);
1654
1655 if (!bfd_close (ibfd))
1656 RETURN_NONFATAL (input_filename);
1657 }
1658 else
1659 {
1660 bfd_error_type obj_error = bfd_get_error ();
1661 bfd_error_type core_error;
1662
1663 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
1664 {
1665 /* This probably can't happen.. */
1666 if (obj_error == bfd_error_file_ambiguously_recognized)
1667 free (obj_matching);
1668 goto do_copy;
1669 }
1670
1671 core_error = bfd_get_error ();
1672 /* Report the object error in preference to the core error. */
1673 if (obj_error != core_error)
1674 bfd_set_error (obj_error);
1675
1676 bfd_nonfatal (input_filename);
1677
1678 if (obj_error == bfd_error_file_ambiguously_recognized)
1679 {
1680 list_matching_formats (obj_matching);
1681 free (obj_matching);
1682 }
1683 if (core_error == bfd_error_file_ambiguously_recognized)
1684 {
1685 list_matching_formats (core_matching);
1686 free (core_matching);
1687 }
1688
1689 status = 1;
1690 }
1691}
1692
1693/* Add a name to the section renaming list. */
1694
1695static void
1696add_section_rename (const char * old_name, const char * new_name,
1697 flagword flags)
1698{
1699 section_rename * rename;
1700
1701 /* Check for conflicts first. */
1702 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1703 if (strcmp (rename->old_name, old_name) == 0)
1704 {
1705 /* Silently ignore duplicate definitions. */
1706 if (strcmp (rename->new_name, new_name) == 0
1707 && rename->flags == flags)
1708 return;
1709
1710 fatal (_("Multiple renames of section %s"), old_name);
1711 }
1712
1713 rename = xmalloc (sizeof (* rename));
1714
1715 rename->old_name = old_name;
1716 rename->new_name = new_name;
1717 rename->flags = flags;
1718 rename->next = section_rename_list;
1719
1720 section_rename_list = rename;
1721}
1722
1723/* Check the section rename list for a new name of the input section
1724 ISECTION. Return the new name if one is found.
1725 Also set RETURNED_FLAGS to the flags to be used for this section. */
1726
1727static const char *
1728find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
1729 flagword * returned_flags)
1730{
1731 const char * old_name = bfd_section_name (ibfd, isection);
1732 section_rename * rename;
1733
1734 /* Default to using the flags of the input section. */
1735 * returned_flags = bfd_get_section_flags (ibfd, isection);
1736
1737 for (rename = section_rename_list; rename != NULL; rename = rename->next)
1738 if (strcmp (rename->old_name, old_name) == 0)
1739 {
1740 if (rename->flags != (flagword) -1)
1741 * returned_flags = rename->flags;
1742
1743 return rename->new_name;
1744 }
1745
1746 return old_name;
1747}
1748
1749/* Create a section in OBFD with the same
1750 name and attributes as ISECTION in IBFD. */
1751
1752static void
1753setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1754{
1755 bfd *obfd = obfdarg;
1756 struct section_list *p;
1757 sec_ptr osection;
1758 bfd_size_type size;
1759 bfd_vma vma;
1760 bfd_vma lma;
1761 flagword flags;
1762 const char *err;
1763 const char * name;
1764 char *prefix = NULL;
1765
1766 if (is_strip_section (ibfd, isection))
1767 return;
1768
1769 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
1770 if (p != NULL)
1771 p->used = TRUE;
1772
1773 /* Get the, possibly new, name of the output section. */
1774 name = find_section_rename (ibfd, isection, & flags);
1775
1776 /* Prefix sections. */
1777 if ((prefix_alloc_sections_string)
1778 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
1779 prefix = prefix_alloc_sections_string;
1780 else if (prefix_sections_string)
1781 prefix = prefix_sections_string;
1782
1783 if (prefix)
1784 {
1785 char *n;
1786
1787 n = xmalloc (strlen (prefix) + strlen (name) + 1);
1788 strcpy (n, prefix);
1789 strcat (n, name);
1790 name = n;
1791 }
1792
1793 osection = bfd_make_section_anyway (obfd, name);
1794
1795 if (osection == NULL)
1796 {
1797 err = _("making");
1798 goto loser;
1799 }
1800
1801 size = bfd_section_size (ibfd, isection);
1802 if (copy_byte >= 0)
1803 size = (size + interleave - 1) / interleave;
1804 if (! bfd_set_section_size (obfd, osection, size))
1805 {
1806 err = _("size");
1807 goto loser;
1808 }
1809
1810 vma = bfd_section_vma (ibfd, isection);
1811 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1812 vma += p->vma_val;
1813 else if (p != NULL && p->change_vma == CHANGE_SET)
1814 vma = p->vma_val;
1815 else
1816 vma += change_section_address;
1817
1818 if (! bfd_set_section_vma (obfd, osection, vma))
1819 {
1820 err = _("vma");
1821 goto loser;
1822 }
1823
1824 lma = isection->lma;
1825 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1826 {
1827 if (p->change_lma == CHANGE_MODIFY)
1828 lma += p->lma_val;
1829 else if (p->change_lma == CHANGE_SET)
1830 lma = p->lma_val;
1831 else
1832 abort ();
1833 }
1834 else
1835 lma += change_section_address;
1836
1837 osection->lma = lma;
1838
1839 /* FIXME: This is probably not enough. If we change the LMA we
1840 may have to recompute the header for the file as well. */
1841 if (!bfd_set_section_alignment (obfd,
1842 osection,
1843 bfd_section_alignment (ibfd, isection)))
1844 {
1845 err = _("alignment");
1846 goto loser;
1847 }
1848
1849 if (p != NULL && p->set_flags)
1850 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
1851 if (!bfd_set_section_flags (obfd, osection, flags))
1852 {
1853 err = _("flags");
1854 goto loser;
1855 }
1856
1857 /* Copy merge entity size. */
1858 osection->entsize = isection->entsize;
1859
1860 /* This used to be mangle_section; we do here to avoid using
1861 bfd_get_section_by_name since some formats allow multiple
1862 sections with the same name. */
1863 isection->output_section = osection;
1864 isection->output_offset = 0;
1865
1866 /* Allow the BFD backend to copy any private data it understands
1867 from the input section to the output section. */
1868 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
1869 && strip_symbols == STRIP_NONDEBUG)
1870 /* Do not copy the private data when creating an ELF format
1871 debug info file. We do not want the program headers. */
1872 ;
1873 else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1874 {
1875 err = _("private data");
1876 goto loser;
1877 }
1878
1879 /* All went well. */
1880 return;
1881
1882loser:
1883 non_fatal (_("%s: section `%s': error in %s: %s"),
1884 bfd_get_filename (ibfd),
1885 bfd_section_name (ibfd, isection),
1886 err, bfd_errmsg (bfd_get_error ()));
1887 status = 1;
1888}
1889
1890/* Copy the data of input section ISECTION of IBFD
1891 to an output section with the same name in OBFD.
1892 If stripping then don't copy any relocation info. */
1893
1894static void
1895copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
1896{
1897 bfd *obfd = obfdarg;
1898 struct section_list *p;
1899 arelent **relpp;
1900 long relcount;
1901 sec_ptr osection;
1902 bfd_size_type size;
1903 long relsize;
1904 flagword flags;
1905
1906 /* If we have already failed earlier on,
1907 do not keep on generating complaints now. */
1908 if (status != 0)
1909 return;
1910
1911 if (is_strip_section (ibfd, isection))
1912 return;
1913
1914 flags = bfd_get_section_flags (ibfd, isection);
1915 if ((flags & SEC_GROUP) != 0)
1916 return;
1917
1918 osection = isection->output_section;
1919 size = bfd_get_section_size_before_reloc (isection);
1920
1921 if (size == 0 || osection == 0)
1922 return;
1923
1924 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
1925
1926 /* Core files do not need to be relocated. */
1927 if (bfd_get_format (obfd) == bfd_core)
1928 relsize = 0;
1929 else
1930 {
1931 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1932
1933 if (relsize < 0)
1934 {
1935 /* Do not complain if the target does not support relocations. */
1936 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
1937 relsize = 0;
1938 else
1939 RETURN_NONFATAL (bfd_get_filename (ibfd));
1940 }
1941 }
1942
1943 if (relsize == 0)
1944 bfd_set_reloc (obfd, osection, NULL, 0);
1945 else
1946 {
1947 relpp = xmalloc (relsize);
1948 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1949 if (relcount < 0)
1950 RETURN_NONFATAL (bfd_get_filename (ibfd));
1951
1952 if (strip_symbols == STRIP_ALL)
1953 {
1954 /* Remove relocations which are not in
1955 keep_strip_specific_list. */
1956 arelent **temp_relpp;
1957 long temp_relcount = 0;
1958 long i;
1959
1960 temp_relpp = xmalloc (relsize);
1961 for (i = 0; i < relcount; i++)
1962 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
1963 keep_specific_list))
1964 temp_relpp [temp_relcount++] = relpp [i];
1965 relcount = temp_relcount;
1966 free (relpp);
1967 relpp = temp_relpp;
1968 }
1969
1970 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
1971 }
1972
1973 isection->_cooked_size = isection->_raw_size;
1974 isection->reloc_done = TRUE;
1975
1976 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
1977 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
1978 {
1979 void *memhunk = xmalloc (size);
1980
1981 if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
1982 RETURN_NONFATAL (bfd_get_filename (ibfd));
1983
1984 if (copy_byte >= 0)
1985 filter_bytes (memhunk, &size);
1986
1987 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
1988 RETURN_NONFATAL (bfd_get_filename (obfd));
1989
1990 free (memhunk);
1991 }
1992 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1993 {
1994 void *memhunk = xmalloc (size);
1995
1996 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1997 flag--they can just remove the section entirely and add it
1998 back again. However, we do permit them to turn on the
1999 SEC_HAS_CONTENTS flag, and take it to mean that the section
2000 contents should be zeroed out. */
2001
2002 memset (memhunk, 0, size);
2003 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2004 RETURN_NONFATAL (bfd_get_filename (obfd));
2005 free (memhunk);
2006 }
2007}
2008
2009/* Get all the sections. This is used when --gap-fill or --pad-to is
2010 used. */
2011
2012static void
2013get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2014{
2015 asection ***secppp = secppparg;
2016
2017 **secppp = osection;
2018 ++(*secppp);
2019}
2020
2021/* Sort sections by VMA. This is called via qsort, and is used when
2022 --gap-fill or --pad-to is used. We force non loadable or empty
2023 sections to the front, where they are easier to ignore. */
2024
2025static int
2026compare_section_lma (const void *arg1, const void *arg2)
2027{
2028 const asection *const *sec1 = arg1;
2029 const asection *const *sec2 = arg2;
2030 flagword flags1, flags2;
2031
2032 /* Sort non loadable sections to the front. */
2033 flags1 = (*sec1)->flags;
2034 flags2 = (*sec2)->flags;
2035 if ((flags1 & SEC_HAS_CONTENTS) == 0
2036 || (flags1 & SEC_LOAD) == 0)
2037 {
2038 if ((flags2 & SEC_HAS_CONTENTS) != 0
2039 && (flags2 & SEC_LOAD) != 0)
2040 return -1;
2041 }
2042 else
2043 {
2044 if ((flags2 & SEC_HAS_CONTENTS) == 0
2045 || (flags2 & SEC_LOAD) == 0)
2046 return 1;
2047 }
2048
2049 /* Sort sections by LMA. */
2050 if ((*sec1)->lma > (*sec2)->lma)
2051 return 1;
2052 else if ((*sec1)->lma < (*sec2)->lma)
2053 return -1;
2054
2055 /* Sort sections with the same LMA by size. */
2056 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
2057 return 1;
2058 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
2059 return -1;
2060
2061 return 0;
2062}
2063
2064/* Mark all the symbols which will be used in output relocations with
2065 the BSF_KEEP flag so that those symbols will not be stripped.
2066
2067 Ignore relocations which will not appear in the output file. */
2068
2069static void
2070mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2071{
2072 asymbol **symbols = symbolsarg;
2073 long relsize;
2074 arelent **relpp;
2075 long relcount, i;
2076
2077 /* Ignore an input section with no corresponding output section. */
2078 if (isection->output_section == NULL)
2079 return;
2080
2081 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2082 if (relsize < 0)
2083 {
2084 /* Do not complain if the target does not support relocations. */
2085 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2086 return;
2087 bfd_fatal (bfd_get_filename (ibfd));
2088 }
2089
2090 if (relsize == 0)
2091 return;
2092
2093 relpp = xmalloc (relsize);
2094 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2095 if (relcount < 0)
2096 bfd_fatal (bfd_get_filename (ibfd));
2097
2098 /* Examine each symbol used in a relocation. If it's not one of the
2099 special bfd section symbols, then mark it with BSF_KEEP. */
2100 for (i = 0; i < relcount; i++)
2101 {
2102 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2103 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2104 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2105 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2106 }
2107
2108 if (relpp != NULL)
2109 free (relpp);
2110}
2111
2112/* Write out debugging information. */
2113
2114static bfd_boolean
2115write_debugging_info (bfd *obfd, void *dhandle,
2116 long *symcountp ATTRIBUTE_UNUSED,
2117 asymbol ***symppp ATTRIBUTE_UNUSED)
2118{
2119 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2120 return write_ieee_debugging_info (obfd, dhandle);
2121
2122 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2123 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2124 {
2125 bfd_byte *syms, *strings;
2126 bfd_size_type symsize, stringsize;
2127 asection *stabsec, *stabstrsec;
2128
2129 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2130 &symsize, &strings,
2131 &stringsize))
2132 return FALSE;
2133
2134 stabsec = bfd_make_section (obfd, ".stab");
2135 stabstrsec = bfd_make_section (obfd, ".stabstr");
2136 if (stabsec == NULL
2137 || stabstrsec == NULL
2138 || ! bfd_set_section_size (obfd, stabsec, symsize)
2139 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2140 || ! bfd_set_section_alignment (obfd, stabsec, 2)
2141 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
2142 || ! bfd_set_section_flags (obfd, stabsec,
2143 (SEC_HAS_CONTENTS
2144 | SEC_READONLY
2145 | SEC_DEBUGGING))
2146 || ! bfd_set_section_flags (obfd, stabstrsec,
2147 (SEC_HAS_CONTENTS
2148 | SEC_READONLY
2149 | SEC_DEBUGGING)))
2150 {
2151 non_fatal (_("%s: can't create debugging section: %s"),
2152 bfd_get_filename (obfd),
2153 bfd_errmsg (bfd_get_error ()));
2154 return FALSE;
2155 }
2156
2157 /* We can get away with setting the section contents now because
2158 the next thing the caller is going to do is copy over the
2159 real sections. We may someday have to split the contents
2160 setting out of this function. */
2161 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2162 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2163 stringsize))
2164 {
2165 non_fatal (_("%s: can't set debugging section contents: %s"),
2166 bfd_get_filename (obfd),
2167 bfd_errmsg (bfd_get_error ()));
2168 return FALSE;
2169 }
2170
2171 return TRUE;
2172 }
2173
2174 non_fatal (_("%s: don't know how to write debugging information for %s"),
2175 bfd_get_filename (obfd), bfd_get_target (obfd));
2176 return FALSE;
2177}
2178
2179static int
2180strip_main (int argc, char *argv[])
2181{
2182 char *input_target = NULL;
2183 char *output_target = NULL;
2184 bfd_boolean show_version = FALSE;
2185 bfd_boolean formats_info = FALSE;
2186 int c;
2187 int i;
2188 struct section_list *p;
2189 char *output_file = NULL;
2190
2191 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2192 strip_options, (int *) 0)) != EOF)
2193 {
2194 switch (c)
2195 {
2196 case 'I':
2197 input_target = optarg;
2198 break;
2199 case 'O':
2200 output_target = optarg;
2201 break;
2202 case 'F':
2203 input_target = output_target = optarg;
2204 break;
2205 case 'R':
2206 p = find_section_list (optarg, TRUE);
2207 p->remove = TRUE;
2208 sections_removed = TRUE;
2209 break;
2210 case 's':
2211 strip_symbols = STRIP_ALL;
2212 break;
2213 case 'S':
2214 case 'g':
2215 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
2216 strip_symbols = STRIP_DEBUG;
2217 break;
2218 case OPTION_STRIP_UNNEEDED:
2219 strip_symbols = STRIP_UNNEEDED;
2220 break;
2221 case 'K':
2222 add_specific_symbol (optarg, &keep_specific_list);
2223 break;
2224 case 'N':
2225 add_specific_symbol (optarg, &strip_specific_list);
2226 break;
2227 case 'o':
2228 output_file = optarg;
2229 break;
2230 case 'p':
2231 preserve_dates = TRUE;
2232 break;
2233 case 'x':
2234 discard_locals = LOCALS_ALL;
2235 break;
2236 case 'X':
2237 discard_locals = LOCALS_START_L;
2238 break;
2239 case 'v':
2240 verbose = TRUE;
2241 break;
2242 case 'V':
2243 show_version = TRUE;
2244 break;
2245 case OPTION_FORMATS_INFO:
2246 formats_info = TRUE;
2247 break;
2248 case OPTION_ONLY_KEEP_DEBUG:
2249 strip_symbols = STRIP_NONDEBUG;
2250 break;
2251 case 0:
2252 /* We've been given a long option. */
2253 break;
2254 case 'w':
2255 wildcard = TRUE;
2256 break;
2257 case 'H':
2258 case 'h':
2259 strip_usage (stdout, 0);
2260 default:
2261 strip_usage (stderr, 1);
2262 }
2263 }
2264
2265 if (formats_info)
2266 {
2267 display_info ();
2268 return 0;
2269 }
2270
2271 if (show_version)
2272 print_version ("strip");
2273
2274 /* Default is to strip all symbols. */
2275 if (strip_symbols == STRIP_UNDEF
2276 && discard_locals == LOCALS_UNDEF
2277 && strip_specific_list == NULL)
2278 strip_symbols = STRIP_ALL;
2279
2280 if (output_target == NULL)
2281 output_target = input_target;
2282
2283 i = optind;
2284 if (i == argc
2285 || (output_file != NULL && (i + 1) < argc))
2286 strip_usage (stderr, 1);
2287
2288 for (; i < argc; i++)
2289 {
2290 int hold_status = status;
2291 struct stat statbuf;
2292 char *tmpname;
2293
2294 if (get_file_size (argv[i]) < 1)
2295 continue;
2296
2297 if (preserve_dates)
2298 /* No need to check the return value of stat().
2299 It has already been checked in get_file_size(). */
2300 stat (argv[i], &statbuf);
2301
2302 if (output_file != NULL)
2303 tmpname = output_file;
2304 else
2305 tmpname = make_tempname (argv[i]);
2306 status = 0;
2307
2308 copy_file (argv[i], tmpname, input_target, output_target);
2309 if (status == 0)
2310 {
2311 if (preserve_dates)
2312 set_times (tmpname, &statbuf);
2313 if (output_file == NULL)
2314 smart_rename (tmpname, argv[i], preserve_dates);
2315 status = hold_status;
2316 }
2317 else
2318 unlink (tmpname);
2319 if (output_file == NULL)
2320 free (tmpname);
2321 }
2322
2323 return 0;
2324}
2325
2326static int
2327copy_main (int argc, char *argv[])
2328{
2329 char * binary_architecture = NULL;
2330 char *input_filename = NULL;
2331 char *output_filename = NULL;
2332 char *input_target = NULL;
2333 char *output_target = NULL;
2334 bfd_boolean show_version = FALSE;
2335 bfd_boolean change_warn = TRUE;
2336 bfd_boolean formats_info = FALSE;
2337 int c;
2338 struct section_list *p;
2339 struct stat statbuf;
2340
2341 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2342 copy_options, (int *) 0)) != EOF)
2343 {
2344 switch (c)
2345 {
2346 case 'b':
2347 copy_byte = atoi (optarg);
2348 if (copy_byte < 0)
2349 fatal (_("byte number must be non-negative"));
2350 break;
2351
2352 case 'B':
2353 binary_architecture = optarg;
2354 break;
2355
2356 case 'i':
2357 interleave = atoi (optarg);
2358 if (interleave < 1)
2359 fatal (_("interleave must be positive"));
2360 break;
2361
2362 case 'I':
2363 case 's': /* "source" - 'I' is preferred */
2364 input_target = optarg;
2365 break;
2366
2367 case 'O':
2368 case 'd': /* "destination" - 'O' is preferred */
2369 output_target = optarg;
2370 break;
2371
2372 case 'F':
2373 input_target = output_target = optarg;
2374 break;
2375
2376 case 'j':
2377 p = find_section_list (optarg, TRUE);
2378 if (p->remove)
2379 fatal (_("%s both copied and removed"), optarg);
2380 p->copy = TRUE;
2381 sections_copied = TRUE;
2382 break;
2383
2384 case 'R':
2385 p = find_section_list (optarg, TRUE);
2386 if (p->copy)
2387 fatal (_("%s both copied and removed"), optarg);
2388 p->remove = TRUE;
2389 sections_removed = TRUE;
2390 break;
2391
2392 case 'S':
2393 strip_symbols = STRIP_ALL;
2394 break;
2395
2396 case 'g':
2397 strip_symbols = STRIP_DEBUG;
2398 break;
2399
2400 case OPTION_STRIP_UNNEEDED:
2401 strip_symbols = STRIP_UNNEEDED;
2402 break;
2403
2404 case OPTION_ONLY_KEEP_DEBUG:
2405 strip_symbols = STRIP_NONDEBUG;
2406 break;
2407
2408 case OPTION_ADD_GNU_DEBUGLINK:
2409 gnu_debuglink_filename = optarg;
2410 break;
2411
2412 case 'K':
2413 add_specific_symbol (optarg, &keep_specific_list);
2414 break;
2415
2416 case 'N':
2417 add_specific_symbol (optarg, &strip_specific_list);
2418 break;
2419
2420 case 'L':
2421 add_specific_symbol (optarg, &localize_specific_list);
2422 break;
2423
2424 case 'G':
2425 add_specific_symbol (optarg, &keepglobal_specific_list);
2426 break;
2427
2428 case 'W':
2429 add_specific_symbol (optarg, &weaken_specific_list);
2430 break;
2431
2432 case 'p':
2433 preserve_dates = TRUE;
2434 break;
2435
2436 case 'w':
2437 wildcard = TRUE;
2438 break;
2439
2440 case 'x':
2441 discard_locals = LOCALS_ALL;
2442 break;
2443
2444 case 'X':
2445 discard_locals = LOCALS_START_L;
2446 break;
2447
2448 case 'v':
2449 verbose = TRUE;
2450 break;
2451
2452 case 'V':
2453 show_version = TRUE;
2454 break;
2455
2456 case OPTION_FORMATS_INFO:
2457 formats_info = TRUE;
2458 break;
2459
2460 case OPTION_WEAKEN:
2461 weaken = TRUE;
2462 break;
2463
2464 case OPTION_ADD_SECTION:
2465 {
2466 const char *s;
2467 off_t size;
2468 struct section_add *pa;
2469 int len;
2470 char *name;
2471 FILE *f;
2472
2473 s = strchr (optarg, '=');
2474
2475 if (s == NULL)
2476 fatal (_("bad format for %s"), "--add-section");
2477
2478 size = get_file_size (s + 1);
2479 if (size < 1)
2480 break;
2481
2482 pa = xmalloc (sizeof (struct section_add));
2483
2484 len = s - optarg;
2485 name = xmalloc (len + 1);
2486 strncpy (name, optarg, len);
2487 name[len] = '\0';
2488 pa->name = name;
2489
2490 pa->filename = s + 1;
2491 pa->size = size;
2492 pa->contents = xmalloc (size);
2493
2494 f = fopen (pa->filename, FOPEN_RB);
2495
2496 if (f == NULL)
2497 fatal (_("cannot open: %s: %s"),
2498 pa->filename, strerror (errno));
2499
2500 if (fread (pa->contents, 1, pa->size, f) == 0
2501 || ferror (f))
2502 fatal (_("%s: fread failed"), pa->filename);
2503
2504 fclose (f);
2505
2506 pa->next = add_sections;
2507 add_sections = pa;
2508 }
2509 break;
2510
2511 case OPTION_CHANGE_START:
2512 change_start = parse_vma (optarg, "--change-start");
2513 break;
2514
2515 case OPTION_CHANGE_SECTION_ADDRESS:
2516 case OPTION_CHANGE_SECTION_LMA:
2517 case OPTION_CHANGE_SECTION_VMA:
2518 {
2519 const char *s;
2520 int len;
2521 char *name;
2522 char *option = NULL;
2523 bfd_vma val;
2524 enum change_action what = CHANGE_IGNORE;
2525
2526 switch (c)
2527 {
2528 case OPTION_CHANGE_SECTION_ADDRESS:
2529 option = "--change-section-address";
2530 break;
2531 case OPTION_CHANGE_SECTION_LMA:
2532 option = "--change-section-lma";
2533 break;
2534 case OPTION_CHANGE_SECTION_VMA:
2535 option = "--change-section-vma";
2536 break;
2537 }
2538
2539 s = strchr (optarg, '=');
2540 if (s == NULL)
2541 {
2542 s = strchr (optarg, '+');
2543 if (s == NULL)
2544 {
2545 s = strchr (optarg, '-');
2546 if (s == NULL)
2547 fatal (_("bad format for %s"), option);
2548 }
2549 }
2550
2551 len = s - optarg;
2552 name = xmalloc (len + 1);
2553 strncpy (name, optarg, len);
2554 name[len] = '\0';
2555
2556 p = find_section_list (name, TRUE);
2557
2558 val = parse_vma (s + 1, option);
2559
2560 switch (*s)
2561 {
2562 case '=': what = CHANGE_SET; break;
2563 case '-': val = - val; /* Drop through. */
2564 case '+': what = CHANGE_MODIFY; break;
2565 }
2566
2567 switch (c)
2568 {
2569 case OPTION_CHANGE_SECTION_ADDRESS:
2570 p->change_vma = what;
2571 p->vma_val = val;
2572 /* Drop through. */
2573
2574 case OPTION_CHANGE_SECTION_LMA:
2575 p->change_lma = what;
2576 p->lma_val = val;
2577 break;
2578
2579 case OPTION_CHANGE_SECTION_VMA:
2580 p->change_vma = what;
2581 p->vma_val = val;
2582 break;
2583 }
2584 }
2585 break;
2586
2587 case OPTION_CHANGE_ADDRESSES:
2588 change_section_address = parse_vma (optarg, "--change-addresses");
2589 change_start = change_section_address;
2590 break;
2591
2592 case OPTION_CHANGE_WARNINGS:
2593 change_warn = TRUE;
2594 break;
2595
2596 case OPTION_CHANGE_LEADING_CHAR:
2597 change_leading_char = TRUE;
2598 break;
2599
2600 case OPTION_DEBUGGING:
2601 convert_debugging = TRUE;
2602 break;
2603
2604 case OPTION_GAP_FILL:
2605 {
2606 bfd_vma gap_fill_vma;
2607
2608 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2609 gap_fill = (bfd_byte) gap_fill_vma;
2610 if ((bfd_vma) gap_fill != gap_fill_vma)
2611 {
2612 char buff[20];
2613
2614 sprintf_vma (buff, gap_fill_vma);
2615
2616 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2617 buff, gap_fill);
2618 }
2619 gap_fill_set = TRUE;
2620 }
2621 break;
2622
2623 case OPTION_NO_CHANGE_WARNINGS:
2624 change_warn = FALSE;
2625 break;
2626
2627 case OPTION_PAD_TO:
2628 pad_to = parse_vma (optarg, "--pad-to");
2629 pad_to_set = TRUE;
2630 break;
2631
2632 case OPTION_REMOVE_LEADING_CHAR:
2633 remove_leading_char = TRUE;
2634 break;
2635
2636 case OPTION_REDEFINE_SYM:
2637 {
2638 /* Push this redefinition onto redefine_symbol_list. */
2639
2640 int len;
2641 const char *s;
2642 const char *nextarg;
2643 char *source, *target;
2644
2645 s = strchr (optarg, '=');
2646 if (s == NULL)
2647 fatal (_("bad format for %s"), "--redefine-sym");
2648
2649 len = s - optarg;
2650 source = xmalloc (len + 1);
2651 strncpy (source, optarg, len);
2652 source[len] = '\0';
2653
2654 nextarg = s + 1;
2655 len = strlen (nextarg);
2656 target = xmalloc (len + 1);
2657 strcpy (target, nextarg);
2658
2659 redefine_list_append ("--redefine-sym", source, target);
2660
2661 free (source);
2662 free (target);
2663 }
2664 break;
2665
2666 case OPTION_REDEFINE_SYMS:
2667 add_redefine_syms_file (optarg);
2668 break;
2669
2670 case OPTION_SET_SECTION_FLAGS:
2671 {
2672 const char *s;
2673 int len;
2674 char *name;
2675
2676 s = strchr (optarg, '=');
2677 if (s == NULL)
2678 fatal (_("bad format for %s"), "--set-section-flags");
2679
2680 len = s - optarg;
2681 name = xmalloc (len + 1);
2682 strncpy (name, optarg, len);
2683 name[len] = '\0';
2684
2685 p = find_section_list (name, TRUE);
2686
2687 p->set_flags = TRUE;
2688 p->flags = parse_flags (s + 1);
2689 }
2690 break;
2691
2692 case OPTION_RENAME_SECTION:
2693 {
2694 flagword flags;
2695 const char *eq, *fl;
2696 char *old_name;
2697 char *new_name;
2698 unsigned int len;
2699
2700 eq = strchr (optarg, '=');
2701 if (eq == NULL)
2702 fatal (_("bad format for %s"), "--rename-section");
2703
2704 len = eq - optarg;
2705 if (len == 0)
2706 fatal (_("bad format for %s"), "--rename-section");
2707
2708 old_name = xmalloc (len + 1);
2709 strncpy (old_name, optarg, len);
2710 old_name[len] = 0;
2711
2712 eq++;
2713 fl = strchr (eq, ',');
2714 if (fl)
2715 {
2716 flags = parse_flags (fl + 1);
2717 len = fl - eq;
2718 }
2719 else
2720 {
2721 flags = -1;
2722 len = strlen (eq);
2723 }
2724
2725 if (len == 0)
2726 fatal (_("bad format for %s"), "--rename-section");
2727
2728 new_name = xmalloc (len + 1);
2729 strncpy (new_name, eq, len);
2730 new_name[len] = 0;
2731
2732 add_section_rename (old_name, new_name, flags);
2733 }
2734 break;
2735
2736 case OPTION_SET_START:
2737 set_start = parse_vma (optarg, "--set-start");
2738 set_start_set = TRUE;
2739 break;
2740
2741 case OPTION_SREC_LEN:
2742 Chunk = parse_vma (optarg, "--srec-len");
2743 break;
2744
2745 case OPTION_SREC_FORCES3:
2746 S3Forced = TRUE;
2747 break;
2748
2749 case OPTION_STRIP_SYMBOLS:
2750 add_specific_symbols (optarg, &strip_specific_list);
2751 break;
2752
2753 case OPTION_KEEP_SYMBOLS:
2754 add_specific_symbols (optarg, &keep_specific_list);
2755 break;
2756
2757 case OPTION_LOCALIZE_SYMBOLS:
2758 add_specific_symbols (optarg, &localize_specific_list);
2759 break;
2760
2761 case OPTION_KEEPGLOBAL_SYMBOLS:
2762 add_specific_symbols (optarg, &keepglobal_specific_list);
2763 break;
2764
2765 case OPTION_WEAKEN_SYMBOLS:
2766 add_specific_symbols (optarg, &weaken_specific_list);
2767 break;
2768
2769 case OPTION_ALT_MACH_CODE:
2770 use_alt_mach_code = atoi (optarg);
2771 if (use_alt_mach_code <= 0)
2772 fatal (_("alternate machine code index must be positive"));
2773 break;
2774
2775 case OPTION_PREFIX_SYMBOLS:
2776 prefix_symbols_string = optarg;
2777 break;
2778
2779 case OPTION_PREFIX_SECTIONS:
2780 prefix_sections_string = optarg;
2781 break;
2782
2783 case OPTION_PREFIX_ALLOC_SECTIONS:
2784 prefix_alloc_sections_string = optarg;
2785 break;
2786
2787 case 0:
2788 /* We've been given a long option. */
2789 break;
2790
2791 case 'H':
2792 case 'h':
2793 copy_usage (stdout, 0);
2794
2795 default:
2796 copy_usage (stderr, 1);
2797 }
2798 }
2799
2800 if (formats_info)
2801 {
2802 display_info ();
2803 return 0;
2804 }
2805
2806 if (show_version)
2807 print_version ("objcopy");
2808
2809 if (copy_byte >= interleave)
2810 fatal (_("byte number must be less than interleave"));
2811
2812 if (optind == argc || optind + 2 < argc)
2813 copy_usage (stderr, 1);
2814
2815 input_filename = argv[optind];
2816 if (optind + 1 < argc)
2817 output_filename = argv[optind + 1];
2818
2819 /* Default is to strip no symbols. */
2820 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2821 strip_symbols = STRIP_NONE;
2822
2823 if (output_target == NULL)
2824 output_target = input_target;
2825
2826 if (binary_architecture != NULL)
2827 {
2828 if (input_target && strcmp (input_target, "binary") == 0)
2829 {
2830 const bfd_arch_info_type * temp_arch_info;
2831
2832 temp_arch_info = bfd_scan_arch (binary_architecture);
2833
2834 if (temp_arch_info != NULL)
2835 {
2836 bfd_external_binary_architecture = temp_arch_info->arch;
2837 bfd_external_machine = temp_arch_info->mach;
2838 }
2839 else
2840 fatal (_("architecture %s unknown"), binary_architecture);
2841 }
2842 else
2843 {
2844 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2845 non_fatal (_(" Argument %s ignored"), binary_architecture);
2846 }
2847 }
2848
2849 if (preserve_dates)
2850 if (stat (input_filename, & statbuf) < 0)
2851 fatal (_("warning: could not locate '%s'. System error message: %s"),
2852 input_filename, strerror (errno));
2853
2854 /* If there is no destination file, or the source and destination files
2855 are the same, then create a temp and rename the result into the input. */
2856 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
2857 {
2858 char *tmpname = make_tempname (input_filename);
2859
2860 copy_file (input_filename, tmpname, input_target, output_target);
2861 if (status == 0)
2862 {
2863 if (preserve_dates)
2864 set_times (tmpname, &statbuf);
2865 smart_rename (tmpname, input_filename, preserve_dates);
2866 }
2867 else
2868 unlink (tmpname);
2869 }
2870 else
2871 {
2872 copy_file (input_filename, output_filename, input_target, output_target);
2873
2874 if (status == 0 && preserve_dates)
2875 set_times (output_filename, &statbuf);
2876 }
2877
2878 if (change_warn)
2879 {
2880 for (p = change_sections; p != NULL; p = p->next)
2881 {
2882 if (! p->used)
2883 {
2884 if (p->change_vma != CHANGE_IGNORE)
2885 {
2886 char buff [20];
2887
2888 sprintf_vma (buff, p->vma_val);
2889
2890 /* xgettext:c-format */
2891 non_fatal (_("%s %s%c0x%s never used"),
2892 "--change-section-vma",
2893 p->name,
2894 p->change_vma == CHANGE_SET ? '=' : '+',
2895 buff);
2896 }
2897
2898 if (p->change_lma != CHANGE_IGNORE)
2899 {
2900 char buff [20];
2901
2902 sprintf_vma (buff, p->lma_val);
2903
2904 /* xgettext:c-format */
2905 non_fatal (_("%s %s%c0x%s never used"),
2906 "--change-section-lma",
2907 p->name,
2908 p->change_lma == CHANGE_SET ? '=' : '+',
2909 buff);
2910 }
2911 }
2912 }
2913 }
2914
2915 return 0;
2916}
2917
2918int
2919main (int argc, char *argv[])
2920{
2921#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2922 setlocale (LC_MESSAGES, "");
2923#endif
2924#if defined (HAVE_SETLOCALE)
2925 setlocale (LC_CTYPE, "");
2926#endif
2927 bindtextdomain (PACKAGE, LOCALEDIR);
2928 textdomain (PACKAGE);
2929
2930 program_name = argv[0];
2931 xmalloc_set_program_name (program_name);
2932
2933 START_PROGRESS (program_name, 0);
2934
2935 strip_symbols = STRIP_UNDEF;
2936 discard_locals = LOCALS_UNDEF;
2937
2938 bfd_init ();
2939 set_default_bfd_target ();
2940
2941 if (is_strip < 0)
2942 {
2943 int i = strlen (program_name);
2944#ifdef HAVE_DOS_BASED_FILE_SYSTEM
2945 /* Drop the .exe suffix, if any. */
2946 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2947 {
2948 i -= 4;
2949 program_name[i] = '\0';
2950 }
2951#endif
2952 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2953 }
2954
2955 if (is_strip)
2956 strip_main (argc, argv);
2957 else
2958 copy_main (argc, argv);
2959
2960 END_PROGRESS (program_name);
2961
2962 return status;
2963}
This page took 0.032244 seconds and 4 git commands to generate.