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