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