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