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