PR binutils/13482
[deliverable/binutils-gdb.git] / binutils / objcopy.c
CommitLineData
252b5132 1/* objcopy.c -- copy object file from input to output, optionally massaging it.
8c2bc687 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
19094d10 3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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
32866df7 10 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
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
b43b5d5f
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
252b5132 22\f
3db64b00 23#include "sysdep.h"
252b5132
RH
24#include "bfd.h"
25#include "progress.h"
252b5132
RH
26#include "getopt.h"
27#include "libiberty.h"
3db64b00 28#include "bucomm.h"
252b5132 29#include "budbg.h"
5af11cab 30#include "filenames.h"
5fe11841 31#include "fnmatch.h"
f0312d39 32#include "elf-bfd.h"
252b5132 33#include <sys/stat.h>
6e2c86ac 34#include "libbfd.h"
0408dee6
DK
35#include "coff/internal.h"
36#include "libcoff.h"
252b5132 37
92dd4511
L
38/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
39 header in generic PE code. */
40#include "coff/i386.h"
41#include "coff/pe.h"
42
43static bfd_vma pe_file_alignment = (bfd_vma) -1;
44static bfd_vma pe_heap_commit = (bfd_vma) -1;
45static bfd_vma pe_heap_reserve = (bfd_vma) -1;
46static bfd_vma pe_image_base = (bfd_vma) -1;
47static bfd_vma pe_section_alignment = (bfd_vma) -1;
48static bfd_vma pe_stack_commit = (bfd_vma) -1;
49static bfd_vma pe_stack_reserve = (bfd_vma) -1;
50static short pe_subsystem = -1;
51static short pe_major_subsystem_version = -1;
52static short pe_minor_subsystem_version = -1;
53
047c9024 54struct is_specified_symbol_predicate_data
252b5132 55{
047c9024
NC
56 const char *name;
57 bfd_boolean found;
252b5132
RH
58};
59
57938635
AM
60/* A list to support redefine_sym. */
61struct redefine_node
62{
63 char *source;
64 char *target;
65 struct redefine_node *next;
66};
67
594ef5db
NC
68typedef struct section_rename
69{
70 const char * old_name;
71 const char * new_name;
72 flagword flags;
73 struct section_rename * next;
74}
75section_rename;
76
77/* List of sections to be renamed. */
84e2f313 78static section_rename *section_rename_list;
594ef5db 79
84e2f313
NC
80static asymbol **isympp = NULL; /* Input symbols. */
81static asymbol **osympp = NULL; /* Output symbols that survive stripping. */
252b5132 82
b7dd81f7 83/* If `copy_byte' >= 0, copy 'copy_width' byte(s) of every `interleave' bytes. */
252b5132 84static int copy_byte = -1;
b7dd81f7
NC
85static int interleave = 0; /* Initialised to 4 in copy_main(). */
86static int copy_width = 1;
252b5132 87
b34976b6
AM
88static bfd_boolean verbose; /* Print file and target names. */
89static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
252b5132
RH
90static int status = 0; /* Exit status. */
91
92enum strip_action
93 {
94 STRIP_UNDEF,
84e2f313
NC
95 STRIP_NONE, /* Don't strip. */
96 STRIP_DEBUG, /* Strip all debugger symbols. */
97 STRIP_UNNEEDED, /* Strip unnecessary symbols. */
ed1653a7 98 STRIP_NONDEBUG, /* Strip everything but debug info. */
84e2f313 99 STRIP_ALL /* Strip all symbols. */
252b5132
RH
100 };
101
0af11b59 102/* Which symbols to remove. */
252b5132
RH
103static enum strip_action strip_symbols;
104
105enum locals_action
106 {
107 LOCALS_UNDEF,
84e2f313
NC
108 LOCALS_START_L, /* Discard locals starting with L. */
109 LOCALS_ALL /* Discard all locals. */
252b5132
RH
110 };
111
112/* Which local symbols to remove. Overrides STRIP_ALL. */
113static enum locals_action discard_locals;
114
115/* What kind of change to perform. */
116enum change_action
117{
118 CHANGE_IGNORE,
119 CHANGE_MODIFY,
120 CHANGE_SET
121};
122
123/* Structure used to hold lists of sections and actions to take. */
124struct section_list
125{
b34976b6
AM
126 struct section_list * next; /* Next section to change. */
127 const char * name; /* Section name. */
128 bfd_boolean used; /* Whether this entry was used. */
129 bfd_boolean remove; /* Whether to remove this section. */
130 bfd_boolean copy; /* Whether to copy this section. */
131 enum change_action change_vma;/* Whether to change or set VMA. */
132 bfd_vma vma_val; /* Amount to change by or set to. */
133 enum change_action change_lma;/* Whether to change or set LMA. */
134 bfd_vma lma_val; /* Amount to change by or set to. */
135 bfd_boolean set_flags; /* Whether to set the section flags. */
136 flagword flags; /* What to set the section flags to. */
252b5132
RH
137};
138
139static struct section_list *change_sections;
594ef5db 140
b34976b6
AM
141/* TRUE if some sections are to be removed. */
142static bfd_boolean sections_removed;
594ef5db 143
b34976b6
AM
144/* TRUE if only some sections are to be copied. */
145static bfd_boolean sections_copied;
252b5132
RH
146
147/* Changes to the start address. */
148static bfd_vma change_start = 0;
b34976b6 149static bfd_boolean set_start_set = FALSE;
252b5132
RH
150static bfd_vma set_start;
151
152/* Changes to section addresses. */
153static bfd_vma change_section_address = 0;
154
155/* Filling gaps between sections. */
b34976b6 156static bfd_boolean gap_fill_set = FALSE;
252b5132
RH
157static bfd_byte gap_fill = 0;
158
159/* Pad to a given address. */
b34976b6 160static bfd_boolean pad_to_set = FALSE;
252b5132
RH
161static bfd_vma pad_to;
162
f9d4ad2a
NC
163/* Use alternative machine code? */
164static unsigned long use_alt_mach_code = 0;
1ae8b3d2 165
4087920c
MR
166/* Output BFD flags user wants to set or clear */
167static flagword bfd_flags_to_set;
168static flagword bfd_flags_to_clear;
169
252b5132 170/* List of sections to add. */
252b5132
RH
171struct section_add
172{
173 /* Next section to add. */
174 struct section_add *next;
175 /* Name of section to add. */
176 const char *name;
177 /* Name of file holding section contents. */
178 const char *filename;
179 /* Size of file. */
180 size_t size;
181 /* Contents of file. */
182 bfd_byte *contents;
183 /* BFD section, after it has been added. */
184 asection *section;
185};
186
594ef5db 187/* List of sections to add to the output BFD. */
252b5132
RH
188static struct section_add *add_sections;
189
2593f09a
NC
190/* If non-NULL the argument to --add-gnu-debuglink.
191 This should be the filename to store in the .gnu_debuglink section. */
192static const char * gnu_debuglink_filename = NULL;
193
252b5132 194/* Whether to convert debugging information. */
b34976b6 195static bfd_boolean convert_debugging = FALSE;
252b5132 196
4a114e3e
L
197/* Whether to compress/decompress DWARF debug sections. */
198static enum
199{
200 nothing,
201 compress,
202 decompress
203} do_debug_sections = nothing;
204
252b5132 205/* Whether to change the leading character in symbol names. */
b34976b6 206static bfd_boolean change_leading_char = FALSE;
252b5132
RH
207
208/* Whether to remove the leading character from global symbol names. */
b34976b6 209static bfd_boolean remove_leading_char = FALSE;
252b5132 210
aaad4cf3 211/* Whether to permit wildcard in symbol comparison. */
5fe11841
NC
212static bfd_boolean wildcard = FALSE;
213
d58c2e3a
RS
214/* True if --localize-hidden is in effect. */
215static bfd_boolean localize_hidden = FALSE;
216
16b2b71c
NC
217/* List of symbols to strip, keep, localize, keep-global, weaken,
218 or redefine. */
047c9024
NC
219static htab_t strip_specific_htab = NULL;
220static htab_t strip_unneeded_htab = NULL;
221static htab_t keep_specific_htab = NULL;
222static htab_t localize_specific_htab = NULL;
223static htab_t globalize_specific_htab = NULL;
224static htab_t keepglobal_specific_htab = NULL;
225static htab_t weaken_specific_htab = NULL;
57938635 226static struct redefine_node *redefine_sym_list = NULL;
252b5132 227
b34976b6
AM
228/* If this is TRUE, we weaken global symbols (set BSF_WEAK). */
229static bfd_boolean weaken = FALSE;
252b5132 230
1637cd90
JB
231/* If this is TRUE, we retain BSF_FILE symbols. */
232static bfd_boolean keep_file_symbols = FALSE;
233
d7fb0dd2
NC
234/* Prefix symbols/sections. */
235static char *prefix_symbols_string = 0;
236static char *prefix_sections_string = 0;
237static char *prefix_alloc_sections_string = 0;
238
d3e52d40
RS
239/* True if --extract-symbol was passed on the command line. */
240static bfd_boolean extract_symbol = FALSE;
241
9e48b4c6
NC
242/* If `reverse_bytes' is nonzero, then reverse the order of every chunk
243 of <reverse_bytes> bytes within each output section. */
244static int reverse_bytes = 0;
245
0408dee6
DK
246/* For Coff objects, we may want to allow or disallow long section names,
247 or preserve them where found in the inputs. Debug info relies on them. */
248enum long_section_name_handling
249 {
250 DISABLE,
251 ENABLE,
252 KEEP
253 };
254
255/* The default long section handling mode is to preserve them.
256 This is also the only behaviour for 'strip'. */
257static enum long_section_name_handling long_section_names = KEEP;
9e48b4c6 258
252b5132 259/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
84e2f313
NC
260enum command_line_switch
261 {
262 OPTION_ADD_SECTION=150,
263 OPTION_CHANGE_ADDRESSES,
264 OPTION_CHANGE_LEADING_CHAR,
265 OPTION_CHANGE_START,
266 OPTION_CHANGE_SECTION_ADDRESS,
267 OPTION_CHANGE_SECTION_LMA,
268 OPTION_CHANGE_SECTION_VMA,
269 OPTION_CHANGE_WARNINGS,
4a114e3e 270 OPTION_COMPRESS_DEBUG_SECTIONS,
84e2f313 271 OPTION_DEBUGGING,
4a114e3e 272 OPTION_DECOMPRESS_DEBUG_SECTIONS,
84e2f313
NC
273 OPTION_GAP_FILL,
274 OPTION_NO_CHANGE_WARNINGS,
275 OPTION_PAD_TO,
276 OPTION_REMOVE_LEADING_CHAR,
277 OPTION_SET_SECTION_FLAGS,
278 OPTION_SET_START,
279 OPTION_STRIP_UNNEEDED,
280 OPTION_WEAKEN,
281 OPTION_REDEFINE_SYM,
282 OPTION_REDEFINE_SYMS,
283 OPTION_SREC_LEN,
284 OPTION_SREC_FORCES3,
285 OPTION_STRIP_SYMBOLS,
bcf32829
JB
286 OPTION_STRIP_UNNEEDED_SYMBOL,
287 OPTION_STRIP_UNNEEDED_SYMBOLS,
84e2f313 288 OPTION_KEEP_SYMBOLS,
d58c2e3a 289 OPTION_LOCALIZE_HIDDEN,
84e2f313 290 OPTION_LOCALIZE_SYMBOLS,
0408dee6 291 OPTION_LONG_SECTION_NAMES,
7b4a0685
NC
292 OPTION_GLOBALIZE_SYMBOL,
293 OPTION_GLOBALIZE_SYMBOLS,
84e2f313
NC
294 OPTION_KEEPGLOBAL_SYMBOLS,
295 OPTION_WEAKEN_SYMBOLS,
296 OPTION_RENAME_SECTION,
297 OPTION_ALT_MACH_CODE,
298 OPTION_PREFIX_SYMBOLS,
299 OPTION_PREFIX_SECTIONS,
300 OPTION_PREFIX_ALLOC_SECTIONS,
301 OPTION_FORMATS_INFO,
302 OPTION_ADD_GNU_DEBUGLINK,
4087920c 303 OPTION_ONLY_KEEP_DEBUG,
1637cd90 304 OPTION_KEEP_FILE_SYMBOLS,
4087920c
MR
305 OPTION_READONLY_TEXT,
306 OPTION_WRITABLE_TEXT,
307 OPTION_PURE,
d3e52d40 308 OPTION_IMPURE,
9e48b4c6 309 OPTION_EXTRACT_SYMBOL,
92dd4511
L
310 OPTION_REVERSE_BYTES,
311 OPTION_FILE_ALIGNMENT,
312 OPTION_HEAP,
313 OPTION_IMAGE_BASE,
314 OPTION_SECTION_ALIGNMENT,
315 OPTION_STACK,
b7dd81f7 316 OPTION_INTERLEAVE_WIDTH,
92dd4511 317 OPTION_SUBSYSTEM
84e2f313 318 };
252b5132
RH
319
320/* Options to handle if running as "strip". */
321
322static struct option strip_options[] =
323{
324 {"discard-all", no_argument, 0, 'x'},
325 {"discard-locals", no_argument, 0, 'X'},
326 {"format", required_argument, 0, 'F'}, /* Obsolete */
327 {"help", no_argument, 0, 'h'},
7c29036b 328 {"info", no_argument, 0, OPTION_FORMATS_INFO},
252b5132
RH
329 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
330 {"input-target", required_argument, 0, 'I'},
1637cd90 331 {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
252b5132 332 {"keep-symbol", required_argument, 0, 'K'},
ed1653a7 333 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
252b5132
RH
334 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
335 {"output-target", required_argument, 0, 'O'},
af3bdff7 336 {"output-file", required_argument, 0, 'o'},
252b5132
RH
337 {"preserve-dates", no_argument, 0, 'p'},
338 {"remove-section", required_argument, 0, 'R'},
339 {"strip-all", no_argument, 0, 's'},
340 {"strip-debug", no_argument, 0, 'S'},
341 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
342 {"strip-symbol", required_argument, 0, 'N'},
343 {"target", required_argument, 0, 'F'},
344 {"verbose", no_argument, 0, 'v'},
345 {"version", no_argument, 0, 'V'},
5fe11841 346 {"wildcard", no_argument, 0, 'w'},
252b5132
RH
347 {0, no_argument, 0, 0}
348};
349
350/* Options to handle if running as "objcopy". */
351
352static struct option copy_options[] =
353{
2593f09a 354 {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
252b5132
RH
355 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
356 {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
357 {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
358 {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
359 {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
d7fb0dd2 360 {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
43a0748c 361 {"binary-architecture", required_argument, 0, 'B'},
252b5132
RH
362 {"byte", required_argument, 0, 'b'},
363 {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
364 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
365 {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
366 {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
367 {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
368 {"change-start", required_argument, 0, OPTION_CHANGE_START},
369 {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
4a114e3e 370 {"compress-debug-sections", no_argument, 0, OPTION_COMPRESS_DEBUG_SECTIONS},
252b5132 371 {"debugging", no_argument, 0, OPTION_DEBUGGING},
4a114e3e 372 {"decompress-debug-sections", no_argument, 0, OPTION_DECOMPRESS_DEBUG_SECTIONS},
252b5132
RH
373 {"discard-all", no_argument, 0, 'x'},
374 {"discard-locals", no_argument, 0, 'X'},
d3e52d40 375 {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
252b5132
RH
376 {"format", required_argument, 0, 'F'}, /* Obsolete */
377 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
7b4a0685
NC
378 {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
379 {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
252b5132 380 {"help", no_argument, 0, 'h'},
4087920c 381 {"impure", no_argument, 0, OPTION_IMPURE},
7c29036b 382 {"info", no_argument, 0, OPTION_FORMATS_INFO},
252b5132
RH
383 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
384 {"input-target", required_argument, 0, 'I'},
b7dd81f7
NC
385 {"interleave", optional_argument, 0, 'i'},
386 {"interleave-width", required_argument, 0, OPTION_INTERLEAVE_WIDTH},
1637cd90 387 {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
d7fb0dd2
NC
388 {"keep-global-symbol", required_argument, 0, 'G'},
389 {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
252b5132 390 {"keep-symbol", required_argument, 0, 'K'},
d7fb0dd2 391 {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
d58c2e3a 392 {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
d7fb0dd2
NC
393 {"localize-symbol", required_argument, 0, 'L'},
394 {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
0408dee6 395 {"long-section-names", required_argument, 0, OPTION_LONG_SECTION_NAMES},
252b5132
RH
396 {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
397 {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
ed1653a7 398 {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
d7fb0dd2 399 {"only-section", required_argument, 0, 'j'},
252b5132
RH
400 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
401 {"output-target", required_argument, 0, 'O'},
402 {"pad-to", required_argument, 0, OPTION_PAD_TO},
d7fb0dd2
NC
403 {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
404 {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
405 {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
252b5132 406 {"preserve-dates", no_argument, 0, 'p'},
4087920c
MR
407 {"pure", no_argument, 0, OPTION_PURE},
408 {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
d7fb0dd2 409 {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
92991082 410 {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
252b5132
RH
411 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
412 {"remove-section", required_argument, 0, 'R'},
594ef5db 413 {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
9e48b4c6 414 {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
252b5132
RH
415 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
416 {"set-start", required_argument, 0, OPTION_SET_START},
d7fb0dd2
NC
417 {"srec-len", required_argument, 0, OPTION_SREC_LEN},
418 {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
252b5132
RH
419 {"strip-all", no_argument, 0, 'S'},
420 {"strip-debug", no_argument, 0, 'g'},
421 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
bcf32829
JB
422 {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
423 {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
252b5132 424 {"strip-symbol", required_argument, 0, 'N'},
d7fb0dd2 425 {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
252b5132
RH
426 {"target", required_argument, 0, 'F'},
427 {"verbose", no_argument, 0, 'v'},
428 {"version", no_argument, 0, 'V'},
429 {"weaken", no_argument, 0, OPTION_WEAKEN},
430 {"weaken-symbol", required_argument, 0, 'W'},
16b2b71c 431 {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
5fe11841 432 {"wildcard", no_argument, 0, 'w'},
4087920c 433 {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
92dd4511
L
434 {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
435 {"heap", required_argument, 0, OPTION_HEAP},
436 {"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
437 {"section-alignment", required_argument, 0, OPTION_SECTION_ALIGNMENT},
438 {"stack", required_argument, 0, OPTION_STACK},
439 {"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
252b5132
RH
440 {0, no_argument, 0, 0}
441};
442
443/* IMPORTS */
444extern char *program_name;
445
446/* This flag distinguishes between strip and objcopy:
447 1 means this is 'strip'; 0 means this is 'objcopy'.
0af11b59 448 -1 means if we should use argv[0] to decide. */
252b5132
RH
449extern int is_strip;
450
420496c1
NC
451/* The maximum length of an S record. This variable is declared in srec.c
452 and can be modified by the --srec-len parameter. */
453extern unsigned int Chunk;
454
455/* Restrict the generation of Srecords to type S3 only.
456 This variable is declare in bfd/srec.c and can be toggled
457 on by the --srec-forceS3 command line switch. */
b34976b6 458extern bfd_boolean S3Forced;
252b5132 459
d3ba0551
AM
460/* Forward declarations. */
461static void setup_section (bfd *, asection *, void *);
80fccad2 462static void setup_bfd_headers (bfd *, bfd *);
d3ba0551
AM
463static void copy_section (bfd *, asection *, void *);
464static void get_sections (bfd *, asection *, void *);
465static int compare_section_lma (const void *, const void *);
466static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
467static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
468static const char *lookup_sym_redefinition (const char *);
594ef5db 469\f
252b5132 470static void
84e2f313 471copy_usage (FILE *stream, int exit_status)
252b5132 472{
8b53311e
NC
473 fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
474 fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
6364e0b4 475 fprintf (stream, _(" The options are:\n"));
252b5132 476 fprintf (stream, _("\
d5bcb29d
NC
477 -I --input-target <bfdname> Assume input file is in format <bfdname>\n\
478 -O --output-target <bfdname> Create an output file in format <bfdname>\n\
8b31b6c4 479 -B --binary-architecture <arch> Set output arch, when input is arch-less\n\
d5bcb29d
NC
480 -F --target <bfdname> Set both input and output format to <bfdname>\n\
481 --debugging Convert debugging information, if possible\n\
482 -p --preserve-dates Copy modified/access timestamps to the output\n\
483 -j --only-section <name> Only copy section <name> into the output\n\
2593f09a 484 --add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
d5bcb29d
NC
485 -R --remove-section <name> Remove section <name> from the output\n\
486 -S --strip-all Remove all symbol and relocation information\n\
2593f09a 487 -g --strip-debug Remove all debugging symbols & sections\n\
d5bcb29d
NC
488 --strip-unneeded Remove all symbols not needed by relocations\n\
489 -N --strip-symbol <name> Do not copy symbol <name>\n\
bcf32829
JB
490 --strip-unneeded-symbol <name>\n\
491 Do not copy symbol <name> unless needed by\n\
492 relocations\n\
6ea3dd37 493 --only-keep-debug Strip everything but the debug information\n\
d3e52d40 494 --extract-symbol Remove section contents but keep symbols\n\
e7f918ad 495 -K --keep-symbol <name> Do not strip symbol <name>\n\
1637cd90 496 --keep-file-symbols Do not strip file symbol(s)\n\
d58c2e3a 497 --localize-hidden Turn all ELF hidden symbols into locals\n\
d5bcb29d 498 -L --localize-symbol <name> Force symbol <name> to be marked as a local\n\
7b4a0685 499 --globalize-symbol <name> Force symbol <name> to be marked as a global\n\
16b2b71c 500 -G --keep-global-symbol <name> Localize all symbols except <name>\n\
d5bcb29d
NC
501 -W --weaken-symbol <name> Force symbol <name> to be marked as a weak\n\
502 --weaken Force all global symbols to be marked as weak\n\
a95b5cf9 503 -w --wildcard Permit wildcard in symbol comparison\n\
d5bcb29d
NC
504 -x --discard-all Remove all non-global symbols\n\
505 -X --discard-locals Remove any compiler-generated symbols\n\
b7dd81f7
NC
506 -i --interleave [<number>] Only copy N out of every <number> bytes\n\
507 --interleave-width <number> Set N for --interleave\n\
d5bcb29d
NC
508 -b --byte <num> Select byte <num> in every interleaved block\n\
509 --gap-fill <val> Fill gaps between sections with <val>\n\
510 --pad-to <addr> Pad the last section up to address <addr>\n\
511 --set-start <addr> Set the start address to <addr>\n\
512 {--change-start|--adjust-start} <incr>\n\
513 Add <incr> to the start address\n\
514 {--change-addresses|--adjust-vma} <incr>\n\
515 Add <incr> to LMA, VMA and start addresses\n\
516 {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
517 Change LMA and VMA of section <name> by <val>\n\
518 --change-section-lma <name>{=|+|-}<val>\n\
519 Change the LMA of section <name> by <val>\n\
520 --change-section-vma <name>{=|+|-}<val>\n\
521 Change the VMA of section <name> by <val>\n\
522 {--[no-]change-warnings|--[no-]adjust-warnings}\n\
523 Warn if a named section does not exist\n\
524 --set-section-flags <name>=<flags>\n\
525 Set section <name>'s properties to <flags>\n\
526 --add-section <name>=<file> Add section <name> found in <file> to output\n\
594ef5db 527 --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
0408dee6
DK
528 --long-section-names {enable|disable|keep}\n\
529 Handle long section names in Coff objects.\n\
d5bcb29d
NC
530 --change-leading-char Force output format's leading character style\n\
531 --remove-leading-char Remove leading character from global symbols\n\
9e48b4c6 532 --reverse-bytes=<num> Reverse <num> bytes at a time, in output sections with content\n\
57938635 533 --redefine-sym <old>=<new> Redefine symbol name <old> to <new>\n\
92991082
JT
534 --redefine-syms <file> --redefine-sym for all symbol pairs \n\
535 listed in <file>\n\
420496c1
NC
536 --srec-len <number> Restrict the length of generated Srecords\n\
537 --srec-forceS3 Restrict the type of generated Srecords to S3\n\
16b2b71c 538 --strip-symbols <file> -N for all symbols listed in <file>\n\
bcf32829
JB
539 --strip-unneeded-symbols <file>\n\
540 --strip-unneeded-symbol for all symbols listed\n\
541 in <file>\n\
16b2b71c
NC
542 --keep-symbols <file> -K for all symbols listed in <file>\n\
543 --localize-symbols <file> -L for all symbols listed in <file>\n\
7b4a0685 544 --globalize-symbols <file> --globalize-symbol for all in <file>\n\
16b2b71c
NC
545 --keep-global-symbols <file> -G for all symbols listed in <file>\n\
546 --weaken-symbols <file> -W for all symbols listed in <file>\n\
f9d4ad2a 547 --alt-machine-code <index> Use the target's <index>'th alternative machine\n\
4087920c
MR
548 --writable-text Mark the output text as writable\n\
549 --readonly-text Make the output text write protected\n\
550 --pure Mark the output file as demand paged\n\
551 --impure Mark the output file as impure\n\
d7fb0dd2
NC
552 --prefix-symbols <prefix> Add <prefix> to start of every symbol name\n\
553 --prefix-sections <prefix> Add <prefix> to start of every section name\n\
554 --prefix-alloc-sections <prefix>\n\
555 Add <prefix> to start of every allocatable\n\
556 section name\n\
92dd4511
L
557 --file-alignment <num> Set PE file alignment to <num>\n\
558 --heap <reserve>[,<commit>] Set PE reserve/commit heap to <reserve>/\n\
559 <commit>\n\
560 --image-base <address> Set PE image base to <address>\n\
561 --section-alignment <num> Set PE section alignment to <num>\n\
562 --stack <reserve>[,<commit>] Set PE reserve/commit stack to <reserve>/\n\
563 <commit>\n\
564 --subsystem <name>[:<version>]\n\
447049af 565 Set PE subsystem to <name> [& <version>]\n\
4a114e3e
L
566 --compress-debug-sections Compress DWARF debug sections using zlib\n\
567 --decompress-debug-sections Decompress DWARF debug sections using zlib\n\
d5bcb29d 568 -v --verbose List all object files modified\n\
07012eee 569 @<file> Read options from <file>\n\
d5bcb29d
NC
570 -V --version Display this program's version number\n\
571 -h --help Display this output\n\
7c29036b 572 --info List object formats & architectures supported\n\
d5bcb29d 573"));
252b5132 574 list_supported_targets (program_name, stream);
92f01d61 575 if (REPORT_BUGS_TO[0] && exit_status == 0)
8ad3436c 576 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
577 exit (exit_status);
578}
579
580static void
84e2f313 581strip_usage (FILE *stream, int exit_status)
252b5132 582{
8b53311e
NC
583 fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
584 fprintf (stream, _(" Removes symbols and sections from files\n"));
6364e0b4 585 fprintf (stream, _(" The options are:\n"));
252b5132 586 fprintf (stream, _("\
8b53311e
NC
587 -I --input-target=<bfdname> Assume input file is in format <bfdname>\n\
588 -O --output-target=<bfdname> Create an output file in format <bfdname>\n\
589 -F --target=<bfdname> Set both input and output format to <bfdname>\n\
d5bcb29d 590 -p --preserve-dates Copy modified/access timestamps to the output\n\
8b53311e 591 -R --remove-section=<name> Remove section <name> from the output\n\
d5bcb29d 592 -s --strip-all Remove all symbol and relocation information\n\
2593f09a 593 -g -S -d --strip-debug Remove all debugging symbols & sections\n\
d5bcb29d 594 --strip-unneeded Remove all symbols not needed by relocations\n\
6ea3dd37 595 --only-keep-debug Strip everything but the debug information\n\
8b53311e 596 -N --strip-symbol=<name> Do not copy symbol <name>\n\
5219e4c0 597 -K --keep-symbol=<name> Do not strip symbol <name>\n\
1637cd90 598 --keep-file-symbols Do not strip file symbol(s)\n\
a95b5cf9 599 -w --wildcard Permit wildcard in symbol comparison\n\
d5bcb29d
NC
600 -x --discard-all Remove all non-global symbols\n\
601 -X --discard-locals Remove any compiler-generated symbols\n\
602 -v --verbose List all object files modified\n\
603 -V --version Display this program's version number\n\
604 -h --help Display this output\n\
7c29036b 605 --info List object formats & architectures supported\n\
d5bcb29d
NC
606 -o <file> Place stripped output into <file>\n\
607"));
608
252b5132 609 list_supported_targets (program_name, stream);
92f01d61 610 if (REPORT_BUGS_TO[0] && exit_status == 0)
8ad3436c 611 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
612 exit (exit_status);
613}
614
615/* Parse section flags into a flagword, with a fatal error if the
616 string can't be parsed. */
617
618static flagword
84e2f313 619parse_flags (const char *s)
252b5132
RH
620{
621 flagword ret;
622 const char *snext;
623 int len;
624
625 ret = SEC_NO_FLAGS;
626
627 do
628 {
629 snext = strchr (s, ',');
630 if (snext == NULL)
631 len = strlen (s);
632 else
633 {
634 len = snext - s;
635 ++snext;
636 }
637
638 if (0) ;
639#define PARSE_FLAG(fname,fval) \
640 else if (strncasecmp (fname, s, len) == 0) ret |= fval
641 PARSE_FLAG ("alloc", SEC_ALLOC);
642 PARSE_FLAG ("load", SEC_LOAD);
3994e2c6 643 PARSE_FLAG ("noload", SEC_NEVER_LOAD);
252b5132 644 PARSE_FLAG ("readonly", SEC_READONLY);
3994e2c6 645 PARSE_FLAG ("debug", SEC_DEBUGGING);
252b5132
RH
646 PARSE_FLAG ("code", SEC_CODE);
647 PARSE_FLAG ("data", SEC_DATA);
648 PARSE_FLAG ("rom", SEC_ROM);
ebe372c1 649 PARSE_FLAG ("share", SEC_COFF_SHARED);
252b5132
RH
650 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
651#undef PARSE_FLAG
652 else
653 {
654 char *copy;
655
3f5e193b 656 copy = (char *) xmalloc (len + 1);
252b5132
RH
657 strncpy (copy, s, len);
658 copy[len] = '\0';
659 non_fatal (_("unrecognized section flag `%s'"), copy);
57938635
AM
660 fatal (_("supported flags: %s"),
661 "alloc, load, noload, readonly, debug, code, data, rom, share, contents");
252b5132
RH
662 }
663
664 s = snext;
665 }
666 while (s != NULL);
667
668 return ret;
669}
670
671/* Find and optionally add an entry in the change_sections list. */
672
673static struct section_list *
84e2f313 674find_section_list (const char *name, bfd_boolean add)
252b5132 675{
84e2f313 676 struct section_list *p;
252b5132
RH
677
678 for (p = change_sections; p != NULL; p = p->next)
679 if (strcmp (p->name, name) == 0)
680 return p;
681
682 if (! add)
683 return NULL;
684
3f5e193b 685 p = (struct section_list *) xmalloc (sizeof (struct section_list));
252b5132 686 p->name = name;
b34976b6
AM
687 p->used = FALSE;
688 p->remove = FALSE;
689 p->copy = FALSE;
252b5132
RH
690 p->change_vma = CHANGE_IGNORE;
691 p->change_lma = CHANGE_IGNORE;
692 p->vma_val = 0;
693 p->lma_val = 0;
b34976b6 694 p->set_flags = FALSE;
252b5132
RH
695 p->flags = 0;
696
697 p->next = change_sections;
698 change_sections = p;
699
700 return p;
701}
702
047c9024
NC
703/* There is htab_hash_string but no htab_eq_string. Makes sense. */
704
705static int
706eq_string (const void *s1, const void *s2)
707{
3f5e193b 708 return strcmp ((const char *) s1, (const char *) s2) == 0;
047c9024
NC
709}
710
711static htab_t
712create_symbol_htab (void)
713{
714 return htab_create_alloc (16, htab_hash_string, eq_string, NULL, xcalloc, free);
715}
252b5132 716
57938635 717static void
047c9024 718create_symbol_htabs (void)
252b5132 719{
047c9024
NC
720 strip_specific_htab = create_symbol_htab ();
721 strip_unneeded_htab = create_symbol_htab ();
722 keep_specific_htab = create_symbol_htab ();
723 localize_specific_htab = create_symbol_htab ();
724 globalize_specific_htab = create_symbol_htab ();
725 keepglobal_specific_htab = create_symbol_htab ();
726 weaken_specific_htab = create_symbol_htab ();
727}
728
729/* Add a symbol to strip_specific_list. */
252b5132 730
047c9024
NC
731static void
732add_specific_symbol (const char *name, htab_t htab)
733{
734 *htab_find_slot (htab, name, INSERT) = (char *) name;
252b5132
RH
735}
736
0af11b59 737/* Add symbols listed in `filename' to strip_specific_list. */
16b2b71c
NC
738
739#define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
740#define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
741
742static void
047c9024 743add_specific_symbols (const char *filename, htab_t htab)
16b2b71c 744{
f24ddbdd 745 off_t size;
16b2b71c
NC
746 FILE * f;
747 char * line;
748 char * buffer;
749 unsigned int line_count;
0af11b59 750
f24ddbdd
NC
751 size = get_file_size (filename);
752 if (size == 0)
d68c385b
NC
753 {
754 status = 1;
755 return;
756 }
16b2b71c 757
3f5e193b 758 buffer = (char *) xmalloc (size + 2);
16b2b71c
NC
759 f = fopen (filename, FOPEN_RT);
760 if (f == NULL)
f24ddbdd 761 fatal (_("cannot open '%s': %s"), filename, strerror (errno));
16b2b71c 762
f24ddbdd 763 if (fread (buffer, 1, size, f) == 0 || ferror (f))
16b2b71c
NC
764 fatal (_("%s: fread failed"), filename);
765
766 fclose (f);
f24ddbdd
NC
767 buffer [size] = '\n';
768 buffer [size + 1] = '\0';
16b2b71c
NC
769
770 line_count = 1;
0af11b59 771
16b2b71c
NC
772 for (line = buffer; * line != '\0'; line ++)
773 {
774 char * eol;
775 char * name;
776 char * name_end;
b34976b6 777 int finished = FALSE;
16b2b71c
NC
778
779 for (eol = line;; eol ++)
780 {
781 switch (* eol)
782 {
783 case '\n':
784 * eol = '\0';
785 /* Cope with \n\r. */
786 if (eol[1] == '\r')
787 ++ eol;
b34976b6 788 finished = TRUE;
16b2b71c 789 break;
0af11b59 790
16b2b71c
NC
791 case '\r':
792 * eol = '\0';
793 /* Cope with \r\n. */
794 if (eol[1] == '\n')
795 ++ eol;
b34976b6 796 finished = TRUE;
16b2b71c 797 break;
0af11b59 798
16b2b71c 799 case 0:
b34976b6 800 finished = TRUE;
16b2b71c 801 break;
0af11b59 802
16b2b71c
NC
803 case '#':
804 /* Line comment, Terminate the line here, in case a
805 name is present and then allow the rest of the
806 loop to find the real end of the line. */
807 * eol = '\0';
808 break;
0af11b59 809
16b2b71c
NC
810 default:
811 break;
812 }
813
814 if (finished)
815 break;
816 }
817
818 /* A name may now exist somewhere between 'line' and 'eol'.
819 Strip off leading whitespace and trailing whitespace,
820 then add it to the list. */
821 for (name = line; IS_WHITESPACE (* name); name ++)
822 ;
823 for (name_end = name;
824 (! IS_WHITESPACE (* name_end))
825 && (! IS_LINE_TERMINATOR (* name_end));
0af11b59
KH
826 name_end ++)
827 ;
16b2b71c
NC
828
829 if (! IS_LINE_TERMINATOR (* name_end))
830 {
831 char * extra;
832
833 for (extra = name_end + 1; IS_WHITESPACE (* extra); extra ++)
834 ;
835
836 if (! IS_LINE_TERMINATOR (* extra))
d412a550
NC
837 non_fatal (_("%s:%d: Ignoring rubbish found on this line"),
838 filename, line_count);
16b2b71c 839 }
0af11b59 840
16b2b71c
NC
841 * name_end = '\0';
842
843 if (name_end > name)
047c9024 844 add_specific_symbol (name, htab);
16b2b71c
NC
845
846 /* Advance line pointer to end of line. The 'eol ++' in the for
847 loop above will then advance us to the start of the next line. */
848 line = eol;
849 line_count ++;
850 }
851}
852
047c9024
NC
853/* See whether a symbol should be stripped or kept
854 based on strip_specific_list and keep_symbols. */
252b5132 855
047c9024
NC
856static int
857is_specified_symbol_predicate (void **slot, void *data)
252b5132 858{
3f5e193b
NC
859 struct is_specified_symbol_predicate_data *d =
860 (struct is_specified_symbol_predicate_data *) data;
861 const char *slot_name = (char *) *slot;
252b5132 862
047c9024 863 if (*slot_name != '!')
5fe11841 864 {
047c9024
NC
865 if (! fnmatch (slot_name, d->name, 0))
866 {
867 d->found = TRUE;
868 /* Stop traversal. */
869 return 0;
870 }
5fe11841
NC
871 }
872 else
873 {
047c9024
NC
874 if (fnmatch (slot_name + 1, d->name, 0))
875 {
876 d->found = TRUE;
877 /* Stop traversal. */
878 return 0;
879 }
5fe11841 880 }
594ef5db 881
047c9024
NC
882 /* Continue traversal. */
883 return 1;
884}
885
886static bfd_boolean
887is_specified_symbol (const char *name, htab_t htab)
888{
889 if (wildcard)
890 {
891 struct is_specified_symbol_predicate_data data;
892
893 data.name = name;
894 data.found = FALSE;
895
896 htab_traverse (htab, is_specified_symbol_predicate, &data);
897
898 return data.found;
899 }
900
901 return htab_find (htab, name) != NULL;
252b5132
RH
902}
903
30288845
AM
904/* Return a pointer to the symbol used as a signature for GROUP. */
905
906static asymbol *
907group_signature (asection *group)
908{
909 bfd *abfd = group->owner;
910 Elf_Internal_Shdr *ghdr;
911
912 if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
913 return NULL;
914
915 ghdr = &elf_section_data (group)->this_hdr;
916 if (ghdr->sh_link < elf_numsections (abfd))
917 {
918 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
919 Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link];
920
921 if (symhdr->sh_type == SHT_SYMTAB
922 && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym)
748fc5e9 923 return isympp[ghdr->sh_info - 1];
30288845
AM
924 }
925 return NULL;
926}
927
4c8e8a7e 928/* See if a non-group section is being removed. */
252b5132 929
b34976b6 930static bfd_boolean
4c8e8a7e 931is_strip_section_1 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
252b5132 932{
2593f09a
NC
933 if (sections_removed || sections_copied)
934 {
935 struct section_list *p;
936
937 p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
938
939 if (sections_removed && p != NULL && p->remove)
940 return TRUE;
941 if (sections_copied && (p == NULL || ! p->copy))
942 return TRUE;
943 }
252b5132 944
2593f09a
NC
945 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
946 {
947 if (strip_symbols == STRIP_DEBUG
252b5132
RH
948 || strip_symbols == STRIP_UNNEEDED
949 || strip_symbols == STRIP_ALL
950 || discard_locals == LOCALS_ALL
2593f09a
NC
951 || convert_debugging)
952 return TRUE;
ed1653a7
NC
953
954 if (strip_symbols == STRIP_NONDEBUG)
955 return FALSE;
2593f09a 956 }
f91ea849 957
4c8e8a7e
L
958 return FALSE;
959}
960
961/* See if a section is being removed. */
962
963static bfd_boolean
964is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
965{
966 if (is_strip_section_1 (abfd, sec))
967 return TRUE;
968
30288845
AM
969 if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0)
970 {
971 asymbol *gsym;
972 const char *gname;
4c8e8a7e 973 asection *elt, *first;
30288845 974
30288845
AM
975 /* PR binutils/3181
976 If we are going to strip the group signature symbol, then
977 strip the group section too. */
978 gsym = group_signature (sec);
979 if (gsym != NULL)
980 gname = gsym->name;
981 else
982 gname = sec->name;
983 if ((strip_symbols == STRIP_ALL
047c9024
NC
984 && !is_specified_symbol (gname, keep_specific_htab))
985 || is_specified_symbol (gname, strip_specific_htab))
30288845 986 return TRUE;
4c8e8a7e
L
987
988 /* Remove the group section if all members are removed. */
989 first = elt = elf_next_in_group (sec);
990 while (elt != NULL)
991 {
992 if (!is_strip_section_1 (abfd, elt))
993 return FALSE;
994 elt = elf_next_in_group (elt);
995 if (elt == first)
996 break;
997 }
998
999 return TRUE;
30288845 1000 }
91bb255c 1001
f0312d39 1002 return FALSE;
252b5132
RH
1003}
1004
d58c2e3a
RS
1005/* Return true if SYM is a hidden symbol. */
1006
1007static bfd_boolean
1008is_hidden_symbol (asymbol *sym)
1009{
1010 elf_symbol_type *elf_sym;
1011
1012 elf_sym = elf_symbol_from (sym->the_bfd, sym);
1013 if (elf_sym != NULL)
1014 switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other))
1015 {
1016 case STV_HIDDEN:
1017 case STV_INTERNAL:
1018 return TRUE;
1019 }
1020 return FALSE;
1021}
1022
252b5132
RH
1023/* Choose which symbol entries to copy; put the result in OSYMS.
1024 We don't copy in place, because that confuses the relocs.
1025 Return the number of symbols to print. */
1026
1027static unsigned int
84e2f313
NC
1028filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
1029 asymbol **isyms, long symcount)
252b5132 1030{
84e2f313 1031 asymbol **from = isyms, **to = osyms;
252b5132 1032 long src_count = 0, dst_count = 0;
e205a099 1033 int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
252b5132
RH
1034
1035 for (; src_count < symcount; src_count++)
1036 {
1037 asymbol *sym = from[src_count];
1038 flagword flags = sym->flags;
d7fb0dd2 1039 char *name = (char *) bfd_asymbol_name (sym);
312aaa3c
NC
1040 bfd_boolean keep;
1041 bfd_boolean used_in_reloc = FALSE;
b34976b6 1042 bfd_boolean undefined;
d7fb0dd2
NC
1043 bfd_boolean rem_leading_char;
1044 bfd_boolean add_leading_char;
1045
1046 undefined = bfd_is_und_section (bfd_get_section (sym));
252b5132 1047
57938635
AM
1048 if (redefine_sym_list)
1049 {
d7fb0dd2 1050 char *old_name, *new_name;
57938635 1051
d7fb0dd2
NC
1052 old_name = (char *) bfd_asymbol_name (sym);
1053 new_name = (char *) lookup_sym_redefinition (old_name);
66491ebc
AM
1054 bfd_asymbol_name (sym) = new_name;
1055 name = new_name;
57938635
AM
1056 }
1057
d7fb0dd2
NC
1058 /* Check if we will remove the current leading character. */
1059 rem_leading_char =
1060 (name[0] == bfd_get_symbol_leading_char (abfd))
1061 && (change_leading_char
1062 || (remove_leading_char
1063 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1064 || undefined
1065 || bfd_is_com_section (bfd_get_section (sym)))));
1066
1067 /* Check if we will add a new leading character. */
1068 add_leading_char =
1069 change_leading_char
1070 && (bfd_get_symbol_leading_char (obfd) != '\0')
1071 && (bfd_get_symbol_leading_char (abfd) == '\0'
1072 || (name[0] == bfd_get_symbol_leading_char (abfd)));
1073
1074 /* Short circuit for change_leading_char if we can do it in-place. */
1075 if (rem_leading_char && add_leading_char && !prefix_symbols_string)
1076 {
1077 name[0] = bfd_get_symbol_leading_char (obfd);
1078 bfd_asymbol_name (sym) = name;
1079 rem_leading_char = FALSE;
1080 add_leading_char = FALSE;
1081 }
1082
1083 /* Remove leading char. */
1084 if (rem_leading_char)
66491ebc 1085 bfd_asymbol_name (sym) = ++name;
d7fb0dd2
NC
1086
1087 /* Add new leading char and/or prefix. */
1088 if (add_leading_char || prefix_symbols_string)
1089 {
1090 char *n, *ptr;
1091
3f5e193b
NC
1092 ptr = n = (char *) xmalloc (1 + strlen (prefix_symbols_string)
1093 + strlen (name) + 1);
d7fb0dd2
NC
1094 if (add_leading_char)
1095 *ptr++ = bfd_get_symbol_leading_char (obfd);
1096
1097 if (prefix_symbols_string)
1098 {
1099 strcpy (ptr, prefix_symbols_string);
1100 ptr += strlen (prefix_symbols_string);
1101 }
1102
1103 strcpy (ptr, name);
66491ebc
AM
1104 bfd_asymbol_name (sym) = n;
1105 name = n;
252b5132
RH
1106 }
1107
252b5132 1108 if (strip_symbols == STRIP_ALL)
312aaa3c 1109 keep = FALSE;
252b5132
RH
1110 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
1111 || ((flags & BSF_SECTION_SYM) != 0
1112 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
1113 & BSF_KEEP) != 0))
312aaa3c
NC
1114 {
1115 keep = TRUE;
1116 used_in_reloc = TRUE;
1117 }
0af11b59 1118 else if (relocatable /* Relocatable file. */
0691f7af
L
1119 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1120 || bfd_is_com_section (bfd_get_section (sym))))
312aaa3c 1121 keep = TRUE;
16b2b71c
NC
1122 else if (bfd_decode_symclass (sym) == 'I')
1123 /* Global symbols in $idata sections need to be retained
b34976b6 1124 even if relocatable is FALSE. External users of the
16b2b71c
NC
1125 library containing the $idata section may reference these
1126 symbols. */
312aaa3c 1127 keep = TRUE;
252b5132
RH
1128 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
1129 || (flags & BSF_WEAK) != 0
24e01a36 1130 || undefined
252b5132
RH
1131 || bfd_is_com_section (bfd_get_section (sym)))
1132 keep = strip_symbols != STRIP_UNNEEDED;
1133 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
1134 keep = (strip_symbols != STRIP_DEBUG
1135 && strip_symbols != STRIP_UNNEEDED
1136 && ! convert_debugging);
082b7297 1137 else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
af3bdff7
NC
1138 /* COMDAT sections store special information in local
1139 symbols, so we cannot risk stripping any of them. */
312aaa3c 1140 keep = TRUE;
252b5132
RH
1141 else /* Local symbol. */
1142 keep = (strip_symbols != STRIP_UNNEEDED
1143 && (discard_locals != LOCALS_ALL
1144 && (discard_locals != LOCALS_START_L
1145 || ! bfd_is_local_label (abfd, sym))));
1146
047c9024 1147 if (keep && is_specified_symbol (name, strip_specific_htab))
312aaa3c
NC
1148 {
1149 /* There are multiple ways to set 'keep' above, but if it
1150 was the relocatable symbol case, then that's an error. */
1151 if (used_in_reloc)
1152 {
1153 non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name);
1154 status = 1;
1155 }
1156 else
1157 keep = FALSE;
1158 }
1159
bcf32829
JB
1160 if (keep
1161 && !(flags & BSF_KEEP)
047c9024 1162 && is_specified_symbol (name, strip_unneeded_htab))
312aaa3c
NC
1163 keep = FALSE;
1164
1637cd90
JB
1165 if (!keep
1166 && ((keep_file_symbols && (flags & BSF_FILE))
047c9024 1167 || is_specified_symbol (name, keep_specific_htab)))
312aaa3c
NC
1168 keep = TRUE;
1169
252b5132 1170 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
312aaa3c 1171 keep = FALSE;
e0c60db2 1172
7b4a0685 1173 if (keep)
252b5132 1174 {
7b4a0685 1175 if ((flags & BSF_GLOBAL) != 0
047c9024 1176 && (weaken || is_specified_symbol (name, weaken_specific_htab)))
7b4a0685
NC
1177 {
1178 sym->flags &= ~ BSF_GLOBAL;
1179 sym->flags |= BSF_WEAK;
1180 }
252b5132 1181
7b4a0685
NC
1182 if (!undefined
1183 && (flags & (BSF_GLOBAL | BSF_WEAK))
047c9024
NC
1184 && (is_specified_symbol (name, localize_specific_htab)
1185 || (htab_elements (keepglobal_specific_htab) != 0
1186 && ! is_specified_symbol (name, keepglobal_specific_htab))
d58c2e3a 1187 || (localize_hidden && is_hidden_symbol (sym))))
7b4a0685
NC
1188 {
1189 sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
1190 sym->flags |= BSF_LOCAL;
1191 }
1192
1193 if (!undefined
c1c0eb9e 1194 && (flags & BSF_LOCAL)
047c9024 1195 && is_specified_symbol (name, globalize_specific_htab))
7b4a0685
NC
1196 {
1197 sym->flags &= ~ BSF_LOCAL;
1198 sym->flags |= BSF_GLOBAL;
1199 }
1200
1201 to[dst_count++] = sym;
1202 }
252b5132
RH
1203 }
1204
1205 to[dst_count] = NULL;
1206
1207 return dst_count;
1208}
1209
594ef5db
NC
1210/* Find the redefined name of symbol SOURCE. */
1211
57938635 1212static const char *
84e2f313 1213lookup_sym_redefinition (const char *source)
57938635 1214{
57938635
AM
1215 struct redefine_node *list;
1216
57938635 1217 for (list = redefine_sym_list; list != NULL; list = list->next)
594ef5db
NC
1218 if (strcmp (source, list->source) == 0)
1219 return list->target;
1220
1221 return source;
57938635
AM
1222}
1223
594ef5db 1224/* Add a node to a symbol redefine list. */
57938635
AM
1225
1226static void
84e2f313 1227redefine_list_append (const char *cause, const char *source, const char *target)
57938635
AM
1228{
1229 struct redefine_node **p;
1230 struct redefine_node *list;
1231 struct redefine_node *new_node;
1232
1233 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
1234 {
1235 if (strcmp (source, list->source) == 0)
594ef5db 1236 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
92991082 1237 cause, source);
57938635
AM
1238
1239 if (strcmp (target, list->target) == 0)
594ef5db 1240 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
92991082 1241 cause, target);
57938635
AM
1242 }
1243
3f5e193b 1244 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
57938635
AM
1245
1246 new_node->source = strdup (source);
1247 new_node->target = strdup (target);
1248 new_node->next = NULL;
1249
1250 *p = new_node;
1251}
1252
92991082
JT
1253/* Handle the --redefine-syms option. Read lines containing "old new"
1254 from the file, and add them to the symbol redefine list. */
1255
2593f09a 1256static void
84e2f313 1257add_redefine_syms_file (const char *filename)
92991082
JT
1258{
1259 FILE *file;
1260 char *buf;
84e2f313
NC
1261 size_t bufsize;
1262 size_t len;
1263 size_t outsym_off;
92991082
JT
1264 int c, lineno;
1265
1266 file = fopen (filename, "r");
d3ba0551 1267 if (file == NULL)
92991082
JT
1268 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
1269 filename, strerror (errno));
1270
1271 bufsize = 100;
a6da20b5 1272 buf = (char *) xmalloc (bufsize + 1 /* For the terminating NUL. */);
92991082
JT
1273
1274 lineno = 1;
1275 c = getc (file);
1276 len = 0;
1277 outsym_off = 0;
1278 while (c != EOF)
1279 {
1280 /* Collect the input symbol name. */
1281 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1282 {
1283 if (c == '#')
1284 goto comment;
1285 buf[len++] = c;
1286 if (len >= bufsize)
1287 {
1288 bufsize *= 2;
a6da20b5 1289 buf = (char *) xrealloc (buf, bufsize + 1);
92991082
JT
1290 }
1291 c = getc (file);
1292 }
1293 buf[len++] = '\0';
1294 if (c == EOF)
1295 break;
1296
1297 /* Eat white space between the symbol names. */
1298 while (IS_WHITESPACE (c))
1299 c = getc (file);
1300 if (c == '#' || IS_LINE_TERMINATOR (c))
1301 goto comment;
1302 if (c == EOF)
1303 break;
1304
1305 /* Collect the output symbol name. */
1306 outsym_off = len;
1307 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1308 {
1309 if (c == '#')
1310 goto comment;
1311 buf[len++] = c;
1312 if (len >= bufsize)
1313 {
1314 bufsize *= 2;
a6da20b5 1315 buf = (char *) xrealloc (buf, bufsize + 1);
92991082
JT
1316 }
1317 c = getc (file);
1318 }
1319 buf[len++] = '\0';
1320 if (c == EOF)
1321 break;
1322
1323 /* Eat white space at end of line. */
1324 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1325 c = getc (file);
1326 if (c == '#')
1327 goto comment;
1328 /* Handle \r\n. */
1329 if ((c == '\r' && (c = getc (file)) == '\n')
1330 || c == '\n' || c == EOF)
1331 {
1332 end_of_line:
1333 /* Append the redefinition to the list. */
1334 if (buf[0] != '\0')
1335 redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1336
c1c0eb9e 1337 lineno++;
92991082
JT
1338 len = 0;
1339 outsym_off = 0;
1340 if (c == EOF)
1341 break;
1342 c = getc (file);
1343 continue;
1344 }
1345 else
d412a550 1346 fatal (_("%s:%d: garbage found at end of line"), filename, lineno);
92991082
JT
1347 comment:
1348 if (len != 0 && (outsym_off == 0 || outsym_off == len))
d412a550 1349 fatal (_("%s:%d: missing new symbol name"), filename, lineno);
92991082
JT
1350 buf[len++] = '\0';
1351
1352 /* Eat the rest of the line and finish it. */
1353 while (c != '\n' && c != EOF)
1354 c = getc (file);
1355 goto end_of_line;
1356 }
1357
1358 if (len != 0)
d412a550 1359 fatal (_("%s:%d: premature end of file"), filename, lineno);
92991082
JT
1360
1361 free (buf);
1362}
1363
77f762d6
L
1364/* Copy unkown object file IBFD onto OBFD.
1365 Returns TRUE upon success, FALSE otherwise. */
1366
1367static bfd_boolean
1368copy_unknown_object (bfd *ibfd, bfd *obfd)
1369{
1370 char *cbuf;
1371 int tocopy;
1372 long ncopied;
1373 long size;
1374 struct stat buf;
1375
1376 if (bfd_stat_arch_elt (ibfd, &buf) != 0)
1377 {
8d8e0703 1378 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
77f762d6
L
1379 return FALSE;
1380 }
1381
1382 size = buf.st_size;
1383 if (size < 0)
1384 {
1385 non_fatal (_("stat returns negative size for `%s'"),
1386 bfd_get_archive_filename (ibfd));
1387 return FALSE;
1388 }
1389
1390 if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
1391 {
1392 bfd_nonfatal (bfd_get_archive_filename (ibfd));
1393 return FALSE;
1394 }
1395
1396 if (verbose)
1397 printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"),
1398 bfd_get_archive_filename (ibfd), bfd_get_filename (obfd));
1399
3f5e193b 1400 cbuf = (char *) xmalloc (BUFSIZE);
77f762d6
L
1401 ncopied = 0;
1402 while (ncopied < size)
1403 {
1404 tocopy = size - ncopied;
1405 if (tocopy > BUFSIZE)
1406 tocopy = BUFSIZE;
1407
1408 if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd)
1409 != (bfd_size_type) tocopy)
1410 {
8d8e0703 1411 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
77f762d6
L
1412 free (cbuf);
1413 return FALSE;
1414 }
1415
1416 if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
1417 != (bfd_size_type) tocopy)
1418 {
2db6cde7 1419 bfd_nonfatal_message (NULL, obfd, NULL, NULL);
77f762d6
L
1420 free (cbuf);
1421 return FALSE;
1422 }
1423
1424 ncopied += tocopy;
1425 }
1426
1e99536a
L
1427 /* We should at least to be able to read it back when copying an
1428 unknown object in an archive. */
1429 chmod (bfd_get_filename (obfd), buf.st_mode | S_IRUSR);
77f762d6
L
1430 free (cbuf);
1431 return TRUE;
1432}
1433
950d48e7 1434/* Copy object file IBFD onto OBFD.
5b8c74e6 1435 Returns TRUE upon success, FALSE otherwise. */
252b5132 1436
950d48e7 1437static bfd_boolean
8b31b6c4 1438copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
252b5132
RH
1439{
1440 bfd_vma start;
1441 long symcount;
1442 asection **osections = NULL;
84e2f313 1443 asection *gnu_debuglink_section = NULL;
252b5132
RH
1444 bfd_size_type *gaps = NULL;
1445 bfd_size_type max_gap = 0;
1446 long symsize;
84e2f313 1447 void *dhandle;
66491ebc
AM
1448 enum bfd_architecture iarch;
1449 unsigned int imach;
252b5132 1450
23719f39
NC
1451 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1452 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1453 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
950d48e7 1454 fatal (_("Unable to change endianness of input file(s)"));
252b5132
RH
1455
1456 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
950d48e7 1457 {
2db6cde7 1458 bfd_nonfatal_message (NULL, obfd, NULL, NULL);
950d48e7
NC
1459 return FALSE;
1460 }
252b5132
RH
1461
1462 if (verbose)
77f762d6
L
1463 printf (_("copy from `%s' [%s] to `%s' [%s]\n"),
1464 bfd_get_archive_filename (ibfd), bfd_get_target (ibfd),
252b5132
RH
1465 bfd_get_filename (obfd), bfd_get_target (obfd));
1466
d3e52d40
RS
1467 if (extract_symbol)
1468 start = 0;
252b5132 1469 else
d3e52d40
RS
1470 {
1471 if (set_start_set)
1472 start = set_start;
1473 else
1474 start = bfd_get_start_address (ibfd);
1475 start += change_start;
1476 }
252b5132 1477
0af11b59
KH
1478 /* Neither the start address nor the flags
1479 need to be set for a core file. */
4dd67f29
MS
1480 if (bfd_get_format (obfd) != bfd_core)
1481 {
4087920c
MR
1482 flagword flags;
1483
1484 flags = bfd_get_file_flags (ibfd);
1485 flags |= bfd_flags_to_set;
1486 flags &= ~bfd_flags_to_clear;
1487 flags &= bfd_applicable_file_flags (obfd);
1488
3516e984
L
1489 if (strip_symbols == STRIP_ALL)
1490 flags &= ~HAS_RELOC;
1491
4dd67f29 1492 if (!bfd_set_start_address (obfd, start)
4087920c 1493 || !bfd_set_file_flags (obfd, flags))
950d48e7 1494 {
8d8e0703 1495 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
950d48e7
NC
1496 return FALSE;
1497 }
4dd67f29 1498 }
252b5132 1499
594ef5db 1500 /* Copy architecture of input file to output file. */
66491ebc
AM
1501 iarch = bfd_get_arch (ibfd);
1502 imach = bfd_get_mach (ibfd);
8b31b6c4
NC
1503 if (input_arch)
1504 {
1505 if (bfd_get_arch_info (ibfd) == NULL
1506 || bfd_get_arch_info (ibfd)->arch == bfd_arch_unknown)
1507 {
1508 iarch = input_arch->arch;
1509 imach = input_arch->mach;
1510 }
1511 else
1512 non_fatal (_("Input file `%s' ignores binary architecture parameter."),
1513 bfd_get_archive_filename (ibfd));
1514 }
66491ebc 1515 if (!bfd_set_arch_mach (obfd, iarch, imach)
212a3c4d
L
1516 && (ibfd->target_defaulted
1517 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
f57a841a
NC
1518 {
1519 if (bfd_get_arch (ibfd) == bfd_arch_unknown)
77f762d6
L
1520 non_fatal (_("Unable to recognise the format of the input file `%s'"),
1521 bfd_get_archive_filename (ibfd));
f57a841a 1522 else
c1e2cb9d 1523 non_fatal (_("Output file cannot represent architecture `%s'"),
77f762d6
L
1524 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1525 bfd_get_mach (ibfd)));
1526 return FALSE;
f57a841a 1527 }
57938635 1528
252b5132 1529 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
950d48e7 1530 {
8d8e0703 1531 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
950d48e7
NC
1532 return FALSE;
1533 }
252b5132 1534
92dd4511
L
1535 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1536 && bfd_pei_p (obfd))
1537 {
1538 /* Set up PE parameters. */
1539 pe_data_type *pe = pe_data (obfd);
1540
325c681d
L
1541 /* Copy PE parameters before changing them. */
1542 if (ibfd->xvec->flavour == bfd_target_coff_flavour
1543 && bfd_pei_p (ibfd))
1544 pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1545
92dd4511
L
1546 if (pe_file_alignment != (bfd_vma) -1)
1547 pe->pe_opthdr.FileAlignment = pe_file_alignment;
1548 else
1549 pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
1550
1551 if (pe_heap_commit != (bfd_vma) -1)
1552 pe->pe_opthdr.SizeOfHeapCommit = pe_heap_commit;
1553
1554 if (pe_heap_reserve != (bfd_vma) -1)
1555 pe->pe_opthdr.SizeOfHeapCommit = pe_heap_reserve;
1556
1557 if (pe_image_base != (bfd_vma) -1)
1558 pe->pe_opthdr.ImageBase = pe_image_base;
1559
1560 if (pe_section_alignment != (bfd_vma) -1)
1561 pe->pe_opthdr.SectionAlignment = pe_section_alignment;
1562 else
1563 pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
1564
1565 if (pe_stack_commit != (bfd_vma) -1)
1566 pe->pe_opthdr.SizeOfStackCommit = pe_stack_commit;
1567
1568 if (pe_stack_reserve != (bfd_vma) -1)
1569 pe->pe_opthdr.SizeOfStackCommit = pe_stack_reserve;
1570
1571 if (pe_subsystem != -1)
1572 pe->pe_opthdr.Subsystem = pe_subsystem;
1573
1574 if (pe_major_subsystem_version != -1)
1575 pe->pe_opthdr.MajorSubsystemVersion = pe_major_subsystem_version;
1576
1577 if (pe_minor_subsystem_version != -1)
1578 pe->pe_opthdr.MinorSubsystemVersion = pe_minor_subsystem_version;
1579
1580 if (pe_file_alignment > pe_section_alignment)
1581 {
1582 char file_alignment[20], section_alignment[20];
1583
1584 sprintf_vma (file_alignment, pe_file_alignment);
1585 sprintf_vma (section_alignment, pe_section_alignment);
1586 non_fatal (_("warning: file alignment (0x%s) > section alignment (0x%s)"),
1587
1588 file_alignment, section_alignment);
1589 }
1590 }
1591
252b5132 1592 if (isympp)
62d732f5 1593 free (isympp);
57938635 1594
252b5132 1595 if (osympp != isympp)
62d732f5
AM
1596 free (osympp);
1597
1598 isympp = NULL;
1599 osympp = NULL;
252b5132 1600
c39ada54
AM
1601 symsize = bfd_get_symtab_upper_bound (ibfd);
1602 if (symsize < 0)
1603 {
8d8e0703 1604 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
c39ada54
AM
1605 return FALSE;
1606 }
1607
3f5e193b 1608 osympp = isympp = (asymbol **) xmalloc (symsize);
c39ada54
AM
1609 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1610 if (symcount < 0)
1611 {
2db6cde7 1612 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
c39ada54
AM
1613 return FALSE;
1614 }
1615
252b5132
RH
1616 /* BFD mandates that all output sections be created and sizes set before
1617 any output is done. Thus, we traverse all sections multiple times. */
d3ba0551 1618 bfd_map_over_sections (ibfd, setup_section, obfd);
252b5132 1619
237dcb53
AM
1620 if (!extract_symbol)
1621 setup_bfd_headers (ibfd, obfd);
80fccad2 1622
252b5132
RH
1623 if (add_sections != NULL)
1624 {
1625 struct section_add *padd;
1626 struct section_list *pset;
1627
1628 for (padd = add_sections; padd != NULL; padd = padd->next)
1629 {
2593f09a
NC
1630 flagword flags;
1631
551b43fd
AM
1632 pset = find_section_list (padd->name, FALSE);
1633 if (pset != NULL)
1634 pset->used = TRUE;
1635
1636 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1637 if (pset != NULL && pset->set_flags)
1638 flags = pset->flags | SEC_HAS_CONTENTS;
1639
c8782eee
NC
1640 /* bfd_make_section_with_flags() does not return very helpful
1641 error codes, so check for the most likely user error first. */
1642 if (bfd_get_section_by_name (obfd, padd->name))
252b5132 1643 {
2db6cde7
NS
1644 bfd_nonfatal_message (NULL, obfd, NULL,
1645 _("can't add section '%s'"), padd->name);
950d48e7 1646 return FALSE;
252b5132 1647 }
c8782eee
NC
1648 else
1649 {
0930eddd
NS
1650 /* We use LINKER_CREATED here so that the backend hooks
1651 will create any special section type information,
1652 instead of presuming we know what we're doing merely
1653 because we set the flags. */
1654 padd->section = bfd_make_section_with_flags
1655 (obfd, padd->name, flags | SEC_LINKER_CREATED);
c8782eee
NC
1656 if (padd->section == NULL)
1657 {
2db6cde7
NS
1658 bfd_nonfatal_message (NULL, obfd, NULL,
1659 _("can't create section `%s'"),
1660 padd->name);
c8782eee
NC
1661 return FALSE;
1662 }
1663 }
252b5132 1664
2593f09a 1665 if (! bfd_set_section_size (obfd, padd->section, padd->size))
950d48e7 1666 {
2db6cde7 1667 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1668 return FALSE;
1669 }
252b5132 1670
2593f09a
NC
1671 if (pset != NULL)
1672 {
1673 if (pset->change_vma != CHANGE_IGNORE)
84e2f313
NC
1674 if (! bfd_set_section_vma (obfd, padd->section,
1675 pset->vma_val))
950d48e7 1676 {
2db6cde7 1677 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1678 return FALSE;
1679 }
57938635 1680
2593f09a
NC
1681 if (pset->change_lma != CHANGE_IGNORE)
1682 {
1683 padd->section->lma = pset->lma_val;
950d48e7 1684
2593f09a
NC
1685 if (! bfd_set_section_alignment
1686 (obfd, padd->section,
1687 bfd_section_alignment (obfd, padd->section)))
950d48e7 1688 {
2db6cde7 1689 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1690 return FALSE;
1691 }
252b5132
RH
1692 }
1693 }
1694 }
1695 }
1696
2593f09a
NC
1697 if (gnu_debuglink_filename != NULL)
1698 {
84e2f313
NC
1699 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1700 (obfd, gnu_debuglink_filename);
e7c81c25
NC
1701
1702 if (gnu_debuglink_section == NULL)
950d48e7 1703 {
2db6cde7
NS
1704 bfd_nonfatal_message (NULL, obfd, NULL,
1705 _("cannot create debug link section `%s'"),
1706 gnu_debuglink_filename);
950d48e7
NC
1707 return FALSE;
1708 }
6e2c86ac
NC
1709
1710 /* Special processing for PE format files. We
1711 have no way to distinguish PE from COFF here. */
1712 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1713 {
1714 bfd_vma debuglink_vma;
1715 asection * highest_section;
1716 asection * sec;
1717
1718 /* The PE spec requires that all sections be adjacent and sorted
1719 in ascending order of VMA. It also specifies that debug
1720 sections should be last. This is despite the fact that debug
1721 sections are not loaded into memory and so in theory have no
1722 use for a VMA.
1723
1724 This means that the debuglink section must be given a non-zero
1725 VMA which makes it contiguous with other debug sections. So
1726 walk the current section list, find the section with the
1727 highest VMA and start the debuglink section after that one. */
1728 for (sec = obfd->sections, highest_section = NULL;
1729 sec != NULL;
1730 sec = sec->next)
1731 if (sec->vma > 0
1732 && (highest_section == NULL
1733 || sec->vma > highest_section->vma))
1734 highest_section = sec;
1735
1736 if (highest_section)
1737 debuglink_vma = BFD_ALIGN (highest_section->vma
1738 + highest_section->size,
1739 /* FIXME: We ought to be using
1740 COFF_PAGE_SIZE here or maybe
1741 bfd_get_section_alignment() (if it
1742 was set) but since this is for PE
1743 and we know the required alignment
1744 it is easier just to hard code it. */
1745 0x1000);
1746 else
1747 /* Umm, not sure what to do in this case. */
1748 debuglink_vma = 0x1000;
1749
1750 bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
1751 }
950d48e7
NC
1752 }
1753
1aa9ef63
L
1754 if (bfd_count_sections (obfd) != 0
1755 && (gap_fill_set || pad_to_set))
252b5132
RH
1756 {
1757 asection **set;
1758 unsigned int c, i;
1759
1760 /* We must fill in gaps between the sections and/or we must pad
1761 the last section to a specified address. We do this by
1762 grabbing a list of the sections, sorting them by VMA, and
1763 increasing the section sizes as required to fill the gaps.
1764 We write out the gap contents below. */
1765
1766 c = bfd_count_sections (obfd);
3f5e193b 1767 osections = (asection **) xmalloc (c * sizeof (asection *));
252b5132 1768 set = osections;
d3ba0551 1769 bfd_map_over_sections (obfd, get_sections, &set);
252b5132
RH
1770
1771 qsort (osections, c, sizeof (asection *), compare_section_lma);
1772
3f5e193b 1773 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
252b5132
RH
1774 memset (gaps, 0, c * sizeof (bfd_size_type));
1775
1776 if (gap_fill_set)
1777 {
1778 for (i = 0; i < c - 1; i++)
1779 {
1780 flagword flags;
1781 bfd_size_type size;
1782 bfd_vma gap_start, gap_stop;
1783
1784 flags = bfd_get_section_flags (obfd, osections[i]);
1785 if ((flags & SEC_HAS_CONTENTS) == 0
1786 || (flags & SEC_LOAD) == 0)
1787 continue;
1788
1789 size = bfd_section_size (obfd, osections[i]);
1790 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1791 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1792 if (gap_start < gap_stop)
1793 {
1794 if (! bfd_set_section_size (obfd, osections[i],
1795 size + (gap_stop - gap_start)))
1796 {
2db6cde7
NS
1797 bfd_nonfatal_message (NULL, obfd, osections[i],
1798 _("Can't fill gap after section"));
252b5132
RH
1799 status = 1;
1800 break;
1801 }
1802 gaps[i] = gap_stop - gap_start;
1803 if (max_gap < gap_stop - gap_start)
1804 max_gap = gap_stop - gap_start;
1805 }
1806 }
1807 }
1808
1809 if (pad_to_set)
1810 {
1811 bfd_vma lma;
1812 bfd_size_type size;
1813
1814 lma = bfd_section_lma (obfd, osections[c - 1]);
1815 size = bfd_section_size (obfd, osections[c - 1]);
1816 if (lma + size < pad_to)
1817 {
1818 if (! bfd_set_section_size (obfd, osections[c - 1],
1819 pad_to - lma))
1820 {
2db6cde7
NS
1821 bfd_nonfatal_message (NULL, obfd, osections[c - 1],
1822 _("can't add padding"));
252b5132
RH
1823 status = 1;
1824 }
1825 else
1826 {
1827 gaps[c - 1] = pad_to - (lma + size);
1828 if (max_gap < pad_to - (lma + size))
1829 max_gap = pad_to - (lma + size);
1830 }
1831 }
1832 }
1833 }
1834
594ef5db
NC
1835 /* Symbol filtering must happen after the output sections
1836 have been created, but before their contents are set. */
252b5132 1837 dhandle = NULL;
252b5132 1838 if (convert_debugging)
b922d590 1839 dhandle = read_debugging_info (ibfd, isympp, symcount, FALSE);
57938635
AM
1840
1841 if (strip_symbols == STRIP_DEBUG
252b5132
RH
1842 || strip_symbols == STRIP_ALL
1843 || strip_symbols == STRIP_UNNEEDED
ed1653a7 1844 || strip_symbols == STRIP_NONDEBUG
252b5132 1845 || discard_locals != LOCALS_UNDEF
d58c2e3a 1846 || localize_hidden
047c9024
NC
1847 || htab_elements (strip_specific_htab) != 0
1848 || htab_elements (keep_specific_htab) != 0
1849 || htab_elements (localize_specific_htab) != 0
1850 || htab_elements (globalize_specific_htab) != 0
1851 || htab_elements (keepglobal_specific_htab) != 0
1852 || htab_elements (weaken_specific_htab) != 0
d7fb0dd2 1853 || prefix_symbols_string
252b5132 1854 || sections_removed
f91ea849 1855 || sections_copied
252b5132
RH
1856 || convert_debugging
1857 || change_leading_char
1858 || remove_leading_char
57938635 1859 || redefine_sym_list
252b5132
RH
1860 || weaken)
1861 {
1862 /* Mark symbols used in output relocations so that they
1863 are kept, even if they are local labels or static symbols.
57938635 1864
252b5132
RH
1865 Note we iterate over the input sections examining their
1866 relocations since the relocations for the output sections
1867 haven't been set yet. mark_symbols_used_in_relocations will
1868 ignore input sections which have no corresponding output
1869 section. */
1870 if (strip_symbols != STRIP_ALL)
1871 bfd_map_over_sections (ibfd,
1872 mark_symbols_used_in_relocations,
d3ba0551 1873 isympp);
3f5e193b 1874 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
252b5132
RH
1875 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1876 }
1877
1878 if (convert_debugging && dhandle != NULL)
1879 {
1880 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1881 {
1882 status = 1;
950d48e7 1883 return FALSE;
252b5132
RH
1884 }
1885 }
1886
1887 bfd_set_symtab (obfd, osympp, symcount);
1888
1889 /* This has to happen after the symbol table has been set. */
d3ba0551 1890 bfd_map_over_sections (ibfd, copy_section, obfd);
252b5132
RH
1891
1892 if (add_sections != NULL)
1893 {
1894 struct section_add *padd;
1895
1896 for (padd = add_sections; padd != NULL; padd = padd->next)
1897 {
d3ba0551
AM
1898 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1899 0, padd->size))
950d48e7 1900 {
2db6cde7 1901 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1902 return FALSE;
1903 }
252b5132
RH
1904 }
1905 }
1906
e7c81c25
NC
1907 if (gnu_debuglink_filename != NULL)
1908 {
1909 if (! bfd_fill_in_gnu_debuglink_section
1910 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
950d48e7 1911 {
2db6cde7
NS
1912 bfd_nonfatal_message (NULL, obfd, NULL,
1913 _("cannot fill debug link section `%s'"),
1914 gnu_debuglink_filename);
950d48e7
NC
1915 return FALSE;
1916 }
e7c81c25
NC
1917 }
1918
252b5132
RH
1919 if (gap_fill_set || pad_to_set)
1920 {
1921 bfd_byte *buf;
1922 int c, i;
1923
1924 /* Fill in the gaps. */
252b5132
RH
1925 if (max_gap > 8192)
1926 max_gap = 8192;
3f5e193b 1927 buf = (bfd_byte *) xmalloc (max_gap);
d3ba0551 1928 memset (buf, gap_fill, max_gap);
252b5132
RH
1929
1930 c = bfd_count_sections (obfd);
1931 for (i = 0; i < c; i++)
1932 {
1933 if (gaps[i] != 0)
1934 {
1935 bfd_size_type left;
1936 file_ptr off;
1937
1938 left = gaps[i];
1939 off = bfd_section_size (obfd, osections[i]) - left;
594ef5db 1940
252b5132
RH
1941 while (left > 0)
1942 {
1943 bfd_size_type now;
1944
1945 if (left > 8192)
1946 now = 8192;
1947 else
1948 now = left;
1949
1950 if (! bfd_set_section_contents (obfd, osections[i], buf,
1951 off, now))
950d48e7 1952 {
2db6cde7 1953 bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
950d48e7
NC
1954 return FALSE;
1955 }
252b5132
RH
1956
1957 left -= now;
1958 off += now;
1959 }
1960 }
1961 }
1962 }
1963
d3e52d40
RS
1964 /* Do not copy backend data if --extract-symbol is passed; anything
1965 that needs to look at the section contents will fail. */
1966 if (extract_symbol)
1967 return TRUE;
1968
252b5132
RH
1969 /* Allow the BFD backend to copy any private data it understands
1970 from the input BFD to the output BFD. This is done last to
1971 permit the routine to look at the filtered symbol table, which is
1972 important for the ECOFF code at least. */
42bb2e33 1973 if (! bfd_copy_private_bfd_data (ibfd, obfd))
252b5132 1974 {
2db6cde7
NS
1975 bfd_nonfatal_message (NULL, obfd, NULL,
1976 _("error copying private BFD data"));
950d48e7 1977 return FALSE;
252b5132 1978 }
1ae8b3d2
AO
1979
1980 /* Switch to the alternate machine code. We have to do this at the
1981 very end, because we only initialize the header when we create
1982 the first section. */
f9d4ad2a
NC
1983 if (use_alt_mach_code != 0)
1984 {
1985 if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
1986 {
1987 non_fatal (_("this target does not support %lu alternative machine codes"),
1988 use_alt_mach_code);
1989 if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1990 {
1991 non_fatal (_("treating that number as an absolute e_machine value instead"));
1992 elf_elfheader (obfd)->e_machine = use_alt_mach_code;
1993 }
1994 else
1995 non_fatal (_("ignoring the alternative value"));
1996 }
1997 }
950d48e7
NC
1998
1999 return TRUE;
252b5132
RH
2000}
2001
2002/* Read each archive element in turn from IBFD, copy the
ee873e00
NC
2003 contents to temp file, and keep the temp file handle.
2004 If 'force_output_target' is TRUE then make sure that
2005 all elements in the new archive are of the type
2006 'output_target'. */
252b5132
RH
2007
2008static void
ee873e00 2009copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
8b31b6c4
NC
2010 bfd_boolean force_output_target,
2011 const bfd_arch_info_type *input_arch)
252b5132
RH
2012{
2013 struct name_list
2014 {
2015 struct name_list *next;
4c168fa3 2016 const char *name;
252b5132
RH
2017 bfd *obfd;
2018 } *list, *l;
2019 bfd **ptr = &obfd->archive_head;
2020 bfd *this_element;
8d8e0703
AM
2021 char *dir;
2022 const char *filename;
252b5132
RH
2023
2024 /* Make a temp directory to hold the contents. */
f9c026a8 2025 dir = make_tempdir (bfd_get_filename (obfd));
f9c026a8
NC
2026 if (dir == NULL)
2027 fatal (_("cannot create tempdir for archive copying (error: %s)"),
2028 strerror (errno));
84e2f313 2029
252b5132 2030 obfd->has_armap = ibfd->has_armap;
a8da6403 2031 obfd->is_thin_archive = ibfd->is_thin_archive;
252b5132
RH
2032
2033 list = NULL;
2034
2035 this_element = bfd_openr_next_archived_file (ibfd, NULL);
594ef5db 2036
b667df2e 2037 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
8d8e0703
AM
2038 {
2039 status = 1;
2040 bfd_nonfatal_message (NULL, obfd, NULL, NULL);
2041 return;
2042 }
b667df2e 2043
d3ba0551 2044 while (!status && this_element != NULL)
252b5132 2045 {
4c168fa3
AM
2046 char *output_name;
2047 bfd *output_bfd;
252b5132 2048 bfd *last_element;
8066d1a2
AS
2049 struct stat buf;
2050 int stat_status = 0;
3f5e193b 2051 bfd_boolean del = TRUE;
19094d10 2052 bfd_boolean ok_object;
8066d1a2 2053
4c168fa3
AM
2054 /* Create an output file for this member. */
2055 output_name = concat (dir, "/",
2056 bfd_get_filename (this_element), (char *) 0);
2057
2058 /* If the file already exists, make another temp dir. */
2059 if (stat (output_name, &buf) >= 0)
2060 {
f9c026a8
NC
2061 output_name = make_tempdir (output_name);
2062 if (output_name == NULL)
485be063
AM
2063 fatal (_("cannot create tempdir for archive copying (error: %s)"),
2064 strerror (errno));
84e2f313 2065
3f5e193b 2066 l = (struct name_list *) xmalloc (sizeof (struct name_list));
4c168fa3
AM
2067 l->name = output_name;
2068 l->next = list;
2069 l->obfd = NULL;
2070 list = l;
2071 output_name = concat (output_name, "/",
2072 bfd_get_filename (this_element), (char *) 0);
2073 }
2074
8066d1a2
AS
2075 if (preserve_dates)
2076 {
2077 stat_status = bfd_stat_arch_elt (this_element, &buf);
594ef5db 2078
8066d1a2
AS
2079 if (stat_status != 0)
2080 non_fatal (_("internal stat error on %s"),
2081 bfd_get_filename (this_element));
2082 }
252b5132 2083
3f5e193b 2084 l = (struct name_list *) xmalloc (sizeof (struct name_list));
252b5132
RH
2085 l->name = output_name;
2086 l->next = list;
bee59fd2 2087 l->obfd = NULL;
252b5132
RH
2088 list = l;
2089
19094d10
AM
2090 ok_object = bfd_check_format (this_element, bfd_object);
2091 if (!ok_object)
2092 bfd_nonfatal_message (NULL, this_element, NULL,
2093 _("Unable to recognise the format of file"));
2094
2095 /* PR binutils/3110: Cope with archives
2096 containing multiple target types. */
2097 if (force_output_target || !ok_object)
2098 output_bfd = bfd_openw (output_name, output_target);
2099 else
2100 output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
2101
2102 if (output_bfd == NULL)
77f762d6 2103 {
19094d10
AM
2104 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
2105 status = 1;
2106 return;
2107 }
2108
2109 if (ok_object)
2110 {
2111 del = !copy_object (this_element, output_bfd, input_arch);
ee873e00 2112
19094d10
AM
2113 if (del && bfd_get_arch (this_element) == bfd_arch_unknown)
2114 /* Try again as an unknown object file. */
2115 ok_object = FALSE;
2116 else if (!bfd_close (output_bfd))
2db6cde7
NS
2117 {
2118 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
19094d10 2119 /* Error in new object file. Don't change archive. */
2db6cde7 2120 status = 1;
77f762d6 2121 }
77f762d6 2122 }
77f762d6 2123
19094d10
AM
2124 if (!ok_object)
2125 {
3f5e193b 2126 del = !copy_unknown_object (this_element, output_bfd);
77f762d6
L
2127 if (!bfd_close_all_done (output_bfd))
2128 {
8d8e0703 2129 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
77f762d6
L
2130 /* Error in new object file. Don't change archive. */
2131 status = 1;
2132 }
252b5132
RH
2133 }
2134
3f5e193b 2135 if (del)
950d48e7
NC
2136 {
2137 unlink (output_name);
2138 status = 1;
2139 }
2140 else
2141 {
2142 if (preserve_dates && stat_status == 0)
2143 set_times (output_name, &buf);
8066d1a2 2144
950d48e7
NC
2145 /* Open the newly output file and attach to our list. */
2146 output_bfd = bfd_openr (output_name, output_target);
252b5132 2147
950d48e7 2148 l->obfd = output_bfd;
252b5132 2149
950d48e7 2150 *ptr = output_bfd;
cc481421 2151 ptr = &output_bfd->archive_next;
252b5132 2152
950d48e7 2153 last_element = this_element;
252b5132 2154
950d48e7 2155 this_element = bfd_openr_next_archived_file (ibfd, last_element);
252b5132 2156
950d48e7
NC
2157 bfd_close (last_element);
2158 }
252b5132 2159 }
d3ba0551 2160 *ptr = NULL;
252b5132 2161
8d8e0703 2162 filename = bfd_get_filename (obfd);
252b5132 2163 if (!bfd_close (obfd))
8d8e0703
AM
2164 {
2165 status = 1;
2166 bfd_nonfatal_message (filename, NULL, NULL, NULL);
2167 return;
2168 }
252b5132 2169
8d8e0703 2170 filename = bfd_get_filename (ibfd);
252b5132 2171 if (!bfd_close (ibfd))
8d8e0703
AM
2172 {
2173 status = 1;
2174 bfd_nonfatal_message (filename, NULL, NULL, NULL);
2175 return;
2176 }
252b5132
RH
2177
2178 /* Delete all the files that we opened. */
2179 for (l = list; l != NULL; l = l->next)
2180 {
4c168fa3
AM
2181 if (l->obfd == NULL)
2182 rmdir (l->name);
2183 else
2184 {
2185 bfd_close (l->obfd);
2186 unlink (l->name);
2187 }
252b5132
RH
2188 }
2189 rmdir (dir);
2190}
2191
0408dee6
DK
2192static void
2193set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style)
2194{
2195 /* This is only relevant to Coff targets. */
2196 if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
2197 {
78e82dc3
AM
2198 if (style == KEEP
2199 && bfd_get_flavour (input_bfd) == bfd_target_coff_flavour)
0408dee6
DK
2200 style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE;
2201 bfd_coff_set_long_section_names (output_bfd, style != DISABLE);
2202 }
2203}
2204
252b5132
RH
2205/* The top-level control. */
2206
2207static void
84e2f313 2208copy_file (const char *input_filename, const char *output_filename,
8b31b6c4
NC
2209 const char *input_target, const char *output_target,
2210 const bfd_arch_info_type *input_arch)
252b5132
RH
2211{
2212 bfd *ibfd;
49c12576
AM
2213 char **obj_matching;
2214 char **core_matching;
52a476ee 2215 off_t size = get_file_size (input_filename);
252b5132 2216
52a476ee 2217 if (size < 1)
f24ddbdd 2218 {
52a476ee
L
2219 if (size == 0)
2220 non_fatal (_("error: the input file '%s' is empty"),
2221 input_filename);
f24ddbdd
NC
2222 status = 1;
2223 return;
2224 }
2225
252b5132
RH
2226 /* To allow us to do "strip *" without dying on the first
2227 non-object file, failures are nonfatal. */
252b5132
RH
2228 ibfd = bfd_openr (input_filename, input_target);
2229 if (ibfd == NULL)
2db6cde7
NS
2230 {
2231 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2232 status = 1;
2233 return;
2234 }
252b5132 2235
4a114e3e
L
2236 switch (do_debug_sections)
2237 {
2238 case compress:
2239 ibfd->flags |= BFD_COMPRESS;
2240 break;
2241 case decompress:
2242 ibfd->flags |= BFD_DECOMPRESS;
2243 break;
2244 default:
2245 break;
2246 }
2247
252b5132
RH
2248 if (bfd_check_format (ibfd, bfd_archive))
2249 {
ee873e00 2250 bfd_boolean force_output_target;
252b5132
RH
2251 bfd *obfd;
2252
2253 /* bfd_get_target does not return the correct value until
2254 bfd_check_format succeeds. */
2255 if (output_target == NULL)
ee873e00
NC
2256 {
2257 output_target = bfd_get_target (ibfd);
2258 force_output_target = FALSE;
2259 }
2260 else
2261 force_output_target = TRUE;
252b5132
RH
2262
2263 obfd = bfd_openw (output_filename, output_target);
2264 if (obfd == NULL)
2db6cde7
NS
2265 {
2266 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2267 status = 1;
2268 return;
2269 }
0408dee6
DK
2270 /* This is a no-op on non-Coff targets. */
2271 set_long_section_mode (obfd, ibfd, long_section_names);
252b5132 2272
8b31b6c4 2273 copy_archive (ibfd, obfd, output_target, force_output_target, input_arch);
252b5132 2274 }
49c12576 2275 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
252b5132
RH
2276 {
2277 bfd *obfd;
49c12576 2278 do_copy:
950d48e7 2279
252b5132
RH
2280 /* bfd_get_target does not return the correct value until
2281 bfd_check_format succeeds. */
2282 if (output_target == NULL)
2283 output_target = bfd_get_target (ibfd);
2284
2285 obfd = bfd_openw (output_filename, output_target);
2286 if (obfd == NULL)
2db6cde7
NS
2287 {
2288 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2289 status = 1;
2290 return;
2291 }
0408dee6
DK
2292 /* This is a no-op on non-Coff targets. */
2293 set_long_section_mode (obfd, ibfd, long_section_names);
252b5132 2294
8b31b6c4 2295 if (! copy_object (ibfd, obfd, input_arch))
a580b8e0 2296 status = 1;
252b5132
RH
2297
2298 if (!bfd_close (obfd))
8d8e0703
AM
2299 {
2300 status = 1;
2301 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2302 return;
2303 }
252b5132
RH
2304
2305 if (!bfd_close (ibfd))
8d8e0703
AM
2306 {
2307 status = 1;
2308 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2309 return;
2310 }
252b5132
RH
2311 }
2312 else
2313 {
49c12576
AM
2314 bfd_error_type obj_error = bfd_get_error ();
2315 bfd_error_type core_error;
b34976b6 2316
49c12576
AM
2317 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
2318 {
2319 /* This probably can't happen.. */
2320 if (obj_error == bfd_error_file_ambiguously_recognized)
2321 free (obj_matching);
2322 goto do_copy;
2323 }
2324
2325 core_error = bfd_get_error ();
2326 /* Report the object error in preference to the core error. */
2327 if (obj_error != core_error)
2328 bfd_set_error (obj_error);
2329
2db6cde7 2330 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
57938635 2331
49c12576
AM
2332 if (obj_error == bfd_error_file_ambiguously_recognized)
2333 {
2334 list_matching_formats (obj_matching);
2335 free (obj_matching);
2336 }
2337 if (core_error == bfd_error_file_ambiguously_recognized)
252b5132 2338 {
49c12576
AM
2339 list_matching_formats (core_matching);
2340 free (core_matching);
252b5132 2341 }
57938635 2342
252b5132
RH
2343 status = 1;
2344 }
2345}
2346
594ef5db
NC
2347/* Add a name to the section renaming list. */
2348
2349static void
84e2f313
NC
2350add_section_rename (const char * old_name, const char * new_name,
2351 flagword flags)
594ef5db 2352{
91d6fa6a 2353 section_rename * srename;
594ef5db
NC
2354
2355 /* Check for conflicts first. */
91d6fa6a
NC
2356 for (srename = section_rename_list; srename != NULL; srename = srename->next)
2357 if (strcmp (srename->old_name, old_name) == 0)
594ef5db
NC
2358 {
2359 /* Silently ignore duplicate definitions. */
91d6fa6a
NC
2360 if (strcmp (srename->new_name, new_name) == 0
2361 && srename->flags == flags)
594ef5db 2362 return;
0af11b59 2363
594ef5db
NC
2364 fatal (_("Multiple renames of section %s"), old_name);
2365 }
2366
91d6fa6a 2367 srename = (section_rename *) xmalloc (sizeof (* srename));
594ef5db 2368
91d6fa6a
NC
2369 srename->old_name = old_name;
2370 srename->new_name = new_name;
2371 srename->flags = flags;
2372 srename->next = section_rename_list;
0af11b59 2373
91d6fa6a 2374 section_rename_list = srename;
594ef5db
NC
2375}
2376
2377/* Check the section rename list for a new name of the input section
2378 ISECTION. Return the new name if one is found.
2379 Also set RETURNED_FLAGS to the flags to be used for this section. */
2380
2381static const char *
84e2f313
NC
2382find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
2383 flagword * returned_flags)
594ef5db
NC
2384{
2385 const char * old_name = bfd_section_name (ibfd, isection);
91d6fa6a 2386 section_rename * srename;
594ef5db
NC
2387
2388 /* Default to using the flags of the input section. */
2389 * returned_flags = bfd_get_section_flags (ibfd, isection);
2390
91d6fa6a
NC
2391 for (srename = section_rename_list; srename != NULL; srename = srename->next)
2392 if (strcmp (srename->old_name, old_name) == 0)
594ef5db 2393 {
91d6fa6a
NC
2394 if (srename->flags != (flagword) -1)
2395 * returned_flags = srename->flags;
594ef5db 2396
91d6fa6a 2397 return srename->new_name;
594ef5db
NC
2398 }
2399
2400 return old_name;
2401}
2402
80fccad2
BW
2403/* Once each of the sections is copied, we may still need to do some
2404 finalization work for private section headers. Do that here. */
2405
2406static void
2407setup_bfd_headers (bfd *ibfd, bfd *obfd)
2408{
80fccad2
BW
2409 /* Allow the BFD backend to copy any private data it understands
2410 from the input section to the output section. */
2411 if (! bfd_copy_private_header_data (ibfd, obfd))
2412 {
2db6cde7
NS
2413 status = 1;
2414 bfd_nonfatal_message (NULL, ibfd, NULL,
8d8e0703 2415 _("error in private header data"));
2db6cde7 2416 return;
80fccad2
BW
2417 }
2418
2419 /* All went well. */
2420 return;
80fccad2
BW
2421}
2422
594ef5db
NC
2423/* Create a section in OBFD with the same
2424 name and attributes as ISECTION in IBFD. */
252b5132
RH
2425
2426static void
84e2f313 2427setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 2428{
3f5e193b 2429 bfd *obfd = (bfd *) obfdarg;
252b5132
RH
2430 struct section_list *p;
2431 sec_ptr osection;
2432 bfd_size_type size;
2433 bfd_vma vma;
2434 bfd_vma lma;
2435 flagword flags;
1a89cc7d 2436 const char *err;
594ef5db 2437 const char * name;
d7fb0dd2 2438 char *prefix = NULL;
66125551 2439 bfd_boolean make_nobits;
0af11b59 2440
2593f09a 2441 if (is_strip_section (ibfd, isection))
252b5132
RH
2442 return;
2443
b34976b6 2444 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
252b5132 2445 if (p != NULL)
b34976b6 2446 p->used = TRUE;
252b5132 2447
594ef5db
NC
2448 /* Get the, possibly new, name of the output section. */
2449 name = find_section_rename (ibfd, isection, & flags);
0af11b59 2450
d7fb0dd2 2451 /* Prefix sections. */
84e2f313
NC
2452 if ((prefix_alloc_sections_string)
2453 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
d7fb0dd2
NC
2454 prefix = prefix_alloc_sections_string;
2455 else if (prefix_sections_string)
2456 prefix = prefix_sections_string;
2457
2458 if (prefix)
2459 {
2460 char *n;
2461
3f5e193b 2462 n = (char *) xmalloc (strlen (prefix) + strlen (name) + 1);
d7fb0dd2
NC
2463 strcpy (n, prefix);
2464 strcat (n, name);
2465 name = n;
2466 }
66491ebc 2467
66125551 2468 make_nobits = FALSE;
551b43fd
AM
2469 if (p != NULL && p->set_flags)
2470 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
42bb2e33 2471 else if (strip_symbols == STRIP_NONDEBUG
6c67a030
AM
2472 && (flags & (SEC_ALLOC | SEC_GROUP)) != 0
2473 && !(ibfd->xvec->flavour == bfd_target_elf_flavour
2474 && elf_section_type (isection) == SHT_NOTE))
66125551 2475 {
6c67a030 2476 flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
66125551
AM
2477 if (obfd->xvec->flavour == bfd_target_elf_flavour)
2478 {
2479 make_nobits = TRUE;
2480
2481 /* Twiddle the input section flags so that it seems to
2482 elf.c:copy_private_bfd_data that section flags have not
2483 changed between input and output sections. This hack
2484 prevents wholesale rewriting of the program headers. */
6c67a030 2485 isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
66125551
AM
2486 }
2487 }
551b43fd
AM
2488
2489 osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
57938635 2490
252b5132
RH
2491 if (osection == NULL)
2492 {
2db6cde7 2493 err = _("failed to create output section");
252b5132
RH
2494 goto loser;
2495 }
2496
66125551 2497 if (make_nobits)
551b43fd
AM
2498 elf_section_type (osection) = SHT_NOBITS;
2499
252b5132
RH
2500 size = bfd_section_size (ibfd, isection);
2501 if (copy_byte >= 0)
b7dd81f7 2502 size = (size + interleave - 1) / interleave * copy_width;
d3e52d40
RS
2503 else if (extract_symbol)
2504 size = 0;
252b5132
RH
2505 if (! bfd_set_section_size (obfd, osection, size))
2506 {
2db6cde7 2507 err = _("failed to set size");
252b5132
RH
2508 goto loser;
2509 }
57938635 2510
252b5132
RH
2511 vma = bfd_section_vma (ibfd, isection);
2512 if (p != NULL && p->change_vma == CHANGE_MODIFY)
2513 vma += p->vma_val;
2514 else if (p != NULL && p->change_vma == CHANGE_SET)
2515 vma = p->vma_val;
2516 else
2517 vma += change_section_address;
57938635 2518
237dcb53 2519 if (! bfd_set_section_vma (obfd, osection, vma))
252b5132 2520 {
2db6cde7 2521 err = _("failed to set vma");
252b5132
RH
2522 goto loser;
2523 }
2524
2525 lma = isection->lma;
2526 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2527 {
2528 if (p->change_lma == CHANGE_MODIFY)
2529 lma += p->lma_val;
2530 else if (p->change_lma == CHANGE_SET)
2531 lma = p->lma_val;
2532 else
2533 abort ();
2534 }
2535 else
2536 lma += change_section_address;
57938635 2537
237dcb53 2538 osection->lma = lma;
252b5132
RH
2539
2540 /* FIXME: This is probably not enough. If we change the LMA we
2541 may have to recompute the header for the file as well. */
b34976b6
AM
2542 if (!bfd_set_section_alignment (obfd,
2543 osection,
2544 bfd_section_alignment (ibfd, isection)))
252b5132 2545 {
2db6cde7 2546 err = _("failed to set alignment");
252b5132
RH
2547 goto loser;
2548 }
2549
bc408b8a
JJ
2550 /* Copy merge entity size. */
2551 osection->entsize = isection->entsize;
2552
252b5132
RH
2553 /* This used to be mangle_section; we do here to avoid using
2554 bfd_get_section_by_name since some formats allow multiple
2555 sections with the same name. */
2556 isection->output_section = osection;
237dcb53 2557 isection->output_offset = 0;
d3e52d40
RS
2558
2559 /* Do not copy backend data if --extract-symbol is passed; anything
2560 that needs to look at the section contents will fail. */
2561 if (extract_symbol)
2562 return;
252b5132 2563
119f4245
AM
2564 if ((isection->flags & SEC_GROUP) != 0)
2565 {
2566 asymbol *gsym = group_signature (isection);
2567
2568 if (gsym != NULL)
2569 {
2570 gsym->flags |= BSF_KEEP;
2571 if (ibfd->xvec->flavour == bfd_target_elf_flavour)
2572 elf_group_id (isection) = gsym;
2573 }
2574 }
2575
252b5132
RH
2576 /* Allow the BFD backend to copy any private data it understands
2577 from the input section to the output section. */
42bb2e33 2578 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
252b5132 2579 {
2db6cde7 2580 err = _("failed to copy private data");
252b5132
RH
2581 goto loser;
2582 }
2583
594ef5db 2584 /* All went well. */
252b5132
RH
2585 return;
2586
2587loser:
252b5132 2588 status = 1;
2db6cde7 2589 bfd_nonfatal_message (NULL, obfd, osection, err);
252b5132
RH
2590}
2591
2592/* Copy the data of input section ISECTION of IBFD
2593 to an output section with the same name in OBFD.
2594 If stripping then don't copy any relocation info. */
2595
2596static void
84e2f313 2597copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 2598{
3f5e193b 2599 bfd *obfd = (bfd *) obfdarg;
252b5132
RH
2600 struct section_list *p;
2601 arelent **relpp;
2602 long relcount;
2603 sec_ptr osection;
2604 bfd_size_type size;
2605 long relsize;
dc156bc0 2606 flagword flags;
252b5132 2607
594ef5db
NC
2608 /* If we have already failed earlier on,
2609 do not keep on generating complaints now. */
252b5132
RH
2610 if (status != 0)
2611 return;
57938635 2612
2593f09a 2613 if (is_strip_section (ibfd, isection))
e0c60db2 2614 return;
252b5132 2615
2593f09a 2616 flags = bfd_get_section_flags (ibfd, isection);
dc156bc0
AM
2617 if ((flags & SEC_GROUP) != 0)
2618 return;
2619
252b5132 2620 osection = isection->output_section;
135dfb4a 2621 size = bfd_get_section_size (isection);
252b5132
RH
2622
2623 if (size == 0 || osection == 0)
2624 return;
2625
237dcb53
AM
2626 if (extract_symbol)
2627 return;
2628
2593f09a
NC
2629 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2630
0af11b59 2631 /* Core files do not need to be relocated. */
4dd67f29
MS
2632 if (bfd_get_format (obfd) == bfd_core)
2633 relsize = 0;
2634 else
ed570f48
NC
2635 {
2636 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
4dd67f29 2637
ed570f48
NC
2638 if (relsize < 0)
2639 {
2640 /* Do not complain if the target does not support relocations. */
2641 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2642 relsize = 0;
2643 else
2db6cde7
NS
2644 {
2645 status = 1;
2646 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2647 return;
2648 }
ed570f48
NC
2649 }
2650 }
57938635 2651
252b5132 2652 if (relsize == 0)
d3ba0551 2653 bfd_set_reloc (obfd, osection, NULL, 0);
252b5132
RH
2654 else
2655 {
3f5e193b 2656 relpp = (arelent **) xmalloc (relsize);
252b5132
RH
2657 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2658 if (relcount < 0)
2db6cde7
NS
2659 {
2660 status = 1;
2661 bfd_nonfatal_message (NULL, ibfd, isection,
2662 _("relocation count is negative"));
2663 return;
2664 }
57938635 2665
252b5132
RH
2666 if (strip_symbols == STRIP_ALL)
2667 {
2668 /* Remove relocations which are not in
0af11b59 2669 keep_strip_specific_list. */
252b5132
RH
2670 arelent **temp_relpp;
2671 long temp_relcount = 0;
2672 long i;
57938635 2673
3f5e193b 2674 temp_relpp = (arelent **) xmalloc (relsize);
252b5132 2675 for (i = 0; i < relcount; i++)
d3ba0551 2676 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
047c9024 2677 keep_specific_htab))
252b5132
RH
2678 temp_relpp [temp_relcount++] = relpp [i];
2679 relcount = temp_relcount;
2680 free (relpp);
2681 relpp = temp_relpp;
2682 }
e0c60db2 2683
d3ba0551 2684 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
f0312d39
JJ
2685 if (relcount == 0)
2686 free (relpp);
252b5132 2687 }
57938635 2688
0af11b59 2689 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
4dd67f29 2690 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
252b5132 2691 {
4a114e3e 2692 bfd_byte *memhunk = NULL;
252b5132 2693
4a114e3e 2694 if (!bfd_get_full_section_contents (ibfd, isection, &memhunk))
2db6cde7
NS
2695 {
2696 status = 1;
2697 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2698 return;
2699 }
252b5132 2700
9e48b4c6
NC
2701 if (reverse_bytes)
2702 {
2703 /* We don't handle leftover bytes (too many possible behaviors,
2704 and we don't know what the user wants). The section length
2705 must be a multiple of the number of bytes to swap. */
2706 if ((size % reverse_bytes) == 0)
2707 {
2708 unsigned long i, j;
2709 bfd_byte b;
2710
2711 for (i = 0; i < size; i += reverse_bytes)
2712 for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2713 {
2714 bfd_byte *m = (bfd_byte *) memhunk;
2715
2716 b = m[i + j];
2717 m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2718 m[(i + reverse_bytes) - (j + 1)] = b;
2719 }
2720 }
2721 else
2722 /* User must pad the section up in order to do this. */
2723 fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2724 bfd_section_name (ibfd, isection), reverse_bytes);
2725 }
2726
57938635 2727 if (copy_byte >= 0)
5e675b72
AM
2728 {
2729 /* Keep only every `copy_byte'th byte in MEMHUNK. */
2f01ffbf 2730 char *from = (char *) memhunk + copy_byte;
3f5e193b 2731 char *to = (char *) memhunk;
2f01ffbf 2732 char *end = (char *) memhunk + size;
b7dd81f7 2733 int i;
5e675b72
AM
2734
2735 for (; from < end; from += interleave)
b7dd81f7
NC
2736 for (i = 0; i < copy_width; i++)
2737 *to++ = from[i];
5e675b72 2738
b7dd81f7 2739 size = (size + interleave - 1 - copy_byte) / interleave * copy_width;
5e675b72
AM
2740 osection->lma /= interleave;
2741 }
252b5132 2742
d3ba0551 2743 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2db6cde7
NS
2744 {
2745 status = 1;
2746 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2747 return;
2748 }
252b5132
RH
2749 free (memhunk);
2750 }
2751 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2752 {
d3ba0551 2753 void *memhunk = xmalloc (size);
252b5132
RH
2754
2755 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2756 flag--they can just remove the section entirely and add it
2757 back again. However, we do permit them to turn on the
2758 SEC_HAS_CONTENTS flag, and take it to mean that the section
2759 contents should be zeroed out. */
2760
2761 memset (memhunk, 0, size);
d3ba0551 2762 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2db6cde7
NS
2763 {
2764 status = 1;
2765 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2766 return;
2767 }
252b5132
RH
2768 free (memhunk);
2769 }
2770}
2771
2772/* Get all the sections. This is used when --gap-fill or --pad-to is
2773 used. */
2774
2775static void
84e2f313 2776get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
252b5132 2777{
3f5e193b 2778 asection ***secppp = (asection ***) secppparg;
252b5132
RH
2779
2780 **secppp = osection;
2781 ++(*secppp);
2782}
2783
2784/* Sort sections by VMA. This is called via qsort, and is used when
2785 --gap-fill or --pad-to is used. We force non loadable or empty
2786 sections to the front, where they are easier to ignore. */
2787
2788static int
84e2f313 2789compare_section_lma (const void *arg1, const void *arg2)
252b5132 2790{
3f5e193b
NC
2791 const asection *const *sec1 = (const asection * const *) arg1;
2792 const asection *const *sec2 = (const asection * const *) arg2;
252b5132
RH
2793 flagword flags1, flags2;
2794
2795 /* Sort non loadable sections to the front. */
2796 flags1 = (*sec1)->flags;
2797 flags2 = (*sec2)->flags;
2798 if ((flags1 & SEC_HAS_CONTENTS) == 0
2799 || (flags1 & SEC_LOAD) == 0)
2800 {
2801 if ((flags2 & SEC_HAS_CONTENTS) != 0
2802 && (flags2 & SEC_LOAD) != 0)
2803 return -1;
2804 }
2805 else
2806 {
2807 if ((flags2 & SEC_HAS_CONTENTS) == 0
2808 || (flags2 & SEC_LOAD) == 0)
2809 return 1;
2810 }
2811
2812 /* Sort sections by LMA. */
2813 if ((*sec1)->lma > (*sec2)->lma)
2814 return 1;
2815 else if ((*sec1)->lma < (*sec2)->lma)
2816 return -1;
2817
2818 /* Sort sections with the same LMA by size. */
135dfb4a 2819 if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
252b5132 2820 return 1;
135dfb4a 2821 else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
252b5132
RH
2822 return -1;
2823
2824 return 0;
2825}
2826
2827/* Mark all the symbols which will be used in output relocations with
2828 the BSF_KEEP flag so that those symbols will not be stripped.
2829
2830 Ignore relocations which will not appear in the output file. */
2831
2832static void
84e2f313 2833mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
252b5132 2834{
3f5e193b 2835 asymbol **symbols = (asymbol **) symbolsarg;
252b5132
RH
2836 long relsize;
2837 arelent **relpp;
2838 long relcount, i;
2839
2840 /* Ignore an input section with no corresponding output section. */
2841 if (isection->output_section == NULL)
2842 return;
2843
2844 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2845 if (relsize < 0)
ed570f48
NC
2846 {
2847 /* Do not complain if the target does not support relocations. */
2848 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2849 return;
2850 bfd_fatal (bfd_get_filename (ibfd));
2851 }
252b5132
RH
2852
2853 if (relsize == 0)
2854 return;
2855
3f5e193b 2856 relpp = (arelent **) xmalloc (relsize);
252b5132
RH
2857 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2858 if (relcount < 0)
2859 bfd_fatal (bfd_get_filename (ibfd));
2860
ec5d57d5
NC
2861 /* Examine each symbol used in a relocation. If it's not one of the
2862 special bfd section symbols, then mark it with BSF_KEEP. */
252b5132
RH
2863 for (i = 0; i < relcount; i++)
2864 {
ec5d57d5
NC
2865 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2866 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2867 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2868 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
252b5132
RH
2869 }
2870
2871 if (relpp != NULL)
2872 free (relpp);
2873}
2874
2875/* Write out debugging information. */
2876
b34976b6 2877static bfd_boolean
84e2f313
NC
2878write_debugging_info (bfd *obfd, void *dhandle,
2879 long *symcountp ATTRIBUTE_UNUSED,
2880 asymbol ***symppp ATTRIBUTE_UNUSED)
252b5132
RH
2881{
2882 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2883 return write_ieee_debugging_info (obfd, dhandle);
2884
2885 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2886 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2887 {
2888 bfd_byte *syms, *strings;
2889 bfd_size_type symsize, stringsize;
2890 asection *stabsec, *stabstrsec;
551b43fd 2891 flagword flags;
252b5132
RH
2892
2893 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2894 &symsize, &strings,
2895 &stringsize))
b34976b6 2896 return FALSE;
252b5132 2897
551b43fd
AM
2898 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2899 stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2900 stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
252b5132
RH
2901 if (stabsec == NULL
2902 || stabstrsec == NULL
2903 || ! bfd_set_section_size (obfd, stabsec, symsize)
2904 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2905 || ! bfd_set_section_alignment (obfd, stabsec, 2)
551b43fd 2906 || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
252b5132 2907 {
2db6cde7
NS
2908 bfd_nonfatal_message (NULL, obfd, NULL,
2909 _("can't create debugging section"));
b34976b6 2910 return FALSE;
252b5132
RH
2911 }
2912
2913 /* We can get away with setting the section contents now because
2914 the next thing the caller is going to do is copy over the
2915 real sections. We may someday have to split the contents
2916 setting out of this function. */
d3ba0551
AM
2917 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2918 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2919 stringsize))
252b5132 2920 {
2db6cde7
NS
2921 bfd_nonfatal_message (NULL, obfd, NULL,
2922 _("can't set debugging section contents"));
b34976b6 2923 return FALSE;
252b5132
RH
2924 }
2925
b34976b6 2926 return TRUE;
252b5132
RH
2927 }
2928
2db6cde7
NS
2929 bfd_nonfatal_message (NULL, obfd, NULL,
2930 _("don't know how to write debugging information for %s"),
2931 bfd_get_target (obfd));
b34976b6 2932 return FALSE;
252b5132
RH
2933}
2934
2935static int
84e2f313 2936strip_main (int argc, char *argv[])
252b5132 2937{
7c29036b
NC
2938 char *input_target = NULL;
2939 char *output_target = NULL;
b34976b6 2940 bfd_boolean show_version = FALSE;
7c29036b
NC
2941 bfd_boolean formats_info = FALSE;
2942 int c;
2943 int i;
252b5132
RH
2944 struct section_list *p;
2945 char *output_file = NULL;
2946
5fe11841 2947 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
252b5132
RH
2948 strip_options, (int *) 0)) != EOF)
2949 {
2950 switch (c)
2951 {
2952 case 'I':
2953 input_target = optarg;
2954 break;
2955 case 'O':
2956 output_target = optarg;
2957 break;
2958 case 'F':
2959 input_target = output_target = optarg;
2960 break;
2961 case 'R':
b34976b6
AM
2962 p = find_section_list (optarg, TRUE);
2963 p->remove = TRUE;
2964 sections_removed = TRUE;
252b5132
RH
2965 break;
2966 case 's':
2967 strip_symbols = STRIP_ALL;
2968 break;
2969 case 'S':
2970 case 'g':
db4f6831 2971 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
252b5132
RH
2972 strip_symbols = STRIP_DEBUG;
2973 break;
2974 case OPTION_STRIP_UNNEEDED:
2975 strip_symbols = STRIP_UNNEEDED;
2976 break;
2977 case 'K':
047c9024 2978 add_specific_symbol (optarg, keep_specific_htab);
252b5132
RH
2979 break;
2980 case 'N':
047c9024 2981 add_specific_symbol (optarg, strip_specific_htab);
252b5132
RH
2982 break;
2983 case 'o':
2984 output_file = optarg;
2985 break;
2986 case 'p':
b34976b6 2987 preserve_dates = TRUE;
252b5132
RH
2988 break;
2989 case 'x':
2990 discard_locals = LOCALS_ALL;
2991 break;
2992 case 'X':
2993 discard_locals = LOCALS_START_L;
2994 break;
2995 case 'v':
b34976b6 2996 verbose = TRUE;
252b5132
RH
2997 break;
2998 case 'V':
b34976b6 2999 show_version = TRUE;
252b5132 3000 break;
7c29036b
NC
3001 case OPTION_FORMATS_INFO:
3002 formats_info = TRUE;
3003 break;
ed1653a7
NC
3004 case OPTION_ONLY_KEEP_DEBUG:
3005 strip_symbols = STRIP_NONDEBUG;
3006 break;
1637cd90
JB
3007 case OPTION_KEEP_FILE_SYMBOLS:
3008 keep_file_symbols = 1;
3009 break;
252b5132 3010 case 0:
594ef5db
NC
3011 /* We've been given a long option. */
3012 break;
5fe11841
NC
3013 case 'w':
3014 wildcard = TRUE;
3015 break;
8b53311e 3016 case 'H':
252b5132
RH
3017 case 'h':
3018 strip_usage (stdout, 0);
3019 default:
3020 strip_usage (stderr, 1);
3021 }
3022 }
3023
84e2f313
NC
3024 if (formats_info)
3025 {
3026 display_info ();
3027 return 0;
3028 }
c1c0eb9e 3029
252b5132
RH
3030 if (show_version)
3031 print_version ("strip");
3032
3033 /* Default is to strip all symbols. */
3034 if (strip_symbols == STRIP_UNDEF
3035 && discard_locals == LOCALS_UNDEF
047c9024 3036 && htab_elements (strip_specific_htab) == 0)
252b5132
RH
3037 strip_symbols = STRIP_ALL;
3038
d3ba0551 3039 if (output_target == NULL)
252b5132
RH
3040 output_target = input_target;
3041
3042 i = optind;
3043 if (i == argc
3044 || (output_file != NULL && (i + 1) < argc))
3045 strip_usage (stderr, 1);
3046
3047 for (; i < argc; i++)
3048 {
3049 int hold_status = status;
3050 struct stat statbuf;
3051 char *tmpname;
3052
f24ddbdd 3053 if (get_file_size (argv[i]) < 1)
d68c385b
NC
3054 {
3055 status = 1;
3056 continue;
3057 }
f24ddbdd 3058
252b5132 3059 if (preserve_dates)
f24ddbdd
NC
3060 /* No need to check the return value of stat().
3061 It has already been checked in get_file_size(). */
3062 stat (argv[i], &statbuf);
252b5132 3063
8b6efd89
KT
3064 if (output_file == NULL
3065 || filename_cmp (argv[i], output_file) == 0)
252b5132 3066 tmpname = make_tempname (argv[i]);
12f498a7
NS
3067 else
3068 tmpname = output_file;
252b5132 3069
f9c026a8
NC
3070 if (tmpname == NULL)
3071 {
2db6cde7
NS
3072 bfd_nonfatal_message (argv[i], NULL, NULL,
3073 _("could not create temporary file to hold stripped copy"));
f9c026a8
NC
3074 status = 1;
3075 continue;
3076 }
3077
d68c385b 3078 status = 0;
8b31b6c4 3079 copy_file (argv[i], tmpname, input_target, output_target, NULL);
252b5132
RH
3080 if (status == 0)
3081 {
3082 if (preserve_dates)
3083 set_times (tmpname, &statbuf);
12f498a7 3084 if (output_file != tmpname)
92fac5ec
L
3085 status = (smart_rename (tmpname,
3086 output_file ? output_file : argv[i],
3087 preserve_dates) != 0);
3088 if (status == 0)
3089 status = hold_status;
252b5132
RH
3090 }
3091 else
bb14f524 3092 unlink_if_ordinary (tmpname);
12f498a7 3093 if (output_file != tmpname)
252b5132
RH
3094 free (tmpname);
3095 }
3096
d68c385b 3097 return status;
252b5132
RH
3098}
3099
92dd4511
L
3100/* Set up PE subsystem. */
3101
3102static void
3103set_pe_subsystem (const char *s)
3104{
3105 const char *version, *subsystem;
3106 size_t i;
3107 static const struct
3108 {
3109 const char *name;
3110 const char set_def;
3111 const short value;
3112 }
3113 v[] =
3114 {
3115 { "native", 0, IMAGE_SUBSYSTEM_NATIVE },
3116 { "windows", 0, IMAGE_SUBSYSTEM_WINDOWS_GUI },
3117 { "console", 0, IMAGE_SUBSYSTEM_WINDOWS_CUI },
3118 { "posix", 0, IMAGE_SUBSYSTEM_POSIX_CUI },
3119 { "wince", 0, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI },
3120 { "efi-app", 1, IMAGE_SUBSYSTEM_EFI_APPLICATION },
3121 { "efi-bsd", 1, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER },
3122 { "efi-rtd", 1, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER },
d9118602 3123 { "sal-rtd", 1, IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER },
92dd4511
L
3124 { "xbox", 0, IMAGE_SUBSYSTEM_XBOX }
3125 };
3126 short value;
3127 char *copy;
3128 int set_def = -1;
3129
3130 /* Check for the presence of a version number. */
3131 version = strchr (s, ':');
3132 if (version == NULL)
3133 subsystem = s;
3134 else
3135 {
3136 int len = version - s;
3137 copy = xstrdup (s);
3138 subsystem = copy;
3139 copy[len] = '\0';
3140 version = copy + 1 + len;
3141 pe_major_subsystem_version = strtoul (version, &copy, 0);
3142 if (*copy == '.')
3143 pe_minor_subsystem_version = strtoul (copy + 1, &copy, 0);
3144 if (*copy != '\0')
3145 non_fatal (_("%s: bad version in PE subsystem"), s);
3146 }
3147
3148 /* Check for numeric subsystem. */
3149 value = (short) strtol (subsystem, &copy, 0);
3150 if (*copy == '\0')
3151 {
3152 for (i = 0; i < ARRAY_SIZE (v); i++)
3153 if (v[i].value == value)
3154 {
3155 pe_subsystem = value;
3156 set_def = v[i].set_def;
3157 break;
3158 }
3159 }
3160 else
3161 {
3162 /* Search for subsystem by name. */
3163 for (i = 0; i < ARRAY_SIZE (v); i++)
3164 if (strcmp (subsystem, v[i].name) == 0)
3165 {
3166 pe_subsystem = v[i].value;
3167 set_def = v[i].set_def;
3168 break;
3169 }
3170 }
3171
3172 switch (set_def)
3173 {
3174 case -1:
3175 fatal (_("unknown PE subsystem: %s"), s);
3176 break;
3177 case 0:
3178 break;
3179 default:
3180 if (pe_file_alignment == (bfd_vma) -1)
3181 pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
3182 if (pe_section_alignment == (bfd_vma) -1)
3183 pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
3184 break;
3185 }
0cbf3531
MS
3186 if (s != subsystem)
3187 free ((char *) subsystem);
92dd4511
L
3188}
3189
3190/* Convert EFI target to PEI target. */
3191
3192static void
3193convert_efi_target (char *efi)
3194{
3195 efi[0] = 'p';
3196 efi[1] = 'e';
3197 efi[2] = 'i';
3198
3199 if (strcmp (efi + 4, "ia32") == 0)
3200 {
3201 /* Change ia32 to i386. */
3202 efi[5]= '3';
3203 efi[6]= '8';
3204 efi[7]= '6';
3205 }
3206 else if (strcmp (efi + 4, "x86_64") == 0)
3207 {
3208 /* Change x86_64 to x86-64. */
3209 efi[7] = '-';
3210 }
3211}
3212
252b5132 3213static int
84e2f313 3214copy_main (int argc, char *argv[])
252b5132 3215{
7c29036b
NC
3216 char *input_filename = NULL;
3217 char *output_filename = NULL;
c1c0eb9e 3218 char *tmpname;
7c29036b
NC
3219 char *input_target = NULL;
3220 char *output_target = NULL;
b34976b6
AM
3221 bfd_boolean show_version = FALSE;
3222 bfd_boolean change_warn = TRUE;
7c29036b 3223 bfd_boolean formats_info = FALSE;
252b5132
RH
3224 int c;
3225 struct section_list *p;
3226 struct stat statbuf;
8b31b6c4 3227 const bfd_arch_info_type *input_arch = NULL;
252b5132 3228
5fe11841 3229 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
252b5132
RH
3230 copy_options, (int *) 0)) != EOF)
3231 {
3232 switch (c)
3233 {
3234 case 'b':
3235 copy_byte = atoi (optarg);
3236 if (copy_byte < 0)
3237 fatal (_("byte number must be non-negative"));
3238 break;
57938635 3239
0af11b59 3240 case 'B':
8b31b6c4
NC
3241 input_arch = bfd_scan_arch (optarg);
3242 if (input_arch == NULL)
3243 fatal (_("architecture %s unknown"), optarg);
0af11b59 3244 break;
43a0748c 3245
252b5132 3246 case 'i':
b7dd81f7
NC
3247 if (optarg)
3248 {
3249 interleave = atoi (optarg);
3250 if (interleave < 1)
3251 fatal (_("interleave must be positive"));
3252 }
3253 else
3254 interleave = 4;
3255 break;
3256
3257 case OPTION_INTERLEAVE_WIDTH:
3258 copy_width = atoi (optarg);
3259 if (copy_width < 1)
3260 fatal(_("interleave width must be positive"));
252b5132 3261 break;
57938635 3262
252b5132
RH
3263 case 'I':
3264 case 's': /* "source" - 'I' is preferred */
3265 input_target = optarg;
3266 break;
57938635 3267
252b5132
RH
3268 case 'O':
3269 case 'd': /* "destination" - 'O' is preferred */
3270 output_target = optarg;
3271 break;
57938635 3272
252b5132
RH
3273 case 'F':
3274 input_target = output_target = optarg;
3275 break;
57938635 3276
f91ea849 3277 case 'j':
b34976b6 3278 p = find_section_list (optarg, TRUE);
f91ea849
ILT
3279 if (p->remove)
3280 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
3281 p->copy = TRUE;
3282 sections_copied = TRUE;
f91ea849 3283 break;
57938635 3284
252b5132 3285 case 'R':
b34976b6 3286 p = find_section_list (optarg, TRUE);
f91ea849
ILT
3287 if (p->copy)
3288 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
3289 p->remove = TRUE;
3290 sections_removed = TRUE;
252b5132 3291 break;
57938635 3292
252b5132
RH
3293 case 'S':
3294 strip_symbols = STRIP_ALL;
3295 break;
57938635 3296
252b5132
RH
3297 case 'g':
3298 strip_symbols = STRIP_DEBUG;
3299 break;
57938635 3300
252b5132
RH
3301 case OPTION_STRIP_UNNEEDED:
3302 strip_symbols = STRIP_UNNEEDED;
3303 break;
57938635 3304
ed1653a7
NC
3305 case OPTION_ONLY_KEEP_DEBUG:
3306 strip_symbols = STRIP_NONDEBUG;
3307 break;
3308
1637cd90
JB
3309 case OPTION_KEEP_FILE_SYMBOLS:
3310 keep_file_symbols = 1;
3311 break;
3312
2593f09a
NC
3313 case OPTION_ADD_GNU_DEBUGLINK:
3314 gnu_debuglink_filename = optarg;
3315 break;
3316
252b5132 3317 case 'K':
047c9024 3318 add_specific_symbol (optarg, keep_specific_htab);
252b5132 3319 break;
57938635 3320
252b5132 3321 case 'N':
047c9024 3322 add_specific_symbol (optarg, strip_specific_htab);
252b5132 3323 break;
57938635 3324
bcf32829 3325 case OPTION_STRIP_UNNEEDED_SYMBOL:
047c9024 3326 add_specific_symbol (optarg, strip_unneeded_htab);
bcf32829
JB
3327 break;
3328
252b5132 3329 case 'L':
047c9024 3330 add_specific_symbol (optarg, localize_specific_htab);
252b5132 3331 break;
57938635 3332
7b4a0685 3333 case OPTION_GLOBALIZE_SYMBOL:
047c9024 3334 add_specific_symbol (optarg, globalize_specific_htab);
7b4a0685
NC
3335 break;
3336
16b2b71c 3337 case 'G':
047c9024 3338 add_specific_symbol (optarg, keepglobal_specific_htab);
16b2b71c
NC
3339 break;
3340
252b5132 3341 case 'W':
047c9024 3342 add_specific_symbol (optarg, weaken_specific_htab);
252b5132 3343 break;
57938635 3344
252b5132 3345 case 'p':
b34976b6 3346 preserve_dates = TRUE;
252b5132 3347 break;
57938635 3348
5fe11841
NC
3349 case 'w':
3350 wildcard = TRUE;
3351 break;
3352
252b5132
RH
3353 case 'x':
3354 discard_locals = LOCALS_ALL;
3355 break;
57938635 3356
252b5132
RH
3357 case 'X':
3358 discard_locals = LOCALS_START_L;
3359 break;
57938635 3360
252b5132 3361 case 'v':
b34976b6 3362 verbose = TRUE;
252b5132 3363 break;
57938635 3364
252b5132 3365 case 'V':
b34976b6 3366 show_version = TRUE;
252b5132 3367 break;
57938635 3368
7c29036b
NC
3369 case OPTION_FORMATS_INFO:
3370 formats_info = TRUE;
3371 break;
3372
252b5132 3373 case OPTION_WEAKEN:
b34976b6 3374 weaken = TRUE;
252b5132 3375 break;
57938635 3376
252b5132
RH
3377 case OPTION_ADD_SECTION:
3378 {
3379 const char *s;
500ee42e 3380 size_t off, alloc;
252b5132 3381 struct section_add *pa;
252b5132
RH
3382 FILE *f;
3383
3384 s = strchr (optarg, '=');
57938635 3385
252b5132 3386 if (s == NULL)
57938635 3387 fatal (_("bad format for %s"), "--add-section");
252b5132 3388
3f5e193b 3389 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
500ee42e 3390 pa->name = xstrndup (optarg, s - optarg);
252b5132
RH
3391 pa->filename = s + 1;
3392
500ee42e
ILT
3393 /* We don't use get_file_size so that we can do
3394 --add-section .note.GNU_stack=/dev/null
3395 get_file_size doesn't work on /dev/null. */
57938635 3396
500ee42e 3397 f = fopen (pa->filename, FOPEN_RB);
252b5132 3398 if (f == NULL)
84e2f313
NC
3399 fatal (_("cannot open: %s: %s"),
3400 pa->filename, strerror (errno));
57938635 3401
500ee42e
ILT
3402 off = 0;
3403 alloc = 4096;
3404 pa->contents = (bfd_byte *) xmalloc (alloc);
3405 while (!feof (f))
3406 {
3407 off_t got;
3408
3409 if (off == alloc)
3410 {
3411 alloc <<= 1;
3412 pa->contents = (bfd_byte *) xrealloc (pa->contents, alloc);
3413 }
3414
3415 got = fread (pa->contents + off, 1, alloc - off, f);
3416 if (ferror (f))
3417 fatal (_("%s: fread failed"), pa->filename);
3418
3419 off += got;
3420 }
3421
3422 pa->size = off;
252b5132
RH
3423
3424 fclose (f);
3425
3426 pa->next = add_sections;
3427 add_sections = pa;
3428 }
3429 break;
57938635 3430
252b5132
RH
3431 case OPTION_CHANGE_START:
3432 change_start = parse_vma (optarg, "--change-start");
3433 break;
57938635 3434
252b5132
RH
3435 case OPTION_CHANGE_SECTION_ADDRESS:
3436 case OPTION_CHANGE_SECTION_LMA:
3437 case OPTION_CHANGE_SECTION_VMA:
3438 {
3439 const char *s;
3440 int len;
3441 char *name;
b4c96d0d 3442 char *option = NULL;
252b5132 3443 bfd_vma val;
b4c96d0d 3444 enum change_action what = CHANGE_IGNORE;
57938635 3445
252b5132
RH
3446 switch (c)
3447 {
b4c96d0d
ILT
3448 case OPTION_CHANGE_SECTION_ADDRESS:
3449 option = "--change-section-address";
3450 break;
3451 case OPTION_CHANGE_SECTION_LMA:
3452 option = "--change-section-lma";
3453 break;
3454 case OPTION_CHANGE_SECTION_VMA:
3455 option = "--change-section-vma";
3456 break;
252b5132 3457 }
57938635 3458
252b5132
RH
3459 s = strchr (optarg, '=');
3460 if (s == NULL)
3461 {
3462 s = strchr (optarg, '+');
3463 if (s == NULL)
3464 {
3465 s = strchr (optarg, '-');
3466 if (s == NULL)
3467 fatal (_("bad format for %s"), option);
3468 }
3469 }
3470
3471 len = s - optarg;
3f5e193b 3472 name = (char *) xmalloc (len + 1);
252b5132
RH
3473 strncpy (name, optarg, len);
3474 name[len] = '\0';
3475
b34976b6 3476 p = find_section_list (name, TRUE);
252b5132
RH
3477
3478 val = parse_vma (s + 1, option);
3479
3480 switch (*s)
3481 {
3482 case '=': what = CHANGE_SET; break;
3483 case '-': val = - val; /* Drop through. */
3484 case '+': what = CHANGE_MODIFY; break;
3485 }
57938635 3486
252b5132
RH
3487 switch (c)
3488 {
3489 case OPTION_CHANGE_SECTION_ADDRESS:
3490 p->change_vma = what;
3491 p->vma_val = val;
3492 /* Drop through. */
57938635 3493
252b5132
RH
3494 case OPTION_CHANGE_SECTION_LMA:
3495 p->change_lma = what;
3496 p->lma_val = val;
3497 break;
57938635 3498
252b5132
RH
3499 case OPTION_CHANGE_SECTION_VMA:
3500 p->change_vma = what;
3501 p->vma_val = val;
3502 break;
3503 }
3504 }
3505 break;
57938635 3506
252b5132
RH
3507 case OPTION_CHANGE_ADDRESSES:
3508 change_section_address = parse_vma (optarg, "--change-addresses");
3509 change_start = change_section_address;
3510 break;
57938635 3511
252b5132 3512 case OPTION_CHANGE_WARNINGS:
b34976b6 3513 change_warn = TRUE;
252b5132 3514 break;
57938635 3515
252b5132 3516 case OPTION_CHANGE_LEADING_CHAR:
b34976b6 3517 change_leading_char = TRUE;
252b5132 3518 break;
57938635 3519
4a114e3e
L
3520 case OPTION_COMPRESS_DEBUG_SECTIONS:
3521 do_debug_sections = compress;
3522 break;
3523
252b5132 3524 case OPTION_DEBUGGING:
b34976b6 3525 convert_debugging = TRUE;
252b5132 3526 break;
57938635 3527
4a114e3e
L
3528 case OPTION_DECOMPRESS_DEBUG_SECTIONS:
3529 do_debug_sections = decompress;
3530 break;
3531
252b5132
RH
3532 case OPTION_GAP_FILL:
3533 {
3534 bfd_vma gap_fill_vma;
3535
3536 gap_fill_vma = parse_vma (optarg, "--gap-fill");
3537 gap_fill = (bfd_byte) gap_fill_vma;
3538 if ((bfd_vma) gap_fill != gap_fill_vma)
3539 {
3540 char buff[20];
57938635 3541
252b5132 3542 sprintf_vma (buff, gap_fill_vma);
57938635 3543
252b5132
RH
3544 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3545 buff, gap_fill);
3546 }
b34976b6 3547 gap_fill_set = TRUE;
252b5132
RH
3548 }
3549 break;
57938635 3550
252b5132 3551 case OPTION_NO_CHANGE_WARNINGS:
b34976b6 3552 change_warn = FALSE;
252b5132 3553 break;
57938635 3554
252b5132
RH
3555 case OPTION_PAD_TO:
3556 pad_to = parse_vma (optarg, "--pad-to");
b34976b6 3557 pad_to_set = TRUE;
252b5132 3558 break;
57938635 3559
252b5132 3560 case OPTION_REMOVE_LEADING_CHAR:
b34976b6 3561 remove_leading_char = TRUE;
252b5132 3562 break;
57938635
AM
3563
3564 case OPTION_REDEFINE_SYM:
3565 {
3566 /* Push this redefinition onto redefine_symbol_list. */
3567
3568 int len;
3569 const char *s;
3570 const char *nextarg;
3571 char *source, *target;
3572
3573 s = strchr (optarg, '=');
3574 if (s == NULL)
594ef5db 3575 fatal (_("bad format for %s"), "--redefine-sym");
57938635
AM
3576
3577 len = s - optarg;
3f5e193b 3578 source = (char *) xmalloc (len + 1);
57938635
AM
3579 strncpy (source, optarg, len);
3580 source[len] = '\0';
3581
3582 nextarg = s + 1;
3583 len = strlen (nextarg);
3f5e193b 3584 target = (char *) xmalloc (len + 1);
57938635
AM
3585 strcpy (target, nextarg);
3586
92991082 3587 redefine_list_append ("--redefine-sym", source, target);
57938635
AM
3588
3589 free (source);
3590 free (target);
3591 }
3592 break;
3593
92991082
JT
3594 case OPTION_REDEFINE_SYMS:
3595 add_redefine_syms_file (optarg);
3596 break;
3597
252b5132
RH
3598 case OPTION_SET_SECTION_FLAGS:
3599 {
3600 const char *s;
3601 int len;
3602 char *name;
3603
3604 s = strchr (optarg, '=');
3605 if (s == NULL)
57938635 3606 fatal (_("bad format for %s"), "--set-section-flags");
252b5132
RH
3607
3608 len = s - optarg;
3f5e193b 3609 name = (char *) xmalloc (len + 1);
252b5132
RH
3610 strncpy (name, optarg, len);
3611 name[len] = '\0';
3612
b34976b6 3613 p = find_section_list (name, TRUE);
252b5132 3614
b34976b6 3615 p->set_flags = TRUE;
252b5132
RH
3616 p->flags = parse_flags (s + 1);
3617 }
3618 break;
57938635 3619
594ef5db
NC
3620 case OPTION_RENAME_SECTION:
3621 {
3622 flagword flags;
3bcfb3e4
AM
3623 const char *eq, *fl;
3624 char *old_name;
3625 char *new_name;
594ef5db
NC
3626 unsigned int len;
3627
3bcfb3e4
AM
3628 eq = strchr (optarg, '=');
3629 if (eq == NULL)
594ef5db
NC
3630 fatal (_("bad format for %s"), "--rename-section");
3631
3bcfb3e4 3632 len = eq - optarg;
594ef5db 3633 if (len == 0)
3bcfb3e4 3634 fatal (_("bad format for %s"), "--rename-section");
594ef5db 3635
3f5e193b 3636 old_name = (char *) xmalloc (len + 1);
594ef5db
NC
3637 strncpy (old_name, optarg, len);
3638 old_name[len] = 0;
3639
3bcfb3e4
AM
3640 eq++;
3641 fl = strchr (eq, ',');
3642 if (fl)
594ef5db 3643 {
3bcfb3e4
AM
3644 flags = parse_flags (fl + 1);
3645 len = fl - eq;
594ef5db
NC
3646 }
3647 else
3648 {
594ef5db 3649 flags = -1;
3bcfb3e4 3650 len = strlen (eq);
594ef5db
NC
3651 }
3652
3bcfb3e4
AM
3653 if (len == 0)
3654 fatal (_("bad format for %s"), "--rename-section");
3655
3f5e193b 3656 new_name = (char *) xmalloc (len + 1);
3bcfb3e4
AM
3657 strncpy (new_name, eq, len);
3658 new_name[len] = 0;
3659
594ef5db
NC
3660 add_section_rename (old_name, new_name, flags);
3661 }
3662 break;
3663
252b5132
RH
3664 case OPTION_SET_START:
3665 set_start = parse_vma (optarg, "--set-start");
b34976b6 3666 set_start_set = TRUE;
252b5132 3667 break;
57938635 3668
0af11b59
KH
3669 case OPTION_SREC_LEN:
3670 Chunk = parse_vma (optarg, "--srec-len");
3671 break;
420496c1 3672
0af11b59 3673 case OPTION_SREC_FORCES3:
b34976b6 3674 S3Forced = TRUE;
0af11b59 3675 break;
420496c1 3676
16b2b71c 3677 case OPTION_STRIP_SYMBOLS:
047c9024 3678 add_specific_symbols (optarg, strip_specific_htab);
16b2b71c
NC
3679 break;
3680
bcf32829 3681 case OPTION_STRIP_UNNEEDED_SYMBOLS:
047c9024 3682 add_specific_symbols (optarg, strip_unneeded_htab);
bcf32829
JB
3683 break;
3684
16b2b71c 3685 case OPTION_KEEP_SYMBOLS:
047c9024 3686 add_specific_symbols (optarg, keep_specific_htab);
16b2b71c
NC
3687 break;
3688
d58c2e3a
RS
3689 case OPTION_LOCALIZE_HIDDEN:
3690 localize_hidden = TRUE;
3691 break;
3692
16b2b71c 3693 case OPTION_LOCALIZE_SYMBOLS:
047c9024 3694 add_specific_symbols (optarg, localize_specific_htab);
16b2b71c
NC
3695 break;
3696
0408dee6
DK
3697 case OPTION_LONG_SECTION_NAMES:
3698 if (!strcmp ("enable", optarg))
3699 long_section_names = ENABLE;
3700 else if (!strcmp ("disable", optarg))
3701 long_section_names = DISABLE;
3702 else if (!strcmp ("keep", optarg))
3703 long_section_names = KEEP;
3704 else
3705 fatal (_("unknown long section names option '%s'"), optarg);
3706 break;
3707
7b4a0685 3708 case OPTION_GLOBALIZE_SYMBOLS:
047c9024 3709 add_specific_symbols (optarg, globalize_specific_htab);
7b4a0685
NC
3710 break;
3711
16b2b71c 3712 case OPTION_KEEPGLOBAL_SYMBOLS:
047c9024 3713 add_specific_symbols (optarg, keepglobal_specific_htab);
16b2b71c
NC
3714 break;
3715
3716 case OPTION_WEAKEN_SYMBOLS:
047c9024 3717 add_specific_symbols (optarg, weaken_specific_htab);
16b2b71c
NC
3718 break;
3719
1ae8b3d2 3720 case OPTION_ALT_MACH_CODE:
f9d4ad2a
NC
3721 use_alt_mach_code = strtoul (optarg, NULL, 0);
3722 if (use_alt_mach_code == 0)
3723 fatal (_("unable to parse alternative machine code"));
1ae8b3d2
AO
3724 break;
3725
d7fb0dd2
NC
3726 case OPTION_PREFIX_SYMBOLS:
3727 prefix_symbols_string = optarg;
3728 break;
3729
3730 case OPTION_PREFIX_SECTIONS:
3731 prefix_sections_string = optarg;
3732 break;
3733
3734 case OPTION_PREFIX_ALLOC_SECTIONS:
3735 prefix_alloc_sections_string = optarg;
3736 break;
3737
4087920c
MR
3738 case OPTION_READONLY_TEXT:
3739 bfd_flags_to_set |= WP_TEXT;
3740 bfd_flags_to_clear &= ~WP_TEXT;
3741 break;
3742
3743 case OPTION_WRITABLE_TEXT:
3744 bfd_flags_to_clear |= WP_TEXT;
3745 bfd_flags_to_set &= ~WP_TEXT;
3746 break;
3747
3748 case OPTION_PURE:
3749 bfd_flags_to_set |= D_PAGED;
3750 bfd_flags_to_clear &= ~D_PAGED;
3751 break;
3752
3753 case OPTION_IMPURE:
3754 bfd_flags_to_clear |= D_PAGED;
3755 bfd_flags_to_set &= ~D_PAGED;
3756 break;
3757
d3e52d40
RS
3758 case OPTION_EXTRACT_SYMBOL:
3759 extract_symbol = TRUE;
3760 break;
3761
9e48b4c6
NC
3762 case OPTION_REVERSE_BYTES:
3763 {
3764 int prev = reverse_bytes;
3765
3766 reverse_bytes = atoi (optarg);
3767 if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3768 fatal (_("number of bytes to reverse must be positive and even"));
3769
3770 if (prev && prev != reverse_bytes)
3771 non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3772 prev);
3773 break;
3774 }
3775
92dd4511
L
3776 case OPTION_FILE_ALIGNMENT:
3777 pe_file_alignment = parse_vma (optarg, "--file-alignment");
3778 break;
3779
3780 case OPTION_HEAP:
3781 {
3782 char *end;
3783 pe_heap_reserve = strtoul (optarg, &end, 0);
3784 if (end == optarg
3785 || (*end != '.' && *end != '\0'))
3786 non_fatal (_("%s: invalid reserve value for --heap"),
3787 optarg);
3788 else if (*end != '\0')
3789 {
3790 pe_heap_commit = strtoul (end + 1, &end, 0);
3791 if (*end != '\0')
3792 non_fatal (_("%s: invalid commit value for --heap"),
3793 optarg);
3794 }
3795 }
3796 break;
3797
3798 case OPTION_IMAGE_BASE:
3799 pe_image_base = parse_vma (optarg, "--image-base");
3800 break;
3801
3802 case OPTION_SECTION_ALIGNMENT:
3803 pe_section_alignment = parse_vma (optarg,
3804 "--section-alignment");
3805 break;
3806
3807 case OPTION_SUBSYSTEM:
3808 set_pe_subsystem (optarg);
3809 break;
3810
3811 case OPTION_STACK:
3812 {
3813 char *end;
3814 pe_stack_reserve = strtoul (optarg, &end, 0);
3815 if (end == optarg
3816 || (*end != '.' && *end != '\0'))
3817 non_fatal (_("%s: invalid reserve value for --stack"),
3818 optarg);
3819 else if (*end != '\0')
3820 {
3821 pe_stack_commit = strtoul (end + 1, &end, 0);
3822 if (*end != '\0')
3823 non_fatal (_("%s: invalid commit value for --stack"),
3824 optarg);
3825 }
3826 }
3827 break;
3828
252b5132 3829 case 0:
2593f09a
NC
3830 /* We've been given a long option. */
3831 break;
57938635 3832
8b53311e 3833 case 'H':
252b5132
RH
3834 case 'h':
3835 copy_usage (stdout, 0);
57938635 3836
252b5132
RH
3837 default:
3838 copy_usage (stderr, 1);
3839 }
3840 }
3841
7c29036b
NC
3842 if (formats_info)
3843 {
3844 display_info ();
3845 return 0;
3846 }
c1c0eb9e 3847
252b5132
RH
3848 if (show_version)
3849 print_version ("objcopy");
3850
b7dd81f7
NC
3851 if (interleave && copy_byte == -1)
3852 fatal (_("interleave start byte must be set with --byte"));
3853
252b5132
RH
3854 if (copy_byte >= interleave)
3855 fatal (_("byte number must be less than interleave"));
3856
b7dd81f7
NC
3857 if (copy_width > interleave - copy_byte)
3858 fatal (_("interleave width must be less than or equal to interleave - byte`"));
3859
252b5132
RH
3860 if (optind == argc || optind + 2 < argc)
3861 copy_usage (stderr, 1);
3862
3863 input_filename = argv[optind];
3864 if (optind + 1 < argc)
3865 output_filename = argv[optind + 1];
3866
3867 /* Default is to strip no symbols. */
3868 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3869 strip_symbols = STRIP_NONE;
3870
d3ba0551 3871 if (output_target == NULL)
252b5132
RH
3872 output_target = input_target;
3873
92dd4511
L
3874 /* Convert input EFI target to PEI target. */
3875 if (input_target != NULL
3876 && strncmp (input_target, "efi-", 4) == 0)
3877 {
3878 char *efi;
3879
3880 efi = xstrdup (output_target + 4);
3881 if (strncmp (efi, "bsdrv-", 6) == 0
3882 || strncmp (efi, "rtdrv-", 6) == 0)
3883 efi += 2;
3884 else if (strncmp (efi, "app-", 4) != 0)
3885 fatal (_("unknown input EFI target: %s"), input_target);
3886
3887 input_target = efi;
3888 convert_efi_target (efi);
3889 }
3890
3891 /* Convert output EFI target to PEI target. */
3892 if (output_target != NULL
3893 && strncmp (output_target, "efi-", 4) == 0)
3894 {
3895 char *efi;
3896
3897 efi = xstrdup (output_target + 4);
3898 if (strncmp (efi, "app-", 4) == 0)
3899 {
3900 if (pe_subsystem == -1)
3901 pe_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
3902 }
3903 else if (strncmp (efi, "bsdrv-", 6) == 0)
3904 {
3905 if (pe_subsystem == -1)
3906 pe_subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
3907 efi += 2;
3908 }
3909 else if (strncmp (efi, "rtdrv-", 6) == 0)
3910 {
3911 if (pe_subsystem == -1)
3912 pe_subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
3913 efi += 2;
3914 }
3915 else
3916 fatal (_("unknown output EFI target: %s"), output_target);
3917
3918 if (pe_file_alignment == (bfd_vma) -1)
3919 pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
3920 if (pe_section_alignment == (bfd_vma) -1)
3921 pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
3922
3923 output_target = efi;
3924 convert_efi_target (efi);
3925 }
3926
43a0748c
NC
3927 if (preserve_dates)
3928 if (stat (input_filename, & statbuf) < 0)
f24ddbdd
NC
3929 fatal (_("warning: could not locate '%s'. System error message: %s"),
3930 input_filename, strerror (errno));
43a0748c 3931
0fcdcb91 3932 /* If there is no destination file, or the source and destination files
d3ba0551 3933 are the same, then create a temp and rename the result into the input. */
8b6efd89
KT
3934 if (output_filename == NULL
3935 || filename_cmp (input_filename, output_filename) == 0)
12f498a7 3936 tmpname = make_tempname (input_filename);
252b5132 3937 else
12f498a7 3938 tmpname = output_filename;
c1c0eb9e 3939
12f498a7
NS
3940 if (tmpname == NULL)
3941 fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3942 input_filename, strerror (errno));
594ef5db 3943
8b31b6c4 3944 copy_file (input_filename, tmpname, input_target, output_target, input_arch);
12f498a7
NS
3945 if (status == 0)
3946 {
3947 if (preserve_dates)
3948 set_times (tmpname, &statbuf);
3949 if (tmpname != output_filename)
92fac5ec
L
3950 status = (smart_rename (tmpname, input_filename,
3951 preserve_dates) != 0);
252b5132 3952 }
12f498a7
NS
3953 else
3954 unlink_if_ordinary (tmpname);
252b5132
RH
3955
3956 if (change_warn)
3957 {
3958 for (p = change_sections; p != NULL; p = p->next)
3959 {
3960 if (! p->used)
3961 {
3962 if (p->change_vma != CHANGE_IGNORE)
3963 {
3964 char buff [20];
3965
3966 sprintf_vma (buff, p->vma_val);
57938635 3967
252b5132 3968 /* xgettext:c-format */
57938635
AM
3969 non_fatal (_("%s %s%c0x%s never used"),
3970 "--change-section-vma",
252b5132
RH
3971 p->name,
3972 p->change_vma == CHANGE_SET ? '=' : '+',
3973 buff);
3974 }
57938635 3975
252b5132
RH
3976 if (p->change_lma != CHANGE_IGNORE)
3977 {
3978 char buff [20];
3979
3980 sprintf_vma (buff, p->lma_val);
57938635 3981
252b5132 3982 /* xgettext:c-format */
57938635
AM
3983 non_fatal (_("%s %s%c0x%s never used"),
3984 "--change-section-lma",
252b5132
RH
3985 p->name,
3986 p->change_lma == CHANGE_SET ? '=' : '+',
3987 buff);
3988 }
3989 }
3990 }
3991 }
3992
3993 return 0;
3994}
3995
3996int
84e2f313 3997main (int argc, char *argv[])
252b5132
RH
3998{
3999#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
4000 setlocale (LC_MESSAGES, "");
3882b010
L
4001#endif
4002#if defined (HAVE_SETLOCALE)
4003 setlocale (LC_CTYPE, "");
252b5132
RH
4004#endif
4005 bindtextdomain (PACKAGE, LOCALEDIR);
4006 textdomain (PACKAGE);
4007
4008 program_name = argv[0];
4009 xmalloc_set_program_name (program_name);
4010
4011 START_PROGRESS (program_name, 0);
4012
869b9d07
MM
4013 expandargv (&argc, &argv);
4014
252b5132
RH
4015 strip_symbols = STRIP_UNDEF;
4016 discard_locals = LOCALS_UNDEF;
4017
4018 bfd_init ();
4019 set_default_bfd_target ();
4020
4021 if (is_strip < 0)
4022 {
4023 int i = strlen (program_name);
5af11cab
AM
4024#ifdef HAVE_DOS_BASED_FILE_SYSTEM
4025 /* Drop the .exe suffix, if any. */
4026 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
4027 {
4028 i -= 4;
4029 program_name[i] = '\0';
4030 }
4031#endif
4032 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
252b5132
RH
4033 }
4034
047c9024
NC
4035 create_symbol_htabs ();
4036
252b5132
RH
4037 if (is_strip)
4038 strip_main (argc, argv);
4039 else
4040 copy_main (argc, argv);
4041
4042 END_PROGRESS (program_name);
4043
4044 return status;
4045}
This page took 0.873555 seconds and 4 git commands to generate.