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