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