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

Subversion Repositories open8_urisc

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

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

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

powered by: WebSVN 2.1.0

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