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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [binutils/] [objcopy.c] - Blame information for rev 841

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

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

powered by: WebSVN 2.1.0

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