Remove patch accidentally checked in with readelf.c patch
[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 else if (sections_removed)
1620 {
1621 /* Remove relocations which are against symbols
1622 in sections that have been removed, unless
1623 the symbols are going to be preserved. */
1624 arelent ** temp_relpp;
1625 asymbol * sym;
1626 long temp_relcount = 0;
1627 long i;
1628
1629 temp_relpp = (arelent **) xmalloc (relsize);
1630 for (i = 0; i < relcount; i++)
1631 {
1632 sym = *relpp [i]->sym_ptr_ptr;
1633
1634 /* FIXME: Should we warn about deleted relocs ? */
1635 if (is_specified_symbol (bfd_asymbol_name (sym),
1636 keep_specific_list)
1637 || bfd_get_output_section (sym) != NULL)
1638 temp_relpp [temp_relcount++] = relpp [i];
1639 }
1640
1641 relcount = temp_relcount;
1642 free (relpp);
1643 relpp = temp_relpp;
1644 }
1645
1646 bfd_set_reloc (obfd, osection,
1647 (relcount == 0 ? (arelent **) NULL : relpp), relcount);
1648 }
1649
1650 isection->_cooked_size = isection->_raw_size;
1651 isection->reloc_done = true;
1652
1653 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
1654 {
1655 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1656
1657 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1658 size))
1659 RETURN_NONFATAL (bfd_get_filename (ibfd));
1660
1661 if (copy_byte >= 0)
1662 filter_bytes (memhunk, &size);
1663
1664 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1665 size))
1666 RETURN_NONFATAL (bfd_get_filename (obfd));
1667
1668 free (memhunk);
1669 }
1670 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
1671 {
1672 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1673
1674 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1675 flag--they can just remove the section entirely and add it
1676 back again. However, we do permit them to turn on the
1677 SEC_HAS_CONTENTS flag, and take it to mean that the section
1678 contents should be zeroed out. */
1679
1680 memset (memhunk, 0, size);
1681 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1682 size))
1683 RETURN_NONFATAL (bfd_get_filename (obfd));
1684 free (memhunk);
1685 }
1686 }
1687
1688 /* Get all the sections. This is used when --gap-fill or --pad-to is
1689 used. */
1690
1691 static void
1692 get_sections (obfd, osection, secppparg)
1693 bfd *obfd ATTRIBUTE_UNUSED;
1694 asection *osection;
1695 PTR secppparg;
1696 {
1697 asection ***secppp = (asection ***) secppparg;
1698
1699 **secppp = osection;
1700 ++(*secppp);
1701 }
1702
1703 /* Sort sections by VMA. This is called via qsort, and is used when
1704 --gap-fill or --pad-to is used. We force non loadable or empty
1705 sections to the front, where they are easier to ignore. */
1706
1707 static int
1708 compare_section_lma (arg1, arg2)
1709 const PTR arg1;
1710 const PTR arg2;
1711 {
1712 const asection **sec1 = (const asection **) arg1;
1713 const asection **sec2 = (const asection **) arg2;
1714 flagword flags1, flags2;
1715
1716 /* Sort non loadable sections to the front. */
1717 flags1 = (*sec1)->flags;
1718 flags2 = (*sec2)->flags;
1719 if ((flags1 & SEC_HAS_CONTENTS) == 0
1720 || (flags1 & SEC_LOAD) == 0)
1721 {
1722 if ((flags2 & SEC_HAS_CONTENTS) != 0
1723 && (flags2 & SEC_LOAD) != 0)
1724 return -1;
1725 }
1726 else
1727 {
1728 if ((flags2 & SEC_HAS_CONTENTS) == 0
1729 || (flags2 & SEC_LOAD) == 0)
1730 return 1;
1731 }
1732
1733 /* Sort sections by LMA. */
1734 if ((*sec1)->lma > (*sec2)->lma)
1735 return 1;
1736 else if ((*sec1)->lma < (*sec2)->lma)
1737 return -1;
1738
1739 /* Sort sections with the same LMA by size. */
1740 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1741 return 1;
1742 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1743 return -1;
1744
1745 return 0;
1746 }
1747
1748 /* Mark all the symbols which will be used in output relocations with
1749 the BSF_KEEP flag so that those symbols will not be stripped.
1750
1751 Ignore relocations which will not appear in the output file. */
1752
1753 static void
1754 mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
1755 bfd *ibfd;
1756 sec_ptr isection;
1757 PTR symbolsarg;
1758 {
1759 asymbol **symbols = (asymbol **) symbolsarg;
1760 long relsize;
1761 arelent **relpp;
1762 long relcount, i;
1763
1764 /* Ignore an input section with no corresponding output section. */
1765 if (isection->output_section == NULL)
1766 return;
1767
1768 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1769 if (relsize < 0)
1770 bfd_fatal (bfd_get_filename (ibfd));
1771
1772 if (relsize == 0)
1773 return;
1774
1775 relpp = (arelent **) xmalloc (relsize);
1776 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
1777 if (relcount < 0)
1778 bfd_fatal (bfd_get_filename (ibfd));
1779
1780 /* Examine each symbol used in a relocation. If it's not one of the
1781 special bfd section symbols, then mark it with BSF_KEEP. */
1782 for (i = 0; i < relcount; i++)
1783 {
1784 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1785 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1786 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
1787 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1788 }
1789
1790 if (relpp != NULL)
1791 free (relpp);
1792 }
1793
1794 /* Write out debugging information. */
1795
1796 static boolean
1797 write_debugging_info (obfd, dhandle, symcountp, symppp)
1798 bfd *obfd;
1799 PTR dhandle;
1800 long *symcountp ATTRIBUTE_UNUSED;
1801 asymbol ***symppp ATTRIBUTE_UNUSED;
1802 {
1803 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1804 return write_ieee_debugging_info (obfd, dhandle);
1805
1806 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1807 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1808 {
1809 bfd_byte *syms, *strings;
1810 bfd_size_type symsize, stringsize;
1811 asection *stabsec, *stabstrsec;
1812
1813 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1814 &symsize, &strings,
1815 &stringsize))
1816 return false;
1817
1818 stabsec = bfd_make_section (obfd, ".stab");
1819 stabstrsec = bfd_make_section (obfd, ".stabstr");
1820 if (stabsec == NULL
1821 || stabstrsec == NULL
1822 || ! bfd_set_section_size (obfd, stabsec, symsize)
1823 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1824 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1825 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1826 || ! bfd_set_section_flags (obfd, stabsec,
1827 (SEC_HAS_CONTENTS
1828 | SEC_READONLY
1829 | SEC_DEBUGGING))
1830 || ! bfd_set_section_flags (obfd, stabstrsec,
1831 (SEC_HAS_CONTENTS
1832 | SEC_READONLY
1833 | SEC_DEBUGGING)))
1834 {
1835 non_fatal (_("%s: can't create debugging section: %s"),
1836 bfd_get_filename (obfd),
1837 bfd_errmsg (bfd_get_error ()));
1838 return false;
1839 }
1840
1841 /* We can get away with setting the section contents now because
1842 the next thing the caller is going to do is copy over the
1843 real sections. We may someday have to split the contents
1844 setting out of this function. */
1845 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1846 symsize)
1847 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1848 (file_ptr) 0, stringsize))
1849 {
1850 non_fatal (_("%s: can't set debugging section contents: %s"),
1851 bfd_get_filename (obfd),
1852 bfd_errmsg (bfd_get_error ()));
1853 return false;
1854 }
1855
1856 return true;
1857 }
1858
1859 non_fatal (_("%s: don't know how to write debugging information for %s"),
1860 bfd_get_filename (obfd), bfd_get_target (obfd));
1861 return false;
1862 }
1863
1864 static int
1865 strip_main (argc, argv)
1866 int argc;
1867 char *argv[];
1868 {
1869 char *input_target = NULL, *output_target = NULL;
1870 boolean show_version = false;
1871 int c, i;
1872 struct section_list *p;
1873 char *output_file = NULL;
1874
1875 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXVv",
1876 strip_options, (int *) 0)) != EOF)
1877 {
1878 switch (c)
1879 {
1880 case 'I':
1881 input_target = optarg;
1882 break;
1883 case 'O':
1884 output_target = optarg;
1885 break;
1886 case 'F':
1887 input_target = output_target = optarg;
1888 break;
1889 case 'R':
1890 p = find_section_list (optarg, true);
1891 p->remove = true;
1892 sections_removed = true;
1893 break;
1894 case 's':
1895 strip_symbols = STRIP_ALL;
1896 break;
1897 case 'S':
1898 case 'g':
1899 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
1900 strip_symbols = STRIP_DEBUG;
1901 break;
1902 case OPTION_STRIP_UNNEEDED:
1903 strip_symbols = STRIP_UNNEEDED;
1904 break;
1905 case 'K':
1906 add_specific_symbol (optarg, &keep_specific_list);
1907 break;
1908 case 'N':
1909 add_specific_symbol (optarg, &strip_specific_list);
1910 break;
1911 case 'o':
1912 output_file = optarg;
1913 break;
1914 case 'p':
1915 preserve_dates = true;
1916 break;
1917 case 'x':
1918 discard_locals = LOCALS_ALL;
1919 break;
1920 case 'X':
1921 discard_locals = LOCALS_START_L;
1922 break;
1923 case 'v':
1924 verbose = true;
1925 break;
1926 case 'V':
1927 show_version = true;
1928 break;
1929 case 0:
1930 break; /* we've been given a long option */
1931 case 'h':
1932 strip_usage (stdout, 0);
1933 default:
1934 strip_usage (stderr, 1);
1935 }
1936 }
1937
1938 if (show_version)
1939 print_version ("strip");
1940
1941 /* Default is to strip all symbols. */
1942 if (strip_symbols == STRIP_UNDEF
1943 && discard_locals == LOCALS_UNDEF
1944 && strip_specific_list == NULL)
1945 strip_symbols = STRIP_ALL;
1946
1947 if (output_target == (char *) NULL)
1948 output_target = input_target;
1949
1950 i = optind;
1951 if (i == argc
1952 || (output_file != NULL && (i + 1) < argc))
1953 strip_usage (stderr, 1);
1954
1955 for (; i < argc; i++)
1956 {
1957 int hold_status = status;
1958 struct stat statbuf;
1959 char *tmpname;
1960
1961 if (preserve_dates)
1962 {
1963 if (stat (argv[i], &statbuf) < 0)
1964 {
1965 non_fatal (_("%s: cannot stat: %s"), argv[i], strerror (errno));
1966 continue;
1967 }
1968 }
1969
1970 if (output_file != NULL)
1971 tmpname = output_file;
1972 else
1973 tmpname = make_tempname (argv[i]);
1974 status = 0;
1975
1976 copy_file (argv[i], tmpname, input_target, output_target);
1977 if (status == 0)
1978 {
1979 if (preserve_dates)
1980 set_times (tmpname, &statbuf);
1981 if (output_file == NULL)
1982 smart_rename (tmpname, argv[i], preserve_dates);
1983 status = hold_status;
1984 }
1985 else
1986 unlink (tmpname);
1987 if (output_file == NULL)
1988 free (tmpname);
1989 }
1990
1991 return 0;
1992 }
1993
1994 static int
1995 copy_main (argc, argv)
1996 int argc;
1997 char *argv[];
1998 {
1999 char * binary_architecture = NULL;
2000 char *input_filename = NULL, *output_filename = NULL;
2001 char *input_target = NULL, *output_target = NULL;
2002 boolean show_version = false;
2003 boolean change_warn = true;
2004 int c;
2005 struct section_list *p;
2006 struct stat statbuf;
2007
2008 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXVvW:",
2009 copy_options, (int *) 0)) != EOF)
2010 {
2011 switch (c)
2012 {
2013 case 'b':
2014 copy_byte = atoi (optarg);
2015 if (copy_byte < 0)
2016 fatal (_("byte number must be non-negative"));
2017 break;
2018
2019 case 'B':
2020 binary_architecture = optarg;
2021 break;
2022
2023 case 'i':
2024 interleave = atoi (optarg);
2025 if (interleave < 1)
2026 fatal (_("interleave must be positive"));
2027 break;
2028
2029 case 'I':
2030 case 's': /* "source" - 'I' is preferred */
2031 input_target = optarg;
2032 break;
2033
2034 case 'O':
2035 case 'd': /* "destination" - 'O' is preferred */
2036 output_target = optarg;
2037 break;
2038
2039 case 'F':
2040 input_target = output_target = optarg;
2041 break;
2042
2043 case 'j':
2044 p = find_section_list (optarg, true);
2045 if (p->remove)
2046 fatal (_("%s both copied and removed"), optarg);
2047 p->copy = true;
2048 sections_copied = true;
2049 break;
2050
2051 case 'R':
2052 p = find_section_list (optarg, true);
2053 if (p->copy)
2054 fatal (_("%s both copied and removed"), optarg);
2055 p->remove = true;
2056 sections_removed = true;
2057 break;
2058
2059 case 'S':
2060 strip_symbols = STRIP_ALL;
2061 break;
2062
2063 case 'g':
2064 strip_symbols = STRIP_DEBUG;
2065 break;
2066
2067 case OPTION_STRIP_UNNEEDED:
2068 strip_symbols = STRIP_UNNEEDED;
2069 break;
2070
2071 case 'K':
2072 add_specific_symbol (optarg, &keep_specific_list);
2073 break;
2074
2075 case 'N':
2076 add_specific_symbol (optarg, &strip_specific_list);
2077 break;
2078
2079 case 'L':
2080 add_specific_symbol (optarg, &localize_specific_list);
2081 break;
2082
2083 case 'G':
2084 add_specific_symbol (optarg, &keepglobal_specific_list);
2085 break;
2086
2087 case 'W':
2088 add_specific_symbol (optarg, &weaken_specific_list);
2089 break;
2090
2091 case 'p':
2092 preserve_dates = true;
2093 break;
2094
2095 case 'x':
2096 discard_locals = LOCALS_ALL;
2097 break;
2098
2099 case 'X':
2100 discard_locals = LOCALS_START_L;
2101 break;
2102
2103 case 'v':
2104 verbose = true;
2105 break;
2106
2107 case 'V':
2108 show_version = true;
2109 break;
2110
2111 case OPTION_WEAKEN:
2112 weaken = true;
2113 break;
2114
2115 case OPTION_ADD_SECTION:
2116 {
2117 const char *s;
2118 struct stat st;
2119 struct section_add *pa;
2120 int len;
2121 char *name;
2122 FILE *f;
2123
2124 s = strchr (optarg, '=');
2125
2126 if (s == NULL)
2127 fatal (_("bad format for %s"), "--add-section");
2128
2129 if (stat (s + 1, & st) < 0)
2130 fatal (_("cannot stat: %s: %s"), s + 1, strerror (errno));
2131
2132 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
2133
2134 len = s - optarg;
2135 name = (char *) xmalloc (len + 1);
2136 strncpy (name, optarg, len);
2137 name[len] = '\0';
2138 pa->name = name;
2139
2140 pa->filename = s + 1;
2141
2142 pa->size = st.st_size;
2143
2144 pa->contents = (bfd_byte *) xmalloc (pa->size);
2145 f = fopen (pa->filename, FOPEN_RB);
2146
2147 if (f == NULL)
2148 fatal (_("cannot open: %s: %s"), pa->filename, strerror (errno));
2149
2150 if (fread (pa->contents, 1, pa->size, f) == 0
2151 || ferror (f))
2152 fatal (_("%s: fread failed"), pa->filename);
2153
2154 fclose (f);
2155
2156 pa->next = add_sections;
2157 add_sections = pa;
2158 }
2159 break;
2160
2161 case OPTION_CHANGE_START:
2162 change_start = parse_vma (optarg, "--change-start");
2163 break;
2164
2165 case OPTION_CHANGE_SECTION_ADDRESS:
2166 case OPTION_CHANGE_SECTION_LMA:
2167 case OPTION_CHANGE_SECTION_VMA:
2168 {
2169 const char *s;
2170 int len;
2171 char *name;
2172 char *option = NULL;
2173 bfd_vma val;
2174 enum change_action what = CHANGE_IGNORE;
2175
2176 switch (c)
2177 {
2178 case OPTION_CHANGE_SECTION_ADDRESS:
2179 option = "--change-section-address";
2180 break;
2181 case OPTION_CHANGE_SECTION_LMA:
2182 option = "--change-section-lma";
2183 break;
2184 case OPTION_CHANGE_SECTION_VMA:
2185 option = "--change-section-vma";
2186 break;
2187 }
2188
2189 s = strchr (optarg, '=');
2190 if (s == NULL)
2191 {
2192 s = strchr (optarg, '+');
2193 if (s == NULL)
2194 {
2195 s = strchr (optarg, '-');
2196 if (s == NULL)
2197 fatal (_("bad format for %s"), option);
2198 }
2199 }
2200
2201 len = s - optarg;
2202 name = (char *) xmalloc (len + 1);
2203 strncpy (name, optarg, len);
2204 name[len] = '\0';
2205
2206 p = find_section_list (name, true);
2207
2208 val = parse_vma (s + 1, option);
2209
2210 switch (*s)
2211 {
2212 case '=': what = CHANGE_SET; break;
2213 case '-': val = - val; /* Drop through. */
2214 case '+': what = CHANGE_MODIFY; break;
2215 }
2216
2217 switch (c)
2218 {
2219 case OPTION_CHANGE_SECTION_ADDRESS:
2220 p->change_vma = what;
2221 p->vma_val = val;
2222 /* Drop through. */
2223
2224 case OPTION_CHANGE_SECTION_LMA:
2225 p->change_lma = what;
2226 p->lma_val = val;
2227 break;
2228
2229 case OPTION_CHANGE_SECTION_VMA:
2230 p->change_vma = what;
2231 p->vma_val = val;
2232 break;
2233 }
2234 }
2235 break;
2236
2237 case OPTION_CHANGE_ADDRESSES:
2238 change_section_address = parse_vma (optarg, "--change-addresses");
2239 change_start = change_section_address;
2240 break;
2241
2242 case OPTION_CHANGE_WARNINGS:
2243 change_warn = true;
2244 break;
2245
2246 case OPTION_CHANGE_LEADING_CHAR:
2247 change_leading_char = true;
2248 break;
2249
2250 case OPTION_DEBUGGING:
2251 convert_debugging = true;
2252 break;
2253
2254 case OPTION_GAP_FILL:
2255 {
2256 bfd_vma gap_fill_vma;
2257
2258 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2259 gap_fill = (bfd_byte) gap_fill_vma;
2260 if ((bfd_vma) gap_fill != gap_fill_vma)
2261 {
2262 char buff[20];
2263
2264 sprintf_vma (buff, gap_fill_vma);
2265
2266 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
2267 buff, gap_fill);
2268 }
2269 gap_fill_set = true;
2270 }
2271 break;
2272
2273 case OPTION_NO_CHANGE_WARNINGS:
2274 change_warn = false;
2275 break;
2276
2277 case OPTION_PAD_TO:
2278 pad_to = parse_vma (optarg, "--pad-to");
2279 pad_to_set = true;
2280 break;
2281
2282 case OPTION_REMOVE_LEADING_CHAR:
2283 remove_leading_char = true;
2284 break;
2285
2286 case OPTION_REDEFINE_SYM:
2287 {
2288 /* Push this redefinition onto redefine_symbol_list. */
2289
2290 int len;
2291 const char *s;
2292 const char *nextarg;
2293 char *source, *target;
2294
2295 s = strchr (optarg, '=');
2296 if (s == NULL)
2297 {
2298 fatal (_("bad format for %s"), "--redefine-sym");
2299 }
2300
2301 len = s - optarg;
2302 source = (char *) xmalloc (len + 1);
2303 strncpy (source, optarg, len);
2304 source[len] = '\0';
2305
2306 nextarg = s + 1;
2307 len = strlen (nextarg);
2308 target = (char *) xmalloc (len + 1);
2309 strcpy (target, nextarg);
2310
2311 redefine_list_append (source, target);
2312
2313 free (source);
2314 free (target);
2315 }
2316 break;
2317
2318 case OPTION_SET_SECTION_FLAGS:
2319 {
2320 const char *s;
2321 int len;
2322 char *name;
2323
2324 s = strchr (optarg, '=');
2325 if (s == NULL)
2326 fatal (_("bad format for %s"), "--set-section-flags");
2327
2328 len = s - optarg;
2329 name = (char *) xmalloc (len + 1);
2330 strncpy (name, optarg, len);
2331 name[len] = '\0';
2332
2333 p = find_section_list (name, true);
2334
2335 p->set_flags = true;
2336 p->flags = parse_flags (s + 1);
2337 }
2338 break;
2339
2340 case OPTION_SET_START:
2341 set_start = parse_vma (optarg, "--set-start");
2342 set_start_set = true;
2343 break;
2344
2345 case OPTION_SREC_LEN:
2346 Chunk = parse_vma (optarg, "--srec-len");
2347 break;
2348
2349 case OPTION_SREC_FORCES3:
2350 S3Forced = true;
2351 break;
2352
2353 case OPTION_STRIP_SYMBOLS:
2354 add_specific_symbols (optarg, &strip_specific_list);
2355 break;
2356
2357 case OPTION_KEEP_SYMBOLS:
2358 add_specific_symbols (optarg, &keep_specific_list);
2359 break;
2360
2361 case OPTION_LOCALIZE_SYMBOLS:
2362 add_specific_symbols (optarg, &localize_specific_list);
2363 break;
2364
2365 case OPTION_KEEPGLOBAL_SYMBOLS:
2366 add_specific_symbols (optarg, &keepglobal_specific_list);
2367 break;
2368
2369 case OPTION_WEAKEN_SYMBOLS:
2370 add_specific_symbols (optarg, &weaken_specific_list);
2371 break;
2372
2373 case 0:
2374 break; /* we've been given a long option */
2375
2376 case 'h':
2377 copy_usage (stdout, 0);
2378
2379 default:
2380 copy_usage (stderr, 1);
2381 }
2382 }
2383
2384 if (show_version)
2385 print_version ("objcopy");
2386
2387 if (copy_byte >= interleave)
2388 fatal (_("byte number must be less than interleave"));
2389
2390 if (optind == argc || optind + 2 < argc)
2391 copy_usage (stderr, 1);
2392
2393 input_filename = argv[optind];
2394 if (optind + 1 < argc)
2395 output_filename = argv[optind + 1];
2396
2397 /* Default is to strip no symbols. */
2398 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
2399 strip_symbols = STRIP_NONE;
2400
2401 if (output_target == (char *) NULL)
2402 output_target = input_target;
2403
2404 if (binary_architecture != (char *) NULL)
2405 {
2406 if (input_target && strcmp (input_target, "binary") == 0)
2407 {
2408 const bfd_arch_info_type * temp_arch_info;
2409
2410 temp_arch_info = bfd_scan_arch (binary_architecture);
2411
2412 if (temp_arch_info != NULL)
2413 bfd_external_binary_architecture = temp_arch_info->arch;
2414 else
2415 fatal (_("architecture %s unknown"), binary_architecture);
2416 }
2417 else
2418 {
2419 non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
2420 non_fatal (_(" Argument %s ignored"), binary_architecture);
2421 }
2422 }
2423
2424 if (preserve_dates)
2425 if (stat (input_filename, & statbuf) < 0)
2426 fatal (_("Cannot stat: %s: %s"), input_filename, strerror (errno));
2427
2428 /* If there is no destination file then create a temp and rename
2429 the result into the input. */
2430
2431 if (output_filename == (char *) NULL)
2432 {
2433 char *tmpname = make_tempname (input_filename);
2434
2435 copy_file (input_filename, tmpname, input_target, output_target);
2436 if (status == 0)
2437 {
2438 if (preserve_dates)
2439 set_times (tmpname, &statbuf);
2440 smart_rename (tmpname, input_filename, preserve_dates);
2441 }
2442 else
2443 unlink (tmpname);
2444 }
2445 else
2446 {
2447 copy_file (input_filename, output_filename, input_target, output_target);
2448 if (status == 0 && preserve_dates)
2449 set_times (output_filename, &statbuf);
2450 }
2451
2452 if (change_warn)
2453 {
2454 for (p = change_sections; p != NULL; p = p->next)
2455 {
2456 if (! p->used)
2457 {
2458 if (p->change_vma != CHANGE_IGNORE)
2459 {
2460 char buff [20];
2461
2462 sprintf_vma (buff, p->vma_val);
2463
2464 /* xgettext:c-format */
2465 non_fatal (_("%s %s%c0x%s never used"),
2466 "--change-section-vma",
2467 p->name,
2468 p->change_vma == CHANGE_SET ? '=' : '+',
2469 buff);
2470 }
2471
2472 if (p->change_lma != CHANGE_IGNORE)
2473 {
2474 char buff [20];
2475
2476 sprintf_vma (buff, p->lma_val);
2477
2478 /* xgettext:c-format */
2479 non_fatal (_("%s %s%c0x%s never used"),
2480 "--change-section-lma",
2481 p->name,
2482 p->change_lma == CHANGE_SET ? '=' : '+',
2483 buff);
2484 }
2485 }
2486 }
2487 }
2488
2489 return 0;
2490 }
2491
2492 int
2493 main (argc, argv)
2494 int argc;
2495 char *argv[];
2496 {
2497 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
2498 setlocale (LC_MESSAGES, "");
2499 #endif
2500 bindtextdomain (PACKAGE, LOCALEDIR);
2501 textdomain (PACKAGE);
2502
2503 program_name = argv[0];
2504 xmalloc_set_program_name (program_name);
2505
2506 START_PROGRESS (program_name, 0);
2507
2508 strip_symbols = STRIP_UNDEF;
2509 discard_locals = LOCALS_UNDEF;
2510
2511 bfd_init ();
2512 set_default_bfd_target ();
2513
2514 if (is_strip < 0)
2515 {
2516 int i = strlen (program_name);
2517 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2518 /* Drop the .exe suffix, if any. */
2519 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
2520 {
2521 i -= 4;
2522 program_name[i] = '\0';
2523 }
2524 #endif
2525 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
2526 }
2527
2528 if (is_strip)
2529 strip_main (argc, argv);
2530 else
2531 copy_main (argc, argv);
2532
2533 END_PROGRESS (program_name);
2534
2535 return status;
2536 }
This page took 0.085514 seconds and 5 git commands to generate.