]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/objcopy.c
2001-06-24 H.J. Lu <hjl@gnu.org>
[thirdparty/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
727 if (redefine_sym_list)
728 {
729 const char *old_name, *new_name;
730
731 old_name = bfd_asymbol_name (sym);
732 new_name = lookup_sym_redefinition (old_name);
733 name = bfd_asymbol_name (sym) = new_name;
734 }
735
736 if (change_leading_char
737 && (bfd_get_symbol_leading_char (abfd)
738 != bfd_get_symbol_leading_char (obfd))
739 && (bfd_get_symbol_leading_char (abfd) == '\0'
740 || (name[0] == bfd_get_symbol_leading_char (abfd))))
741 {
742 if (bfd_get_symbol_leading_char (obfd) == '\0')
743 name = bfd_asymbol_name (sym) = name + 1;
744 else
745 {
746 char *n;
747
748 n = xmalloc (strlen (name) + 2);
749 n[0] = bfd_get_symbol_leading_char (obfd);
750 if (bfd_get_symbol_leading_char (abfd) == '\0')
751 strcpy (n + 1, name);
752 else
753 strcpy (n + 1, name + 1);
754 name = bfd_asymbol_name (sym) = n;
755 }
756 }
757
758 if (remove_leading_char
759 && ((flags & BSF_GLOBAL) != 0
760 || (flags & BSF_WEAK) != 0
761 || bfd_is_und_section (bfd_get_section (sym))
762 || bfd_is_com_section (bfd_get_section (sym)))
763 && name[0] == bfd_get_symbol_leading_char (abfd))
764 name = bfd_asymbol_name (sym) = name + 1;
765
766 if (strip_symbols == STRIP_ALL)
767 keep = 0;
768 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
769 || ((flags & BSF_SECTION_SYM) != 0
770 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
771 & BSF_KEEP) != 0))
772 keep = 1;
773 else if (relocatable /* Relocatable file. */
774 && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
775 keep = 1;
776 else if (bfd_decode_symclass (sym) == 'I')
777 /* Global symbols in $idata sections need to be retained
778 even if relocatable is false. External users of the
779 library containing the $idata section may reference these
780 symbols. */
781 keep = 1;
782 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
783 || (flags & BSF_WEAK) != 0
784 || bfd_is_und_section (bfd_get_section (sym))
785 || bfd_is_com_section (bfd_get_section (sym)))
786 keep = strip_symbols != STRIP_UNNEEDED;
787 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
788 keep = (strip_symbols != STRIP_DEBUG
789 && strip_symbols != STRIP_UNNEEDED
790 && ! convert_debugging);
791 else if (bfd_get_section (sym)->comdat)
792 /* COMDAT sections store special information in local
793 symbols, so we cannot risk stripping any of them. */
794 keep = 1;
795 else /* Local symbol. */
796 keep = (strip_symbols != STRIP_UNNEEDED
797 && (discard_locals != LOCALS_ALL
798 && (discard_locals != LOCALS_START_L
799 || ! bfd_is_local_label (abfd, sym))));
800
801 if (keep && is_specified_symbol (name, strip_specific_list))
802 keep = 0;
803 if (!keep && is_specified_symbol (name, keep_specific_list))
804 keep = 1;
805 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
806 keep = 0;
807
808 if (keep && (flags & BSF_GLOBAL) != 0
809 && (weaken || is_specified_symbol (name, weaken_specific_list)))
810 {
811 sym->flags &=~ BSF_GLOBAL;
812 sym->flags |= BSF_WEAK;
813 }
814 if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
815 && (is_specified_symbol (name, localize_specific_list)
816 || (keepglobal_specific_list != NULL
817 && ! is_specified_symbol (name, keepglobal_specific_list))))
818 {
819 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
820 sym->flags |= BSF_LOCAL;
821 }
822
823 if (keep)
824 to[dst_count++] = sym;
825 }
826
827 to[dst_count] = NULL;
828
829 return dst_count;
830 }
831
832 static const char *
833 lookup_sym_redefinition (source)
834 const char *source;
835 {
836 const char *result;
837 struct redefine_node *list;
838
839 result = source;
840
841 for (list = redefine_sym_list; list != NULL; list = list->next)
842 {
843 if (strcmp (source, list->source) == 0)
844 {
845 result = list->target;
846 break;
847 }
848 }
849 return result;
850 }
851
852 /* Add a node to a symbol redefine list */
853
854 static void
855 redefine_list_append (source, target)
856 const char *source;
857 const char *target;
858 {
859 struct redefine_node **p;
860 struct redefine_node *list;
861 struct redefine_node *new_node;
862
863 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
864 {
865 if (strcmp (source, list->source) == 0)
866 {
867 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
868 "--redefine-sym",
869 source);
870 }
871
872 if (strcmp (target, list->target) == 0)
873 {
874 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
875 "--redefine-sym",
876 target);
877 }
878 }
879
880 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
881
882 new_node->source = strdup (source);
883 new_node->target = strdup (target);
884 new_node->next = NULL;
885
886 *p = new_node;
887 }
888
889
890 /* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
891 Adjust *SIZE. */
892
893 static void
894 filter_bytes (memhunk, size)
895 char *memhunk;
896 bfd_size_type *size;
897 {
898 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
899
900 for (; from < end; from += interleave)
901 *to++ = *from;
902 if (*size % interleave > (bfd_size_type) copy_byte)
903 *size = (*size / interleave) + 1;
904 else
905 *size /= interleave;
906 }
907
908 /* Copy object file IBFD onto OBFD. */
909
910 static void
911 copy_object (ibfd, obfd)
912 bfd *ibfd;
913 bfd *obfd;
914 {
915 bfd_vma start;
916 long symcount;
917 asection **osections = NULL;
918 bfd_size_type *gaps = NULL;
919 bfd_size_type max_gap = 0;
920 long symsize;
921 PTR dhandle;
922
923 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
924 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
925 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
926 {
927 fatal (_("Unable to change endianness of input file(s)"));
928 return;
929 }
930
931 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
932 RETURN_NONFATAL (bfd_get_filename (obfd));
933
934 if (verbose)
935 printf (_("copy from %s(%s) to %s(%s)\n"),
936 bfd_get_filename (ibfd), bfd_get_target (ibfd),
937 bfd_get_filename (obfd), bfd_get_target (obfd));
938
939 if (set_start_set)
940 start = set_start;
941 else
942 start = bfd_get_start_address (ibfd);
943 start += change_start;
944
945 if (!bfd_set_start_address (obfd, start)
946 || !bfd_set_file_flags (obfd,
947 (bfd_get_file_flags (ibfd)
948 & bfd_applicable_file_flags (obfd))))
949 RETURN_NONFATAL (bfd_get_filename (ibfd));
950
951 /* Copy architecture of input file to output file */
952 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
953 bfd_get_mach (ibfd)))
954 non_fatal (_("Warning: Output file cannot represent architecture %s"),
955 bfd_printable_arch_mach (bfd_get_arch (ibfd),
956 bfd_get_mach (ibfd)));
957
958 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
959 RETURN_NONFATAL (bfd_get_filename (ibfd));
960
961 if (isympp)
962 free (isympp);
963
964 if (osympp != isympp)
965 free (osympp);
966
967 /* BFD mandates that all output sections be created and sizes set before
968 any output is done. Thus, we traverse all sections multiple times. */
969 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
970
971 if (add_sections != NULL)
972 {
973 struct section_add *padd;
974 struct section_list *pset;
975
976 for (padd = add_sections; padd != NULL; padd = padd->next)
977 {
978 padd->section = bfd_make_section (obfd, padd->name);
979 if (padd->section == NULL)
980 {
981 non_fatal (_("can't create section `%s': %s"),
982 padd->name, bfd_errmsg (bfd_get_error ()));
983 status = 1;
984 return;
985 }
986 else
987 {
988 flagword flags;
989
990 if (! bfd_set_section_size (obfd, padd->section, padd->size))
991 RETURN_NONFATAL (bfd_get_filename (obfd));
992
993 pset = find_section_list (padd->name, false);
994 if (pset != NULL)
995 pset->used = true;
996
997 if (pset != NULL && pset->set_flags)
998 flags = pset->flags | SEC_HAS_CONTENTS;
999 else
1000 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1001
1002 if (! bfd_set_section_flags (obfd, padd->section, flags))
1003 RETURN_NONFATAL (bfd_get_filename (obfd));
1004
1005 if (pset != NULL)
1006 {
1007 if (pset->change_vma != CHANGE_IGNORE)
1008 if (! bfd_set_section_vma (obfd, padd->section, pset->vma_val))
1009 RETURN_NONFATAL (bfd_get_filename (obfd));
1010
1011 if (pset->change_lma != CHANGE_IGNORE)
1012 {
1013 padd->section->lma = pset->lma_val;
1014
1015 if (! bfd_set_section_alignment
1016 (obfd, padd->section,
1017 bfd_section_alignment (obfd, padd->section)))
1018 RETURN_NONFATAL (bfd_get_filename (obfd));
1019 }
1020 }
1021 }
1022 }
1023 }
1024
1025 if (gap_fill_set || pad_to_set)
1026 {
1027 asection **set;
1028 unsigned int c, i;
1029
1030 /* We must fill in gaps between the sections and/or we must pad
1031 the last section to a specified address. We do this by
1032 grabbing a list of the sections, sorting them by VMA, and
1033 increasing the section sizes as required to fill the gaps.
1034 We write out the gap contents below. */
1035
1036 c = bfd_count_sections (obfd);
1037 osections = (asection **) xmalloc (c * sizeof (asection *));
1038 set = osections;
1039 bfd_map_over_sections (obfd, get_sections, (void *) &set);
1040
1041 qsort (osections, c, sizeof (asection *), compare_section_lma);
1042
1043 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
1044 memset (gaps, 0, c * sizeof (bfd_size_type));
1045
1046 if (gap_fill_set)
1047 {
1048 for (i = 0; i < c - 1; i++)
1049 {
1050 flagword flags;
1051 bfd_size_type size;
1052 bfd_vma gap_start, gap_stop;
1053
1054 flags = bfd_get_section_flags (obfd, osections[i]);
1055 if ((flags & SEC_HAS_CONTENTS) == 0
1056 || (flags & SEC_LOAD) == 0)
1057 continue;
1058
1059 size = bfd_section_size (obfd, osections[i]);
1060 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1061 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1062 if (gap_start < gap_stop)
1063 {
1064 if (! bfd_set_section_size (obfd, osections[i],
1065 size + (gap_stop - gap_start)))
1066 {
1067 non_fatal (_("Can't fill gap after %s: %s"),
1068 bfd_get_section_name (obfd, osections[i]),
1069 bfd_errmsg (bfd_get_error ()));
1070 status = 1;
1071 break;
1072 }
1073 gaps[i] = gap_stop - gap_start;
1074 if (max_gap < gap_stop - gap_start)
1075 max_gap = gap_stop - gap_start;
1076 }
1077 }
1078 }
1079
1080 if (pad_to_set)
1081 {
1082 bfd_vma lma;
1083 bfd_size_type size;
1084
1085 lma = bfd_section_lma (obfd, osections[c - 1]);
1086 size = bfd_section_size (obfd, osections[c - 1]);
1087 if (lma + size < pad_to)
1088 {
1089 if (! bfd_set_section_size (obfd, osections[c - 1],
1090 pad_to - lma))
1091 {
1092 non_fatal (_("Can't add padding to %s: %s"),
1093 bfd_get_section_name (obfd, osections[c - 1]),
1094 bfd_errmsg (bfd_get_error ()));
1095 status = 1;
1096 }
1097 else
1098 {
1099 gaps[c - 1] = pad_to - (lma + size);
1100 if (max_gap < pad_to - (lma + size))
1101 max_gap = pad_to - (lma + size);
1102 }
1103 }
1104 }
1105 }
1106
1107 /* Symbol filtering must happen after the output sections have
1108 been created, but before their contents are set. */
1109 dhandle = NULL;
1110 symsize = bfd_get_symtab_upper_bound (ibfd);
1111 if (symsize < 0)
1112 RETURN_NONFATAL (bfd_get_filename (ibfd));
1113
1114 osympp = isympp = (asymbol **) xmalloc (symsize);
1115 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1116 if (symcount < 0)
1117 RETURN_NONFATAL (bfd_get_filename (ibfd));
1118
1119 if (convert_debugging)
1120 dhandle = read_debugging_info (ibfd, isympp, symcount);
1121
1122 if (strip_symbols == STRIP_DEBUG
1123 || strip_symbols == STRIP_ALL
1124 || strip_symbols == STRIP_UNNEEDED
1125 || discard_locals != LOCALS_UNDEF
1126 || strip_specific_list != NULL
1127 || keep_specific_list != NULL
1128 || localize_specific_list != NULL
1129 || keepglobal_specific_list != NULL
1130 || weaken_specific_list != NULL
1131 || sections_removed
1132 || sections_copied
1133 || convert_debugging
1134 || change_leading_char
1135 || remove_leading_char
1136 || redefine_sym_list
1137 || weaken)
1138 {
1139 /* Mark symbols used in output relocations so that they
1140 are kept, even if they are local labels or static symbols.
1141
1142 Note we iterate over the input sections examining their
1143 relocations since the relocations for the output sections
1144 haven't been set yet. mark_symbols_used_in_relocations will
1145 ignore input sections which have no corresponding output
1146 section. */
1147 if (strip_symbols != STRIP_ALL)
1148 bfd_map_over_sections (ibfd,
1149 mark_symbols_used_in_relocations,
1150 (PTR)isympp);
1151 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
1152 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1153 }
1154
1155 if (convert_debugging && dhandle != NULL)
1156 {
1157 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1158 {
1159 status = 1;
1160 return;
1161 }
1162 }
1163
1164 bfd_set_symtab (obfd, osympp, symcount);
1165
1166 /* This has to happen after the symbol table has been set. */
1167 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
1168
1169 if (add_sections != NULL)
1170 {
1171 struct section_add *padd;
1172
1173 for (padd = add_sections; padd != NULL; padd = padd->next)
1174 {
1175 if (! bfd_set_section_contents (obfd, padd->section,
1176 (PTR) padd->contents,
1177 (file_ptr) 0,
1178 (bfd_size_type) padd->size))
1179 RETURN_NONFATAL (bfd_get_filename (obfd));
1180 }
1181 }
1182
1183 if (gap_fill_set || pad_to_set)
1184 {
1185 bfd_byte *buf;
1186 int c, i;
1187
1188 /* Fill in the gaps. */
1189
1190 if (max_gap > 8192)
1191 max_gap = 8192;
1192 buf = (bfd_byte *) xmalloc (max_gap);
1193 memset (buf, gap_fill, (size_t) max_gap);
1194
1195 c = bfd_count_sections (obfd);
1196 for (i = 0; i < c; i++)
1197 {
1198 if (gaps[i] != 0)
1199 {
1200 bfd_size_type left;
1201 file_ptr off;
1202
1203 left = gaps[i];
1204 off = bfd_section_size (obfd, osections[i]) - left;
1205 while (left > 0)
1206 {
1207 bfd_size_type now;
1208
1209 if (left > 8192)
1210 now = 8192;
1211 else
1212 now = left;
1213
1214 if (! bfd_set_section_contents (obfd, osections[i], buf,
1215 off, now))
1216 RETURN_NONFATAL (bfd_get_filename (obfd));
1217
1218 left -= now;
1219 off += now;
1220 }
1221 }
1222 }
1223 }
1224
1225 /* Allow the BFD backend to copy any private data it understands
1226 from the input BFD to the output BFD. This is done last to
1227 permit the routine to look at the filtered symbol table, which is
1228 important for the ECOFF code at least. */
1229 if (!bfd_copy_private_bfd_data (ibfd, obfd))
1230 {
1231 non_fatal (_("%s: error copying private BFD data: %s"),
1232 bfd_get_filename (obfd),
1233 bfd_errmsg (bfd_get_error ()));
1234 status = 1;
1235 return;
1236 }
1237 }
1238
1239 /* Read each archive element in turn from IBFD, copy the
1240 contents to temp file, and keep the temp file handle. */
1241
1242 static void
1243 copy_archive (ibfd, obfd, output_target)
1244 bfd *ibfd;
1245 bfd *obfd;
1246 const char *output_target;
1247 {
1248 struct name_list
1249 {
1250 struct name_list *next;
1251 char *name;
1252 bfd *obfd;
1253 } *list, *l;
1254 bfd **ptr = &obfd->archive_head;
1255 bfd *this_element;
1256 char *dir = make_tempname (bfd_get_filename (obfd));
1257
1258 /* Make a temp directory to hold the contents. */
1259 #if defined (_WIN32) && !defined (__CYGWIN32__)
1260 if (mkdir (dir) != 0)
1261 #else
1262 if (mkdir (dir, 0700) != 0)
1263 #endif
1264 {
1265 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
1266 dir, strerror (errno));
1267 }
1268 obfd->has_armap = ibfd->has_armap;
1269
1270 list = NULL;
1271
1272 this_element = bfd_openr_next_archived_file (ibfd, NULL);
1273 while (!status && this_element != (bfd *) NULL)
1274 {
1275 /* Create an output file for this member. */
1276 char *output_name = concat (dir, "/", bfd_get_filename (this_element),
1277 (char *) NULL);
1278 bfd *output_bfd = bfd_openw (output_name, output_target);
1279 bfd *last_element;
1280 struct stat buf;
1281 int stat_status = 0;
1282
1283 if (preserve_dates)
1284 {
1285 stat_status = bfd_stat_arch_elt (this_element, &buf);
1286 if (stat_status != 0)
1287 non_fatal (_("internal stat error on %s"),
1288 bfd_get_filename (this_element));
1289 }
1290
1291 l = (struct name_list *) xmalloc (sizeof (struct name_list));
1292 l->name = output_name;
1293 l->next = list;
1294 list = l;
1295
1296 if (output_bfd == (bfd *) NULL)
1297 RETURN_NONFATAL (output_name);
1298
1299 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1300 RETURN_NONFATAL (bfd_get_filename (obfd));
1301
1302 if (bfd_check_format (this_element, bfd_object) == true)
1303 copy_object (this_element, output_bfd);
1304
1305 if (!bfd_close (output_bfd))
1306 {
1307 bfd_nonfatal (bfd_get_filename (output_bfd));
1308 /* Error in new object file. Don't change archive. */
1309 status = 1;
1310 }
1311
1312 if (preserve_dates && stat_status == 0)
1313 set_times (output_name, &buf);
1314
1315 /* Open the newly output file and attach to our list. */
1316 output_bfd = bfd_openr (output_name, output_target);
1317
1318 l->obfd = output_bfd;
1319
1320 *ptr = output_bfd;
1321 ptr = &output_bfd->next;
1322
1323 last_element = this_element;
1324
1325 this_element = bfd_openr_next_archived_file (ibfd, last_element);
1326
1327 bfd_close (last_element);
1328 }
1329 *ptr = (bfd *) NULL;
1330
1331 if (!bfd_close (obfd))
1332 RETURN_NONFATAL (bfd_get_filename (obfd));
1333
1334 if (!bfd_close (ibfd))
1335 RETURN_NONFATAL (bfd_get_filename (ibfd));
1336
1337 /* Delete all the files that we opened. */
1338 for (l = list; l != NULL; l = l->next)
1339 {
1340 bfd_close (l->obfd);
1341 unlink (l->name);
1342 }
1343 rmdir (dir);
1344 }
1345
1346 /* The top-level control. */
1347
1348 static void
1349 copy_file (input_filename, output_filename, input_target, output_target)
1350 const char *input_filename;
1351 const char *output_filename;
1352 const char *input_target;
1353 const char *output_target;
1354 {
1355 bfd *ibfd;
1356 char **matching;
1357
1358 /* To allow us to do "strip *" without dying on the first
1359 non-object file, failures are nonfatal. */
1360
1361 ibfd = bfd_openr (input_filename, input_target);
1362 if (ibfd == NULL)
1363 RETURN_NONFATAL (input_filename);
1364
1365 if (bfd_check_format (ibfd, bfd_archive))
1366 {
1367 bfd *obfd;
1368
1369 /* bfd_get_target does not return the correct value until
1370 bfd_check_format succeeds. */
1371 if (output_target == NULL)
1372 output_target = bfd_get_target (ibfd);
1373
1374 obfd = bfd_openw (output_filename, output_target);
1375 if (obfd == NULL)
1376 RETURN_NONFATAL (output_filename);
1377
1378 copy_archive (ibfd, obfd, output_target);
1379 }
1380 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
1381 {
1382 bfd *obfd;
1383
1384 /* bfd_get_target does not return the correct value until
1385 bfd_check_format succeeds. */
1386 if (output_target == NULL)
1387 output_target = bfd_get_target (ibfd);
1388
1389 obfd = bfd_openw (output_filename, output_target);
1390 if (obfd == NULL)
1391 RETURN_NONFATAL (output_filename);
1392
1393 copy_object (ibfd, obfd);
1394
1395 if (!bfd_close (obfd))
1396 RETURN_NONFATAL (output_filename);
1397
1398 if (!bfd_close (ibfd))
1399 RETURN_NONFATAL (input_filename);
1400 }
1401 else
1402 {
1403 bfd_nonfatal (input_filename);
1404
1405 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1406 {
1407 list_matching_formats (matching);
1408 free (matching);
1409 }
1410
1411 status = 1;
1412 }
1413 }
1414
1415 /* Create a section in OBFD with the same name and attributes
1416 as ISECTION in IBFD. */
1417
1418 static void
1419 setup_section (ibfd, isection, obfdarg)
1420 bfd *ibfd;
1421 sec_ptr isection;
1422 PTR obfdarg;
1423 {
1424 bfd *obfd = (bfd *) obfdarg;
1425 struct section_list *p;
1426 sec_ptr osection;
1427 bfd_size_type size;
1428 bfd_vma vma;
1429 bfd_vma lma;
1430 flagword flags;
1431 const char *err;
1432
1433 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1434 && (strip_symbols == STRIP_DEBUG
1435 || strip_symbols == STRIP_UNNEEDED
1436 || strip_symbols == STRIP_ALL
1437 || discard_locals == LOCALS_ALL
1438 || convert_debugging))
1439 return;
1440
1441 p = find_section_list (bfd_section_name (ibfd, isection), false);
1442 if (p != NULL)
1443 p->used = true;
1444
1445 if (sections_removed && p != NULL && p->remove)
1446 return;
1447 if (sections_copied && (p == NULL || ! p->copy))
1448 return;
1449
1450 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
1451
1452 if (osection == NULL)
1453 {
1454 err = _("making");
1455 goto loser;
1456 }
1457
1458 size = bfd_section_size (ibfd, isection);
1459 if (copy_byte >= 0)
1460 size = (size + interleave - 1) / interleave;
1461 if (! bfd_set_section_size (obfd, osection, size))
1462 {
1463 err = _("size");
1464 goto loser;
1465 }
1466
1467 vma = bfd_section_vma (ibfd, isection);
1468 if (p != NULL && p->change_vma == CHANGE_MODIFY)
1469 vma += p->vma_val;
1470 else if (p != NULL && p->change_vma == CHANGE_SET)
1471 vma = p->vma_val;
1472 else
1473 vma += change_section_address;
1474
1475 if (! bfd_set_section_vma (obfd, osection, vma))
1476 {
1477 err = _("vma");
1478 goto loser;
1479 }
1480
1481 lma = isection->lma;
1482 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
1483 {
1484 if (p->change_lma == CHANGE_MODIFY)
1485 lma += p->lma_val;
1486 else if (p->change_lma == CHANGE_SET)
1487 lma = p->lma_val;
1488 else
1489 abort ();
1490 }
1491 else
1492 lma += change_section_address;
1493
1494 osection->lma = lma;
1495
1496 /* FIXME: This is probably not enough. If we change the LMA we
1497 may have to recompute the header for the file as well. */
1498 if (bfd_set_section_alignment (obfd,
1499 osection,
1500 bfd_section_alignment (ibfd, isection))
1501 == false)
1502 {
1503 err = _("alignment");
1504 goto loser;
1505 }
1506
1507 flags = bfd_get_section_flags (ibfd, isection);
1508 if (p != NULL && p->set_flags)
1509 flags = p->flags | (flags & SEC_HAS_CONTENTS);
1510 if (!bfd_set_section_flags (obfd, osection, flags))
1511 {
1512 err = _("flags");
1513 goto loser;
1514 }
1515
1516 /* This used to be mangle_section; we do here to avoid using
1517 bfd_get_section_by_name since some formats allow multiple
1518 sections with the same name. */
1519 isection->output_section = osection;
1520 isection->output_offset = 0;
1521
1522 /* Allow the BFD backend to copy any private data it understands
1523 from the input section to the output section. */
1524 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1525 {
1526 err = _("private data");
1527 goto loser;
1528 }
1529
1530 /* All went well */
1531 return;
1532
1533 loser:
1534 non_fatal (_("%s: section `%s': error in %s: %s"),
1535 bfd_get_filename (ibfd),
1536 bfd_section_name (ibfd, isection),
1537 err, bfd_errmsg (bfd_get_error ()));
1538 status = 1;
1539 }
1540
1541 /* Copy the data of input section ISECTION of IBFD
1542 to an output section with the same name in OBFD.
1543 If stripping then don't copy any relocation info. */
1544
1545 static void
1546 copy_section (ibfd, isection, obfdarg)
1547 bfd *ibfd;
1548 sec_ptr isection;
1549 PTR obfdarg;
1550 {
1551 bfd *obfd = (bfd *) obfdarg;
1552 struct section_list *p;
1553 arelent **relpp;
1554 long relcount;
1555 sec_ptr osection;
1556 bfd_size_type size;
1557 long relsize;
1558
1559 /* If we have already failed earlier on, do not keep on generating
1560 complaints now. */
1561 if (status != 0)
1562 return;
1563
1564 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1565 && (strip_symbols == STRIP_DEBUG
1566 || strip_symbols == STRIP_UNNEEDED
1567 || strip_symbols == STRIP_ALL
1568 || discard_locals == LOCALS_ALL
1569 || convert_debugging))
1570 {
1571 return;
1572 }
1573
1574 p = find_section_list (bfd_section_name (ibfd, isection), false);
1575
1576 if (sections_removed && p != NULL && p->remove)
1577 return;
1578 if (sections_copied && (p == NULL || ! p->copy))
1579 return;
1580
1581 osection = isection->output_section;
1582 size = bfd_get_section_size_before_reloc (isection);
1583
1584 if (size == 0 || osection == 0)
1585 return;
1586
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 bfd_set_reloc (obfd, osection,
1620 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1621 }
1622
1623 isection->_cooked_size = isection->_raw_size;
1624 isection->reloc_done = true;
1625
1626 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1627 {
1628 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1629
1630 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1631 size))
1632 RETURN_NONFATAL (bfd_get_filename (ibfd));
1633
1634 if (copy_byte >= 0)
1635 filter_bytes (memhunk, &size);
1636
1637 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1638 size))
1639 RETURN_NONFATAL (bfd_get_filename (obfd));
1640
1641 free (memhunk);
1642 }
1643 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1644 {
1645 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1646
1647 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1648 flag--they can just remove the section entirely and add it
1649 back again. However, we do permit them to turn on the
1650 SEC_HAS_CONTENTS flag, and take it to mean that the section
1651 contents should be zeroed out. */
1652
1653 memset (memhunk, 0, size);
1654 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1655 size))
1656 RETURN_NONFATAL (bfd_get_filename (obfd));
1657 free (memhunk);
1658 }
1659 }
1660
1661 /* Get all the sections. This is used when --gap-fill or --pad-to is
1662 used. */
1663
1664 static void
1665 get_sections (obfd, osection, secppparg)
1666 bfd *obfd ATTRIBUTE_UNUSED;
1667 asection *osection;
1668 PTR secppparg;
1669 {
1670 asection ***secppp = (asection ***) secppparg;
1671
1672 **secppp = osection;
1673 ++(*secppp);
1674 }
1675
1676 /* Sort sections by VMA. This is called via qsort, and is used when
1677 --gap-fill or --pad-to is used. We force non loadable or empty
1678 sections to the front, where they are easier to ignore. */
1679
1680 static int
1681 compare_section_lma (arg1, arg2)
1682 const PTR arg1;
1683 const PTR arg2;
1684 {
1685 const asection **sec1 = (const asection **) arg1;
1686 const asection **sec2 = (const asection **) arg2;
1687 flagword flags1, flags2;
1688
1689 /* Sort non loadable sections to the front. */
1690 flags1 = (*sec1)->flags;
1691 flags2 = (*sec2)->flags;
1692 if ((flags1 & SEC_HAS_CONTENTS) == 0
1693 || (flags1 & SEC_LOAD) == 0)
1694 {
1695 if ((flags2 & SEC_HAS_CONTENTS) != 0
1696 && (flags2 & SEC_LOAD) != 0)
1697 return -1;
1698 }
1699 else
1700 {
1701 if ((flags2 & SEC_HAS_CONTENTS) == 0
1702 || (flags2 & SEC_LOAD) == 0)
1703 return 1;
1704 }
1705
1706 /* Sort sections by LMA. */
1707 if ((*sec1)->lma > (*sec2)->lma)
1708 return 1;
1709 else if ((*sec1)->lma < (*sec2)->lma)
1710 return -1;
1711
1712 /* Sort sections with the same LMA by size. */
1713 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1714 return 1;
1715 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1716 return -1;
1717
1718 return 0;
1719 }
1720
1721 /* Mark all the symbols which will be used in output relocations with
1722 the BSF_KEEP flag so that those symbols will not be stripped.
1723
1724 Ignore relocations which will not appear in the output file. */
1725
1726 static void
1727 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1728 bfd *ibfd;
1729 sec_ptr isection;
1730 PTR symbolsarg;
1731 {
1732 asymbol **symbols = (asymbol **) symbolsarg;
1733 long relsize;
1734 arelent **relpp;
1735 long relcount, i;
1736
1737 /* Ignore an input section with no corresponding output section. */
1738 if (isection->output_section == NULL)
1739 return;
1740
1741 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1742 if (relsize < 0)
1743 bfd_fatal (bfd_get_filename (ibfd));
1744
1745 if (relsize == 0)
1746 return;
1747
1748 relpp = (arelent **) xmalloc (relsize);
1749 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1750 if (relcount < 0)
1751 bfd_fatal (bfd_get_filename (ibfd));
1752
1753 /* Examine each symbol used in a relocation. If it's not one of the
1754 special bfd section symbols, then mark it with BSF_KEEP. */
1755 for (i = 0; i < relcount; i++)
1756 {
1757 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1758 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1759 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1760 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1761 }
1762
1763 if (relpp != NULL)
1764 free (relpp);
1765 }
1766
1767 /* Write out debugging information. */
1768
1769 static boolean
1770 write_debugging_info (obfd, dhandle, symcountp, symppp)
1771 bfd *obfd;
1772 PTR dhandle;
1773 long *symcountp ATTRIBUTE_UNUSED;
1774 asymbol ***symppp ATTRIBUTE_UNUSED;
1775 {
1776 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1777 return write_ieee_debugging_info (obfd, dhandle);
1778
1779 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1780 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1781 {
1782 bfd_byte *syms, *strings;
1783 bfd_size_type symsize, stringsize;
1784 asection *stabsec, *stabstrsec;
1785
1786 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1787 &symsize, &strings,
1788 &stringsize))
1789 return false;
1790
1791 stabsec = bfd_make_section (obfd, ".stab");
1792 stabstrsec = bfd_make_section (obfd, ".stabstr");
1793 if (stabsec == NULL
1794 || stabstrsec == NULL
1795 || ! bfd_set_section_size (obfd, stabsec, symsize)
1796 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1797 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1798 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1799 || ! bfd_set_section_flags (obfd, stabsec,
1800 (SEC_HAS_CONTENTS
1801 | SEC_READONLY
1802 | SEC_DEBUGGING))
1803 || ! bfd_set_section_flags (obfd, stabstrsec,
1804 (SEC_HAS_CONTENTS
1805 | SEC_READONLY
1806 | SEC_DEBUGGING)))
1807 {
1808 non_fatal (_("%s: can't create debugging section: %s"),
1809 bfd_get_filename (obfd),
1810 bfd_errmsg (bfd_get_error ()));
1811 return false;
1812 }
1813
1814 /* We can get away with setting the section contents now because
1815 the next thing the caller is going to do is copy over the
1816 real sections. We may someday have to split the contents
1817 setting out of this function. */
1818 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1819 symsize)
1820 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1821 (file_ptr) 0, stringsize))
1822 {
1823 non_fatal (_("%s: can't set debugging section contents: %s"),
1824 bfd_get_filename (obfd),
1825 bfd_errmsg (bfd_get_error ()));
1826 return false;
1827 }
1828
1829 return true;
1830 }
1831
1832 non_fatal (_("%s: don't know how to write debugging information for %s"),
1833 bfd_get_filename (obfd), bfd_get_target (obfd));
1834 return false;
1835 }
1836
1837 static int
1838 strip_main (argc, argv)
1839 int argc;
1840 char *argv[];
1841 {
1842 char *input_target = NULL, *output_target = NULL;
1843 boolean show_version = false;
1844 int c, i;
1845 struct section_list *p;
1846 char *output_file = NULL;
1847
1848 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1849 strip_options, (int *) 0)) != EOF)
1850 {
1851 switch (c)
1852 {
1853 case 'I':
1854 input_target = optarg;
1855 break;
1856 case 'O':
1857 output_target = optarg;
1858 break;
1859 case 'F':
1860 input_target = output_target = optarg;
1861 break;
1862 case 'R':
1863 p = find_section_list (optarg, true);
1864 p->remove = true;
1865 sections_removed = true;
1866 break;
1867 case 's':
1868 strip_symbols = STRIP_ALL;
1869 break;
1870 case 'S':
1871 case 'g':
1872 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1873 strip_symbols = STRIP_DEBUG;
1874 break;
1875 case OPTION_STRIP_UNNEEDED:
1876 strip_symbols = STRIP_UNNEEDED;
1877 break;
1878 case 'K':
1879 add_specific_symbol (optarg, &keep_specific_list);
1880 break;
1881 case 'N':
1882 add_specific_symbol (optarg, &strip_specific_list);
1883 break;
1884 case 'o':
1885 output_file = optarg;
1886 break;
1887 case 'p':
1888 preserve_dates = true;
1889 break;
1890 case 'x':
1891 discard_locals = LOCALS_ALL;
1892 break;
1893 case 'X':
1894 discard_locals = LOCALS_START_L;
1895 break;
1896 case 'v':
1897 verbose = true;
1898 break;
1899 case 'V':
1900 show_version = true;
1901 break;
1902 case 0:
1903 break; /* we've been given a long option */
1904 case 'h':
1905 strip_usage (stdout, 0);
1906 default:
1907 strip_usage (stderr, 1);
1908 }
1909 }
1910
1911 if (show_version)
1912 print_version ("strip");
1913
1914 /* Default is to strip all symbols. */
1915 if (strip_symbols == STRIP_UNDEF
1916 && discard_locals == LOCALS_UNDEF
1917 && strip_specific_list == NULL)
1918 strip_symbols = STRIP_ALL;
1919
1920 if (output_target == (char *) NULL)
1921 output_target = input_target;
1922
1923 i = optind;
1924 if (i == argc
1925 || (output_file != NULL && (i + 1) < argc))
1926 strip_usage (stderr, 1);
1927
1928 for (; i < argc; i++)
1929 {
1930 int hold_status = status;
1931 struct stat statbuf;
1932 char *tmpname;
1933
1934 if (preserve_dates)
1935 {
1936 if (stat (argv[i], &statbuf) < 0)
1937 {
1938 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1939 continue;
1940 }
1941 }
1942
1943 if (output_file != NULL)
1944 tmpname = output_file;
1945 else
1946 tmpname = make_tempname (argv[i]);
1947 status = 0;
1948
1949 copy_file (argv[i], tmpname, input_target, output_target);
1950 if (status == 0)
1951 {
1952 if (preserve_dates)
1953 set_times (tmpname, &statbuf);
1954 if (output_file == NULL)
1955 smart_rename (tmpname, argv[i], preserve_dates);
1956 status = hold_status;
1957 }
1958 else
1959 unlink (tmpname);
1960 if (output_file == NULL)
1961 free (tmpname);
1962 }
1963
1964 return 0;
1965 }
1966
1967 static int
1968 copy_main (argc, argv)
1969 int argc;
1970 char *argv[];
1971 {
1972 char * binary_architecture = NULL;
1973 char *input_filename = NULL, *output_filename = NULL;
1974 char *input_target = NULL, *output_target = NULL;
1975 boolean show_version = false;
1976 boolean change_warn = true;
1977 int c;
1978 struct section_list *p;
1979 struct stat statbuf;
1980
1981 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
1982 copy_options, (int *) 0)) != EOF)
1983 {
1984 switch (c)
1985 {
1986 case 'b':
1987 copy_byte = atoi (optarg);
1988 if (copy_byte < 0)
1989 fatal (_("byte number must be non-negative"));
1990 break;
1991
1992 case 'B':
1993 binary_architecture = optarg;
1994 break;
1995
1996 case 'i':
1997 interleave = atoi (optarg);
1998 if (interleave < 1)
1999 fatal (_("interleave must be positive"));
2000 break;
2001
2002 case 'I':
2003 case 's': /* "source" - 'I' is preferred */
2004 input_target = optarg;
2005 break;
2006
2007 case 'O':
2008 case 'd': /* "destination" - 'O' is preferred */
2009 output_target = optarg;
2010 break;
2011
2012 case 'F':
2013 input_target = output_target = optarg;
2014 break;
2015
2016 case 'j':
2017 p = find_section_list (optarg, true);
2018 if (p->remove)
2019 fatal (_("%s both copied and removed"), optarg);
2020 p->copy = true;
2021 sections_copied = true;
2022 break;
2023
2024 case 'R':
2025 p = find_section_list (optarg, true);
2026 if (p->copy)
2027 fatal (_("%s both copied and removed"), optarg);
2028 p->remove = true;
2029 sections_removed = true;
2030 break;
2031
2032 case 'S':
2033 strip_symbols = STRIP_ALL;
2034 break;
2035
2036 case 'g':
2037 strip_symbols = STRIP_DEBUG;
2038 break;
2039
2040 case OPTION_STRIP_UNNEEDED:
2041 strip_symbols = STRIP_UNNEEDED;
2042 break;
2043
2044 case 'K':
2045 add_specific_symbol (optarg, &keep_specific_list);
2046 break;
2047
2048 case 'N':
2049 add_specific_symbol (optarg, &strip_specific_list);
2050 break;
2051
2052 case 'L':
2053 add_specific_symbol (optarg, &localize_specific_list);
2054 break;
2055
2056 case 'G':
2057 add_specific_symbol (optarg, &keepglobal_specific_list);
2058 break;
2059
2060 case 'W':
2061 add_specific_symbol (optarg, &weaken_specific_list);
2062 break;
2063
2064 case 'p':
2065 preserve_dates = true;
2066 break;
2067
2068 case 'x':
2069 discard_locals = LOCALS_ALL;
2070 break;
2071
2072 case 'X':
2073 discard_locals = LOCALS_START_L;
2074 break;
2075
2076 case 'v':
2077 verbose = true;
2078 break;
2079
2080 case 'V':
2081 show_version = true;
2082 break;
2083
2084 case OPTION_WEAKEN:
2085 weaken = true;
2086 break;
2087
2088 case OPTION_ADD_SECTION:
2089 {
2090 const char *s;
2091 struct stat st;
2092 struct section_add *pa;
2093 int len;
2094 char *name;
2095 FILE *f;
2096
2097 s = strchr (optarg, '=');
2098
2099 if (s == NULL)
2100 fatal (_("bad format for %s"), "--add-section");
2101
2102 if (stat (s + 1, & st) < 0)
2103 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
2104
2105 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
2106
2107 len = s - optarg;
2108 name = (char *) xmalloc (len + 1);
2109 strncpy (name, optarg, len);
2110 name[len] = '\0';
2111 pa->name = name;
2112
2113 pa->filename = s + 1;
2114
2115 pa->size = st.st_size;
2116
2117 pa->contents = (bfd_byte *) xmalloc (pa->size);
2118 f = fopen (pa->filename, FOPEN_RB);
2119
2120 if (f == NULL)
2121 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
2122
2123 if (fread (pa->contents, 1, pa->size, f) == 0
2124 || ferror (f))
2125 fatal (_("%s: fread failed"), pa->filename);
2126
2127 fclose (f);
2128
2129 pa->next = add_sections;
2130 add_sections = pa;
2131 }
2132 break;
2133
2134 case OPTION_CHANGE_START:
2135 change_start = parse_vma (optarg, "--change-start");
2136 break;
2137
2138 case OPTION_CHANGE_SECTION_ADDRESS:
2139 case OPTION_CHANGE_SECTION_LMA:
2140 case OPTION_CHANGE_SECTION_VMA:
2141 {
2142 const char *s;
2143 int len;
2144 char *name;
2145 char *option = NULL;
2146 bfd_vma val;
2147 enum change_action what = CHANGE_IGNORE;
2148
2149 switch (c)
2150 {
2151 case OPTION_CHANGE_SECTION_ADDRESS:
2152 option = "--change-section-address";
2153 break;
2154 case OPTION_CHANGE_SECTION_LMA:
2155 option = "--change-section-lma";
2156 break;
2157 case OPTION_CHANGE_SECTION_VMA:
2158 option = "--change-section-vma";
2159 break;
2160 }
2161
2162 s = strchr (optarg, '=');
2163 if (s == NULL)
2164 {
2165 s = strchr (optarg, '+');
2166 if (s == NULL)
2167 {
2168 s = strchr (optarg, '-');
2169 if (s == NULL)
2170 fatal (_("bad format for %s"), option);
2171 }
2172 }
2173
2174 len = s - optarg;
2175 name = (char *) xmalloc (len + 1);
2176 strncpy (name, optarg, len);
2177 name[len] = '\0';
2178
2179 p = find_section_list (name, true);
2180
2181 val = parse_vma (s + 1, option);
2182
2183 switch (*s)
2184 {
2185 case '=': what = CHANGE_SET; break;
2186 case '-': val = - val; /* Drop through. */
2187 case '+': what = CHANGE_MODIFY; break;
2188 }
2189
2190 switch (c)
2191 {
2192 case OPTION_CHANGE_SECTION_ADDRESS:
2193 p->change_vma = what;
2194 p->vma_val = val;
2195 /* Drop through. */
2196
2197 case OPTION_CHANGE_SECTION_LMA:
2198 p->change_lma = what;
2199 p->lma_val = val;
2200 break;
2201
2202 case OPTION_CHANGE_SECTION_VMA:
2203 p->change_vma = what;
2204 p->vma_val = val;
2205 break;
2206 }
2207 }
2208 break;
2209
2210 case OPTION_CHANGE_ADDRESSES:
2211 change_section_address = parse_vma (optarg, "--change-addresses");
2212 change_start = change_section_address;
2213 break;
2214
2215 case OPTION_CHANGE_WARNINGS:
2216 change_warn = true;
2217 break;
2218
2219 case OPTION_CHANGE_LEADING_CHAR:
2220 change_leading_char = true;
2221 break;
2222
2223 case OPTION_DEBUGGING:
2224 convert_debugging = true;
2225 break;
2226
2227 case OPTION_GAP_FILL:
2228 {
2229 bfd_vma gap_fill_vma;
2230
2231 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2232 gap_fill = (bfd_byte) gap_fill_vma;
2233 if ((bfd_vma) gap_fill != gap_fill_vma)
2234 {
2235 char buff[20];
2236
2237 sprintf_vma (buff, gap_fill_vma);
2238
2239 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2240 buff, gap_fill);
2241 }
2242 gap_fill_set = true;
2243 }
2244 break;
2245
2246 case OPTION_NO_CHANGE_WARNINGS:
2247 change_warn = false;
2248 break;
2249
2250 case OPTION_PAD_TO:
2251 pad_to = parse_vma (optarg, "--pad-to");
2252 pad_to_set = true;
2253 break;
2254
2255 case OPTION_REMOVE_LEADING_CHAR:
2256 remove_leading_char = true;
2257 break;
2258
2259 case OPTION_REDEFINE_SYM:
2260 {
2261 /* Push this redefinition onto redefine_symbol_list. */
2262
2263 int len;
2264 const char *s;
2265 const char *nextarg;
2266 char *source, *target;
2267
2268 s = strchr (optarg, '=');
2269 if (s == NULL)
2270 {
2271 fatal (_("bad format for %s"), "--redefine-sym");
2272 }
2273
2274 len = s - optarg;
2275 source = (char *) xmalloc (len + 1);
2276 strncpy (source, optarg, len);
2277 source[len] = '\0';
2278
2279 nextarg = s + 1;
2280 len = strlen (nextarg);
2281 target = (char *) xmalloc (len + 1);
2282 strcpy (target, nextarg);
2283
2284 redefine_list_append (source, target);
2285
2286 free (source);
2287 free (target);
2288 }
2289 break;
2290
2291 case OPTION_SET_SECTION_FLAGS:
2292 {
2293 const char *s;
2294 int len;
2295 char *name;
2296
2297 s = strchr (optarg, '=');
2298 if (s == NULL)
2299 fatal (_("bad format for %s"), "--set-section-flags");
2300
2301 len = s - optarg;
2302 name = (char *) xmalloc (len + 1);
2303 strncpy (name, optarg, len);
2304 name[len] = '\0';
2305
2306 p = find_section_list (name, true);
2307
2308 p->set_flags = true;
2309 p->flags = parse_flags (s + 1);
2310 }
2311 break;
2312
2313 case OPTION_SET_START:
2314 set_start = parse_vma (optarg, "--set-start");
2315 set_start_set = true;
2316 break;
2317
2318 case OPTION_SREC_LEN:
2319 Chunk = parse_vma (optarg, "--srec-len");
2320 break;
2321
2322 case OPTION_SREC_FORCES3:
2323 S3Forced = true;
2324 break;
2325
2326 case OPTION_STRIP_SYMBOLS:
2327 add_specific_symbols (optarg, &strip_specific_list);
2328 break;
2329
2330 case OPTION_KEEP_SYMBOLS:
2331 add_specific_symbols (optarg, &keep_specific_list);
2332 break;
2333
2334 case OPTION_LOCALIZE_SYMBOLS:
2335 add_specific_symbols (optarg, &localize_specific_list);
2336 break;
2337
2338 case OPTION_KEEPGLOBAL_SYMBOLS:
2339 add_specific_symbols (optarg, &keepglobal_specific_list);
2340 break;
2341
2342 case OPTION_WEAKEN_SYMBOLS:
2343 add_specific_symbols (optarg, &weaken_specific_list);
2344 break;
2345
2346 case 0:
2347 break; /* we've been given a long option */
2348
2349 case 'h':
2350 copy_usage (stdout, 0);
2351
2352 default:
2353 copy_usage (stderr, 1);
2354 }
2355 }
2356
2357 if (show_version)
2358 print_version ("objcopy");
2359
2360 if (copy_byte >= interleave)
2361 fatal (_("byte number must be less than interleave"));
2362
2363 if (optind == argc || optind + 2 < argc)
2364 copy_usage (stderr, 1);
2365
2366 input_filename = argv[optind];
2367 if (optind + 1 < argc)
2368 output_filename = argv[optind + 1];
2369
2370 /* Default is to strip no symbols. */
2371 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2372 strip_symbols = STRIP_NONE;
2373
2374 if (output_target == (char *) NULL)
2375 output_target = input_target;
2376
2377 if (binary_architecture != (char *) NULL)
2378 {
2379 if (input_target && strcmp (input_target, "binary") == 0)
2380 {
2381 const bfd_arch_info_type * temp_arch_info;
2382
2383 temp_arch_info = bfd_scan_arch (binary_architecture);
2384
2385 if (temp_arch_info != NULL)
2386 bfd_external_binary_architecture = temp_arch_info->arch;
2387 else
2388 fatal (_("architecture %s unknown"), binary_architecture);
2389 }
2390 else
2391 {
2392 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2393 non_fatal (_(" Argument %s ignored"), binary_architecture);
2394 }
2395 }
2396
2397 if (preserve_dates)
2398 if (stat (input_filename, & statbuf) < 0)
2399 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2400
2401 /* If there is no destination file then create a temp and rename
2402 the result into the input. */
2403
2404 if (output_filename == (char *) NULL)
2405 {
2406 char *tmpname = make_tempname (input_filename);
2407
2408 copy_file (input_filename, tmpname, input_target, output_target);
2409 if (status == 0)
2410 {
2411 if (preserve_dates)
2412 set_times (tmpname, &statbuf);
2413 smart_rename (tmpname, input_filename, preserve_dates);
2414 }
2415 else
2416 unlink (tmpname);
2417 }
2418 else
2419 {
2420 copy_file (input_filename, output_filename, input_target, output_target);
2421 if (status == 0 && preserve_dates)
2422 set_times (output_filename, &statbuf);
2423 }
2424
2425 if (change_warn)
2426 {
2427 for (p = change_sections; p != NULL; p = p->next)
2428 {
2429 if (! p->used)
2430 {
2431 if (p->change_vma != CHANGE_IGNORE)
2432 {
2433 char buff [20];
2434
2435 sprintf_vma (buff, p->vma_val);
2436
2437 /* xgettext:c-format */
2438 non_fatal (_("%s %s%c0x%s never used"),
2439 "--change-section-vma",
2440 p->name,
2441 p->change_vma == CHANGE_SET ? '=' : '+',
2442 buff);
2443 }
2444
2445 if (p->change_lma != CHANGE_IGNORE)
2446 {
2447 char buff [20];
2448
2449 sprintf_vma (buff, p->lma_val);
2450
2451 /* xgettext:c-format */
2452 non_fatal (_("%s %s%c0x%s never used"),
2453 "--change-section-lma",
2454 p->name,
2455 p->change_lma == CHANGE_SET ? '=' : '+',
2456 buff);
2457 }
2458 }
2459 }
2460 }
2461
2462 return 0;
2463 }
2464
2465 int
2466 main (argc, argv)
2467 int argc;
2468 char *argv[];
2469 {
2470 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2471 setlocale (LC_MESSAGES, "");
2472 #endif
2473 bindtextdomain (PACKAGE, LOCALEDIR);
2474 textdomain (PACKAGE);
2475
2476 program_name = argv[0];
2477 xmalloc_set_program_name (program_name);
2478
2479 START_PROGRESS (program_name, 0);
2480
2481 strip_symbols = STRIP_UNDEF;
2482 discard_locals = LOCALS_UNDEF;
2483
2484 bfd_init ();
2485 set_default_bfd_target ();
2486
2487 if (is_strip < 0)
2488 {
2489 int i = strlen (program_name);
2490 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2491 /* Drop the .exe suffix, if any. */
2492 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2493 {
2494 i -= 4;
2495 program_name[i] = '\0';
2496 }
2497 #endif
2498 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2499 }
2500
2501 if (is_strip)
2502 strip_main (argc, argv);
2503 else
2504 copy_main (argc, argv);
2505
2506 END_PROGRESS (program_name);
2507
2508 return status;
2509 }