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