OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [binutils/] [objcopy.c] - Blame information for rev 410

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

Line No. Rev Author Line
1 38 julius
/* objcopy.c -- copy object file from input to output, optionally massaging it.
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
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
  setup_bfd_headers (ibfd, obfd);
1465
 
1466
  if (add_sections != NULL)
1467
    {
1468
      struct section_add *padd;
1469
      struct section_list *pset;
1470
 
1471
      for (padd = add_sections; padd != NULL; padd = padd->next)
1472
        {
1473
          flagword flags;
1474
 
1475
          pset = find_section_list (padd->name, FALSE);
1476
          if (pset != NULL)
1477
            pset->used = TRUE;
1478
 
1479
          flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
1480
          if (pset != NULL && pset->set_flags)
1481
            flags = pset->flags | SEC_HAS_CONTENTS;
1482
 
1483
          /* bfd_make_section_with_flags() does not return very helpful
1484
             error codes, so check for the most likely user error first.  */
1485
          if (bfd_get_section_by_name (obfd, padd->name))
1486
            {
1487
              bfd_nonfatal_message (NULL, obfd, NULL,
1488
                                 _("can't add section '%s'"), padd->name);
1489
              return FALSE;
1490
            }
1491
          else
1492
            {
1493
              padd->section = bfd_make_section_with_flags (obfd, padd->name, flags);
1494
              if (padd->section == NULL)
1495
                {
1496
                  bfd_nonfatal_message (NULL, obfd, NULL,
1497
                                        _("can't create section `%s'"),
1498
                                        padd->name);
1499
                  return FALSE;
1500
                }
1501
            }
1502
 
1503
          if (! bfd_set_section_size (obfd, padd->section, padd->size))
1504
            {
1505
              bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1506
              return FALSE;
1507
            }
1508
 
1509
          if (pset != NULL)
1510
            {
1511
              if (pset->change_vma != CHANGE_IGNORE)
1512
                if (! bfd_set_section_vma (obfd, padd->section,
1513
                                           pset->vma_val))
1514
                  {
1515
                    bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1516
                    return FALSE;
1517
                  }
1518
 
1519
              if (pset->change_lma != CHANGE_IGNORE)
1520
                {
1521
                  padd->section->lma = pset->lma_val;
1522
 
1523
                  if (! bfd_set_section_alignment
1524
                      (obfd, padd->section,
1525
                       bfd_section_alignment (obfd, padd->section)))
1526
                    {
1527
                      bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1528
                      return FALSE;
1529
                    }
1530
                }
1531
            }
1532
        }
1533
    }
1534
 
1535
  if (gnu_debuglink_filename != NULL)
1536
    {
1537
      gnu_debuglink_section = bfd_create_gnu_debuglink_section
1538
        (obfd, gnu_debuglink_filename);
1539
 
1540
      if (gnu_debuglink_section == NULL)
1541
        {
1542
          bfd_nonfatal_message (NULL, obfd, NULL,
1543
                                _("cannot create debug link section `%s'"),
1544
                                gnu_debuglink_filename);
1545
          return FALSE;
1546
        }
1547
 
1548
      /* Special processing for PE format files.  We
1549
         have no way to distinguish PE from COFF here.  */
1550
      if (bfd_get_flavour (obfd) == bfd_target_coff_flavour)
1551
        {
1552
          bfd_vma debuglink_vma;
1553
          asection * highest_section;
1554
          asection * sec;
1555
 
1556
          /* The PE spec requires that all sections be adjacent and sorted
1557
             in ascending order of VMA.  It also specifies that debug
1558
             sections should be last.  This is despite the fact that debug
1559
             sections are not loaded into memory and so in theory have no
1560
             use for a VMA.
1561
 
1562
             This means that the debuglink section must be given a non-zero
1563
             VMA which makes it contiguous with other debug sections.  So
1564
             walk the current section list, find the section with the
1565
             highest VMA and start the debuglink section after that one.  */
1566
          for (sec = obfd->sections, highest_section = NULL;
1567
               sec != NULL;
1568
               sec = sec->next)
1569
            if (sec->vma > 0
1570
                && (highest_section == NULL
1571
                    || sec->vma > highest_section->vma))
1572
              highest_section = sec;
1573
 
1574
          if (highest_section)
1575
            debuglink_vma = BFD_ALIGN (highest_section->vma
1576
                                       + highest_section->size,
1577
                                       /* FIXME: We ought to be using
1578
                                          COFF_PAGE_SIZE here or maybe
1579
                                          bfd_get_section_alignment() (if it
1580
                                          was set) but since this is for PE
1581
                                          and we know the required alignment
1582
                                          it is easier just to hard code it.  */
1583
                                       0x1000);
1584
          else
1585
            /* Umm, not sure what to do in this case.  */
1586
            debuglink_vma = 0x1000;
1587
 
1588
          bfd_set_section_vma (obfd, gnu_debuglink_section, debuglink_vma);
1589
        }
1590
    }
1591
 
1592
  if (bfd_count_sections (obfd) != 0
1593
      && (gap_fill_set || pad_to_set))
1594
    {
1595
      asection **set;
1596
      unsigned int c, i;
1597
 
1598
      /* We must fill in gaps between the sections and/or we must pad
1599
         the last section to a specified address.  We do this by
1600
         grabbing a list of the sections, sorting them by VMA, and
1601
         increasing the section sizes as required to fill the gaps.
1602
         We write out the gap contents below.  */
1603
 
1604
      c = bfd_count_sections (obfd);
1605
      osections = xmalloc (c * sizeof (asection *));
1606
      set = osections;
1607
      bfd_map_over_sections (obfd, get_sections, &set);
1608
 
1609
      qsort (osections, c, sizeof (asection *), compare_section_lma);
1610
 
1611
      gaps = xmalloc (c * sizeof (bfd_size_type));
1612
      memset (gaps, 0, c * sizeof (bfd_size_type));
1613
 
1614
      if (gap_fill_set)
1615
        {
1616
          for (i = 0; i < c - 1; i++)
1617
            {
1618
              flagword flags;
1619
              bfd_size_type size;
1620
              bfd_vma gap_start, gap_stop;
1621
 
1622
              flags = bfd_get_section_flags (obfd, osections[i]);
1623
              if ((flags & SEC_HAS_CONTENTS) == 0
1624
                  || (flags & SEC_LOAD) == 0)
1625
                continue;
1626
 
1627
              size = bfd_section_size (obfd, osections[i]);
1628
              gap_start = bfd_section_lma (obfd, osections[i]) + size;
1629
              gap_stop = bfd_section_lma (obfd, osections[i + 1]);
1630
              if (gap_start < gap_stop)
1631
                {
1632
                  if (! bfd_set_section_size (obfd, osections[i],
1633
                                              size + (gap_stop - gap_start)))
1634
                    {
1635
                      bfd_nonfatal_message (NULL, obfd, osections[i],
1636
                                            _("Can't fill gap after section"));
1637
                      status = 1;
1638
                      break;
1639
                    }
1640
                  gaps[i] = gap_stop - gap_start;
1641
                  if (max_gap < gap_stop - gap_start)
1642
                    max_gap = gap_stop - gap_start;
1643
                }
1644
            }
1645
        }
1646
 
1647
      if (pad_to_set)
1648
        {
1649
          bfd_vma lma;
1650
          bfd_size_type size;
1651
 
1652
          lma = bfd_section_lma (obfd, osections[c - 1]);
1653
          size = bfd_section_size (obfd, osections[c - 1]);
1654
          if (lma + size < pad_to)
1655
            {
1656
              if (! bfd_set_section_size (obfd, osections[c - 1],
1657
                                          pad_to - lma))
1658
                {
1659
                  bfd_nonfatal_message (NULL, obfd, osections[c - 1],
1660
                                        _("can't add padding"));
1661
                  status = 1;
1662
                }
1663
              else
1664
                {
1665
                  gaps[c - 1] = pad_to - (lma + size);
1666
                  if (max_gap < pad_to - (lma + size))
1667
                    max_gap = pad_to - (lma + size);
1668
                }
1669
            }
1670
        }
1671
    }
1672
 
1673
  /* Symbol filtering must happen after the output sections
1674
     have been created, but before their contents are set.  */
1675
  dhandle = NULL;
1676
  if (convert_debugging)
1677
    dhandle = read_debugging_info (ibfd, isympp, symcount);
1678
 
1679
  if (strip_symbols == STRIP_DEBUG
1680
      || strip_symbols == STRIP_ALL
1681
      || strip_symbols == STRIP_UNNEEDED
1682
      || strip_symbols == STRIP_NONDEBUG
1683
      || discard_locals != LOCALS_UNDEF
1684
      || localize_hidden
1685
      || htab_elements (strip_specific_htab) != 0
1686
      || htab_elements (keep_specific_htab) != 0
1687
      || htab_elements (localize_specific_htab) != 0
1688
      || htab_elements (globalize_specific_htab) != 0
1689
      || htab_elements (keepglobal_specific_htab) != 0
1690
      || htab_elements (weaken_specific_htab) != 0
1691
      || prefix_symbols_string
1692
      || sections_removed
1693
      || sections_copied
1694
      || convert_debugging
1695
      || change_leading_char
1696
      || remove_leading_char
1697
      || redefine_sym_list
1698
      || weaken)
1699
    {
1700
      /* Mark symbols used in output relocations so that they
1701
         are kept, even if they are local labels or static symbols.
1702
 
1703
         Note we iterate over the input sections examining their
1704
         relocations since the relocations for the output sections
1705
         haven't been set yet.  mark_symbols_used_in_relocations will
1706
         ignore input sections which have no corresponding output
1707
         section.  */
1708
      if (strip_symbols != STRIP_ALL)
1709
        bfd_map_over_sections (ibfd,
1710
                               mark_symbols_used_in_relocations,
1711
                               isympp);
1712
      osympp = xmalloc ((symcount + 1) * sizeof (asymbol *));
1713
      symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
1714
    }
1715
 
1716
  if (convert_debugging && dhandle != NULL)
1717
    {
1718
      if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
1719
        {
1720
          status = 1;
1721
          return FALSE;
1722
        }
1723
    }
1724
 
1725
  bfd_set_symtab (obfd, osympp, symcount);
1726
 
1727
  /* This has to happen after the symbol table has been set.  */
1728
  bfd_map_over_sections (ibfd, copy_section, obfd);
1729
 
1730
  if (add_sections != NULL)
1731
    {
1732
      struct section_add *padd;
1733
 
1734
      for (padd = add_sections; padd != NULL; padd = padd->next)
1735
        {
1736
          if (! bfd_set_section_contents (obfd, padd->section, padd->contents,
1737
                                          0, padd->size))
1738
            {
1739
              bfd_nonfatal_message (NULL, obfd, padd->section, NULL);
1740
              return FALSE;
1741
            }
1742
        }
1743
    }
1744
 
1745
  if (gnu_debuglink_filename != NULL)
1746
    {
1747
      if (! bfd_fill_in_gnu_debuglink_section
1748
          (obfd, gnu_debuglink_section, gnu_debuglink_filename))
1749
        {
1750
          bfd_nonfatal_message (NULL, obfd, NULL,
1751
                                _("cannot fill debug link section `%s'"),
1752
                                gnu_debuglink_filename);
1753
          return FALSE;
1754
        }
1755
    }
1756
 
1757
  if (gap_fill_set || pad_to_set)
1758
    {
1759
      bfd_byte *buf;
1760
      int c, i;
1761
 
1762
      /* Fill in the gaps.  */
1763
      if (max_gap > 8192)
1764
        max_gap = 8192;
1765
      buf = xmalloc (max_gap);
1766
      memset (buf, gap_fill, max_gap);
1767
 
1768
      c = bfd_count_sections (obfd);
1769
      for (i = 0; i < c; i++)
1770
        {
1771
          if (gaps[i] != 0)
1772
            {
1773
              bfd_size_type left;
1774
              file_ptr off;
1775
 
1776
              left = gaps[i];
1777
              off = bfd_section_size (obfd, osections[i]) - left;
1778
 
1779
              while (left > 0)
1780
                {
1781
                  bfd_size_type now;
1782
 
1783
                  if (left > 8192)
1784
                    now = 8192;
1785
                  else
1786
                    now = left;
1787
 
1788
                  if (! bfd_set_section_contents (obfd, osections[i], buf,
1789
                                                  off, now))
1790
                    {
1791
                      bfd_nonfatal_message (NULL, obfd, osections[i], NULL);
1792
                      return FALSE;
1793
                    }
1794
 
1795
                  left -= now;
1796
                  off += now;
1797
                }
1798
            }
1799
        }
1800
    }
1801
 
1802
  /* Do not copy backend data if --extract-symbol is passed; anything
1803
     that needs to look at the section contents will fail.  */
1804
  if (extract_symbol)
1805
    return TRUE;
1806
 
1807
  /* Allow the BFD backend to copy any private data it understands
1808
     from the input BFD to the output BFD.  This is done last to
1809
     permit the routine to look at the filtered symbol table, which is
1810
     important for the ECOFF code at least.  */
1811
  if (! bfd_copy_private_bfd_data (ibfd, obfd))
1812
    {
1813
      bfd_nonfatal_message (NULL, obfd, NULL,
1814
                            _("error copying private BFD data"));
1815
      return FALSE;
1816
    }
1817
 
1818
  /* Switch to the alternate machine code.  We have to do this at the
1819
     very end, because we only initialize the header when we create
1820
     the first section.  */
1821
  if (use_alt_mach_code != 0)
1822
    {
1823
      if (! bfd_alt_mach_code (obfd, use_alt_mach_code))
1824
        {
1825
          non_fatal (_("this target does not support %lu alternative machine codes"),
1826
                     use_alt_mach_code);
1827
          if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1828
            {
1829
              non_fatal (_("treating that number as an absolute e_machine value instead"));
1830
              elf_elfheader (obfd)->e_machine = use_alt_mach_code;
1831
            }
1832
          else
1833
            non_fatal (_("ignoring the alternative value"));
1834
        }
1835
    }
1836
 
1837
  return TRUE;
1838
}
1839
 
1840
/* Read each archive element in turn from IBFD, copy the
1841
   contents to temp file, and keep the temp file handle.
1842
   If 'force_output_target' is TRUE then make sure that
1843
   all elements in the new archive are of the type
1844
   'output_target'.  */
1845
 
1846
static void
1847
copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
1848
              bfd_boolean force_output_target)
1849
{
1850
  struct name_list
1851
    {
1852
      struct name_list *next;
1853
      const char *name;
1854
      bfd *obfd;
1855
    } *list, *l;
1856
  bfd **ptr = &obfd->archive_head;
1857
  bfd *this_element;
1858
  char * dir;
1859
 
1860
  /* Make a temp directory to hold the contents.  */
1861
  dir = make_tempdir (bfd_get_filename (obfd));
1862
  if (dir == NULL)
1863
      fatal (_("cannot create tempdir for archive copying (error: %s)"),
1864
           strerror (errno));
1865
 
1866
  obfd->has_armap = ibfd->has_armap;
1867
  obfd->is_thin_archive = ibfd->is_thin_archive;
1868
 
1869
  list = NULL;
1870
 
1871
  this_element = bfd_openr_next_archived_file (ibfd, NULL);
1872
 
1873
  if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
1874
    RETURN_NONFATAL (obfd);
1875
 
1876
  while (!status && this_element != NULL)
1877
    {
1878
      char *output_name;
1879
      bfd *output_bfd;
1880
      bfd *last_element;
1881
      struct stat buf;
1882
      int stat_status = 0;
1883
      bfd_boolean delete = TRUE;
1884
 
1885
      /* Create an output file for this member.  */
1886
      output_name = concat (dir, "/",
1887
                            bfd_get_filename (this_element), (char *) 0);
1888
 
1889
      /* If the file already exists, make another temp dir.  */
1890
      if (stat (output_name, &buf) >= 0)
1891
        {
1892
          output_name = make_tempdir (output_name);
1893
          if (output_name == NULL)
1894
            fatal (_("cannot create tempdir for archive copying (error: %s)"),
1895
                   strerror (errno));
1896
 
1897
          l = xmalloc (sizeof (struct name_list));
1898
          l->name = output_name;
1899
          l->next = list;
1900
          l->obfd = NULL;
1901
          list = l;
1902
          output_name = concat (output_name, "/",
1903
                                bfd_get_filename (this_element), (char *) 0);
1904
        }
1905
 
1906
      if (preserve_dates)
1907
        {
1908
          stat_status = bfd_stat_arch_elt (this_element, &buf);
1909
 
1910
          if (stat_status != 0)
1911
            non_fatal (_("internal stat error on %s"),
1912
                       bfd_get_filename (this_element));
1913
        }
1914
 
1915
      l = xmalloc (sizeof (struct name_list));
1916
      l->name = output_name;
1917
      l->next = list;
1918
      l->obfd = NULL;
1919
      list = l;
1920
 
1921
      if (bfd_check_format (this_element, bfd_object))
1922
        {
1923
          /* PR binutils/3110: Cope with archives
1924
             containing multiple target types.  */
1925
          if (force_output_target)
1926
            output_bfd = bfd_openw (output_name, output_target);
1927
          else
1928
            output_bfd = bfd_openw (output_name, bfd_get_target (this_element));
1929
 
1930
          if (output_bfd == NULL)
1931
            {
1932
              bfd_nonfatal_message (output_name, NULL, NULL, NULL);
1933
              status = 1;
1934
              return;
1935
            }
1936
 
1937
          delete = ! copy_object (this_element, output_bfd);
1938
 
1939
          if (! delete
1940
              || bfd_get_arch (this_element) != bfd_arch_unknown)
1941
            {
1942
              if (!bfd_close (output_bfd))
1943
                {
1944
                  bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
1945
                  /* Error in new object file. Don't change archive.  */
1946
                  status = 1;
1947
                }
1948
            }
1949
          else
1950
            goto copy_unknown_element;
1951
        }
1952
      else
1953
        {
1954
          bfd_nonfatal_message (bfd_get_archive_filename (this_element),
1955
                                NULL, NULL,
1956
                                _("Unable to recognise the format of file"));
1957
 
1958
          output_bfd = bfd_openw (output_name, output_target);
1959
copy_unknown_element:
1960
          delete = !copy_unknown_object (this_element, output_bfd);
1961
          if (!bfd_close_all_done (output_bfd))
1962
            {
1963
              bfd_nonfatal_message (NULL, output_bfd, NULL, NULL);
1964
              /* Error in new object file. Don't change archive.  */
1965
              status = 1;
1966
            }
1967
        }
1968
 
1969
      if (delete)
1970
        {
1971
          unlink (output_name);
1972
          status = 1;
1973
        }
1974
      else
1975
        {
1976
          if (preserve_dates && stat_status == 0)
1977
            set_times (output_name, &buf);
1978
 
1979
          /* Open the newly output file and attach to our list.  */
1980
          output_bfd = bfd_openr (output_name, output_target);
1981
 
1982
          l->obfd = output_bfd;
1983
 
1984
          *ptr = output_bfd;
1985
          ptr = &output_bfd->archive_next;
1986
 
1987
          last_element = this_element;
1988
 
1989
          this_element = bfd_openr_next_archived_file (ibfd, last_element);
1990
 
1991
          bfd_close (last_element);
1992
        }
1993
    }
1994
  *ptr = NULL;
1995
 
1996
  if (!bfd_close (obfd))
1997
    RETURN_NONFATAL (obfd);
1998
 
1999
  if (!bfd_close (ibfd))
2000
    RETURN_NONFATAL (obfd);
2001
 
2002
  /* Delete all the files that we opened.  */
2003
  for (l = list; l != NULL; l = l->next)
2004
    {
2005
      if (l->obfd == NULL)
2006
        rmdir (l->name);
2007
      else
2008
        {
2009
          bfd_close (l->obfd);
2010
          unlink (l->name);
2011
        }
2012
    }
2013
  rmdir (dir);
2014
}
2015
 
2016
/* The top-level control.  */
2017
 
2018
static void
2019
copy_file (const char *input_filename, const char *output_filename,
2020
           const char *input_target,   const char *output_target)
2021
{
2022
  bfd *ibfd;
2023
  char **obj_matching;
2024
  char **core_matching;
2025
 
2026
  if (get_file_size (input_filename) < 1)
2027
    {
2028
      status = 1;
2029
      return;
2030
    }
2031
 
2032
  /* To allow us to do "strip *" without dying on the first
2033
     non-object file, failures are nonfatal.  */
2034
  ibfd = bfd_openr (input_filename, input_target);
2035
  if (ibfd == NULL)
2036
    {
2037
      bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2038
      status = 1;
2039
      return;
2040
    }
2041
 
2042
  if (bfd_check_format (ibfd, bfd_archive))
2043
    {
2044
      bfd_boolean force_output_target;
2045
      bfd *obfd;
2046
 
2047
      /* bfd_get_target does not return the correct value until
2048
         bfd_check_format succeeds.  */
2049
      if (output_target == NULL)
2050
        {
2051
          output_target = bfd_get_target (ibfd);
2052
          force_output_target = FALSE;
2053
        }
2054
      else
2055
        force_output_target = TRUE;
2056
 
2057
      obfd = bfd_openw (output_filename, output_target);
2058
      if (obfd == NULL)
2059
        {
2060
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2061
          status = 1;
2062
          return;
2063
        }
2064
 
2065
      copy_archive (ibfd, obfd, output_target, force_output_target);
2066
    }
2067
  else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
2068
    {
2069
      bfd *obfd;
2070
    do_copy:
2071
 
2072
      /* bfd_get_target does not return the correct value until
2073
         bfd_check_format succeeds.  */
2074
      if (output_target == NULL)
2075
        output_target = bfd_get_target (ibfd);
2076
 
2077
      obfd = bfd_openw (output_filename, output_target);
2078
      if (obfd == NULL)
2079
        {
2080
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
2081
          status = 1;
2082
          return;
2083
        }
2084
 
2085
      if (! copy_object (ibfd, obfd))
2086
        status = 1;
2087
 
2088
      if (!bfd_close (obfd))
2089
        RETURN_NONFATAL (obfd);
2090
 
2091
      if (!bfd_close (ibfd))
2092
        RETURN_NONFATAL (ibfd);
2093
    }
2094
  else
2095
    {
2096
      bfd_error_type obj_error = bfd_get_error ();
2097
      bfd_error_type core_error;
2098
 
2099
      if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
2100
        {
2101
          /* This probably can't happen..  */
2102
          if (obj_error == bfd_error_file_ambiguously_recognized)
2103
            free (obj_matching);
2104
          goto do_copy;
2105
        }
2106
 
2107
      core_error = bfd_get_error ();
2108
      /* Report the object error in preference to the core error.  */
2109
      if (obj_error != core_error)
2110
        bfd_set_error (obj_error);
2111
 
2112
      bfd_nonfatal_message (input_filename, NULL, NULL, NULL);
2113
 
2114
      if (obj_error == bfd_error_file_ambiguously_recognized)
2115
        {
2116
          list_matching_formats (obj_matching);
2117
          free (obj_matching);
2118
        }
2119
      if (core_error == bfd_error_file_ambiguously_recognized)
2120
        {
2121
          list_matching_formats (core_matching);
2122
          free (core_matching);
2123
        }
2124
 
2125
      status = 1;
2126
    }
2127
}
2128
 
2129
/* Add a name to the section renaming list.  */
2130
 
2131
static void
2132
add_section_rename (const char * old_name, const char * new_name,
2133
                    flagword flags)
2134
{
2135
  section_rename * rename;
2136
 
2137
  /* Check for conflicts first.  */
2138
  for (rename = section_rename_list; rename != NULL; rename = rename->next)
2139
    if (strcmp (rename->old_name, old_name) == 0)
2140
      {
2141
        /* Silently ignore duplicate definitions.  */
2142
        if (strcmp (rename->new_name, new_name) == 0
2143
            && rename->flags == flags)
2144
          return;
2145
 
2146
        fatal (_("Multiple renames of section %s"), old_name);
2147
      }
2148
 
2149
  rename = xmalloc (sizeof (* rename));
2150
 
2151
  rename->old_name = old_name;
2152
  rename->new_name = new_name;
2153
  rename->flags    = flags;
2154
  rename->next     = section_rename_list;
2155
 
2156
  section_rename_list = rename;
2157
}
2158
 
2159
/* Check the section rename list for a new name of the input section
2160
   ISECTION.  Return the new name if one is found.
2161
   Also set RETURNED_FLAGS to the flags to be used for this section.  */
2162
 
2163
static const char *
2164
find_section_rename (bfd * ibfd ATTRIBUTE_UNUSED, sec_ptr isection,
2165
                     flagword * returned_flags)
2166
{
2167
  const char * old_name = bfd_section_name (ibfd, isection);
2168
  section_rename * rename;
2169
 
2170
  /* Default to using the flags of the input section.  */
2171
  * returned_flags = bfd_get_section_flags (ibfd, isection);
2172
 
2173
  for (rename = section_rename_list; rename != NULL; rename = rename->next)
2174
    if (strcmp (rename->old_name, old_name) == 0)
2175
      {
2176
        if (rename->flags != (flagword) -1)
2177
          * returned_flags = rename->flags;
2178
 
2179
        return rename->new_name;
2180
      }
2181
 
2182
  return old_name;
2183
}
2184
 
2185
/* Once each of the sections is copied, we may still need to do some
2186
   finalization work for private section headers.  Do that here.  */
2187
 
2188
static void
2189
setup_bfd_headers (bfd *ibfd, bfd *obfd)
2190
{
2191
  /* Allow the BFD backend to copy any private data it understands
2192
     from the input section to the output section.  */
2193
  if (! bfd_copy_private_header_data (ibfd, obfd))
2194
    {
2195
      status = 1;
2196
      bfd_nonfatal_message (NULL, ibfd, NULL,
2197
                            _("error in private h       eader data"));
2198
      return;
2199
    }
2200
 
2201
  /* All went well.  */
2202
  return;
2203
}
2204
 
2205
/* Create a section in OBFD with the same
2206
   name and attributes as ISECTION in IBFD.  */
2207
 
2208
static void
2209
setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2210
{
2211
  bfd *obfd = obfdarg;
2212
  struct section_list *p;
2213
  sec_ptr osection;
2214
  bfd_size_type size;
2215
  bfd_vma vma;
2216
  bfd_vma lma;
2217
  flagword flags;
2218
  const char *err;
2219
  const char * name;
2220
  char *prefix = NULL;
2221
  bfd_boolean make_nobits;
2222
 
2223
  if (is_strip_section (ibfd, isection))
2224
    return;
2225
 
2226
  p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
2227
  if (p != NULL)
2228
    p->used = TRUE;
2229
 
2230
  /* Get the, possibly new, name of the output section.  */
2231
  name = find_section_rename (ibfd, isection, & flags);
2232
 
2233
  /* Prefix sections.  */
2234
  if ((prefix_alloc_sections_string)
2235
      && (bfd_get_section_flags (ibfd, isection) & SEC_ALLOC))
2236
    prefix = prefix_alloc_sections_string;
2237
  else if (prefix_sections_string)
2238
    prefix = prefix_sections_string;
2239
 
2240
  if (prefix)
2241
    {
2242
      char *n;
2243
 
2244
      n = xmalloc (strlen (prefix) + strlen (name) + 1);
2245
      strcpy (n, prefix);
2246
      strcat (n, name);
2247
      name = n;
2248
    }
2249
 
2250
  make_nobits = FALSE;
2251
  if (p != NULL && p->set_flags)
2252
    flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
2253
  else if (strip_symbols == STRIP_NONDEBUG
2254
           && (flags & SEC_ALLOC) != 0
2255
           && (ibfd->xvec->flavour != bfd_target_elf_flavour
2256
               || elf_section_type (isection) != SHT_NOTE))
2257
    {
2258
      flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2259
      if (obfd->xvec->flavour == bfd_target_elf_flavour)
2260
        {
2261
          make_nobits = TRUE;
2262
 
2263
          /* Twiddle the input section flags so that it seems to
2264
             elf.c:copy_private_bfd_data that section flags have not
2265
             changed between input and output sections.  This hack
2266
             prevents wholesale rewriting of the program headers.  */
2267
          isection->flags &= ~(SEC_HAS_CONTENTS | SEC_LOAD);
2268
        }
2269
    }
2270
 
2271
  osection = bfd_make_section_anyway_with_flags (obfd, name, flags);
2272
 
2273
  if (osection == NULL)
2274
    {
2275
      err = _("failed to create output section");
2276
      goto loser;
2277
    }
2278
 
2279
  if (make_nobits)
2280
    elf_section_type (osection) = SHT_NOBITS;
2281
 
2282
  size = bfd_section_size (ibfd, isection);
2283
  if (copy_byte >= 0)
2284
    size = (size + interleave - 1) / interleave;
2285
  else if (extract_symbol)
2286
    size = 0;
2287
  if (! bfd_set_section_size (obfd, osection, size))
2288
    {
2289
      err = _("failed to set size");
2290
      goto loser;
2291
    }
2292
 
2293
  vma = bfd_section_vma (ibfd, isection);
2294
  if (p != NULL && p->change_vma == CHANGE_MODIFY)
2295
    vma += p->vma_val;
2296
  else if (p != NULL && p->change_vma == CHANGE_SET)
2297
    vma = p->vma_val;
2298
  else
2299
    vma += change_section_address;
2300
 
2301
  if (! bfd_set_section_vma (obfd, osection, extract_symbol ? 0 : vma))
2302
    {
2303
      err = _("failed to set vma");
2304
      goto loser;
2305
    }
2306
 
2307
  lma = isection->lma;
2308
  if ((p != NULL) && p->change_lma != CHANGE_IGNORE)
2309
    {
2310
      if (p->change_lma == CHANGE_MODIFY)
2311
        lma += p->lma_val;
2312
      else if (p->change_lma == CHANGE_SET)
2313
        lma = p->lma_val;
2314
      else
2315
        abort ();
2316
    }
2317
  else
2318
    lma += change_section_address;
2319
 
2320
  osection->lma = extract_symbol ? 0 : lma;
2321
 
2322
  /* FIXME: This is probably not enough.  If we change the LMA we
2323
     may have to recompute the header for the file as well.  */
2324
  if (!bfd_set_section_alignment (obfd,
2325
                                  osection,
2326
                                  bfd_section_alignment (ibfd, isection)))
2327
    {
2328
      err = _("failed to set alignment");
2329
      goto loser;
2330
    }
2331
 
2332
  /* Copy merge entity size.  */
2333
  osection->entsize = isection->entsize;
2334
 
2335
  /* This used to be mangle_section; we do here to avoid using
2336
     bfd_get_section_by_name since some formats allow multiple
2337
     sections with the same name.  */
2338
  isection->output_section = osection;
2339
  isection->output_offset = extract_symbol ? vma : 0;
2340
 
2341
  /* Do not copy backend data if --extract-symbol is passed; anything
2342
     that needs to look at the section contents will fail.  */
2343
  if (extract_symbol)
2344
    return;
2345
 
2346
  /* Allow the BFD backend to copy any private data it understands
2347
     from the input section to the output section.  */
2348
  if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
2349
    {
2350
      err = _("failed to copy private data");
2351
      goto loser;
2352
    }
2353
  else if ((isection->flags & SEC_GROUP) != 0)
2354
    {
2355
      asymbol *gsym = group_signature (isection);
2356
 
2357
      if (gsym != NULL)
2358
        gsym->flags |= BSF_KEEP;
2359
    }
2360
 
2361
  /* All went well.  */
2362
  return;
2363
 
2364
loser:
2365
  status = 1;
2366
  bfd_nonfatal_message (NULL, obfd, osection, err);
2367
}
2368
 
2369
/* Copy the data of input section ISECTION of IBFD
2370
   to an output section with the same name in OBFD.
2371
   If stripping then don't copy any relocation info.  */
2372
 
2373
static void
2374
copy_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
2375
{
2376
  bfd *obfd = obfdarg;
2377
  struct section_list *p;
2378
  arelent **relpp;
2379
  long relcount;
2380
  sec_ptr osection;
2381
  bfd_size_type size;
2382
  long relsize;
2383
  flagword flags;
2384
 
2385
  /* If we have already failed earlier on,
2386
     do not keep on generating complaints now.  */
2387
  if (status != 0)
2388
    return;
2389
 
2390
  if (is_strip_section (ibfd, isection))
2391
    return;
2392
 
2393
  flags = bfd_get_section_flags (ibfd, isection);
2394
  if ((flags & SEC_GROUP) != 0)
2395
    return;
2396
 
2397
  osection = isection->output_section;
2398
  size = bfd_get_section_size (isection);
2399
 
2400
  if (size == 0 || osection == 0)
2401
    return;
2402
 
2403
  p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
2404
 
2405
  /* Core files do not need to be relocated.  */
2406
  if (bfd_get_format (obfd) == bfd_core)
2407
    relsize = 0;
2408
  else
2409
    {
2410
      relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2411
 
2412
      if (relsize < 0)
2413
        {
2414
          /* Do not complain if the target does not support relocations.  */
2415
          if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2416
            relsize = 0;
2417
          else
2418
            {
2419
              status = 1;
2420
              bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2421
              return;
2422
            }
2423
        }
2424
    }
2425
 
2426
  if (relsize == 0)
2427
    bfd_set_reloc (obfd, osection, NULL, 0);
2428
  else
2429
    {
2430
      relpp = xmalloc (relsize);
2431
      relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
2432
      if (relcount < 0)
2433
        {
2434
          status = 1;
2435
          bfd_nonfatal_message (NULL, ibfd, isection,
2436
                                _("relocation count is negative"));
2437
          return;
2438
        }
2439
 
2440
      if (strip_symbols == STRIP_ALL)
2441
        {
2442
          /* Remove relocations which are not in
2443
             keep_strip_specific_list.  */
2444
          arelent **temp_relpp;
2445
          long temp_relcount = 0;
2446
          long i;
2447
 
2448
          temp_relpp = xmalloc (relsize);
2449
          for (i = 0; i < relcount; i++)
2450
            if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
2451
                                     keep_specific_htab))
2452
              temp_relpp [temp_relcount++] = relpp [i];
2453
          relcount = temp_relcount;
2454
          free (relpp);
2455
          relpp = temp_relpp;
2456
        }
2457
 
2458
      bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
2459
      if (relcount == 0)
2460
        free (relpp);
2461
    }
2462
 
2463
  if (extract_symbol)
2464
    return;
2465
 
2466
  if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
2467
      && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
2468
    {
2469
      void *memhunk = xmalloc (size);
2470
 
2471
      if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
2472
        {
2473
          status = 1;
2474
          bfd_nonfatal_message (NULL, ibfd, isection, NULL);
2475
          return;
2476
        }
2477
 
2478
      if (reverse_bytes)
2479
        {
2480
          /* We don't handle leftover bytes (too many possible behaviors,
2481
             and we don't know what the user wants).  The section length
2482
             must be a multiple of the number of bytes to swap.  */
2483
          if ((size % reverse_bytes) == 0)
2484
            {
2485
              unsigned long i, j;
2486
              bfd_byte b;
2487
 
2488
              for (i = 0; i < size; i += reverse_bytes)
2489
                for (j = 0; j < (unsigned long)(reverse_bytes / 2); j++)
2490
                  {
2491
                    bfd_byte *m = (bfd_byte *) memhunk;
2492
 
2493
                    b = m[i + j];
2494
                    m[i + j] = m[(i + reverse_bytes) - (j + 1)];
2495
                    m[(i + reverse_bytes) - (j + 1)] = b;
2496
                  }
2497
            }
2498
          else
2499
            /* User must pad the section up in order to do this.  */
2500
            fatal (_("cannot reverse bytes: length of section %s must be evenly divisible by %d"),
2501
                   bfd_section_name (ibfd, isection), reverse_bytes);
2502
        }
2503
 
2504
      if (copy_byte >= 0)
2505
        {
2506
          /* Keep only every `copy_byte'th byte in MEMHUNK.  */
2507
          char *from = (char *) memhunk + copy_byte;
2508
          char *to = memhunk;
2509
          char *end = (char *) memhunk + size;
2510
 
2511
          for (; from < end; from += interleave)
2512
            *to++ = *from;
2513
 
2514
          size = (size + interleave - 1 - copy_byte) / interleave;
2515
          osection->lma /= interleave;
2516
        }
2517
 
2518
      if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2519
        {
2520
          status = 1;
2521
          bfd_nonfatal_message (NULL, obfd, osection, NULL);
2522
          return;
2523
        }
2524
      free (memhunk);
2525
    }
2526
  else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
2527
    {
2528
      void *memhunk = xmalloc (size);
2529
 
2530
      /* We don't permit the user to turn off the SEC_HAS_CONTENTS
2531
         flag--they can just remove the section entirely and add it
2532
         back again.  However, we do permit them to turn on the
2533
         SEC_HAS_CONTENTS flag, and take it to mean that the section
2534
         contents should be zeroed out.  */
2535
 
2536
      memset (memhunk, 0, size);
2537
      if (! bfd_set_section_contents (obfd, osection, memhunk, 0, size))
2538
        {
2539
          status = 1;
2540
          bfd_nonfatal_message (NULL, obfd, osection, NULL);
2541
          return;
2542
        }
2543
      free (memhunk);
2544
    }
2545
}
2546
 
2547
/* Get all the sections.  This is used when --gap-fill or --pad-to is
2548
   used.  */
2549
 
2550
static void
2551
get_sections (bfd *obfd ATTRIBUTE_UNUSED, asection *osection, void *secppparg)
2552
{
2553
  asection ***secppp = secppparg;
2554
 
2555
  **secppp = osection;
2556
  ++(*secppp);
2557
}
2558
 
2559
/* Sort sections by VMA.  This is called via qsort, and is used when
2560
   --gap-fill or --pad-to is used.  We force non loadable or empty
2561
   sections to the front, where they are easier to ignore.  */
2562
 
2563
static int
2564
compare_section_lma (const void *arg1, const void *arg2)
2565
{
2566
  const asection *const *sec1 = arg1;
2567
  const asection *const *sec2 = arg2;
2568
  flagword flags1, flags2;
2569
 
2570
  /* Sort non loadable sections to the front.  */
2571
  flags1 = (*sec1)->flags;
2572
  flags2 = (*sec2)->flags;
2573
  if ((flags1 & SEC_HAS_CONTENTS) == 0
2574
      || (flags1 & SEC_LOAD) == 0)
2575
    {
2576
      if ((flags2 & SEC_HAS_CONTENTS) != 0
2577
          && (flags2 & SEC_LOAD) != 0)
2578
        return -1;
2579
    }
2580
  else
2581
    {
2582
      if ((flags2 & SEC_HAS_CONTENTS) == 0
2583
          || (flags2 & SEC_LOAD) == 0)
2584
        return 1;
2585
    }
2586
 
2587
  /* Sort sections by LMA.  */
2588
  if ((*sec1)->lma > (*sec2)->lma)
2589
    return 1;
2590
  else if ((*sec1)->lma < (*sec2)->lma)
2591
    return -1;
2592
 
2593
  /* Sort sections with the same LMA by size.  */
2594
  if (bfd_get_section_size (*sec1) > bfd_get_section_size (*sec2))
2595
    return 1;
2596
  else if (bfd_get_section_size (*sec1) < bfd_get_section_size (*sec2))
2597
    return -1;
2598
 
2599
  return 0;
2600
}
2601
 
2602
/* Mark all the symbols which will be used in output relocations with
2603
   the BSF_KEEP flag so that those symbols will not be stripped.
2604
 
2605
   Ignore relocations which will not appear in the output file.  */
2606
 
2607
static void
2608
mark_symbols_used_in_relocations (bfd *ibfd, sec_ptr isection, void *symbolsarg)
2609
{
2610
  asymbol **symbols = symbolsarg;
2611
  long relsize;
2612
  arelent **relpp;
2613
  long relcount, i;
2614
 
2615
  /* Ignore an input section with no corresponding output section.  */
2616
  if (isection->output_section == NULL)
2617
    return;
2618
 
2619
  relsize = bfd_get_reloc_upper_bound (ibfd, isection);
2620
  if (relsize < 0)
2621
    {
2622
      /* Do not complain if the target does not support relocations.  */
2623
      if (relsize == -1 && bfd_get_error () == bfd_error_invalid_operation)
2624
        return;
2625
      bfd_fatal (bfd_get_filename (ibfd));
2626
    }
2627
 
2628
  if (relsize == 0)
2629
    return;
2630
 
2631
  relpp = xmalloc (relsize);
2632
  relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
2633
  if (relcount < 0)
2634
    bfd_fatal (bfd_get_filename (ibfd));
2635
 
2636
  /* Examine each symbol used in a relocation.  If it's not one of the
2637
     special bfd section symbols, then mark it with BSF_KEEP.  */
2638
  for (i = 0; i < relcount; i++)
2639
    {
2640
      if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
2641
          && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
2642
          && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
2643
        (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
2644
    }
2645
 
2646
  if (relpp != NULL)
2647
    free (relpp);
2648
}
2649
 
2650
/* Write out debugging information.  */
2651
 
2652
static bfd_boolean
2653
write_debugging_info (bfd *obfd, void *dhandle,
2654
                      long *symcountp ATTRIBUTE_UNUSED,
2655
                      asymbol ***symppp ATTRIBUTE_UNUSED)
2656
{
2657
  if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
2658
    return write_ieee_debugging_info (obfd, dhandle);
2659
 
2660
  if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
2661
      || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
2662
    {
2663
      bfd_byte *syms, *strings;
2664
      bfd_size_type symsize, stringsize;
2665
      asection *stabsec, *stabstrsec;
2666
      flagword flags;
2667
 
2668
      if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
2669
                                                    &symsize, &strings,
2670
                                                    &stringsize))
2671
        return FALSE;
2672
 
2673
      flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
2674
      stabsec = bfd_make_section_with_flags (obfd, ".stab", flags);
2675
      stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags);
2676
      if (stabsec == NULL
2677
          || stabstrsec == NULL
2678
          || ! bfd_set_section_size (obfd, stabsec, symsize)
2679
          || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
2680
          || ! bfd_set_section_alignment (obfd, stabsec, 2)
2681
          || ! bfd_set_section_alignment (obfd, stabstrsec, 0))
2682
        {
2683
          bfd_nonfatal_message (NULL, obfd, NULL,
2684
                                _("can't create debugging section"));
2685
          return FALSE;
2686
        }
2687
 
2688
      /* We can get away with setting the section contents now because
2689
         the next thing the caller is going to do is copy over the
2690
         real sections.  We may someday have to split the contents
2691
         setting out of this function.  */
2692
      if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize)
2693
          || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0,
2694
                                         stringsize))
2695
        {
2696
          bfd_nonfatal_message (NULL, obfd, NULL,
2697
                                _("can't set debugging section contents"));
2698
          return FALSE;
2699
        }
2700
 
2701
      return TRUE;
2702
    }
2703
 
2704
  bfd_nonfatal_message (NULL, obfd, NULL,
2705
                        _("don't know how to write debugging information for %s"),
2706
             bfd_get_target (obfd));
2707
  return FALSE;
2708
}
2709
 
2710
static int
2711
strip_main (int argc, char *argv[])
2712
{
2713
  char *input_target = NULL;
2714
  char *output_target = NULL;
2715
  bfd_boolean show_version = FALSE;
2716
  bfd_boolean formats_info = FALSE;
2717
  int c;
2718
  int i;
2719
  struct section_list *p;
2720
  char *output_file = NULL;
2721
 
2722
  while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpdgxXHhVvw",
2723
                           strip_options, (int *) 0)) != EOF)
2724
    {
2725
      switch (c)
2726
        {
2727
        case 'I':
2728
          input_target = optarg;
2729
          break;
2730
        case 'O':
2731
          output_target = optarg;
2732
          break;
2733
        case 'F':
2734
          input_target = output_target = optarg;
2735
          break;
2736
        case 'R':
2737
          p = find_section_list (optarg, TRUE);
2738
          p->remove = TRUE;
2739
          sections_removed = TRUE;
2740
          break;
2741
        case 's':
2742
          strip_symbols = STRIP_ALL;
2743
          break;
2744
        case 'S':
2745
        case 'g':
2746
        case 'd':       /* Historic BSD alias for -g.  Used by early NetBSD.  */
2747
          strip_symbols = STRIP_DEBUG;
2748
          break;
2749
        case OPTION_STRIP_UNNEEDED:
2750
          strip_symbols = STRIP_UNNEEDED;
2751
          break;
2752
        case 'K':
2753
          add_specific_symbol (optarg, keep_specific_htab);
2754
          break;
2755
        case 'N':
2756
          add_specific_symbol (optarg, strip_specific_htab);
2757
          break;
2758
        case 'o':
2759
          output_file = optarg;
2760
          break;
2761
        case 'p':
2762
          preserve_dates = TRUE;
2763
          break;
2764
        case 'x':
2765
          discard_locals = LOCALS_ALL;
2766
          break;
2767
        case 'X':
2768
          discard_locals = LOCALS_START_L;
2769
          break;
2770
        case 'v':
2771
          verbose = TRUE;
2772
          break;
2773
        case 'V':
2774
          show_version = TRUE;
2775
          break;
2776
        case OPTION_FORMATS_INFO:
2777
          formats_info = TRUE;
2778
          break;
2779
        case OPTION_ONLY_KEEP_DEBUG:
2780
          strip_symbols = STRIP_NONDEBUG;
2781
          break;
2782
        case OPTION_KEEP_FILE_SYMBOLS:
2783
          keep_file_symbols = 1;
2784
          break;
2785
        case 0:
2786
          /* We've been given a long option.  */
2787
          break;
2788
        case 'w':
2789
          wildcard = TRUE;
2790
          break;
2791
        case 'H':
2792
        case 'h':
2793
          strip_usage (stdout, 0);
2794
        default:
2795
          strip_usage (stderr, 1);
2796
        }
2797
    }
2798
 
2799
  if (formats_info)
2800
    {
2801
      display_info ();
2802
      return 0;
2803
    }
2804
 
2805
  if (show_version)
2806
    print_version ("strip");
2807
 
2808
  /* Default is to strip all symbols.  */
2809
  if (strip_symbols == STRIP_UNDEF
2810
      && discard_locals == LOCALS_UNDEF
2811
      && htab_elements (strip_specific_htab) == 0)
2812
    strip_symbols = STRIP_ALL;
2813
 
2814
  if (output_target == NULL)
2815
    output_target = input_target;
2816
 
2817
  i = optind;
2818
  if (i == argc
2819
      || (output_file != NULL && (i + 1) < argc))
2820
    strip_usage (stderr, 1);
2821
 
2822
  for (; i < argc; i++)
2823
    {
2824
      int hold_status = status;
2825
      struct stat statbuf;
2826
      char *tmpname;
2827
 
2828
      if (get_file_size (argv[i]) < 1)
2829
        {
2830
          status = 1;
2831
          continue;
2832
        }
2833
 
2834
      if (preserve_dates)
2835
        /* No need to check the return value of stat().
2836
           It has already been checked in get_file_size().  */
2837
        stat (argv[i], &statbuf);
2838
 
2839
      if (output_file == NULL || strcmp (argv[i], output_file) == 0)
2840
        tmpname = make_tempname (argv[i]);
2841
      else
2842
        tmpname = output_file;
2843
 
2844
      if (tmpname == NULL)
2845
        {
2846
          bfd_nonfatal_message (argv[i], NULL, NULL,
2847
                                _("could not create temporary file to hold stripped copy"));
2848
          status = 1;
2849
          continue;
2850
        }
2851
 
2852
      status = 0;
2853
      copy_file (argv[i], tmpname, input_target, output_target);
2854
      if (status == 0)
2855
        {
2856
          if (preserve_dates)
2857
            set_times (tmpname, &statbuf);
2858
          if (output_file != tmpname)
2859
            smart_rename (tmpname, output_file ? output_file : argv[i],
2860
                          preserve_dates);
2861
          status = hold_status;
2862
        }
2863
      else
2864
        unlink_if_ordinary (tmpname);
2865
      if (output_file != tmpname)
2866
        free (tmpname);
2867
    }
2868
 
2869
  return status;
2870
}
2871
 
2872
static int
2873
copy_main (int argc, char *argv[])
2874
{
2875
  char * binary_architecture = NULL;
2876
  char *input_filename = NULL;
2877
  char *output_filename = NULL;
2878
  char *tmpname;
2879
  char *input_target = NULL;
2880
  char *output_target = NULL;
2881
  bfd_boolean show_version = FALSE;
2882
  bfd_boolean change_warn = TRUE;
2883
  bfd_boolean formats_info = FALSE;
2884
  int c;
2885
  struct section_list *p;
2886
  struct stat statbuf;
2887
 
2888
  while ((c = getopt_long (argc, argv, "b:B:i:I:j:K:N:s:O:d:F:L:G:R:SpgxXHhVvW:w",
2889
                           copy_options, (int *) 0)) != EOF)
2890
    {
2891
      switch (c)
2892
        {
2893
        case 'b':
2894
          copy_byte = atoi (optarg);
2895
          if (copy_byte < 0)
2896
            fatal (_("byte number must be non-negative"));
2897
          break;
2898
 
2899
        case 'B':
2900
          binary_architecture = optarg;
2901
          break;
2902
 
2903
        case 'i':
2904
          interleave = atoi (optarg);
2905
          if (interleave < 1)
2906
            fatal (_("interleave must be positive"));
2907
          break;
2908
 
2909
        case 'I':
2910
        case 's':               /* "source" - 'I' is preferred */
2911
          input_target = optarg;
2912
          break;
2913
 
2914
        case 'O':
2915
        case 'd':               /* "destination" - 'O' is preferred */
2916
          output_target = optarg;
2917
          break;
2918
 
2919
        case 'F':
2920
          input_target = output_target = optarg;
2921
          break;
2922
 
2923
        case 'j':
2924
          p = find_section_list (optarg, TRUE);
2925
          if (p->remove)
2926
            fatal (_("%s both copied and removed"), optarg);
2927
          p->copy = TRUE;
2928
          sections_copied = TRUE;
2929
          break;
2930
 
2931
        case 'R':
2932
          p = find_section_list (optarg, TRUE);
2933
          if (p->copy)
2934
            fatal (_("%s both copied and removed"), optarg);
2935
          p->remove = TRUE;
2936
          sections_removed = TRUE;
2937
          break;
2938
 
2939
        case 'S':
2940
          strip_symbols = STRIP_ALL;
2941
          break;
2942
 
2943
        case 'g':
2944
          strip_symbols = STRIP_DEBUG;
2945
          break;
2946
 
2947
        case OPTION_STRIP_UNNEEDED:
2948
          strip_symbols = STRIP_UNNEEDED;
2949
          break;
2950
 
2951
        case OPTION_ONLY_KEEP_DEBUG:
2952
          strip_symbols = STRIP_NONDEBUG;
2953
          break;
2954
 
2955
        case OPTION_KEEP_FILE_SYMBOLS:
2956
          keep_file_symbols = 1;
2957
          break;
2958
 
2959
        case OPTION_ADD_GNU_DEBUGLINK:
2960
          gnu_debuglink_filename = optarg;
2961
          break;
2962
 
2963
        case 'K':
2964
          add_specific_symbol (optarg, keep_specific_htab);
2965
          break;
2966
 
2967
        case 'N':
2968
          add_specific_symbol (optarg, strip_specific_htab);
2969
          break;
2970
 
2971
        case OPTION_STRIP_UNNEEDED_SYMBOL:
2972
          add_specific_symbol (optarg, strip_unneeded_htab);
2973
          break;
2974
 
2975
        case 'L':
2976
          add_specific_symbol (optarg, localize_specific_htab);
2977
          break;
2978
 
2979
        case OPTION_GLOBALIZE_SYMBOL:
2980
          add_specific_symbol (optarg, globalize_specific_htab);
2981
          break;
2982
 
2983
        case 'G':
2984
          add_specific_symbol (optarg, keepglobal_specific_htab);
2985
          break;
2986
 
2987
        case 'W':
2988
          add_specific_symbol (optarg, weaken_specific_htab);
2989
          break;
2990
 
2991
        case 'p':
2992
          preserve_dates = TRUE;
2993
          break;
2994
 
2995
        case 'w':
2996
          wildcard = TRUE;
2997
          break;
2998
 
2999
        case 'x':
3000
          discard_locals = LOCALS_ALL;
3001
          break;
3002
 
3003
        case 'X':
3004
          discard_locals = LOCALS_START_L;
3005
          break;
3006
 
3007
        case 'v':
3008
          verbose = TRUE;
3009
          break;
3010
 
3011
        case 'V':
3012
          show_version = TRUE;
3013
          break;
3014
 
3015
        case OPTION_FORMATS_INFO:
3016
          formats_info = TRUE;
3017
          break;
3018
 
3019
        case OPTION_WEAKEN:
3020
          weaken = TRUE;
3021
          break;
3022
 
3023
        case OPTION_ADD_SECTION:
3024
          {
3025
            const char *s;
3026
            off_t size;
3027
            struct section_add *pa;
3028
            int len;
3029
            char *name;
3030
            FILE *f;
3031
 
3032
            s = strchr (optarg, '=');
3033
 
3034
            if (s == NULL)
3035
              fatal (_("bad format for %s"), "--add-section");
3036
 
3037
            size = get_file_size (s + 1);
3038
            if (size < 1)
3039
              {
3040
                status = 1;
3041
                break;
3042
              }
3043
 
3044
            pa = xmalloc (sizeof (struct section_add));
3045
 
3046
            len = s - optarg;
3047
            name = xmalloc (len + 1);
3048
            strncpy (name, optarg, len);
3049
            name[len] = '\0';
3050
            pa->name = name;
3051
 
3052
            pa->filename = s + 1;
3053
            pa->size = size;
3054
            pa->contents = xmalloc (size);
3055
 
3056
            f = fopen (pa->filename, FOPEN_RB);
3057
 
3058
            if (f == NULL)
3059
              fatal (_("cannot open: %s: %s"),
3060
                     pa->filename, strerror (errno));
3061
 
3062
            if (fread (pa->contents, 1, pa->size, f) == 0
3063
                || ferror (f))
3064
              fatal (_("%s: fread failed"), pa->filename);
3065
 
3066
            fclose (f);
3067
 
3068
            pa->next = add_sections;
3069
            add_sections = pa;
3070
          }
3071
          break;
3072
 
3073
        case OPTION_CHANGE_START:
3074
          change_start = parse_vma (optarg, "--change-start");
3075
          break;
3076
 
3077
        case OPTION_CHANGE_SECTION_ADDRESS:
3078
        case OPTION_CHANGE_SECTION_LMA:
3079
        case OPTION_CHANGE_SECTION_VMA:
3080
          {
3081
            const char *s;
3082
            int len;
3083
            char *name;
3084
            char *option = NULL;
3085
            bfd_vma val;
3086
            enum change_action what = CHANGE_IGNORE;
3087
 
3088
            switch (c)
3089
              {
3090
              case OPTION_CHANGE_SECTION_ADDRESS:
3091
                option = "--change-section-address";
3092
                break;
3093
              case OPTION_CHANGE_SECTION_LMA:
3094
                option = "--change-section-lma";
3095
                break;
3096
              case OPTION_CHANGE_SECTION_VMA:
3097
                option = "--change-section-vma";
3098
                break;
3099
              }
3100
 
3101
            s = strchr (optarg, '=');
3102
            if (s == NULL)
3103
              {
3104
                s = strchr (optarg, '+');
3105
                if (s == NULL)
3106
                  {
3107
                    s = strchr (optarg, '-');
3108
                    if (s == NULL)
3109
                      fatal (_("bad format for %s"), option);
3110
                  }
3111
              }
3112
 
3113
            len = s - optarg;
3114
            name = xmalloc (len + 1);
3115
            strncpy (name, optarg, len);
3116
            name[len] = '\0';
3117
 
3118
            p = find_section_list (name, TRUE);
3119
 
3120
            val = parse_vma (s + 1, option);
3121
 
3122
            switch (*s)
3123
              {
3124
              case '=': what = CHANGE_SET; break;
3125
              case '-': val  = - val; /* Drop through.  */
3126
              case '+': what = CHANGE_MODIFY; break;
3127
              }
3128
 
3129
            switch (c)
3130
              {
3131
              case OPTION_CHANGE_SECTION_ADDRESS:
3132
                p->change_vma = what;
3133
                p->vma_val    = val;
3134
                /* Drop through.  */
3135
 
3136
              case OPTION_CHANGE_SECTION_LMA:
3137
                p->change_lma = what;
3138
                p->lma_val    = val;
3139
                break;
3140
 
3141
              case OPTION_CHANGE_SECTION_VMA:
3142
                p->change_vma = what;
3143
                p->vma_val    = val;
3144
                break;
3145
              }
3146
          }
3147
          break;
3148
 
3149
        case OPTION_CHANGE_ADDRESSES:
3150
          change_section_address = parse_vma (optarg, "--change-addresses");
3151
          change_start = change_section_address;
3152
          break;
3153
 
3154
        case OPTION_CHANGE_WARNINGS:
3155
          change_warn = TRUE;
3156
          break;
3157
 
3158
        case OPTION_CHANGE_LEADING_CHAR:
3159
          change_leading_char = TRUE;
3160
          break;
3161
 
3162
        case OPTION_DEBUGGING:
3163
          convert_debugging = TRUE;
3164
          break;
3165
 
3166
        case OPTION_GAP_FILL:
3167
          {
3168
            bfd_vma gap_fill_vma;
3169
 
3170
            gap_fill_vma = parse_vma (optarg, "--gap-fill");
3171
            gap_fill = (bfd_byte) gap_fill_vma;
3172
            if ((bfd_vma) gap_fill != gap_fill_vma)
3173
              {
3174
                char buff[20];
3175
 
3176
                sprintf_vma (buff, gap_fill_vma);
3177
 
3178
                non_fatal (_("Warning: truncating gap-fill from 0x%s to 0x%x"),
3179
                           buff, gap_fill);
3180
              }
3181
            gap_fill_set = TRUE;
3182
          }
3183
          break;
3184
 
3185
        case OPTION_NO_CHANGE_WARNINGS:
3186
          change_warn = FALSE;
3187
          break;
3188
 
3189
        case OPTION_PAD_TO:
3190
          pad_to = parse_vma (optarg, "--pad-to");
3191
          pad_to_set = TRUE;
3192
          break;
3193
 
3194
        case OPTION_REMOVE_LEADING_CHAR:
3195
          remove_leading_char = TRUE;
3196
          break;
3197
 
3198
        case OPTION_REDEFINE_SYM:
3199
          {
3200
            /* Push this redefinition onto redefine_symbol_list.  */
3201
 
3202
            int len;
3203
            const char *s;
3204
            const char *nextarg;
3205
            char *source, *target;
3206
 
3207
            s = strchr (optarg, '=');
3208
            if (s == NULL)
3209
              fatal (_("bad format for %s"), "--redefine-sym");
3210
 
3211
            len = s - optarg;
3212
            source = xmalloc (len + 1);
3213
            strncpy (source, optarg, len);
3214
            source[len] = '\0';
3215
 
3216
            nextarg = s + 1;
3217
            len = strlen (nextarg);
3218
            target = xmalloc (len + 1);
3219
            strcpy (target, nextarg);
3220
 
3221
            redefine_list_append ("--redefine-sym", source, target);
3222
 
3223
            free (source);
3224
            free (target);
3225
          }
3226
          break;
3227
 
3228
        case OPTION_REDEFINE_SYMS:
3229
          add_redefine_syms_file (optarg);
3230
          break;
3231
 
3232
        case OPTION_SET_SECTION_FLAGS:
3233
          {
3234
            const char *s;
3235
            int len;
3236
            char *name;
3237
 
3238
            s = strchr (optarg, '=');
3239
            if (s == NULL)
3240
              fatal (_("bad format for %s"), "--set-section-flags");
3241
 
3242
            len = s - optarg;
3243
            name = xmalloc (len + 1);
3244
            strncpy (name, optarg, len);
3245
            name[len] = '\0';
3246
 
3247
            p = find_section_list (name, TRUE);
3248
 
3249
            p->set_flags = TRUE;
3250
            p->flags = parse_flags (s + 1);
3251
          }
3252
          break;
3253
 
3254
        case OPTION_RENAME_SECTION:
3255
          {
3256
            flagword flags;
3257
            const char *eq, *fl;
3258
            char *old_name;
3259
            char *new_name;
3260
            unsigned int len;
3261
 
3262
            eq = strchr (optarg, '=');
3263
            if (eq == NULL)
3264
              fatal (_("bad format for %s"), "--rename-section");
3265
 
3266
            len = eq - optarg;
3267
            if (len == 0)
3268
              fatal (_("bad format for %s"), "--rename-section");
3269
 
3270
            old_name = xmalloc (len + 1);
3271
            strncpy (old_name, optarg, len);
3272
            old_name[len] = 0;
3273
 
3274
            eq++;
3275
            fl = strchr (eq, ',');
3276
            if (fl)
3277
              {
3278
                flags = parse_flags (fl + 1);
3279
                len = fl - eq;
3280
              }
3281
            else
3282
              {
3283
                flags = -1;
3284
                len = strlen (eq);
3285
              }
3286
 
3287
            if (len == 0)
3288
              fatal (_("bad format for %s"), "--rename-section");
3289
 
3290
            new_name = xmalloc (len + 1);
3291
            strncpy (new_name, eq, len);
3292
            new_name[len] = 0;
3293
 
3294
            add_section_rename (old_name, new_name, flags);
3295
          }
3296
          break;
3297
 
3298
        case OPTION_SET_START:
3299
          set_start = parse_vma (optarg, "--set-start");
3300
          set_start_set = TRUE;
3301
          break;
3302
 
3303
        case OPTION_SREC_LEN:
3304
          Chunk = parse_vma (optarg, "--srec-len");
3305
          break;
3306
 
3307
        case OPTION_SREC_FORCES3:
3308
          S3Forced = TRUE;
3309
          break;
3310
 
3311
        case OPTION_STRIP_SYMBOLS:
3312
          add_specific_symbols (optarg, strip_specific_htab);
3313
          break;
3314
 
3315
        case OPTION_STRIP_UNNEEDED_SYMBOLS:
3316
          add_specific_symbols (optarg, strip_unneeded_htab);
3317
          break;
3318
 
3319
        case OPTION_KEEP_SYMBOLS:
3320
          add_specific_symbols (optarg, keep_specific_htab);
3321
          break;
3322
 
3323
        case OPTION_LOCALIZE_HIDDEN:
3324
          localize_hidden = TRUE;
3325
          break;
3326
 
3327
        case OPTION_LOCALIZE_SYMBOLS:
3328
          add_specific_symbols (optarg, localize_specific_htab);
3329
          break;
3330
 
3331
        case OPTION_GLOBALIZE_SYMBOLS:
3332
          add_specific_symbols (optarg, globalize_specific_htab);
3333
          break;
3334
 
3335
        case OPTION_KEEPGLOBAL_SYMBOLS:
3336
          add_specific_symbols (optarg, keepglobal_specific_htab);
3337
          break;
3338
 
3339
        case OPTION_WEAKEN_SYMBOLS:
3340
          add_specific_symbols (optarg, weaken_specific_htab);
3341
          break;
3342
 
3343
        case OPTION_ALT_MACH_CODE:
3344
          use_alt_mach_code = strtoul (optarg, NULL, 0);
3345
          if (use_alt_mach_code == 0)
3346
            fatal (_("unable to parse alternative machine code"));
3347
          break;
3348
 
3349
        case OPTION_PREFIX_SYMBOLS:
3350
          prefix_symbols_string = optarg;
3351
          break;
3352
 
3353
        case OPTION_PREFIX_SECTIONS:
3354
          prefix_sections_string = optarg;
3355
          break;
3356
 
3357
        case OPTION_PREFIX_ALLOC_SECTIONS:
3358
          prefix_alloc_sections_string = optarg;
3359
          break;
3360
 
3361
        case OPTION_READONLY_TEXT:
3362
          bfd_flags_to_set |= WP_TEXT;
3363
          bfd_flags_to_clear &= ~WP_TEXT;
3364
          break;
3365
 
3366
        case OPTION_WRITABLE_TEXT:
3367
          bfd_flags_to_clear |= WP_TEXT;
3368
          bfd_flags_to_set &= ~WP_TEXT;
3369
          break;
3370
 
3371
        case OPTION_PURE:
3372
          bfd_flags_to_set |= D_PAGED;
3373
          bfd_flags_to_clear &= ~D_PAGED;
3374
          break;
3375
 
3376
        case OPTION_IMPURE:
3377
          bfd_flags_to_clear |= D_PAGED;
3378
          bfd_flags_to_set &= ~D_PAGED;
3379
          break;
3380
 
3381
        case OPTION_EXTRACT_SYMBOL:
3382
          extract_symbol = TRUE;
3383
          break;
3384
 
3385
        case OPTION_REVERSE_BYTES:
3386
          {
3387
            int prev = reverse_bytes;
3388
 
3389
            reverse_bytes = atoi (optarg);
3390
            if ((reverse_bytes <= 0) || ((reverse_bytes % 2) != 0))
3391
              fatal (_("number of bytes to reverse must be positive and even"));
3392
 
3393
            if (prev && prev != reverse_bytes)
3394
              non_fatal (_("Warning: ignoring previous --reverse-bytes value of %d"),
3395
                         prev);
3396
            break;
3397
          }
3398
 
3399
        case 0:
3400
          /* We've been given a long option.  */
3401
          break;
3402
 
3403
        case 'H':
3404
        case 'h':
3405
          copy_usage (stdout, 0);
3406
 
3407
        default:
3408
          copy_usage (stderr, 1);
3409
        }
3410
    }
3411
 
3412
  if (formats_info)
3413
    {
3414
      display_info ();
3415
      return 0;
3416
    }
3417
 
3418
  if (show_version)
3419
    print_version ("objcopy");
3420
 
3421
  if (copy_byte >= interleave)
3422
    fatal (_("byte number must be less than interleave"));
3423
 
3424
  if (optind == argc || optind + 2 < argc)
3425
    copy_usage (stderr, 1);
3426
 
3427
  input_filename = argv[optind];
3428
  if (optind + 1 < argc)
3429
    output_filename = argv[optind + 1];
3430
 
3431
  /* Default is to strip no symbols.  */
3432
  if (strip_symbols == STRIP_UNDEF && discard_locals == LOCALS_UNDEF)
3433
    strip_symbols = STRIP_NONE;
3434
 
3435
  if (output_target == NULL)
3436
    output_target = input_target;
3437
 
3438
  if (binary_architecture != NULL)
3439
    {
3440
      if (input_target && strcmp (input_target, "binary") == 0)
3441
        {
3442
          const bfd_arch_info_type * temp_arch_info;
3443
 
3444
          temp_arch_info = bfd_scan_arch (binary_architecture);
3445
 
3446
          if (temp_arch_info != NULL)
3447
            {
3448
              bfd_external_binary_architecture = temp_arch_info->arch;
3449
              bfd_external_machine             = temp_arch_info->mach;
3450
            }
3451
          else
3452
            fatal (_("architecture %s unknown"), binary_architecture);
3453
        }
3454
      else
3455
        {
3456
          non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
3457
          non_fatal (_(" Argument %s ignored"), binary_architecture);
3458
        }
3459
    }
3460
 
3461
  if (preserve_dates)
3462
    if (stat (input_filename, & statbuf) < 0)
3463
      fatal (_("warning: could not locate '%s'.  System error message: %s"),
3464
             input_filename, strerror (errno));
3465
 
3466
  /* If there is no destination file, or the source and destination files
3467
     are the same, then create a temp and rename the result into the input.  */
3468
  if (output_filename == NULL || strcmp (input_filename, output_filename) == 0)
3469
    tmpname = make_tempname (input_filename);
3470
  else
3471
    tmpname = output_filename;
3472
 
3473
  if (tmpname == NULL)
3474
    fatal (_("warning: could not create temporary file whilst copying '%s', (error: %s)"),
3475
           input_filename, strerror (errno));
3476
 
3477
  copy_file (input_filename, tmpname, input_target, output_target);
3478
  if (status == 0)
3479
    {
3480
      if (preserve_dates)
3481
        set_times (tmpname, &statbuf);
3482
      if (tmpname != output_filename)
3483
        smart_rename (tmpname, input_filename, preserve_dates);
3484
    }
3485
  else
3486
    unlink_if_ordinary (tmpname);
3487
 
3488
  if (change_warn)
3489
    {
3490
      for (p = change_sections; p != NULL; p = p->next)
3491
        {
3492
          if (! p->used)
3493
            {
3494
              if (p->change_vma != CHANGE_IGNORE)
3495
                {
3496
                  char buff [20];
3497
 
3498
                  sprintf_vma (buff, p->vma_val);
3499
 
3500
                  /* xgettext:c-format */
3501
                  non_fatal (_("%s %s%c0x%s never used"),
3502
                             "--change-section-vma",
3503
                             p->name,
3504
                             p->change_vma == CHANGE_SET ? '=' : '+',
3505
                             buff);
3506
                }
3507
 
3508
              if (p->change_lma != CHANGE_IGNORE)
3509
                {
3510
                  char buff [20];
3511
 
3512
                  sprintf_vma (buff, p->lma_val);
3513
 
3514
                  /* xgettext:c-format */
3515
                  non_fatal (_("%s %s%c0x%s never used"),
3516
                             "--change-section-lma",
3517
                             p->name,
3518
                             p->change_lma == CHANGE_SET ? '=' : '+',
3519
                             buff);
3520
                }
3521
            }
3522
        }
3523
    }
3524
 
3525
  return 0;
3526
}
3527
 
3528
int
3529
main (int argc, char *argv[])
3530
{
3531
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3532
  setlocale (LC_MESSAGES, "");
3533
#endif
3534
#if defined (HAVE_SETLOCALE)
3535
  setlocale (LC_CTYPE, "");
3536
#endif
3537
  bindtextdomain (PACKAGE, LOCALEDIR);
3538
  textdomain (PACKAGE);
3539
 
3540
  program_name = argv[0];
3541
  xmalloc_set_program_name (program_name);
3542
 
3543
  START_PROGRESS (program_name, 0);
3544
 
3545
  expandargv (&argc, &argv);
3546
 
3547
  strip_symbols = STRIP_UNDEF;
3548
  discard_locals = LOCALS_UNDEF;
3549
 
3550
  bfd_init ();
3551
  set_default_bfd_target ();
3552
 
3553
  if (is_strip < 0)
3554
    {
3555
      int i = strlen (program_name);
3556
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
3557
      /* Drop the .exe suffix, if any.  */
3558
      if (i > 4 && FILENAME_CMP (program_name + i - 4, ".exe") == 0)
3559
        {
3560
          i -= 4;
3561
          program_name[i] = '\0';
3562
        }
3563
#endif
3564
      is_strip = (i >= 5 && FILENAME_CMP (program_name + i - 5, "strip") == 0);
3565
    }
3566
 
3567
  create_symbol_htabs ();
3568
 
3569
  if (is_strip)
3570
    strip_main (argc, argv);
3571
  else
3572
    copy_main (argc, argv);
3573
 
3574
  END_PROGRESS (program_name);
3575
 
3576
  return status;
3577
}

powered by: WebSVN 2.1.0

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