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