2011-02-28 Michael Snyder <msnyder@vmware.com>
[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,
a0f19280 3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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
252b5132
RH
928/* See if a section is being removed. */
929
b34976b6 930static bfd_boolean
84e2f313 931is_strip_section (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
30288845
AM
958 if ((bfd_get_section_flags (abfd, sec) & SEC_GROUP) != 0)
959 {
960 asymbol *gsym;
961 const char *gname;
962
30288845
AM
963 /* PR binutils/3181
964 If we are going to strip the group signature symbol, then
965 strip the group section too. */
966 gsym = group_signature (sec);
967 if (gsym != NULL)
968 gname = gsym->name;
969 else
970 gname = sec->name;
971 if ((strip_symbols == STRIP_ALL
047c9024
NC
972 && !is_specified_symbol (gname, keep_specific_htab))
973 || is_specified_symbol (gname, strip_specific_htab))
30288845
AM
974 return TRUE;
975 }
91bb255c 976
f0312d39 977 return FALSE;
252b5132
RH
978}
979
d58c2e3a
RS
980/* Return true if SYM is a hidden symbol. */
981
982static bfd_boolean
983is_hidden_symbol (asymbol *sym)
984{
985 elf_symbol_type *elf_sym;
986
987 elf_sym = elf_symbol_from (sym->the_bfd, sym);
988 if (elf_sym != NULL)
989 switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other))
990 {
991 case STV_HIDDEN:
992 case STV_INTERNAL:
993 return TRUE;
994 }
995 return FALSE;
996}
997
252b5132
RH
998/* Choose which symbol entries to copy; put the result in OSYMS.
999 We don't copy in place, because that confuses the relocs.
1000 Return the number of symbols to print. */
1001
1002static unsigned int
84e2f313
NC
1003filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
1004 asymbol **isyms, long symcount)
252b5132 1005{
84e2f313 1006 asymbol **from = isyms, **to = osyms;
252b5132 1007 long src_count = 0, dst_count = 0;
e205a099 1008 int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
252b5132
RH
1009
1010 for (; src_count < symcount; src_count++)
1011 {
1012 asymbol *sym = from[src_count];
1013 flagword flags = sym->flags;
d7fb0dd2 1014 char *name = (char *) bfd_asymbol_name (sym);
312aaa3c
NC
1015 bfd_boolean keep;
1016 bfd_boolean used_in_reloc = FALSE;
b34976b6 1017 bfd_boolean undefined;
d7fb0dd2
NC
1018 bfd_boolean rem_leading_char;
1019 bfd_boolean add_leading_char;
1020
1021 undefined = bfd_is_und_section (bfd_get_section (sym));
252b5132 1022
57938635
AM
1023 if (redefine_sym_list)
1024 {
d7fb0dd2 1025 char *old_name, *new_name;
57938635 1026
d7fb0dd2
NC
1027 old_name = (char *) bfd_asymbol_name (sym);
1028 new_name = (char *) lookup_sym_redefinition (old_name);
66491ebc
AM
1029 bfd_asymbol_name (sym) = new_name;
1030 name = new_name;
57938635
AM
1031 }
1032
d7fb0dd2
NC
1033 /* Check if we will remove the current leading character. */
1034 rem_leading_char =
1035 (name[0] == bfd_get_symbol_leading_char (abfd))
1036 && (change_leading_char
1037 || (remove_leading_char
1038 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1039 || undefined
1040 || bfd_is_com_section (bfd_get_section (sym)))));
1041
1042 /* Check if we will add a new leading character. */
1043 add_leading_char =
1044 change_leading_char
1045 && (bfd_get_symbol_leading_char (obfd) != '\0')
1046 && (bfd_get_symbol_leading_char (abfd) == '\0'
1047 || (name[0] == bfd_get_symbol_leading_char (abfd)));
1048
1049 /* Short circuit for change_leading_char if we can do it in-place. */
1050 if (rem_leading_char && add_leading_char && !prefix_symbols_string)
1051 {
1052 name[0] = bfd_get_symbol_leading_char (obfd);
1053 bfd_asymbol_name (sym) = name;
1054 rem_leading_char = FALSE;
1055 add_leading_char = FALSE;
1056 }
1057
1058 /* Remove leading char. */
1059 if (rem_leading_char)
66491ebc 1060 bfd_asymbol_name (sym) = ++name;
d7fb0dd2
NC
1061
1062 /* Add new leading char and/or prefix. */
1063 if (add_leading_char || prefix_symbols_string)
1064 {
1065 char *n, *ptr;
1066
3f5e193b
NC
1067 ptr = n = (char *) xmalloc (1 + strlen (prefix_symbols_string)
1068 + strlen (name) + 1);
d7fb0dd2
NC
1069 if (add_leading_char)
1070 *ptr++ = bfd_get_symbol_leading_char (obfd);
1071
1072 if (prefix_symbols_string)
1073 {
1074 strcpy (ptr, prefix_symbols_string);
1075 ptr += strlen (prefix_symbols_string);
1076 }
1077
1078 strcpy (ptr, name);
66491ebc
AM
1079 bfd_asymbol_name (sym) = n;
1080 name = n;
252b5132
RH
1081 }
1082
252b5132 1083 if (strip_symbols == STRIP_ALL)
312aaa3c 1084 keep = FALSE;
252b5132
RH
1085 else if ((flags & BSF_KEEP) != 0 /* Used in relocation. */
1086 || ((flags & BSF_SECTION_SYM) != 0
1087 && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
1088 & BSF_KEEP) != 0))
312aaa3c
NC
1089 {
1090 keep = TRUE;
1091 used_in_reloc = TRUE;
1092 }
0af11b59 1093 else if (relocatable /* Relocatable file. */
0691f7af
L
1094 && ((flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1095 || bfd_is_com_section (bfd_get_section (sym))))
312aaa3c 1096 keep = TRUE;
16b2b71c
NC
1097 else if (bfd_decode_symclass (sym) == 'I')
1098 /* Global symbols in $idata sections need to be retained
b34976b6 1099 even if relocatable is FALSE. External users of the
16b2b71c
NC
1100 library containing the $idata section may reference these
1101 symbols. */
312aaa3c 1102 keep = TRUE;
252b5132
RH
1103 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
1104 || (flags & BSF_WEAK) != 0
24e01a36 1105 || undefined
252b5132
RH
1106 || bfd_is_com_section (bfd_get_section (sym)))
1107 keep = strip_symbols != STRIP_UNNEEDED;
1108 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
1109 keep = (strip_symbols != STRIP_DEBUG
1110 && strip_symbols != STRIP_UNNEEDED
1111 && ! convert_debugging);
082b7297 1112 else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym)))
af3bdff7
NC
1113 /* COMDAT sections store special information in local
1114 symbols, so we cannot risk stripping any of them. */
312aaa3c 1115 keep = TRUE;
252b5132
RH
1116 else /* Local symbol. */
1117 keep = (strip_symbols != STRIP_UNNEEDED
1118 && (discard_locals != LOCALS_ALL
1119 && (discard_locals != LOCALS_START_L
1120 || ! bfd_is_local_label (abfd, sym))));
1121
047c9024 1122 if (keep && is_specified_symbol (name, strip_specific_htab))
312aaa3c
NC
1123 {
1124 /* There are multiple ways to set 'keep' above, but if it
1125 was the relocatable symbol case, then that's an error. */
1126 if (used_in_reloc)
1127 {
1128 non_fatal (_("not stripping symbol `%s' because it is named in a relocation"), name);
1129 status = 1;
1130 }
1131 else
1132 keep = FALSE;
1133 }
1134
bcf32829
JB
1135 if (keep
1136 && !(flags & BSF_KEEP)
047c9024 1137 && is_specified_symbol (name, strip_unneeded_htab))
312aaa3c
NC
1138 keep = FALSE;
1139
1637cd90
JB
1140 if (!keep
1141 && ((keep_file_symbols && (flags & BSF_FILE))
047c9024 1142 || is_specified_symbol (name, keep_specific_htab)))
312aaa3c
NC
1143 keep = TRUE;
1144
252b5132 1145 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
312aaa3c 1146 keep = FALSE;
e0c60db2 1147
7b4a0685 1148 if (keep)
252b5132 1149 {
7b4a0685 1150 if ((flags & BSF_GLOBAL) != 0
047c9024 1151 && (weaken || is_specified_symbol (name, weaken_specific_htab)))
7b4a0685
NC
1152 {
1153 sym->flags &= ~ BSF_GLOBAL;
1154 sym->flags |= BSF_WEAK;
1155 }
252b5132 1156
7b4a0685
NC
1157 if (!undefined
1158 && (flags & (BSF_GLOBAL | BSF_WEAK))
047c9024
NC
1159 && (is_specified_symbol (name, localize_specific_htab)
1160 || (htab_elements (keepglobal_specific_htab) != 0
1161 && ! is_specified_symbol (name, keepglobal_specific_htab))
d58c2e3a 1162 || (localize_hidden && is_hidden_symbol (sym))))
7b4a0685
NC
1163 {
1164 sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
1165 sym->flags |= BSF_LOCAL;
1166 }
1167
1168 if (!undefined
c1c0eb9e 1169 && (flags & BSF_LOCAL)
047c9024 1170 && is_specified_symbol (name, globalize_specific_htab))
7b4a0685
NC
1171 {
1172 sym->flags &= ~ BSF_LOCAL;
1173 sym->flags |= BSF_GLOBAL;
1174 }
1175
1176 to[dst_count++] = sym;
1177 }
252b5132
RH
1178 }
1179
1180 to[dst_count] = NULL;
1181
1182 return dst_count;
1183}
1184
594ef5db
NC
1185/* Find the redefined name of symbol SOURCE. */
1186
57938635 1187static const char *
84e2f313 1188lookup_sym_redefinition (const char *source)
57938635 1189{
57938635
AM
1190 struct redefine_node *list;
1191
57938635 1192 for (list = redefine_sym_list; list != NULL; list = list->next)
594ef5db
NC
1193 if (strcmp (source, list->source) == 0)
1194 return list->target;
1195
1196 return source;
57938635
AM
1197}
1198
594ef5db 1199/* Add a node to a symbol redefine list. */
57938635
AM
1200
1201static void
84e2f313 1202redefine_list_append (const char *cause, const char *source, const char *target)
57938635
AM
1203{
1204 struct redefine_node **p;
1205 struct redefine_node *list;
1206 struct redefine_node *new_node;
1207
1208 for (p = &redefine_sym_list; (list = *p) != NULL; p = &list->next)
1209 {
1210 if (strcmp (source, list->source) == 0)
594ef5db 1211 fatal (_("%s: Multiple redefinition of symbol \"%s\""),
92991082 1212 cause, source);
57938635
AM
1213
1214 if (strcmp (target, list->target) == 0)
594ef5db 1215 fatal (_("%s: Symbol \"%s\" is target of more than one redefinition"),
92991082 1216 cause, target);
57938635
AM
1217 }
1218
3f5e193b 1219 new_node = (struct redefine_node *) xmalloc (sizeof (struct redefine_node));
57938635
AM
1220
1221 new_node->source = strdup (source);
1222 new_node->target = strdup (target);
1223 new_node->next = NULL;
1224
1225 *p = new_node;
1226}
1227
92991082
JT
1228/* Handle the --redefine-syms option. Read lines containing "old new"
1229 from the file, and add them to the symbol redefine list. */
1230
2593f09a 1231static void
84e2f313 1232add_redefine_syms_file (const char *filename)
92991082
JT
1233{
1234 FILE *file;
1235 char *buf;
84e2f313
NC
1236 size_t bufsize;
1237 size_t len;
1238 size_t outsym_off;
92991082
JT
1239 int c, lineno;
1240
1241 file = fopen (filename, "r");
d3ba0551 1242 if (file == NULL)
92991082
JT
1243 fatal (_("couldn't open symbol redefinition file %s (error: %s)"),
1244 filename, strerror (errno));
1245
1246 bufsize = 100;
a6da20b5 1247 buf = (char *) xmalloc (bufsize + 1 /* For the terminating NUL. */);
92991082
JT
1248
1249 lineno = 1;
1250 c = getc (file);
1251 len = 0;
1252 outsym_off = 0;
1253 while (c != EOF)
1254 {
1255 /* Collect the input symbol name. */
1256 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1257 {
1258 if (c == '#')
1259 goto comment;
1260 buf[len++] = c;
1261 if (len >= bufsize)
1262 {
1263 bufsize *= 2;
a6da20b5 1264 buf = (char *) xrealloc (buf, bufsize + 1);
92991082
JT
1265 }
1266 c = getc (file);
1267 }
1268 buf[len++] = '\0';
1269 if (c == EOF)
1270 break;
1271
1272 /* Eat white space between the symbol names. */
1273 while (IS_WHITESPACE (c))
1274 c = getc (file);
1275 if (c == '#' || IS_LINE_TERMINATOR (c))
1276 goto comment;
1277 if (c == EOF)
1278 break;
1279
1280 /* Collect the output symbol name. */
1281 outsym_off = len;
1282 while (! IS_WHITESPACE (c) && ! IS_LINE_TERMINATOR (c) && c != EOF)
1283 {
1284 if (c == '#')
1285 goto comment;
1286 buf[len++] = c;
1287 if (len >= bufsize)
1288 {
1289 bufsize *= 2;
a6da20b5 1290 buf = (char *) xrealloc (buf, bufsize + 1);
92991082
JT
1291 }
1292 c = getc (file);
1293 }
1294 buf[len++] = '\0';
1295 if (c == EOF)
1296 break;
1297
1298 /* Eat white space at end of line. */
1299 while (! IS_LINE_TERMINATOR(c) && c != EOF && IS_WHITESPACE (c))
1300 c = getc (file);
1301 if (c == '#')
1302 goto comment;
1303 /* Handle \r\n. */
1304 if ((c == '\r' && (c = getc (file)) == '\n')
1305 || c == '\n' || c == EOF)
1306 {
1307 end_of_line:
1308 /* Append the redefinition to the list. */
1309 if (buf[0] != '\0')
1310 redefine_list_append (filename, &buf[0], &buf[outsym_off]);
1311
c1c0eb9e 1312 lineno++;
92991082
JT
1313 len = 0;
1314 outsym_off = 0;
1315 if (c == EOF)
1316 break;
1317 c = getc (file);
1318 continue;
1319 }
1320 else
d412a550 1321 fatal (_("%s:%d: garbage found at end of line"), filename, lineno);
92991082
JT
1322 comment:
1323 if (len != 0 && (outsym_off == 0 || outsym_off == len))
d412a550 1324 fatal (_("%s:%d: missing new symbol name"), filename, lineno);
92991082
JT
1325 buf[len++] = '\0';
1326
1327 /* Eat the rest of the line and finish it. */
1328 while (c != '\n' && c != EOF)
1329 c = getc (file);
1330 goto end_of_line;
1331 }
1332
1333 if (len != 0)
d412a550 1334 fatal (_("%s:%d: premature end of file"), filename, lineno);
92991082
JT
1335
1336 free (buf);
1337}
1338
77f762d6
L
1339/* Copy unkown object file IBFD onto OBFD.
1340 Returns TRUE upon success, FALSE otherwise. */
1341
1342static bfd_boolean
1343copy_unknown_object (bfd *ibfd, bfd *obfd)
1344{
1345 char *cbuf;
1346 int tocopy;
1347 long ncopied;
1348 long size;
1349 struct stat buf;
1350
1351 if (bfd_stat_arch_elt (ibfd, &buf) != 0)
1352 {
8d8e0703 1353 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
77f762d6
L
1354 return FALSE;
1355 }
1356
1357 size = buf.st_size;
1358 if (size < 0)
1359 {
1360 non_fatal (_("stat returns negative size for `%s'"),
1361 bfd_get_archive_filename (ibfd));
1362 return FALSE;
1363 }
1364
1365 if (bfd_seek (ibfd, (file_ptr) 0, SEEK_SET) != 0)
1366 {
1367 bfd_nonfatal (bfd_get_archive_filename (ibfd));
1368 return FALSE;
1369 }
1370
1371 if (verbose)
1372 printf (_("copy from `%s' [unknown] to `%s' [unknown]\n"),
1373 bfd_get_archive_filename (ibfd), bfd_get_filename (obfd));
1374
3f5e193b 1375 cbuf = (char *) xmalloc (BUFSIZE);
77f762d6
L
1376 ncopied = 0;
1377 while (ncopied < size)
1378 {
1379 tocopy = size - ncopied;
1380 if (tocopy > BUFSIZE)
1381 tocopy = BUFSIZE;
1382
1383 if (bfd_bread (cbuf, (bfd_size_type) tocopy, ibfd)
1384 != (bfd_size_type) tocopy)
1385 {
8d8e0703 1386 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
77f762d6
L
1387 free (cbuf);
1388 return FALSE;
1389 }
1390
1391 if (bfd_bwrite (cbuf, (bfd_size_type) tocopy, obfd)
1392 != (bfd_size_type) tocopy)
1393 {
2db6cde7 1394 bfd_nonfatal_message (NULL, obfd, NULL, NULL);
77f762d6
L
1395 free (cbuf);
1396 return FALSE;
1397 }
1398
1399 ncopied += tocopy;
1400 }
1401
1402 chmod (bfd_get_filename (obfd), buf.st_mode);
1403 free (cbuf);
1404 return TRUE;
1405}
1406
950d48e7 1407/* Copy object file IBFD onto OBFD.
5b8c74e6 1408 Returns TRUE upon success, FALSE otherwise. */
252b5132 1409
950d48e7 1410static bfd_boolean
8b31b6c4 1411copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
252b5132
RH
1412{
1413 bfd_vma start;
1414 long symcount;
1415 asection **osections = NULL;
84e2f313 1416 asection *gnu_debuglink_section = NULL;
252b5132
RH
1417 bfd_size_type *gaps = NULL;
1418 bfd_size_type max_gap = 0;
1419 long symsize;
84e2f313 1420 void *dhandle;
66491ebc
AM
1421 enum bfd_architecture iarch;
1422 unsigned int imach;
252b5132 1423
23719f39
NC
1424 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1425 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1426 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
950d48e7 1427 fatal (_("Unable to change endianness of input file(s)"));
252b5132
RH
1428
1429 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
950d48e7 1430 {
2db6cde7 1431 bfd_nonfatal_message (NULL, obfd, NULL, NULL);
950d48e7
NC
1432 return FALSE;
1433 }
252b5132
RH
1434
1435 if (verbose)
77f762d6
L
1436 printf (_("copy from `%s' [%s] to `%s' [%s]\n"),
1437 bfd_get_archive_filename (ibfd), bfd_get_target (ibfd),
252b5132
RH
1438 bfd_get_filename (obfd), bfd_get_target (obfd));
1439
d3e52d40
RS
1440 if (extract_symbol)
1441 start = 0;
252b5132 1442 else
d3e52d40
RS
1443 {
1444 if (set_start_set)
1445 start = set_start;
1446 else
1447 start = bfd_get_start_address (ibfd);
1448 start += change_start;
1449 }
252b5132 1450
0af11b59
KH
1451 /* Neither the start address nor the flags
1452 need to be set for a core file. */
4dd67f29
MS
1453 if (bfd_get_format (obfd) != bfd_core)
1454 {
4087920c
MR
1455 flagword flags;
1456
1457 flags = bfd_get_file_flags (ibfd);
1458 flags |= bfd_flags_to_set;
1459 flags &= ~bfd_flags_to_clear;
1460 flags &= bfd_applicable_file_flags (obfd);
1461
3516e984
L
1462 if (strip_symbols == STRIP_ALL)
1463 flags &= ~HAS_RELOC;
1464
4dd67f29 1465 if (!bfd_set_start_address (obfd, start)
4087920c 1466 || !bfd_set_file_flags (obfd, flags))
950d48e7 1467 {
8d8e0703 1468 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
950d48e7
NC
1469 return FALSE;
1470 }
4dd67f29 1471 }
252b5132 1472
594ef5db 1473 /* Copy architecture of input file to output file. */
66491ebc
AM
1474 iarch = bfd_get_arch (ibfd);
1475 imach = bfd_get_mach (ibfd);
8b31b6c4
NC
1476 if (input_arch)
1477 {
1478 if (bfd_get_arch_info (ibfd) == NULL
1479 || bfd_get_arch_info (ibfd)->arch == bfd_arch_unknown)
1480 {
1481 iarch = input_arch->arch;
1482 imach = input_arch->mach;
1483 }
1484 else
1485 non_fatal (_("Input file `%s' ignores binary architecture parameter."),
1486 bfd_get_archive_filename (ibfd));
1487 }
66491ebc 1488 if (!bfd_set_arch_mach (obfd, iarch, imach)
212a3c4d
L
1489 && (ibfd->target_defaulted
1490 || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
f57a841a
NC
1491 {
1492 if (bfd_get_arch (ibfd) == bfd_arch_unknown)
77f762d6
L
1493 non_fatal (_("Unable to recognise the format of the input file `%s'"),
1494 bfd_get_archive_filename (ibfd));
f57a841a 1495 else
c1e2cb9d 1496 non_fatal (_("Output file cannot represent architecture `%s'"),
77f762d6
L
1497 bfd_printable_arch_mach (bfd_get_arch (ibfd),
1498 bfd_get_mach (ibfd)));
1499 return FALSE;
f57a841a 1500 }
57938635 1501
252b5132 1502 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
950d48e7 1503 {
8d8e0703 1504 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
950d48e7
NC
1505 return FALSE;
1506 }
252b5132 1507
92dd4511
L
1508 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1509 && bfd_pei_p (obfd))
1510 {
1511 /* Set up PE parameters. */
1512 pe_data_type *pe = pe_data (obfd);
1513
325c681d
L
1514 /* Copy PE parameters before changing them. */
1515 if (ibfd->xvec->flavour == bfd_target_coff_flavour
1516 && bfd_pei_p (ibfd))
1517 pe->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1518
92dd4511
L
1519 if (pe_file_alignment != (bfd_vma) -1)
1520 pe->pe_opthdr.FileAlignment = pe_file_alignment;
1521 else
1522 pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
1523
1524 if (pe_heap_commit != (bfd_vma) -1)
1525 pe->pe_opthdr.SizeOfHeapCommit = pe_heap_commit;
1526
1527 if (pe_heap_reserve != (bfd_vma) -1)
1528 pe->pe_opthdr.SizeOfHeapCommit = pe_heap_reserve;
1529
1530 if (pe_image_base != (bfd_vma) -1)
1531 pe->pe_opthdr.ImageBase = pe_image_base;
1532
1533 if (pe_section_alignment != (bfd_vma) -1)
1534 pe->pe_opthdr.SectionAlignment = pe_section_alignment;
1535 else
1536 pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
1537
1538 if (pe_stack_commit != (bfd_vma) -1)
1539 pe->pe_opthdr.SizeOfStackCommit = pe_stack_commit;
1540
1541 if (pe_stack_reserve != (bfd_vma) -1)
1542 pe->pe_opthdr.SizeOfStackCommit = pe_stack_reserve;
1543
1544 if (pe_subsystem != -1)
1545 pe->pe_opthdr.Subsystem = pe_subsystem;
1546
1547 if (pe_major_subsystem_version != -1)
1548 pe->pe_opthdr.MajorSubsystemVersion = pe_major_subsystem_version;
1549
1550 if (pe_minor_subsystem_version != -1)
1551 pe->pe_opthdr.MinorSubsystemVersion = pe_minor_subsystem_version;
1552
1553 if (pe_file_alignment > pe_section_alignment)
1554 {
1555 char file_alignment[20], section_alignment[20];
1556
1557 sprintf_vma (file_alignment, pe_file_alignment);
1558 sprintf_vma (section_alignment, pe_section_alignment);
1559 non_fatal (_("warning: file alignment (0x%s) > section alignment (0x%s)"),
1560
1561 file_alignment, section_alignment);
1562 }
1563 }
1564
252b5132 1565 if (isympp)
62d732f5 1566 free (isympp);
57938635 1567
252b5132 1568 if (osympp != isympp)
62d732f5
AM
1569 free (osympp);
1570
1571 isympp = NULL;
1572 osympp = NULL;
252b5132 1573
c39ada54
AM
1574 symsize = bfd_get_symtab_upper_bound (ibfd);
1575 if (symsize < 0)
1576 {
8d8e0703 1577 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
c39ada54
AM
1578 return FALSE;
1579 }
1580
3f5e193b 1581 osympp = isympp = (asymbol **) xmalloc (symsize);
c39ada54
AM
1582 symcount = bfd_canonicalize_symtab (ibfd, isympp);
1583 if (symcount < 0)
1584 {
2db6cde7 1585 bfd_nonfatal_message (NULL, ibfd, NULL, NULL);
c39ada54
AM
1586 return FALSE;
1587 }
1588
252b5132
RH
1589 /* BFD mandates that all output sections be created and sizes set before
1590 any output is done. Thus, we traverse all sections multiple times. */
d3ba0551 1591 bfd_map_over_sections (ibfd, setup_section, obfd);
252b5132 1592
237dcb53
AM
1593 if (!extract_symbol)
1594 setup_bfd_headers (ibfd, obfd);
80fccad2 1595
252b5132
RH
1596 if (add_sections != NULL)
1597 {
1598 struct section_add *padd;
1599 struct section_list *pset;
1600
1601 for (padd = add_sections; padd != NULL; padd = padd->next)
1602 {
2593f09a
NC
1603 flagword flags;
1604
551b43fd
AM
1605 pset = find_section_list (padd->name, FALSE);
1606 if (pset != NULL)
1607 pset->used = TRUE;
1608
1609 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1610 if (pset != NULL && pset->set_flags)
1611 flags = pset->flags | SEC_HAS_CONTENTS;
1612
c8782eee
NC
1613 /* bfd_make_section_with_flags() does not return very helpful
1614 error codes, so check for the most likely user error first. */
1615 if (bfd_get_section_by_name (obfd, padd->name))
252b5132 1616 {
2db6cde7
NS
1617 bfd_nonfatal_message (NULL, obfd, NULL,
1618 _("can't add section '%s'"), padd->name);
950d48e7 1619 return FALSE;
252b5132 1620 }
c8782eee
NC
1621 else
1622 {
0930eddd
NS
1623 /* We use LINKER_CREATED here so that the backend hooks
1624 will create any special section type information,
1625 instead of presuming we know what we're doing merely
1626 because we set the flags. */
1627 padd->section = bfd_make_section_with_flags
1628 (obfd, padd->name, flags | SEC_LINKER_CREATED);
c8782eee
NC
1629 if (padd->section == NULL)
1630 {
2db6cde7
NS
1631 bfd_nonfatal_message (NULL, obfd, NULL,
1632 _("can't create section `%s'"),
1633 padd->name);
c8782eee
NC
1634 return FALSE;
1635 }
1636 }
252b5132 1637
2593f09a 1638 if (! bfd_set_section_size (obfd, padd->section, padd->size))
950d48e7 1639 {
2db6cde7 1640 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1641 return FALSE;
1642 }
252b5132 1643
2593f09a
NC
1644 if (pset != NULL)
1645 {
1646 if (pset->change_vma != CHANGE_IGNORE)
84e2f313
NC
1647 if (! bfd_set_section_vma (obfd, padd->section,
1648 pset->vma_val))
950d48e7 1649 {
2db6cde7 1650 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1651 return FALSE;
1652 }
57938635 1653
2593f09a
NC
1654 if (pset->change_lma != CHANGE_IGNORE)
1655 {
1656 padd->section->lma = pset->lma_val;
950d48e7 1657
2593f09a
NC
1658 if (! bfd_set_section_alignment
1659 (obfd, padd->section,
1660 bfd_section_alignment (obfd, padd->section)))
950d48e7 1661 {
2db6cde7 1662 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1663 return FALSE;
1664 }
252b5132
RH
1665 }
1666 }
1667 }
1668 }
1669
2593f09a
NC
1670 if (gnu_debuglink_filename != NULL)
1671 {
84e2f313
NC
1672 gnu_debuglink_section = bfd_create_gnu_debuglink_section
1673 (obfd, gnu_debuglink_filename);
e7c81c25
NC
1674
1675 if (gnu_debuglink_section == NULL)
950d48e7 1676 {
2db6cde7
NS
1677 bfd_nonfatal_message (NULL, obfd, NULL,
1678 _("cannot create debug link section `%s'"),
1679 gnu_debuglink_filename);
950d48e7
NC
1680 return FALSE;
1681 }
6e2c86ac
NC
1682
1683 /* Special processing for PE format files. We
1684 have no way to distinguish PE from COFF here. */
1685 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1686 {
1687 bfd_vma debuglink_vma;
1688 asection * highest_section;
1689 asection * sec;
1690
1691 /* The PE spec requires that all sections be adjacent and sorted
1692 in ascending order of VMA. It also specifies that debug
1693 sections should be last. This is despite the fact that debug
1694 sections are not loaded into memory and so in theory have no
1695 use for a VMA.
1696
1697 This means that the debuglink section must be given a non-zero
1698 VMA which makes it contiguous with other debug sections. So
1699 walk the current section list, find the section with the
1700 highest VMA and start the debuglink section after that one. */
1701 for (sec = obfd->sections, highest_section = NULL;
1702 sec != NULL;
1703 sec = sec->next)
1704 if (sec->vma > 0
1705 && (highest_section == NULL
1706 || sec->vma > highest_section->vma))
1707 highest_section = sec;
1708
1709 if (highest_section)
1710 debuglink_vma = BFD_ALIGN (highest_section->vma
1711 + highest_section->size,
1712 /* FIXME: We ought to be using
1713 COFF_PAGE_SIZE here or maybe
1714 bfd_get_section_alignment() (if it
1715 was set) but since this is for PE
1716 and we know the required alignment
1717 it is easier just to hard code it. */
1718 0x1000);
1719 else
1720 /* Umm, not sure what to do in this case. */
1721 debuglink_vma = 0x1000;
1722
1723 bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
1724 }
950d48e7
NC
1725 }
1726
1aa9ef63
L
1727 if (bfd_count_sections (obfd) != 0
1728 && (gap_fill_set || pad_to_set))
252b5132
RH
1729 {
1730 asection **set;
1731 unsigned int c, i;
1732
1733 /* We must fill in gaps between the sections and/or we must pad
1734 the last section to a specified address. We do this by
1735 grabbing a list of the sections, sorting them by VMA, and
1736 increasing the section sizes as required to fill the gaps.
1737 We write out the gap contents below. */
1738
1739 c = bfd_count_sections (obfd);
3f5e193b 1740 osections = (asection **) xmalloc (c * sizeof (asection *));
252b5132 1741 set = osections;
d3ba0551 1742 bfd_map_over_sections (obfd, get_sections, &set);
252b5132
RH
1743
1744 qsort (osections, c, sizeof (asection *), compare_section_lma);
1745
3f5e193b 1746 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
252b5132
RH
1747 memset (gaps, 0, c * sizeof (bfd_size_type));
1748
1749 if (gap_fill_set)
1750 {
1751 for (i = 0; i < c - 1; i++)
1752 {
1753 flagword flags;
1754 bfd_size_type size;
1755 bfd_vma gap_start, gap_stop;
1756
1757 flags = bfd_get_section_flags (obfd, osections[i]);
1758 if ((flags & SEC_HAS_CONTENTS) == 0
1759 || (flags & SEC_LOAD) == 0)
1760 continue;
1761
1762 size = bfd_section_size (obfd, osections[i]);
1763 gap_start = bfd_section_lma (obfd, osections[i]) + size;
1764 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1765 if (gap_start < gap_stop)
1766 {
1767 if (! bfd_set_section_size (obfd, osections[i],
1768 size + (gap_stop - gap_start)))
1769 {
2db6cde7
NS
1770 bfd_nonfatal_message (NULL, obfd, osections[i],
1771 _("Can't fill gap after section"));
252b5132
RH
1772 status = 1;
1773 break;
1774 }
1775 gaps[i] = gap_stop - gap_start;
1776 if (max_gap < gap_stop - gap_start)
1777 max_gap = gap_stop - gap_start;
1778 }
1779 }
1780 }
1781
1782 if (pad_to_set)
1783 {
1784 bfd_vma lma;
1785 bfd_size_type size;
1786
1787 lma = bfd_section_lma (obfd, osections[c - 1]);
1788 size = bfd_section_size (obfd, osections[c - 1]);
1789 if (lma + size < pad_to)
1790 {
1791 if (! bfd_set_section_size (obfd, osections[c - 1],
1792 pad_to - lma))
1793 {
2db6cde7
NS
1794 bfd_nonfatal_message (NULL, obfd, osections[c - 1],
1795 _("can't add padding"));
252b5132
RH
1796 status = 1;
1797 }
1798 else
1799 {
1800 gaps[c - 1] = pad_to - (lma + size);
1801 if (max_gap < pad_to - (lma + size))
1802 max_gap = pad_to - (lma + size);
1803 }
1804 }
1805 }
1806 }
1807
594ef5db
NC
1808 /* Symbol filtering must happen after the output sections
1809 have been created, but before their contents are set. */
252b5132 1810 dhandle = NULL;
252b5132 1811 if (convert_debugging)
b922d590 1812 dhandle = read_debugging_info (ibfd, isympp, symcount, FALSE);
57938635
AM
1813
1814 if (strip_symbols == STRIP_DEBUG
252b5132
RH
1815 || strip_symbols == STRIP_ALL
1816 || strip_symbols == STRIP_UNNEEDED
ed1653a7 1817 || strip_symbols == STRIP_NONDEBUG
252b5132 1818 || discard_locals != LOCALS_UNDEF
d58c2e3a 1819 || localize_hidden
047c9024
NC
1820 || htab_elements (strip_specific_htab) != 0
1821 || htab_elements (keep_specific_htab) != 0
1822 || htab_elements (localize_specific_htab) != 0
1823 || htab_elements (globalize_specific_htab) != 0
1824 || htab_elements (keepglobal_specific_htab) != 0
1825 || htab_elements (weaken_specific_htab) != 0
d7fb0dd2 1826 || prefix_symbols_string
252b5132 1827 || sections_removed
f91ea849 1828 || sections_copied
252b5132
RH
1829 || convert_debugging
1830 || change_leading_char
1831 || remove_leading_char
57938635 1832 || redefine_sym_list
252b5132
RH
1833 || weaken)
1834 {
1835 /* Mark symbols used in output relocations so that they
1836 are kept, even if they are local labels or static symbols.
57938635 1837
252b5132
RH
1838 Note we iterate over the input sections examining their
1839 relocations since the relocations for the output sections
1840 haven't been set yet. mark_symbols_used_in_relocations will
1841 ignore input sections which have no corresponding output
1842 section. */
1843 if (strip_symbols != STRIP_ALL)
1844 bfd_map_over_sections (ibfd,
1845 mark_symbols_used_in_relocations,
d3ba0551 1846 isympp);
3f5e193b 1847 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
252b5132
RH
1848 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1849 }
1850
1851 if (convert_debugging && dhandle != NULL)
1852 {
1853 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1854 {
1855 status = 1;
950d48e7 1856 return FALSE;
252b5132
RH
1857 }
1858 }
1859
1860 bfd_set_symtab (obfd, osympp, symcount);
1861
1862 /* This has to happen after the symbol table has been set. */
d3ba0551 1863 bfd_map_over_sections (ibfd, copy_section, obfd);
252b5132
RH
1864
1865 if (add_sections != NULL)
1866 {
1867 struct section_add *padd;
1868
1869 for (padd = add_sections; padd != NULL; padd = padd->next)
1870 {
d3ba0551
AM
1871 if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1872 0, padd->size))
950d48e7 1873 {
2db6cde7 1874 bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
950d48e7
NC
1875 return FALSE;
1876 }
252b5132
RH
1877 }
1878 }
1879
e7c81c25
NC
1880 if (gnu_debuglink_filename != NULL)
1881 {
1882 if (! bfd_fill_in_gnu_debuglink_section
1883 (obfd, gnu_debuglink_section, gnu_debuglink_filename))
950d48e7 1884 {
2db6cde7
NS
1885 bfd_nonfatal_message (NULL, obfd, NULL,
1886 _("cannot fill debug link section `%s'"),
1887 gnu_debuglink_filename);
950d48e7
NC
1888 return FALSE;
1889 }
e7c81c25
NC
1890 }
1891
252b5132
RH
1892 if (gap_fill_set || pad_to_set)
1893 {
1894 bfd_byte *buf;
1895 int c, i;
1896
1897 /* Fill in the gaps. */
252b5132
RH
1898 if (max_gap > 8192)
1899 max_gap = 8192;
3f5e193b 1900 buf = (bfd_byte *) xmalloc (max_gap);
d3ba0551 1901 memset (buf, gap_fill, max_gap);
252b5132
RH
1902
1903 c = bfd_count_sections (obfd);
1904 for (i = 0; i < c; i++)
1905 {
1906 if (gaps[i] != 0)
1907 {
1908 bfd_size_type left;
1909 file_ptr off;
1910
1911 left = gaps[i];
1912 off = bfd_section_size (obfd, osections[i]) - left;
594ef5db 1913
252b5132
RH
1914 while (left > 0)
1915 {
1916 bfd_size_type now;
1917
1918 if (left > 8192)
1919 now = 8192;
1920 else
1921 now = left;
1922
1923 if (! bfd_set_section_contents (obfd, osections[i], buf,
1924 off, now))
950d48e7 1925 {
2db6cde7 1926 bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
950d48e7
NC
1927 return FALSE;
1928 }
252b5132
RH
1929
1930 left -= now;
1931 off += now;
1932 }
1933 }
1934 }
1935 }
1936
d3e52d40
RS
1937 /* Do not copy backend data if --extract-symbol is passed; anything
1938 that needs to look at the section contents will fail. */
1939 if (extract_symbol)
1940 return TRUE;
1941
252b5132
RH
1942 /* Allow the BFD backend to copy any private data it understands
1943 from the input BFD to the output BFD. This is done last to
1944 permit the routine to look at the filtered symbol table, which is
1945 important for the ECOFF code at least. */
42bb2e33 1946 if (! bfd_copy_private_bfd_data (ibfd, obfd))
252b5132 1947 {
2db6cde7
NS
1948 bfd_nonfatal_message (NULL, obfd, NULL,
1949 _("error copying private BFD data"));
950d48e7 1950 return FALSE;
252b5132 1951 }
1ae8b3d2
AO
1952
1953 /* Switch to the alternate machine code. We have to do this at the
1954 very end, because we only initialize the header when we create
1955 the first section. */
f9d4ad2a
NC
1956 if (use_alt_mach_code != 0)
1957 {
1958 if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
1959 {
1960 non_fatal (_("this target does not support %lu alternative machine codes"),
1961 use_alt_mach_code);
1962 if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1963 {
1964 non_fatal (_("treating that number as an absolute e_machine value instead"));
1965 elf_elfheader (obfd)->e_machine = use_alt_mach_code;
1966 }
1967 else
1968 non_fatal (_("ignoring the alternative value"));
1969 }
1970 }
950d48e7
NC
1971
1972 return TRUE;
252b5132
RH
1973}
1974
1975/* Read each archive element in turn from IBFD, copy the
ee873e00
NC
1976 contents to temp file, and keep the temp file handle.
1977 If 'force_output_target' is TRUE then make sure that
1978 all elements in the new archive are of the type
1979 'output_target'. */
252b5132
RH
1980
1981static void
ee873e00 1982copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
8b31b6c4
NC
1983 bfd_boolean force_output_target,
1984 const bfd_arch_info_type *input_arch)
252b5132
RH
1985{
1986 struct name_list
1987 {
1988 struct name_list *next;
4c168fa3 1989 const char *name;
252b5132
RH
1990 bfd *obfd;
1991 } *list, *l;
1992 bfd **ptr = &obfd->archive_head;
1993 bfd *this_element;
8d8e0703
AM
1994 char *dir;
1995 const char *filename;
252b5132
RH
1996
1997 /* Make a temp directory to hold the contents. */
f9c026a8 1998 dir = make_tempdir (bfd_get_filename (obfd));
f9c026a8
NC
1999 if (dir == NULL)
2000 fatal (_("cannot create tempdir for archive copying (error: %s)"),
2001 strerror (errno));
84e2f313 2002
252b5132 2003 obfd->has_armap = ibfd->has_armap;
a8da6403 2004 obfd->is_thin_archive = ibfd->is_thin_archive;
252b5132
RH
2005
2006 list = NULL;
2007
2008 this_element = bfd_openr_next_archived_file (ibfd, NULL);
594ef5db 2009
b667df2e 2010 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
8d8e0703
AM
2011 {
2012 status = 1;
2013 bfd_nonfatal_message (NULL, obfd, NULL, NULL);
2014 return;
2015 }
b667df2e 2016
d3ba0551 2017 while (!status && this_element != NULL)
252b5132 2018 {
4c168fa3
AM
2019 char *output_name;
2020 bfd *output_bfd;
252b5132 2021 bfd *last_element;
8066d1a2
AS
2022 struct stat buf;
2023 int stat_status = 0;
3f5e193b 2024 bfd_boolean del = TRUE;
8066d1a2 2025
4c168fa3
AM
2026 /* Create an output file for this member. */
2027 output_name = concat (dir, "/",
2028 bfd_get_filename (this_element), (char *) 0);
2029
2030 /* If the file already exists, make another temp dir. */
2031 if (stat (output_name, &buf) >= 0)
2032 {
f9c026a8
NC
2033 output_name = make_tempdir (output_name);
2034 if (output_name == NULL)
485be063
AM
2035 fatal (_("cannot create tempdir for archive copying (error: %s)"),
2036 strerror (errno));
84e2f313 2037
3f5e193b 2038 l = (struct name_list *) xmalloc (sizeof (struct name_list));
4c168fa3
AM
2039 l->name = output_name;
2040 l->next = list;
2041 l->obfd = NULL;
2042 list = l;
2043 output_name = concat (output_name, "/",
2044 bfd_get_filename (this_element), (char *) 0);
2045 }
2046
8066d1a2
AS
2047 if (preserve_dates)
2048 {
2049 stat_status = bfd_stat_arch_elt (this_element, &buf);
594ef5db 2050
8066d1a2
AS
2051 if (stat_status != 0)
2052 non_fatal (_("internal stat error on %s"),
2053 bfd_get_filename (this_element));
2054 }
252b5132 2055
3f5e193b 2056 l = (struct name_list *) xmalloc (sizeof (struct name_list));
252b5132
RH
2057 l->name = output_name;
2058 l->next = list;
bee59fd2 2059 l->obfd = NULL;
252b5132
RH
2060 list = l;
2061
b34976b6 2062 if (bfd_check_format (this_element, bfd_object))
77f762d6 2063 {
ee873e00
NC
2064 /* PR binutils/3110: Cope with archives
2065 containing multiple target types. */
2066 if (force_output_target)
2067 output_bfd = bfd_openw (output_name, output_target);
2068 else
2069 output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
2070
2071 if (output_bfd == NULL)
2db6cde7
NS
2072 {
2073 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
2074 status = 1;
2075 return;
2076 }
ee873e00 2077
8b31b6c4 2078 del = ! copy_object (this_element, output_bfd, input_arch);
252b5132 2079
3f5e193b 2080 if (! del
77f762d6
L
2081 || bfd_get_arch (this_element) != bfd_arch_unknown)
2082 {
2083 if (!bfd_close (output_bfd))
2084 {
8d8e0703 2085 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
77f762d6
L
2086 /* Error in new object file. Don't change archive. */
2087 status = 1;
2088 }
2089 }
2090 else
2091 goto copy_unknown_element;
2092 }
2093 else
252b5132 2094 {
8d8e0703 2095 bfd_nonfatal_message (NULL, this_element, NULL,
2db6cde7 2096 _("Unable to recognise the format of file"));
77f762d6 2097
ee873e00 2098 output_bfd = bfd_openw (output_name, output_target);
77f762d6 2099copy_unknown_element:
3f5e193b 2100 del = !copy_unknown_object (this_element, output_bfd);
77f762d6
L
2101 if (!bfd_close_all_done (output_bfd))
2102 {
8d8e0703 2103 bfd_nonfatal_message (output_name, NULL, NULL, NULL);
77f762d6
L
2104 /* Error in new object file. Don't change archive. */
2105 status = 1;
2106 }
252b5132
RH
2107 }
2108
3f5e193b 2109 if (del)
950d48e7
NC
2110 {
2111 unlink (output_name);
2112 status = 1;
2113 }
2114 else
2115 {
2116 if (preserve_dates && stat_status == 0)
2117 set_times (output_name, &buf);
8066d1a2 2118
950d48e7
NC
2119 /* Open the newly output file and attach to our list. */
2120 output_bfd = bfd_openr (output_name, output_target);
252b5132 2121
950d48e7 2122 l->obfd = output_bfd;
252b5132 2123
950d48e7 2124 *ptr = output_bfd;
cc481421 2125 ptr = &output_bfd->archive_next;
252b5132 2126
950d48e7 2127 last_element = this_element;
252b5132 2128
950d48e7 2129 this_element = bfd_openr_next_archived_file (ibfd, last_element);
252b5132 2130
950d48e7
NC
2131 bfd_close (last_element);
2132 }
252b5132 2133 }
d3ba0551 2134 *ptr = NULL;
252b5132 2135
8d8e0703 2136 filename = bfd_get_filename (obfd);
252b5132 2137 if (!bfd_close (obfd))
8d8e0703
AM
2138 {
2139 status = 1;
2140 bfd_nonfatal_message (filename, NULL, NULL, NULL);
2141 return;
2142 }
252b5132 2143
8d8e0703 2144 filename = bfd_get_filename (ibfd);
252b5132 2145 if (!bfd_close (ibfd))
8d8e0703
AM
2146 {
2147 status = 1;
2148 bfd_nonfatal_message (filename, NULL, NULL, NULL);
2149 return;
2150 }
252b5132
RH
2151
2152 /* Delete all the files that we opened. */
2153 for (l = list; l != NULL; l = l->next)
2154 {
4c168fa3
AM
2155 if (l->obfd == NULL)
2156 rmdir (l->name);
2157 else
2158 {
2159 bfd_close (l->obfd);
2160 unlink (l->name);
2161 }
252b5132
RH
2162 }
2163 rmdir (dir);
2164}
2165
0408dee6
DK
2166static void
2167set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style)
2168{
2169 /* This is only relevant to Coff targets. */
2170 if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
2171 {
78e82dc3
AM
2172 if (style == KEEP
2173 && bfd_get_flavour (input_bfd) == bfd_target_coff_flavour)
0408dee6
DK
2174 style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE;
2175 bfd_coff_set_long_section_names (output_bfd, style != DISABLE);
2176 }
2177}
2178
252b5132
RH
2179/* The top-level control. */
2180
2181static void
84e2f313 2182copy_file (const char *input_filename, const char *output_filename,
8b31b6c4
NC
2183 const char *input_target, const char *output_target,
2184 const bfd_arch_info_type *input_arch)
252b5132
RH
2185{
2186 bfd *ibfd;
49c12576
AM
2187 char **obj_matching;
2188 char **core_matching;
52a476ee 2189 off_t size = get_file_size (input_filename);
252b5132 2190
52a476ee 2191 if (size < 1)
f24ddbdd 2192 {
52a476ee
L
2193 if (size == 0)
2194 non_fatal (_("error: the input file '%s' is empty"),
2195 input_filename);
f24ddbdd
NC
2196 status = 1;
2197 return;
2198 }
2199
252b5132
RH
2200 /* To allow us to do "strip *" without dying on the first
2201 non-object file, failures are nonfatal. */
252b5132
RH
2202 ibfd = bfd_openr (input_filename, input_target);
2203 if (ibfd == NULL)
2db6cde7
NS
2204 {
2205 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2206 status = 1;
2207 return;
2208 }
252b5132 2209
4a114e3e
L
2210 switch (do_debug_sections)
2211 {
2212 case compress:
2213 ibfd->flags |= BFD_COMPRESS;
2214 break;
2215 case decompress:
2216 ibfd->flags |= BFD_DECOMPRESS;
2217 break;
2218 default:
2219 break;
2220 }
2221
252b5132
RH
2222 if (bfd_check_format (ibfd, bfd_archive))
2223 {
ee873e00 2224 bfd_boolean force_output_target;
252b5132
RH
2225 bfd *obfd;
2226
2227 /* bfd_get_target does not return the correct value until
2228 bfd_check_format succeeds. */
2229 if (output_target == NULL)
ee873e00
NC
2230 {
2231 output_target = bfd_get_target (ibfd);
2232 force_output_target = FALSE;
2233 }
2234 else
2235 force_output_target = TRUE;
252b5132
RH
2236
2237 obfd = bfd_openw (output_filename, output_target);
2238 if (obfd == NULL)
2db6cde7
NS
2239 {
2240 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2241 status = 1;
2242 return;
2243 }
0408dee6
DK
2244 /* This is a no-op on non-Coff targets. */
2245 set_long_section_mode (obfd, ibfd, long_section_names);
252b5132 2246
8b31b6c4 2247 copy_archive (ibfd, obfd, output_target, force_output_target, input_arch);
252b5132 2248 }
49c12576 2249 else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
252b5132
RH
2250 {
2251 bfd *obfd;
49c12576 2252 do_copy:
950d48e7 2253
252b5132
RH
2254 /* bfd_get_target does not return the correct value until
2255 bfd_check_format succeeds. */
2256 if (output_target == NULL)
2257 output_target = bfd_get_target (ibfd);
2258
2259 obfd = bfd_openw (output_filename, output_target);
2260 if (obfd == NULL)
2db6cde7
NS
2261 {
2262 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2263 status = 1;
2264 return;
2265 }
0408dee6
DK
2266 /* This is a no-op on non-Coff targets. */
2267 set_long_section_mode (obfd, ibfd, long_section_names);
252b5132 2268
8b31b6c4 2269 if (! copy_object (ibfd, obfd, input_arch))
a580b8e0 2270 status = 1;
252b5132
RH
2271
2272 if (!bfd_close (obfd))
8d8e0703
AM
2273 {
2274 status = 1;
2275 bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2276 return;
2277 }
252b5132
RH
2278
2279 if (!bfd_close (ibfd))
8d8e0703
AM
2280 {
2281 status = 1;
2282 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2283 return;
2284 }
252b5132
RH
2285 }
2286 else
2287 {
49c12576
AM
2288 bfd_error_type obj_error = bfd_get_error ();
2289 bfd_error_type core_error;
b34976b6 2290
49c12576
AM
2291 if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
2292 {
2293 /* This probably can't happen.. */
2294 if (obj_error == bfd_error_file_ambiguously_recognized)
2295 free (obj_matching);
2296 goto do_copy;
2297 }
2298
2299 core_error = bfd_get_error ();
2300 /* Report the object error in preference to the core error. */
2301 if (obj_error != core_error)
2302 bfd_set_error (obj_error);
2303
2db6cde7 2304 bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
57938635 2305
49c12576
AM
2306 if (obj_error == bfd_error_file_ambiguously_recognized)
2307 {
2308 list_matching_formats (obj_matching);
2309 free (obj_matching);
2310 }
2311 if (core_error == bfd_error_file_ambiguously_recognized)
252b5132 2312 {
49c12576
AM
2313 list_matching_formats (core_matching);
2314 free (core_matching);
252b5132 2315 }
57938635 2316
252b5132
RH
2317 status = 1;
2318 }
2319}
2320
594ef5db
NC
2321/* Add a name to the section renaming list. */
2322
2323static void
84e2f313
NC
2324add_section_rename (const char * old_name, const char * new_name,
2325 flagword flags)
594ef5db 2326{
91d6fa6a 2327 section_rename * srename;
594ef5db
NC
2328
2329 /* Check for conflicts first. */
91d6fa6a
NC
2330 for (srename = section_rename_list; srename != NULL; srename = srename->next)
2331 if (strcmp (srename->old_name, old_name) == 0)
594ef5db
NC
2332 {
2333 /* Silently ignore duplicate definitions. */
91d6fa6a
NC
2334 if (strcmp (srename->new_name, new_name) == 0
2335 && srename->flags == flags)
594ef5db 2336 return;
0af11b59 2337
594ef5db
NC
2338 fatal (_("Multiple renames of section %s"), old_name);
2339 }
2340
91d6fa6a 2341 srename = (section_rename *) xmalloc (sizeof (* srename));
594ef5db 2342
91d6fa6a
NC
2343 srename->old_name = old_name;
2344 srename->new_name = new_name;
2345 srename->flags = flags;
2346 srename->next = section_rename_list;
0af11b59 2347
91d6fa6a 2348 section_rename_list = srename;
594ef5db
NC
2349}
2350
2351/* Check the section rename list for a new name of the input section
2352 ISECTION. Return the new name if one is found.
2353 Also set RETURNED_FLAGS to the flags to be used for this section. */
2354
2355static const char *
84e2f313
NC
2356find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
2357 flagword * returned_flags)
594ef5db
NC
2358{
2359 const char * old_name = bfd_section_name (ibfd, isection);
91d6fa6a 2360 section_rename * srename;
594ef5db
NC
2361
2362 /* Default to using the flags of the input section. */
2363 * returned_flags = bfd_get_section_flags (ibfd, isection);
2364
91d6fa6a
NC
2365 for (srename = section_rename_list; srename != NULL; srename = srename->next)
2366 if (strcmp (srename->old_name, old_name) == 0)
594ef5db 2367 {
91d6fa6a
NC
2368 if (srename->flags != (flagword) -1)
2369 * returned_flags = srename->flags;
594ef5db 2370
91d6fa6a 2371 return srename->new_name;
594ef5db
NC
2372 }
2373
2374 return old_name;
2375}
2376
80fccad2
BW
2377/* Once each of the sections is copied, we may still need to do some
2378 finalization work for private section headers. Do that here. */
2379
2380static void
2381setup_bfd_headers (bfd *ibfd, bfd *obfd)
2382{
80fccad2
BW
2383 /* Allow the BFD backend to copy any private data it understands
2384 from the input section to the output section. */
2385 if (! bfd_copy_private_header_data (ibfd, obfd))
2386 {
2db6cde7
NS
2387 status = 1;
2388 bfd_nonfatal_message (NULL, ibfd, NULL,
8d8e0703 2389 _("error in private header data"));
2db6cde7 2390 return;
80fccad2
BW
2391 }
2392
2393 /* All went well. */
2394 return;
80fccad2
BW
2395}
2396
594ef5db
NC
2397/* Create a section in OBFD with the same
2398 name and attributes as ISECTION in IBFD. */
252b5132
RH
2399
2400static void
84e2f313 2401setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 2402{
3f5e193b 2403 bfd *obfd = (bfd *) obfdarg;
252b5132
RH
2404 struct section_list *p;
2405 sec_ptr osection;
2406 bfd_size_type size;
2407 bfd_vma vma;
2408 bfd_vma lma;
2409 flagword flags;
1a89cc7d 2410 const char *err;
594ef5db 2411 const char * name;
d7fb0dd2 2412 char *prefix = NULL;
66125551 2413 bfd_boolean make_nobits;
0af11b59 2414
2593f09a 2415 if (is_strip_section (ibfd, isection))
252b5132
RH
2416 return;
2417
b34976b6 2418 p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
252b5132 2419 if (p != NULL)
b34976b6 2420 p->used = TRUE;
252b5132 2421
594ef5db
NC
2422 /* Get the, possibly new, name of the output section. */
2423 name = find_section_rename (ibfd, isection, & flags);
0af11b59 2424
d7fb0dd2 2425 /* Prefix sections. */
84e2f313
NC
2426 if ((prefix_alloc_sections_string)
2427 && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
d7fb0dd2
NC
2428 prefix = prefix_alloc_sections_string;
2429 else if (prefix_sections_string)
2430 prefix = prefix_sections_string;
2431
2432 if (prefix)
2433 {
2434 char *n;
2435
3f5e193b 2436 n = (char *) xmalloc (strlen (prefix) + strlen (name) + 1);
d7fb0dd2
NC
2437 strcpy (n, prefix);
2438 strcat (n, name);
2439 name = n;
2440 }
66491ebc 2441
66125551 2442 make_nobits = FALSE;
551b43fd
AM
2443 if (p != NULL && p->set_flags)
2444 flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
42bb2e33 2445 else if (strip_symbols == STRIP_NONDEBUG
6c67a030
AM
2446 && (flags & (SEC_ALLOC | SEC_GROUP)) != 0
2447 && !(ibfd->xvec->flavour == bfd_target_elf_flavour
2448 && elf_section_type (isection) == SHT_NOTE))
66125551 2449 {
6c67a030 2450 flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
66125551
AM
2451 if (obfd->xvec->flavour == bfd_target_elf_flavour)
2452 {
2453 make_nobits = TRUE;
2454
2455 /* Twiddle the input section flags so that it seems to
2456 elf.c:copy_private_bfd_data that section flags have not
2457 changed between input and output sections. This hack
2458 prevents wholesale rewriting of the program headers. */
6c67a030 2459 isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP);
66125551
AM
2460 }
2461 }
551b43fd
AM
2462
2463 osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
57938635 2464
252b5132
RH
2465 if (osection == NULL)
2466 {
2db6cde7 2467 err = _("failed to create output section");
252b5132
RH
2468 goto loser;
2469 }
2470
66125551 2471 if (make_nobits)
551b43fd
AM
2472 elf_section_type (osection) = SHT_NOBITS;
2473
252b5132
RH
2474 size = bfd_section_size (ibfd, isection);
2475 if (copy_byte >= 0)
b7dd81f7 2476 size = (size + interleave - 1) / interleave * copy_width;
d3e52d40
RS
2477 else if (extract_symbol)
2478 size = 0;
252b5132
RH
2479 if (! bfd_set_section_size (obfd, osection, size))
2480 {
2db6cde7 2481 err = _("failed to set size");
252b5132
RH
2482 goto loser;
2483 }
57938635 2484
252b5132
RH
2485 vma = bfd_section_vma (ibfd, isection);
2486 if (p != NULL && p->change_vma == CHANGE_MODIFY)
2487 vma += p->vma_val;
2488 else if (p != NULL && p->change_vma == CHANGE_SET)
2489 vma = p->vma_val;
2490 else
2491 vma += change_section_address;
57938635 2492
237dcb53 2493 if (! bfd_set_section_vma (obfd, osection, vma))
252b5132 2494 {
2db6cde7 2495 err = _("failed to set vma");
252b5132
RH
2496 goto loser;
2497 }
2498
2499 lma = isection->lma;
2500 if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2501 {
2502 if (p->change_lma == CHANGE_MODIFY)
2503 lma += p->lma_val;
2504 else if (p->change_lma == CHANGE_SET)
2505 lma = p->lma_val;
2506 else
2507 abort ();
2508 }
2509 else
2510 lma += change_section_address;
57938635 2511
237dcb53 2512 osection->lma = lma;
252b5132
RH
2513
2514 /* FIXME: This is probably not enough. If we change the LMA we
2515 may have to recompute the header for the file as well. */
b34976b6
AM
2516 if (!bfd_set_section_alignment (obfd,
2517 osection,
2518 bfd_section_alignment (ibfd, isection)))
252b5132 2519 {
2db6cde7 2520 err = _("failed to set alignment");
252b5132
RH
2521 goto loser;
2522 }
2523
bc408b8a
JJ
2524 /* Copy merge entity size. */
2525 osection->entsize = isection->entsize;
2526
252b5132
RH
2527 /* This used to be mangle_section; we do here to avoid using
2528 bfd_get_section_by_name since some formats allow multiple
2529 sections with the same name. */
2530 isection->output_section = osection;
237dcb53 2531 isection->output_offset = 0;
d3e52d40
RS
2532
2533 /* Do not copy backend data if --extract-symbol is passed; anything
2534 that needs to look at the section contents will fail. */
2535 if (extract_symbol)
2536 return;
252b5132 2537
119f4245
AM
2538 if ((isection->flags & SEC_GROUP) != 0)
2539 {
2540 asymbol *gsym = group_signature (isection);
2541
2542 if (gsym != NULL)
2543 {
2544 gsym->flags |= BSF_KEEP;
2545 if (ibfd->xvec->flavour == bfd_target_elf_flavour)
2546 elf_group_id (isection) = gsym;
2547 }
2548 }
2549
252b5132
RH
2550 /* Allow the BFD backend to copy any private data it understands
2551 from the input section to the output section. */
42bb2e33 2552 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
252b5132 2553 {
2db6cde7 2554 err = _("failed to copy private data");
252b5132
RH
2555 goto loser;
2556 }
2557
594ef5db 2558 /* All went well. */
252b5132
RH
2559 return;
2560
2561loser:
252b5132 2562 status = 1;
2db6cde7 2563 bfd_nonfatal_message (NULL, obfd, osection, err);
252b5132
RH
2564}
2565
2566/* Copy the data of input section ISECTION of IBFD
2567 to an output section with the same name in OBFD.
2568 If stripping then don't copy any relocation info. */
2569
2570static void
84e2f313 2571copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
252b5132 2572{
3f5e193b 2573 bfd *obfd = (bfd *) obfdarg;
252b5132
RH
2574 struct section_list *p;
2575 arelent **relpp;
2576 long relcount;
2577 sec_ptr osection;
2578 bfd_size_type size;
2579 long relsize;
dc156bc0 2580 flagword flags;
252b5132 2581
594ef5db
NC
2582 /* If we have already failed earlier on,
2583 do not keep on generating complaints now. */
252b5132
RH
2584 if (status != 0)
2585 return;
57938635 2586
2593f09a 2587 if (is_strip_section (ibfd, isection))
e0c60db2 2588 return;
252b5132 2589
2593f09a 2590 flags = bfd_get_section_flags (ibfd, isection);
dc156bc0
AM
2591 if ((flags & SEC_GROUP) != 0)
2592 return;
2593
252b5132 2594 osection = isection->output_section;
135dfb4a 2595 size = bfd_get_section_size (isection);
252b5132
RH
2596
2597 if (size == 0 || osection == 0)
2598 return;
2599
237dcb53
AM
2600 if (extract_symbol)
2601 return;
2602
2593f09a
NC
2603 p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2604
0af11b59 2605 /* Core files do not need to be relocated. */
4dd67f29
MS
2606 if (bfd_get_format (obfd) == bfd_core)
2607 relsize = 0;
2608 else
ed570f48
NC
2609 {
2610 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
4dd67f29 2611
ed570f48
NC
2612 if (relsize < 0)
2613 {
2614 /* Do not complain if the target does not support relocations. */
2615 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2616 relsize = 0;
2617 else
2db6cde7
NS
2618 {
2619 status = 1;
2620 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2621 return;
2622 }
ed570f48
NC
2623 }
2624 }
57938635 2625
252b5132 2626 if (relsize == 0)
d3ba0551 2627 bfd_set_reloc (obfd, osection, NULL, 0);
252b5132
RH
2628 else
2629 {
3f5e193b 2630 relpp = (arelent **) xmalloc (relsize);
252b5132
RH
2631 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2632 if (relcount < 0)
2db6cde7
NS
2633 {
2634 status = 1;
2635 bfd_nonfatal_message (NULL, ibfd, isection,
2636 _("relocation count is negative"));
2637 return;
2638 }
57938635 2639
252b5132
RH
2640 if (strip_symbols == STRIP_ALL)
2641 {
2642 /* Remove relocations which are not in
0af11b59 2643 keep_strip_specific_list. */
252b5132
RH
2644 arelent **temp_relpp;
2645 long temp_relcount = 0;
2646 long i;
57938635 2647
3f5e193b 2648 temp_relpp = (arelent **) xmalloc (relsize);
252b5132 2649 for (i = 0; i < relcount; i++)
d3ba0551 2650 if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
047c9024 2651 keep_specific_htab))
252b5132
RH
2652 temp_relpp [temp_relcount++] = relpp [i];
2653 relcount = temp_relcount;
2654 free (relpp);
2655 relpp = temp_relpp;
2656 }
e0c60db2 2657
d3ba0551 2658 bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
f0312d39
JJ
2659 if (relcount == 0)
2660 free (relpp);
252b5132 2661 }
57938635 2662
0af11b59 2663 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
4dd67f29 2664 && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
252b5132 2665 {
4a114e3e 2666 bfd_byte *memhunk = NULL;
252b5132 2667
4a114e3e 2668 if (!bfd_get_full_section_contents (ibfd, isection, &memhunk))
2db6cde7
NS
2669 {
2670 status = 1;
2671 bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2672 return;
2673 }
252b5132 2674
9e48b4c6
NC
2675 if (reverse_bytes)
2676 {
2677 /* We don't handle leftover bytes (too many possible behaviors,
2678 and we don't know what the user wants). The section length
2679 must be a multiple of the number of bytes to swap. */
2680 if ((size % reverse_bytes) == 0)
2681 {
2682 unsigned long i, j;
2683 bfd_byte b;
2684
2685 for (i = 0; i < size; i += reverse_bytes)
2686 for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2687 {
2688 bfd_byte *m = (bfd_byte *) memhunk;
2689
2690 b = m[i + j];
2691 m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2692 m[(i + reverse_bytes) - (j + 1)] = b;
2693 }
2694 }
2695 else
2696 /* User must pad the section up in order to do this. */
2697 fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2698 bfd_section_name (ibfd, isection), reverse_bytes);
2699 }
2700
57938635 2701 if (copy_byte >= 0)
5e675b72
AM
2702 {
2703 /* Keep only every `copy_byte'th byte in MEMHUNK. */
2f01ffbf 2704 char *from = (char *) memhunk + copy_byte;
3f5e193b 2705 char *to = (char *) memhunk;
2f01ffbf 2706 char *end = (char *) memhunk + size;
b7dd81f7 2707 int i;
5e675b72
AM
2708
2709 for (; from < end; from += interleave)
b7dd81f7
NC
2710 for (i = 0; i < copy_width; i++)
2711 *to++ = from[i];
5e675b72 2712
b7dd81f7 2713 size = (size + interleave - 1 - copy_byte) / interleave * copy_width;
5e675b72
AM
2714 osection->lma /= interleave;
2715 }
252b5132 2716
d3ba0551 2717 if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2db6cde7
NS
2718 {
2719 status = 1;
2720 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2721 return;
2722 }
252b5132
RH
2723 free (memhunk);
2724 }
2725 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2726 {
d3ba0551 2727 void *memhunk = xmalloc (size);
252b5132
RH
2728
2729 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2730 flag--they can just remove the section entirely and add it
2731 back again. However, we do permit them to turn on the
2732 SEC_HAS_CONTENTS flag, and take it to mean that the section
2733 contents should be zeroed out. */
2734
2735 memset (memhunk, 0, size);
d3ba0551 2736 if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2db6cde7
NS
2737 {
2738 status = 1;
2739 bfd_nonfatal_message (NULL, obfd, osection, NULL);
2740 return;
2741 }
252b5132
RH
2742 free (memhunk);
2743 }
2744}
2745
2746/* Get all the sections. This is used when --gap-fill or --pad-to is
2747 used. */
2748
2749static void
84e2f313 2750get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
252b5132 2751{
3f5e193b 2752 asection ***secppp = (asection ***) secppparg;
252b5132
RH
2753
2754 **secppp = osection;
2755 ++(*secppp);
2756}
2757
2758/* Sort sections by VMA. This is called via qsort, and is used when
2759 --gap-fill or --pad-to is used. We force non loadable or empty
2760 sections to the front, where they are easier to ignore. */
2761
2762static int
84e2f313 2763compare_section_lma (const void *arg1, const void *arg2)
252b5132 2764{
3f5e193b
NC
2765 const asection *const *sec1 = (const asection * const *) arg1;
2766 const asection *const *sec2 = (const asection * const *) arg2;
252b5132
RH
2767 flagword flags1, flags2;
2768
2769 /* Sort non loadable sections to the front. */
2770 flags1 = (*sec1)->flags;
2771 flags2 = (*sec2)->flags;
2772 if ((flags1 & SEC_HAS_CONTENTS) == 0
2773 || (flags1 & SEC_LOAD) == 0)
2774 {
2775 if ((flags2 & SEC_HAS_CONTENTS) != 0
2776 && (flags2 & SEC_LOAD) != 0)
2777 return -1;
2778 }
2779 else
2780 {
2781 if ((flags2 & SEC_HAS_CONTENTS) == 0
2782 || (flags2 & SEC_LOAD) == 0)
2783 return 1;
2784 }
2785
2786 /* Sort sections by LMA. */
2787 if ((*sec1)->lma > (*sec2)->lma)
2788 return 1;
2789 else if ((*sec1)->lma < (*sec2)->lma)
2790 return -1;
2791
2792 /* Sort sections with the same LMA by size. */
135dfb4a 2793 if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
252b5132 2794 return 1;
135dfb4a 2795 else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
252b5132
RH
2796 return -1;
2797
2798 return 0;
2799}
2800
2801/* Mark all the symbols which will be used in output relocations with
2802 the BSF_KEEP flag so that those symbols will not be stripped.
2803
2804 Ignore relocations which will not appear in the output file. */
2805
2806static void
84e2f313 2807mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
252b5132 2808{
3f5e193b 2809 asymbol **symbols = (asymbol **) symbolsarg;
252b5132
RH
2810 long relsize;
2811 arelent **relpp;
2812 long relcount, i;
2813
2814 /* Ignore an input section with no corresponding output section. */
2815 if (isection->output_section == NULL)
2816 return;
2817
2818 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2819 if (relsize < 0)
ed570f48
NC
2820 {
2821 /* Do not complain if the target does not support relocations. */
2822 if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2823 return;
2824 bfd_fatal (bfd_get_filename (ibfd));
2825 }
252b5132
RH
2826
2827 if (relsize == 0)
2828 return;
2829
3f5e193b 2830 relpp = (arelent **) xmalloc (relsize);
252b5132
RH
2831 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2832 if (relcount < 0)
2833 bfd_fatal (bfd_get_filename (ibfd));
2834
ec5d57d5
NC
2835 /* Examine each symbol used in a relocation. If it's not one of the
2836 special bfd section symbols, then mark it with BSF_KEEP. */
252b5132
RH
2837 for (i = 0; i < relcount; i++)
2838 {
ec5d57d5
NC
2839 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2840 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2841 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2842 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
252b5132
RH
2843 }
2844
2845 if (relpp != NULL)
2846 free (relpp);
2847}
2848
2849/* Write out debugging information. */
2850
b34976b6 2851static bfd_boolean
84e2f313
NC
2852write_debugging_info (bfd *obfd, void *dhandle,
2853 long *symcountp ATTRIBUTE_UNUSED,
2854 asymbol ***symppp ATTRIBUTE_UNUSED)
252b5132
RH
2855{
2856 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2857 return write_ieee_debugging_info (obfd, dhandle);
2858
2859 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2860 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2861 {
2862 bfd_byte *syms, *strings;
2863 bfd_size_type symsize, stringsize;
2864 asection *stabsec, *stabstrsec;
551b43fd 2865 flagword flags;
252b5132
RH
2866
2867 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2868 &symsize, &strings,
2869 &stringsize))
b34976b6 2870 return FALSE;
252b5132 2871
551b43fd
AM
2872 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2873 stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2874 stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
252b5132
RH
2875 if (stabsec == NULL
2876 || stabstrsec == NULL
2877 || ! bfd_set_section_size (obfd, stabsec, symsize)
2878 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2879 || ! bfd_set_section_alignment (obfd, stabsec, 2)
551b43fd 2880 || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
252b5132 2881 {
2db6cde7
NS
2882 bfd_nonfatal_message (NULL, obfd, NULL,
2883 _("can't create debugging section"));
b34976b6 2884 return FALSE;
252b5132
RH
2885 }
2886
2887 /* We can get away with setting the section contents now because
2888 the next thing the caller is going to do is copy over the
2889 real sections. We may someday have to split the contents
2890 setting out of this function. */
d3ba0551
AM
2891 if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2892 || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2893 stringsize))
252b5132 2894 {
2db6cde7
NS
2895 bfd_nonfatal_message (NULL, obfd, NULL,
2896 _("can't set debugging section contents"));
b34976b6 2897 return FALSE;
252b5132
RH
2898 }
2899
b34976b6 2900 return TRUE;
252b5132
RH
2901 }
2902
2db6cde7
NS
2903 bfd_nonfatal_message (NULL, obfd, NULL,
2904 _("don't know how to write debugging information for %s"),
2905 bfd_get_target (obfd));
b34976b6 2906 return FALSE;
252b5132
RH
2907}
2908
2909static int
84e2f313 2910strip_main (int argc, char *argv[])
252b5132 2911{
7c29036b
NC
2912 char *input_target = NULL;
2913 char *output_target = NULL;
b34976b6 2914 bfd_boolean show_version = FALSE;
7c29036b
NC
2915 bfd_boolean formats_info = FALSE;
2916 int c;
2917 int i;
252b5132
RH
2918 struct section_list *p;
2919 char *output_file = NULL;
2920
5fe11841 2921 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
252b5132
RH
2922 strip_options, (int *) 0)) != EOF)
2923 {
2924 switch (c)
2925 {
2926 case 'I':
2927 input_target = optarg;
2928 break;
2929 case 'O':
2930 output_target = optarg;
2931 break;
2932 case 'F':
2933 input_target = output_target = optarg;
2934 break;
2935 case 'R':
b34976b6
AM
2936 p = find_section_list (optarg, TRUE);
2937 p->remove = TRUE;
2938 sections_removed = TRUE;
252b5132
RH
2939 break;
2940 case 's':
2941 strip_symbols = STRIP_ALL;
2942 break;
2943 case 'S':
2944 case 'g':
db4f6831 2945 case 'd': /* Historic BSD alias for -g. Used by early NetBSD. */
252b5132
RH
2946 strip_symbols = STRIP_DEBUG;
2947 break;
2948 case OPTION_STRIP_UNNEEDED:
2949 strip_symbols = STRIP_UNNEEDED;
2950 break;
2951 case 'K':
047c9024 2952 add_specific_symbol (optarg, keep_specific_htab);
252b5132
RH
2953 break;
2954 case 'N':
047c9024 2955 add_specific_symbol (optarg, strip_specific_htab);
252b5132
RH
2956 break;
2957 case 'o':
2958 output_file = optarg;
2959 break;
2960 case 'p':
b34976b6 2961 preserve_dates = TRUE;
252b5132
RH
2962 break;
2963 case 'x':
2964 discard_locals = LOCALS_ALL;
2965 break;
2966 case 'X':
2967 discard_locals = LOCALS_START_L;
2968 break;
2969 case 'v':
b34976b6 2970 verbose = TRUE;
252b5132
RH
2971 break;
2972 case 'V':
b34976b6 2973 show_version = TRUE;
252b5132 2974 break;
7c29036b
NC
2975 case OPTION_FORMATS_INFO:
2976 formats_info = TRUE;
2977 break;
ed1653a7
NC
2978 case OPTION_ONLY_KEEP_DEBUG:
2979 strip_symbols = STRIP_NONDEBUG;
2980 break;
1637cd90
JB
2981 case OPTION_KEEP_FILE_SYMBOLS:
2982 keep_file_symbols = 1;
2983 break;
252b5132 2984 case 0:
594ef5db
NC
2985 /* We've been given a long option. */
2986 break;
5fe11841
NC
2987 case 'w':
2988 wildcard = TRUE;
2989 break;
8b53311e 2990 case 'H':
252b5132
RH
2991 case 'h':
2992 strip_usage (stdout, 0);
2993 default:
2994 strip_usage (stderr, 1);
2995 }
2996 }
2997
84e2f313
NC
2998 if (formats_info)
2999 {
3000 display_info ();
3001 return 0;
3002 }
c1c0eb9e 3003
252b5132
RH
3004 if (show_version)
3005 print_version ("strip");
3006
3007 /* Default is to strip all symbols. */
3008 if (strip_symbols == STRIP_UNDEF
3009 && discard_locals == LOCALS_UNDEF
047c9024 3010 && htab_elements (strip_specific_htab) == 0)
252b5132
RH
3011 strip_symbols = STRIP_ALL;
3012
d3ba0551 3013 if (output_target == NULL)
252b5132
RH
3014 output_target = input_target;
3015
3016 i = optind;
3017 if (i == argc
3018 || (output_file != NULL && (i + 1) < argc))
3019 strip_usage (stderr, 1);
3020
3021 for (; i < argc; i++)
3022 {
3023 int hold_status = status;
3024 struct stat statbuf;
3025 char *tmpname;
3026
f24ddbdd 3027 if (get_file_size (argv[i]) < 1)
d68c385b
NC
3028 {
3029 status = 1;
3030 continue;
3031 }
f24ddbdd 3032
252b5132 3033 if (preserve_dates)
f24ddbdd
NC
3034 /* No need to check the return value of stat().
3035 It has already been checked in get_file_size(). */
3036 stat (argv[i], &statbuf);
252b5132 3037
12f498a7 3038 if (output_file == NULL || strcmp (argv[i], output_file) == 0)
252b5132 3039 tmpname = make_tempname (argv[i]);
12f498a7
NS
3040 else
3041 tmpname = output_file;
252b5132 3042
f9c026a8
NC
3043 if (tmpname == NULL)
3044 {
2db6cde7
NS
3045 bfd_nonfatal_message (argv[i], NULL, NULL,
3046 _("could not create temporary file to hold stripped copy"));
f9c026a8
NC
3047 status = 1;
3048 continue;
3049 }
3050
d68c385b 3051 status = 0;
8b31b6c4 3052 copy_file (argv[i], tmpname, input_target, output_target, NULL);
252b5132
RH
3053 if (status == 0)
3054 {
3055 if (preserve_dates)
3056 set_times (tmpname, &statbuf);
12f498a7 3057 if (output_file != tmpname)
92fac5ec
L
3058 status = (smart_rename (tmpname,
3059 output_file ? output_file : argv[i],
3060 preserve_dates) != 0);
3061 if (status == 0)
3062 status = hold_status;
252b5132
RH
3063 }
3064 else
bb14f524 3065 unlink_if_ordinary (tmpname);
12f498a7 3066 if (output_file != tmpname)
252b5132
RH
3067 free (tmpname);
3068 }
3069
d68c385b 3070 return status;
252b5132
RH
3071}
3072
92dd4511
L
3073/* Set up PE subsystem. */
3074
3075static void
3076set_pe_subsystem (const char *s)
3077{
3078 const char *version, *subsystem;
3079 size_t i;
3080 static const struct
3081 {
3082 const char *name;
3083 const char set_def;
3084 const short value;
3085 }
3086 v[] =
3087 {
3088 { "native", 0, IMAGE_SUBSYSTEM_NATIVE },
3089 { "windows", 0, IMAGE_SUBSYSTEM_WINDOWS_GUI },
3090 { "console", 0, IMAGE_SUBSYSTEM_WINDOWS_CUI },
3091 { "posix", 0, IMAGE_SUBSYSTEM_POSIX_CUI },
3092 { "wince", 0, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI },
3093 { "efi-app", 1, IMAGE_SUBSYSTEM_EFI_APPLICATION },
3094 { "efi-bsd", 1, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER },
3095 { "efi-rtd", 1, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER },
d9118602 3096 { "sal-rtd", 1, IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER },
92dd4511
L
3097 { "xbox", 0, IMAGE_SUBSYSTEM_XBOX }
3098 };
3099 short value;
3100 char *copy;
3101 int set_def = -1;
3102
3103 /* Check for the presence of a version number. */
3104 version = strchr (s, ':');
3105 if (version == NULL)
3106 subsystem = s;
3107 else
3108 {
3109 int len = version - s;
3110 copy = xstrdup (s);
3111 subsystem = copy;
3112 copy[len] = '\0';
3113 version = copy + 1 + len;
3114 pe_major_subsystem_version = strtoul (version, &copy, 0);
3115 if (*copy == '.')
3116 pe_minor_subsystem_version = strtoul (copy + 1, &copy, 0);
3117 if (*copy != '\0')
3118 non_fatal (_("%s: bad version in PE subsystem"), s);
3119 }
3120
3121 /* Check for numeric subsystem. */
3122 value = (short) strtol (subsystem, &copy, 0);
3123 if (*copy == '\0')
3124 {
3125 for (i = 0; i < ARRAY_SIZE (v); i++)
3126 if (v[i].value == value)
3127 {
3128 pe_subsystem = value;
3129 set_def = v[i].set_def;
3130 break;
3131 }
3132 }
3133 else
3134 {
3135 /* Search for subsystem by name. */
3136 for (i = 0; i < ARRAY_SIZE (v); i++)
3137 if (strcmp (subsystem, v[i].name) == 0)
3138 {
3139 pe_subsystem = v[i].value;
3140 set_def = v[i].set_def;
3141 break;
3142 }
3143 }
3144
3145 switch (set_def)
3146 {
3147 case -1:
3148 fatal (_("unknown PE subsystem: %s"), s);
3149 break;
3150 case 0:
3151 break;
3152 default:
3153 if (pe_file_alignment == (bfd_vma) -1)
3154 pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
3155 if (pe_section_alignment == (bfd_vma) -1)
3156 pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
3157 break;
3158 }
3159}
3160
3161/* Convert EFI target to PEI target. */
3162
3163static void
3164convert_efi_target (char *efi)
3165{
3166 efi[0] = 'p';
3167 efi[1] = 'e';
3168 efi[2] = 'i';
3169
3170 if (strcmp (efi + 4, "ia32") == 0)
3171 {
3172 /* Change ia32 to i386. */
3173 efi[5]= '3';
3174 efi[6]= '8';
3175 efi[7]= '6';
3176 }
3177 else if (strcmp (efi + 4, "x86_64") == 0)
3178 {
3179 /* Change x86_64 to x86-64. */
3180 efi[7] = '-';
3181 }
3182}
3183
252b5132 3184static int
84e2f313 3185copy_main (int argc, char *argv[])
252b5132 3186{
7c29036b
NC
3187 char *input_filename = NULL;
3188 char *output_filename = NULL;
c1c0eb9e 3189 char *tmpname;
7c29036b
NC
3190 char *input_target = NULL;
3191 char *output_target = NULL;
b34976b6
AM
3192 bfd_boolean show_version = FALSE;
3193 bfd_boolean change_warn = TRUE;
7c29036b 3194 bfd_boolean formats_info = FALSE;
252b5132
RH
3195 int c;
3196 struct section_list *p;
3197 struct stat statbuf;
8b31b6c4 3198 const bfd_arch_info_type *input_arch = NULL;
252b5132 3199
5fe11841 3200 while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
252b5132
RH
3201 copy_options, (int *) 0)) != EOF)
3202 {
3203 switch (c)
3204 {
3205 case 'b':
3206 copy_byte = atoi (optarg);
3207 if (copy_byte < 0)
3208 fatal (_("byte number must be non-negative"));
3209 break;
57938635 3210
0af11b59 3211 case 'B':
8b31b6c4
NC
3212 input_arch = bfd_scan_arch (optarg);
3213 if (input_arch == NULL)
3214 fatal (_("architecture %s unknown"), optarg);
0af11b59 3215 break;
43a0748c 3216
252b5132 3217 case 'i':
b7dd81f7
NC
3218 if (optarg)
3219 {
3220 interleave = atoi (optarg);
3221 if (interleave < 1)
3222 fatal (_("interleave must be positive"));
3223 }
3224 else
3225 interleave = 4;
3226 break;
3227
3228 case OPTION_INTERLEAVE_WIDTH:
3229 copy_width = atoi (optarg);
3230 if (copy_width < 1)
3231 fatal(_("interleave width must be positive"));
252b5132 3232 break;
57938635 3233
252b5132
RH
3234 case 'I':
3235 case 's': /* "source" - 'I' is preferred */
3236 input_target = optarg;
3237 break;
57938635 3238
252b5132
RH
3239 case 'O':
3240 case 'd': /* "destination" - 'O' is preferred */
3241 output_target = optarg;
3242 break;
57938635 3243
252b5132
RH
3244 case 'F':
3245 input_target = output_target = optarg;
3246 break;
57938635 3247
f91ea849 3248 case 'j':
b34976b6 3249 p = find_section_list (optarg, TRUE);
f91ea849
ILT
3250 if (p->remove)
3251 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
3252 p->copy = TRUE;
3253 sections_copied = TRUE;
f91ea849 3254 break;
57938635 3255
252b5132 3256 case 'R':
b34976b6 3257 p = find_section_list (optarg, TRUE);
f91ea849
ILT
3258 if (p->copy)
3259 fatal (_("%s both copied and removed"), optarg);
b34976b6
AM
3260 p->remove = TRUE;
3261 sections_removed = TRUE;
252b5132 3262 break;
57938635 3263
252b5132
RH
3264 case 'S':
3265 strip_symbols = STRIP_ALL;
3266 break;
57938635 3267
252b5132
RH
3268 case 'g':
3269 strip_symbols = STRIP_DEBUG;
3270 break;
57938635 3271
252b5132
RH
3272 case OPTION_STRIP_UNNEEDED:
3273 strip_symbols = STRIP_UNNEEDED;
3274 break;
57938635 3275
ed1653a7
NC
3276 case OPTION_ONLY_KEEP_DEBUG:
3277 strip_symbols = STRIP_NONDEBUG;
3278 break;
3279
1637cd90
JB
3280 case OPTION_KEEP_FILE_SYMBOLS:
3281 keep_file_symbols = 1;
3282 break;
3283
2593f09a
NC
3284 case OPTION_ADD_GNU_DEBUGLINK:
3285 gnu_debuglink_filename = optarg;
3286 break;
3287
252b5132 3288 case 'K':
047c9024 3289 add_specific_symbol (optarg, keep_specific_htab);
252b5132 3290 break;
57938635 3291
252b5132 3292 case 'N':
047c9024 3293 add_specific_symbol (optarg, strip_specific_htab);
252b5132 3294 break;
57938635 3295
bcf32829 3296 case OPTION_STRIP_UNNEEDED_SYMBOL:
047c9024 3297 add_specific_symbol (optarg, strip_unneeded_htab);
bcf32829
JB
3298 break;
3299
252b5132 3300 case 'L':
047c9024 3301 add_specific_symbol (optarg, localize_specific_htab);
252b5132 3302 break;
57938635 3303
7b4a0685 3304 case OPTION_GLOBALIZE_SYMBOL:
047c9024 3305 add_specific_symbol (optarg, globalize_specific_htab);
7b4a0685
NC
3306 break;
3307
16b2b71c 3308 case 'G':
047c9024 3309 add_specific_symbol (optarg, keepglobal_specific_htab);
16b2b71c
NC
3310 break;
3311
252b5132 3312 case 'W':
047c9024 3313 add_specific_symbol (optarg, weaken_specific_htab);
252b5132 3314 break;
57938635 3315
252b5132 3316 case 'p':
b34976b6 3317 preserve_dates = TRUE;
252b5132 3318 break;
57938635 3319
5fe11841
NC
3320 case 'w':
3321 wildcard = TRUE;
3322 break;
3323
252b5132
RH
3324 case 'x':
3325 discard_locals = LOCALS_ALL;
3326 break;
57938635 3327
252b5132
RH
3328 case 'X':
3329 discard_locals = LOCALS_START_L;
3330 break;
57938635 3331
252b5132 3332 case 'v':
b34976b6 3333 verbose = TRUE;
252b5132 3334 break;
57938635 3335
252b5132 3336 case 'V':
b34976b6 3337 show_version = TRUE;
252b5132 3338 break;
57938635 3339
7c29036b
NC
3340 case OPTION_FORMATS_INFO:
3341 formats_info = TRUE;
3342 break;
3343
252b5132 3344 case OPTION_WEAKEN:
b34976b6 3345 weaken = TRUE;
252b5132 3346 break;
57938635 3347
252b5132
RH
3348 case OPTION_ADD_SECTION:
3349 {
3350 const char *s;
500ee42e 3351 size_t off, alloc;
252b5132 3352 struct section_add *pa;
252b5132
RH
3353 FILE *f;
3354
3355 s = strchr (optarg, '=');
57938635 3356
252b5132 3357 if (s == NULL)
57938635 3358 fatal (_("bad format for %s"), "--add-section");
252b5132 3359
3f5e193b 3360 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
500ee42e 3361 pa->name = xstrndup (optarg, s - optarg);
252b5132
RH
3362 pa->filename = s + 1;
3363
500ee42e
ILT
3364 /* We don't use get_file_size so that we can do
3365 --add-section .note.GNU_stack=/dev/null
3366 get_file_size doesn't work on /dev/null. */
57938635 3367
500ee42e 3368 f = fopen (pa->filename, FOPEN_RB);
252b5132 3369 if (f == NULL)
84e2f313
NC
3370 fatal (_("cannot open: %s: %s"),
3371 pa->filename, strerror (errno));
57938635 3372
500ee42e
ILT
3373 off = 0;
3374 alloc = 4096;
3375 pa->contents = (bfd_byte *) xmalloc (alloc);
3376 while (!feof (f))
3377 {
3378 off_t got;
3379
3380 if (off == alloc)
3381 {
3382 alloc <<= 1;
3383 pa->contents = (bfd_byte *) xrealloc (pa->contents, alloc);
3384 }
3385
3386 got = fread (pa->contents + off, 1, alloc - off, f);
3387 if (ferror (f))
3388 fatal (_("%s: fread failed"), pa->filename);
3389
3390 off += got;
3391 }
3392
3393 pa->size = off;
252b5132
RH
3394
3395 fclose (f);
3396
3397 pa->next = add_sections;
3398 add_sections = pa;
3399 }
3400 break;
57938635 3401
252b5132
RH
3402 case OPTION_CHANGE_START:
3403 change_start = parse_vma (optarg, "--change-start");
3404 break;
57938635 3405
252b5132
RH
3406 case OPTION_CHANGE_SECTION_ADDRESS:
3407 case OPTION_CHANGE_SECTION_LMA:
3408 case OPTION_CHANGE_SECTION_VMA:
3409 {
3410 const char *s;
3411 int len;
3412 char *name;
b4c96d0d 3413 char *option = NULL;
252b5132 3414 bfd_vma val;
b4c96d0d 3415 enum change_action what = CHANGE_IGNORE;
57938635 3416
252b5132
RH
3417 switch (c)
3418 {
b4c96d0d
ILT
3419 case OPTION_CHANGE_SECTION_ADDRESS:
3420 option = "--change-section-address";
3421 break;
3422 case OPTION_CHANGE_SECTION_LMA:
3423 option = "--change-section-lma";
3424 break;
3425 case OPTION_CHANGE_SECTION_VMA:
3426 option = "--change-section-vma";
3427 break;
252b5132 3428 }
57938635 3429
252b5132
RH
3430 s = strchr (optarg, '=');
3431 if (s == NULL)
3432 {
3433 s = strchr (optarg, '+');
3434 if (s == NULL)
3435 {
3436 s = strchr (optarg, '-');
3437 if (s == NULL)
3438 fatal (_("bad format for %s"), option);
3439 }
3440 }
3441
3442 len = s - optarg;
3f5e193b 3443 name = (char *) xmalloc (len + 1);
252b5132
RH
3444 strncpy (name, optarg, len);
3445 name[len] = '\0';
3446
b34976b6 3447 p = find_section_list (name, TRUE);
252b5132
RH
3448
3449 val = parse_vma (s + 1, option);
3450
3451 switch (*s)
3452 {
3453 case '=': what = CHANGE_SET; break;
3454 case '-': val = - val; /* Drop through. */
3455 case '+': what = CHANGE_MODIFY; break;
3456 }
57938635 3457
252b5132
RH
3458 switch (c)
3459 {
3460 case OPTION_CHANGE_SECTION_ADDRESS:
3461 p->change_vma = what;
3462 p->vma_val = val;
3463 /* Drop through. */
57938635 3464
252b5132
RH
3465 case OPTION_CHANGE_SECTION_LMA:
3466 p->change_lma = what;
3467 p->lma_val = val;
3468 break;
57938635 3469
252b5132
RH
3470 case OPTION_CHANGE_SECTION_VMA:
3471 p->change_vma = what;
3472 p->vma_val = val;
3473 break;
3474 }
3475 }
3476 break;
57938635 3477
252b5132
RH
3478 case OPTION_CHANGE_ADDRESSES:
3479 change_section_address = parse_vma (optarg, "--change-addresses");
3480 change_start = change_section_address;
3481 break;
57938635 3482
252b5132 3483 case OPTION_CHANGE_WARNINGS:
b34976b6 3484 change_warn = TRUE;
252b5132 3485 break;
57938635 3486
252b5132 3487 case OPTION_CHANGE_LEADING_CHAR:
b34976b6 3488 change_leading_char = TRUE;
252b5132 3489 break;
57938635 3490
4a114e3e
L
3491 case OPTION_COMPRESS_DEBUG_SECTIONS:
3492 do_debug_sections = compress;
3493 break;
3494
252b5132 3495 case OPTION_DEBUGGING:
b34976b6 3496 convert_debugging = TRUE;
252b5132 3497 break;
57938635 3498
4a114e3e
L
3499 case OPTION_DECOMPRESS_DEBUG_SECTIONS:
3500 do_debug_sections = decompress;
3501 break;
3502
252b5132
RH
3503 case OPTION_GAP_FILL:
3504 {
3505 bfd_vma gap_fill_vma;
3506
3507 gap_fill_vma = parse_vma (optarg, "--gap-fill");
3508 gap_fill = (bfd_byte) gap_fill_vma;
3509 if ((bfd_vma) gap_fill != gap_fill_vma)
3510 {
3511 char buff[20];
57938635 3512
252b5132 3513 sprintf_vma (buff, gap_fill_vma);
57938635 3514
252b5132
RH
3515 non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3516 buff, gap_fill);
3517 }
b34976b6 3518 gap_fill_set = TRUE;
252b5132
RH
3519 }
3520 break;
57938635 3521
252b5132 3522 case OPTION_NO_CHANGE_WARNINGS:
b34976b6 3523 change_warn = FALSE;
252b5132 3524 break;
57938635 3525
252b5132
RH
3526 case OPTION_PAD_TO:
3527 pad_to = parse_vma (optarg, "--pad-to");
b34976b6 3528 pad_to_set = TRUE;
252b5132 3529 break;
57938635 3530
252b5132 3531 case OPTION_REMOVE_LEADING_CHAR:
b34976b6 3532 remove_leading_char = TRUE;
252b5132 3533 break;
57938635
AM
3534
3535 case OPTION_REDEFINE_SYM:
3536 {
3537 /* Push this redefinition onto redefine_symbol_list. */
3538
3539 int len;
3540 const char *s;
3541 const char *nextarg;
3542 char *source, *target;
3543
3544 s = strchr (optarg, '=');
3545 if (s == NULL)
594ef5db 3546 fatal (_("bad format for %s"), "--redefine-sym");
57938635
AM
3547
3548 len = s - optarg;
3f5e193b 3549 source = (char *) xmalloc (len + 1);
57938635
AM
3550 strncpy (source, optarg, len);
3551 source[len] = '\0';
3552
3553 nextarg = s + 1;
3554 len = strlen (nextarg);
3f5e193b 3555 target = (char *) xmalloc (len + 1);
57938635
AM
3556 strcpy (target, nextarg);
3557
92991082 3558 redefine_list_append ("--redefine-sym", source, target);
57938635
AM
3559
3560 free (source);
3561 free (target);
3562 }
3563 break;
3564
92991082
JT
3565 case OPTION_REDEFINE_SYMS:
3566 add_redefine_syms_file (optarg);
3567 break;
3568
252b5132
RH
3569 case OPTION_SET_SECTION_FLAGS:
3570 {
3571 const char *s;
3572 int len;
3573 char *name;
3574
3575 s = strchr (optarg, '=');
3576 if (s == NULL)
57938635 3577 fatal (_("bad format for %s"), "--set-section-flags");
252b5132
RH
3578
3579 len = s - optarg;
3f5e193b 3580 name = (char *) xmalloc (len + 1);
252b5132
RH
3581 strncpy (name, optarg, len);
3582 name[len] = '\0';
3583
b34976b6 3584 p = find_section_list (name, TRUE);
252b5132 3585
b34976b6 3586 p->set_flags = TRUE;
252b5132
RH
3587 p->flags = parse_flags (s + 1);
3588 }
3589 break;
57938635 3590
594ef5db
NC
3591 case OPTION_RENAME_SECTION:
3592 {
3593 flagword flags;
3bcfb3e4
AM
3594 const char *eq, *fl;
3595 char *old_name;
3596 char *new_name;
594ef5db
NC
3597 unsigned int len;
3598
3bcfb3e4
AM
3599 eq = strchr (optarg, '=');
3600 if (eq == NULL)
594ef5db
NC
3601 fatal (_("bad format for %s"), "--rename-section");
3602
3bcfb3e4 3603 len = eq - optarg;
594ef5db 3604 if (len == 0)
3bcfb3e4 3605 fatal (_("bad format for %s"), "--rename-section");
594ef5db 3606
3f5e193b 3607 old_name = (char *) xmalloc (len + 1);
594ef5db
NC
3608 strncpy (old_name, optarg, len);
3609 old_name[len] = 0;
3610
3bcfb3e4
AM
3611 eq++;
3612 fl = strchr (eq, ',');
3613 if (fl)
594ef5db 3614 {
3bcfb3e4
AM
3615 flags = parse_flags (fl + 1);
3616 len = fl - eq;
594ef5db
NC
3617 }
3618 else
3619 {
594ef5db 3620 flags = -1;
3bcfb3e4 3621 len = strlen (eq);
594ef5db
NC
3622 }
3623
3bcfb3e4
AM
3624 if (len == 0)
3625 fatal (_("bad format for %s"), "--rename-section");
3626
3f5e193b 3627 new_name = (char *) xmalloc (len + 1);
3bcfb3e4
AM
3628 strncpy (new_name, eq, len);
3629 new_name[len] = 0;
3630
594ef5db
NC
3631 add_section_rename (old_name, new_name, flags);
3632 }
3633 break;
3634
252b5132
RH
3635 case OPTION_SET_START:
3636 set_start = parse_vma (optarg, "--set-start");
b34976b6 3637 set_start_set = TRUE;
252b5132 3638 break;
57938635 3639
0af11b59
KH
3640 case OPTION_SREC_LEN:
3641 Chunk = parse_vma (optarg, "--srec-len");
3642 break;
420496c1 3643
0af11b59 3644 case OPTION_SREC_FORCES3:
b34976b6 3645 S3Forced = TRUE;
0af11b59 3646 break;
420496c1 3647
16b2b71c 3648 case OPTION_STRIP_SYMBOLS:
047c9024 3649 add_specific_symbols (optarg, strip_specific_htab);
16b2b71c
NC
3650 break;
3651
bcf32829 3652 case OPTION_STRIP_UNNEEDED_SYMBOLS:
047c9024 3653 add_specific_symbols (optarg, strip_unneeded_htab);
bcf32829
JB
3654 break;
3655
16b2b71c 3656 case OPTION_KEEP_SYMBOLS:
047c9024 3657 add_specific_symbols (optarg, keep_specific_htab);
16b2b71c
NC
3658 break;
3659
d58c2e3a
RS
3660 case OPTION_LOCALIZE_HIDDEN:
3661 localize_hidden = TRUE;
3662 break;
3663
16b2b71c 3664 case OPTION_LOCALIZE_SYMBOLS:
047c9024 3665 add_specific_symbols (optarg, localize_specific_htab);
16b2b71c
NC
3666 break;
3667
0408dee6
DK
3668 case OPTION_LONG_SECTION_NAMES:
3669 if (!strcmp ("enable", optarg))
3670 long_section_names = ENABLE;
3671 else if (!strcmp ("disable", optarg))
3672 long_section_names = DISABLE;
3673 else if (!strcmp ("keep", optarg))
3674 long_section_names = KEEP;
3675 else
3676 fatal (_("unknown long section names option '%s'"), optarg);
3677 break;
3678
7b4a0685 3679 case OPTION_GLOBALIZE_SYMBOLS:
047c9024 3680 add_specific_symbols (optarg, globalize_specific_htab);
7b4a0685
NC
3681 break;
3682
16b2b71c 3683 case OPTION_KEEPGLOBAL_SYMBOLS:
047c9024 3684 add_specific_symbols (optarg, keepglobal_specific_htab);
16b2b71c
NC
3685 break;
3686
3687 case OPTION_WEAKEN_SYMBOLS:
047c9024 3688 add_specific_symbols (optarg, weaken_specific_htab);
16b2b71c
NC
3689 break;
3690
1ae8b3d2 3691 case OPTION_ALT_MACH_CODE:
f9d4ad2a
NC
3692 use_alt_mach_code = strtoul (optarg, NULL, 0);
3693 if (use_alt_mach_code == 0)
3694 fatal (_("unable to parse alternative machine code"));
1ae8b3d2
AO
3695 break;
3696
d7fb0dd2
NC
3697 case OPTION_PREFIX_SYMBOLS:
3698 prefix_symbols_string = optarg;
3699 break;
3700
3701 case OPTION_PREFIX_SECTIONS:
3702 prefix_sections_string = optarg;
3703 break;
3704
3705 case OPTION_PREFIX_ALLOC_SECTIONS:
3706 prefix_alloc_sections_string = optarg;
3707 break;
3708
4087920c
MR
3709 case OPTION_READONLY_TEXT:
3710 bfd_flags_to_set |= WP_TEXT;
3711 bfd_flags_to_clear &= ~WP_TEXT;
3712 break;
3713
3714 case OPTION_WRITABLE_TEXT:
3715 bfd_flags_to_clear |= WP_TEXT;
3716 bfd_flags_to_set &= ~WP_TEXT;
3717 break;
3718
3719 case OPTION_PURE:
3720 bfd_flags_to_set |= D_PAGED;
3721 bfd_flags_to_clear &= ~D_PAGED;
3722 break;
3723
3724 case OPTION_IMPURE:
3725 bfd_flags_to_clear |= D_PAGED;
3726 bfd_flags_to_set &= ~D_PAGED;
3727 break;
3728
d3e52d40
RS
3729 case OPTION_EXTRACT_SYMBOL:
3730 extract_symbol = TRUE;
3731 break;
3732
9e48b4c6
NC
3733 case OPTION_REVERSE_BYTES:
3734 {
3735 int prev = reverse_bytes;
3736
3737 reverse_bytes = atoi (optarg);
3738 if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3739 fatal (_("number of bytes to reverse must be positive and even"));
3740
3741 if (prev && prev != reverse_bytes)
3742 non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3743 prev);
3744 break;
3745 }
3746
92dd4511
L
3747 case OPTION_FILE_ALIGNMENT:
3748 pe_file_alignment = parse_vma (optarg, "--file-alignment");
3749 break;
3750
3751 case OPTION_HEAP:
3752 {
3753 char *end;
3754 pe_heap_reserve = strtoul (optarg, &end, 0);
3755 if (end == optarg
3756 || (*end != '.' && *end != '\0'))
3757 non_fatal (_("%s: invalid reserve value for --heap"),
3758 optarg);
3759 else if (*end != '\0')
3760 {
3761 pe_heap_commit = strtoul (end + 1, &end, 0);
3762 if (*end != '\0')
3763 non_fatal (_("%s: invalid commit value for --heap"),
3764 optarg);
3765 }
3766 }
3767 break;
3768
3769 case OPTION_IMAGE_BASE:
3770 pe_image_base = parse_vma (optarg, "--image-base");
3771 break;
3772
3773 case OPTION_SECTION_ALIGNMENT:
3774 pe_section_alignment = parse_vma (optarg,
3775 "--section-alignment");
3776 break;
3777
3778 case OPTION_SUBSYSTEM:
3779 set_pe_subsystem (optarg);
3780 break;
3781
3782 case OPTION_STACK:
3783 {
3784 char *end;
3785 pe_stack_reserve = strtoul (optarg, &end, 0);
3786 if (end == optarg
3787 || (*end != '.' && *end != '\0'))
3788 non_fatal (_("%s: invalid reserve value for --stack"),
3789 optarg);
3790 else if (*end != '\0')
3791 {
3792 pe_stack_commit = strtoul (end + 1, &end, 0);
3793 if (*end != '\0')
3794 non_fatal (_("%s: invalid commit value for --stack"),
3795 optarg);
3796 }
3797 }
3798 break;
3799
252b5132 3800 case 0:
2593f09a
NC
3801 /* We've been given a long option. */
3802 break;
57938635 3803
8b53311e 3804 case 'H':
252b5132
RH
3805 case 'h':
3806 copy_usage (stdout, 0);
57938635 3807
252b5132
RH
3808 default:
3809 copy_usage (stderr, 1);
3810 }
3811 }
3812
7c29036b
NC
3813 if (formats_info)
3814 {
3815 display_info ();
3816 return 0;
3817 }
c1c0eb9e 3818
252b5132
RH
3819 if (show_version)
3820 print_version ("objcopy");
3821
b7dd81f7
NC
3822 if (interleave && copy_byte == -1)
3823 fatal (_("interleave start byte must be set with --byte"));
3824
252b5132
RH
3825 if (copy_byte >= interleave)
3826 fatal (_("byte number must be less than interleave"));
3827
b7dd81f7
NC
3828 if (copy_width > interleave - copy_byte)
3829 fatal (_("interleave width must be less than or equal to interleave - byte`"));
3830
252b5132
RH
3831 if (optind == argc || optind + 2 < argc)
3832 copy_usage (stderr, 1);
3833
3834 input_filename = argv[optind];
3835 if (optind + 1 < argc)
3836 output_filename = argv[optind + 1];
3837
3838 /* Default is to strip no symbols. */
3839 if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3840 strip_symbols = STRIP_NONE;
3841
d3ba0551 3842 if (output_target == NULL)
252b5132
RH
3843 output_target = input_target;
3844
92dd4511
L
3845 /* Convert input EFI target to PEI target. */
3846 if (input_target != NULL
3847 && strncmp (input_target, "efi-", 4) == 0)
3848 {
3849 char *efi;
3850
3851 efi = xstrdup (output_target + 4);
3852 if (strncmp (efi, "bsdrv-", 6) == 0
3853 || strncmp (efi, "rtdrv-", 6) == 0)
3854 efi += 2;
3855 else if (strncmp (efi, "app-", 4) != 0)
3856 fatal (_("unknown input EFI target: %s"), input_target);
3857
3858 input_target = efi;
3859 convert_efi_target (efi);
3860 }
3861
3862 /* Convert output EFI target to PEI target. */
3863 if (output_target != NULL
3864 && strncmp (output_target, "efi-", 4) == 0)
3865 {
3866 char *efi;
3867
3868 efi = xstrdup (output_target + 4);
3869 if (strncmp (efi, "app-", 4) == 0)
3870 {
3871 if (pe_subsystem == -1)
3872 pe_subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION;
3873 }
3874 else if (strncmp (efi, "bsdrv-", 6) == 0)
3875 {
3876 if (pe_subsystem == -1)
3877 pe_subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
3878 efi += 2;
3879 }
3880 else if (strncmp (efi, "rtdrv-", 6) == 0)
3881 {
3882 if (pe_subsystem == -1)
3883 pe_subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
3884 efi += 2;
3885 }
3886 else
3887 fatal (_("unknown output EFI target: %s"), output_target);
3888
3889 if (pe_file_alignment == (bfd_vma) -1)
3890 pe_file_alignment = PE_DEF_FILE_ALIGNMENT;
3891 if (pe_section_alignment == (bfd_vma) -1)
3892 pe_section_alignment = PE_DEF_SECTION_ALIGNMENT;
3893
3894 output_target = efi;
3895 convert_efi_target (efi);
3896 }
3897
43a0748c
NC
3898 if (preserve_dates)
3899 if (stat (input_filename, & statbuf) < 0)
f24ddbdd
NC
3900 fatal (_("warning: could not locate '%s'. System error message: %s"),
3901 input_filename, strerror (errno));
43a0748c 3902
0fcdcb91 3903 /* If there is no destination file, or the source and destination files
d3ba0551
AM
3904 are the same, then create a temp and rename the result into the input. */
3905 if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
12f498a7 3906 tmpname = make_tempname (input_filename);
252b5132 3907 else
12f498a7 3908 tmpname = output_filename;
c1c0eb9e 3909
12f498a7
NS
3910 if (tmpname == NULL)
3911 fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3912 input_filename, strerror (errno));
594ef5db 3913
8b31b6c4 3914 copy_file (input_filename, tmpname, input_target, output_target, input_arch);
12f498a7
NS
3915 if (status == 0)
3916 {
3917 if (preserve_dates)
3918 set_times (tmpname, &statbuf);
3919 if (tmpname != output_filename)
92fac5ec
L
3920 status = (smart_rename (tmpname, input_filename,
3921 preserve_dates) != 0);
252b5132 3922 }
12f498a7
NS
3923 else
3924 unlink_if_ordinary (tmpname);
252b5132
RH
3925
3926 if (change_warn)
3927 {
3928 for (p = change_sections; p != NULL; p = p->next)
3929 {
3930 if (! p->used)
3931 {
3932 if (p->change_vma != CHANGE_IGNORE)
3933 {
3934 char buff [20];
3935
3936 sprintf_vma (buff, p->vma_val);
57938635 3937
252b5132 3938 /* xgettext:c-format */
57938635
AM
3939 non_fatal (_("%s %s%c0x%s never used"),
3940 "--change-section-vma",
252b5132
RH
3941 p->name,
3942 p->change_vma == CHANGE_SET ? '=' : '+',
3943 buff);
3944 }
57938635 3945
252b5132
RH
3946 if (p->change_lma != CHANGE_IGNORE)
3947 {
3948 char buff [20];
3949
3950 sprintf_vma (buff, p->lma_val);
57938635 3951
252b5132 3952 /* xgettext:c-format */
57938635
AM
3953 non_fatal (_("%s %s%c0x%s never used"),
3954 "--change-section-lma",
252b5132
RH
3955 p->name,
3956 p->change_lma == CHANGE_SET ? '=' : '+',
3957 buff);
3958 }
3959 }
3960 }
3961 }
3962
3963 return 0;
3964}
3965
3966int
84e2f313 3967main (int argc, char *argv[])
252b5132
RH
3968{
3969#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3970 setlocale (LC_MESSAGES, "");
3882b010
L
3971#endif
3972#if defined (HAVE_SETLOCALE)
3973 setlocale (LC_CTYPE, "");
252b5132
RH
3974#endif
3975 bindtextdomain (PACKAGE, LOCALEDIR);
3976 textdomain (PACKAGE);
3977
3978 program_name = argv[0];
3979 xmalloc_set_program_name (program_name);
3980
3981 START_PROGRESS (program_name, 0);
3982
869b9d07
MM
3983 expandargv (&argc, &argv);
3984
252b5132
RH
3985 strip_symbols = STRIP_UNDEF;
3986 discard_locals = LOCALS_UNDEF;
3987
3988 bfd_init ();
3989 set_default_bfd_target ();
3990
3991 if (is_strip < 0)
3992 {
3993 int i = strlen (program_name);
5af11cab
AM
3994#ifdef HAVE_DOS_BASED_FILE_SYSTEM
3995 /* Drop the .exe suffix, if any. */
3996 if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3997 {
3998 i -= 4;
3999 program_name[i] = '\0';
4000 }
4001#endif
4002 is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
252b5132
RH
4003 }
4004
047c9024
NC
4005 create_symbol_htabs ();
4006
252b5132
RH
4007 if (is_strip)
4008 strip_main (argc, argv);
4009 else
4010 copy_main (argc, argv);
4011
4012 END_PROGRESS (program_name);
4013
4014 return status;
4015}
This page took 0.880534 seconds and 4 git commands to generate.