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