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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [binutils/] [objcopy.c] - Blame information for rev 6

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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