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 163

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

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

powered by: WebSVN 2.1.0

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