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