OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [objcopy.c] - Blame information for rev 143

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.