objcopy.c 161 KB
Newer Older
Richard Henderson's avatar
Richard Henderson committed
1
/* objcopy.c -- copy object file from input to output, optionally massaging it.
2
   Copyright (C) 1991-2019 Free Software Foundation, Inc.
Richard Henderson's avatar
Richard Henderson committed
3
4
5
6
7

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
Richard Henderson's avatar
Richard Henderson committed
9
10
11
12
13
14
15
16
17
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
Nick Clifton's avatar
Nick Clifton committed
18
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */
Richard Henderson's avatar
Richard Henderson committed
20

Alan Modra's avatar
   
Alan Modra committed
21
#include "sysdep.h"
Richard Henderson's avatar
Richard Henderson committed
22
23
24
25
#include "bfd.h"
#include "progress.h"
#include "getopt.h"
#include "libiberty.h"
Alan Modra's avatar
   
Alan Modra committed
26
#include "bucomm.h"
Richard Henderson's avatar
Richard Henderson committed
27
#include "budbg.h"
28
#include "filenames.h"
29
#include "fnmatch.h"
30
#include "elf-bfd.h"
Dave Korn's avatar
Dave Korn committed
31
32
#include "coff/internal.h"
#include "libcoff.h"
33
#include "safe-ctype.h"
Richard Henderson's avatar
Richard Henderson committed
34

H.J. Lu's avatar
bfd/    
H.J. Lu committed
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
   header in generic PE code.  */
#include "coff/i386.h"
#include "coff/pe.h"

static bfd_vma pe_file_alignment = (bfd_vma) -1;
static bfd_vma pe_heap_commit = (bfd_vma) -1;
static bfd_vma pe_heap_reserve = (bfd_vma) -1;
static bfd_vma pe_image_base = (bfd_vma) -1;
static bfd_vma pe_section_alignment = (bfd_vma) -1;
static bfd_vma pe_stack_commit = (bfd_vma) -1;
static bfd_vma pe_stack_reserve = (bfd_vma) -1;
static short pe_subsystem = -1;
static short pe_major_subsystem_version = -1;
static short pe_minor_subsystem_version = -1;

Nick Clifton's avatar
Nick Clifton committed
51
struct is_specified_symbol_predicate_data
Richard Henderson's avatar
Richard Henderson committed
52
{
53
  const char *  name;
Nick Clifton's avatar
Nick Clifton committed
54
  bfd_boolean	found;
Richard Henderson's avatar
Richard Henderson committed
55
56
};

57
/* A node includes symbol name mapping to support redefine_sym.  */
Alan Modra's avatar
Alan Modra committed
58
59
60
61
62
63
struct redefine_node
{
  char *source;
  char *target;
};

64
65
66
67
68
69
70
71
72
73
struct addsym_node
{
  struct addsym_node *next;
  char *    symdef;
  long      symval;
  flagword  flags;
  char *    section;
  char *    othersym;
};

74
75
76
77
78
79
80
81
82
83
typedef struct section_rename
{
  const char *            old_name;
  const char *            new_name;
  flagword                flags;
  struct section_rename * next;
}
section_rename;

/* List of sections to be renamed.  */
Nick Clifton's avatar
Nick Clifton committed
84
static section_rename *section_rename_list;
85

Nick Clifton's avatar
Nick Clifton committed
86
87
static asymbol **isympp = NULL;	/* Input symbols.  */
static asymbol **osympp = NULL;	/* Output symbols that survive stripping.  */
Richard Henderson's avatar
Richard Henderson committed
88

89
/* If `copy_byte' >= 0, copy 'copy_width' byte(s) of every `interleave' bytes.  */
Richard Henderson's avatar
Richard Henderson committed
90
static int copy_byte = -1;
91
92
static int interleave = 0; /* Initialised to 4 in copy_main().  */
static int copy_width = 1;
Richard Henderson's avatar
Richard Henderson committed
93

94
95
static bfd_boolean verbose;		/* Print file and target names.  */
static bfd_boolean preserve_dates;	/* Preserve input file timestamp.  */
Roland McGrath's avatar
Roland McGrath committed
96
static int deterministic = -1;		/* Enable deterministic archives.  */
97
98
99
100
101
static int status = 0;			/* Exit status.  */

static bfd_boolean    merge_notes = FALSE;	/* Merge note sections.  */
static bfd_byte *     merged_notes = NULL;	/* Contents on note section undergoing a merge.  */
static bfd_size_type  merged_size = 0;		/* New, smaller size of the merged note section.  */
Richard Henderson's avatar
Richard Henderson committed
102
103

enum strip_action
104
105
106
107
108
109
110
111
112
113
{
  STRIP_UNDEF,
  STRIP_NONE,		/* Don't strip.  */
  STRIP_DEBUG,		/* Strip all debugger symbols.  */
  STRIP_UNNEEDED,	/* Strip unnecessary symbols.  */
  STRIP_NONDEBUG,	/* Strip everything but debug info.  */
  STRIP_DWO,		/* Strip all DWO info.  */
  STRIP_NONDWO,		/* Strip everything but DWO info.  */
  STRIP_ALL		/* Strip all symbols.  */
};
Richard Henderson's avatar
Richard Henderson committed
114

Kazu Hirata's avatar
Kazu Hirata committed
115
/* Which symbols to remove.  */
116
static enum strip_action strip_symbols = STRIP_UNDEF;
Richard Henderson's avatar
Richard Henderson committed
117
118

enum locals_action
119
120
121
122
123
{
  LOCALS_UNDEF,
  LOCALS_START_L,	/* Discard locals starting with L.  */
  LOCALS_ALL		/* Discard all locals.  */
};
Richard Henderson's avatar
Richard Henderson committed
124
125
126
127
128
129
130

/* Which local symbols to remove.  Overrides STRIP_ALL.  */
static enum locals_action discard_locals;

/* Structure used to hold lists of sections and actions to take.  */
struct section_list
{
131
  struct section_list * next;	   /* Next section to change.  */
Nick Clifton's avatar
Nick Clifton committed
132
  const char *		pattern;   /* Section name pattern.  */
133
  bfd_boolean		used;	   /* Whether this entry was used.  */
Nick Clifton's avatar
Nick Clifton committed
134
135
136
137
138
139
140
141
142
143
144

  unsigned int          context;   /* What to do with matching sections.  */
  /* Flag bits used in the context field.
     COPY and REMOVE are mutually exlusive.  SET and ALTER are mutually exclusive.  */
#define SECTION_CONTEXT_REMOVE    (1 << 0) /* Remove this section.  */
#define SECTION_CONTEXT_COPY      (1 << 1) /* Copy this section, delete all non-copied section.  */
#define SECTION_CONTEXT_SET_VMA   (1 << 2) /* Set the sections' VMA address.  */
#define SECTION_CONTEXT_ALTER_VMA (1 << 3) /* Increment or decrement the section's VMA address.  */
#define SECTION_CONTEXT_SET_LMA   (1 << 4) /* Set the sections' LMA address.  */
#define SECTION_CONTEXT_ALTER_LMA (1 << 5) /* Increment or decrement the section's LMA address.  */
#define SECTION_CONTEXT_SET_FLAGS (1 << 6) /* Set the section's flags.  */
145
#define SECTION_CONTEXT_REMOVE_RELOCS (1 << 7) /* Remove relocations for this section.  */
146
#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 8) /* Set alignment for section.  */
Nick Clifton's avatar
Nick Clifton committed
147

148
149
150
  bfd_vma		vma_val;   /* Amount to change by or set to.  */
  bfd_vma		lma_val;   /* Amount to change by or set to.  */
  flagword		flags;	   /* What to set the section flags to.	 */
151
  unsigned int	        alignment; /* Alignment of output section.  */
Richard Henderson's avatar
Richard Henderson committed
152
153
154
};

static struct section_list *change_sections;
155

156
157
/* TRUE if some sections are to be removed.  */
static bfd_boolean sections_removed;
158

159
160
/* TRUE if only some sections are to be copied.  */
static bfd_boolean sections_copied;
Richard Henderson's avatar
Richard Henderson committed
161
162
163

/* Changes to the start address.  */
static bfd_vma change_start = 0;
164
static bfd_boolean set_start_set = FALSE;
Richard Henderson's avatar
Richard Henderson committed
165
166
167
168
169
170
static bfd_vma set_start;

/* Changes to section addresses.  */
static bfd_vma change_section_address = 0;

/* Filling gaps between sections.  */
171
static bfd_boolean gap_fill_set = FALSE;
Richard Henderson's avatar
Richard Henderson committed
172
173
174
static bfd_byte gap_fill = 0;

/* Pad to a given address.  */
175
static bfd_boolean pad_to_set = FALSE;
Richard Henderson's avatar
Richard Henderson committed
176
177
static bfd_vma pad_to;

178
179
/* Use alternative machine code?  */
static unsigned long use_alt_mach_code = 0;
180

181
182
183
184
/* Output BFD flags user wants to set or clear */
static flagword bfd_flags_to_set;
static flagword bfd_flags_to_clear;

Richard Henderson's avatar
Richard Henderson committed
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/* List of sections to add.  */
struct section_add
{
  /* Next section to add.  */
  struct section_add *next;
  /* Name of section to add.  */
  const char *name;
  /* Name of file holding section contents.  */
  const char *filename;
  /* Size of file.  */
  size_t size;
  /* Contents of file.  */
  bfd_byte *contents;
  /* BFD section, after it has been added.  */
  asection *section;
};

202
/* List of sections to add to the output BFD.  */
Richard Henderson's avatar
Richard Henderson committed
203
204
static struct section_add *add_sections;

205
206
207
/* List of sections to update in the output BFD.  */
static struct section_add *update_sections;

208
209
210
/* List of sections to dump from the output BFD.  */
static struct section_add *dump_sections;

211
212
213
214
/* If non-NULL the argument to --add-gnu-debuglink.
   This should be the filename to store in the .gnu_debuglink section.  */
static const char * gnu_debuglink_filename = NULL;

Richard Henderson's avatar
Richard Henderson committed
215
/* Whether to convert debugging information.  */
216
static bfd_boolean convert_debugging = FALSE;
Richard Henderson's avatar
Richard Henderson committed
217

218
219
220
/* Whether to compress/decompress DWARF debug sections.  */
static enum
{
221
222
223
224
225
226
  nothing = 0,
  compress = 1 << 0,
  compress_zlib = compress | 1 << 1,
  compress_gnu_zlib = compress | 1 << 2,
  compress_gabi_zlib = compress | 1 << 3,
  decompress = 1 << 4
227
228
} do_debug_sections = nothing;

H.J. Lu's avatar
H.J. Lu committed
229
/* Whether to generate ELF common symbols with the STT_COMMON type.  */
230
static enum bfd_link_elf_stt_common do_elf_stt_common = unchanged;
H.J. Lu's avatar
H.J. Lu committed
231

Richard Henderson's avatar
Richard Henderson committed
232
/* Whether to change the leading character in symbol names.  */
233
static bfd_boolean change_leading_char = FALSE;
Richard Henderson's avatar
Richard Henderson committed
234
235

/* Whether to remove the leading character from global symbol names.  */
236
static bfd_boolean remove_leading_char = FALSE;
Richard Henderson's avatar
Richard Henderson committed
237

238
/* Whether to permit wildcard in symbol comparison.  */
239
240
static bfd_boolean wildcard = FALSE;

Richard Sandiford's avatar
Richard Sandiford committed
241
242
243
/* True if --localize-hidden is in effect.  */
static bfd_boolean localize_hidden = FALSE;

244
245
/* List of symbols to strip, keep, localize, keep-global, weaken,
   or redefine.  */
Nick Clifton's avatar
Nick Clifton committed
246
247
248
249
250
251
252
static htab_t strip_specific_htab = NULL;
static htab_t strip_unneeded_htab = NULL;
static htab_t keep_specific_htab = NULL;
static htab_t localize_specific_htab = NULL;
static htab_t globalize_specific_htab = NULL;
static htab_t keepglobal_specific_htab = NULL;
static htab_t weaken_specific_htab = NULL;
253
254
static htab_t redefine_specific_htab = NULL;
static htab_t redefine_specific_reverse_htab = NULL;
255
256
static struct addsym_node *add_sym_list = NULL, **add_sym_tail = &add_sym_list;
static int add_symbols = 0;
Richard Henderson's avatar
Richard Henderson committed
257

258
259
260
261
262
263
264
265
static char *strip_specific_buffer = NULL;
static char *strip_unneeded_buffer = NULL;
static char *keep_specific_buffer = NULL;
static char *localize_specific_buffer = NULL;
static char *globalize_specific_buffer = NULL;
static char *keepglobal_specific_buffer = NULL;
static char *weaken_specific_buffer = NULL;

266
267
/* If this is TRUE, we weaken global symbols (set BSF_WEAK).  */
static bfd_boolean weaken = FALSE;
Richard Henderson's avatar
Richard Henderson committed
268

Jan Beulich's avatar
Jan Beulich committed
269
270
271
/* If this is TRUE, we retain BSF_FILE symbols.  */
static bfd_boolean keep_file_symbols = FALSE;

272
273
274
275
276
/* Prefix symbols/sections.  */
static char *prefix_symbols_string = 0;
static char *prefix_sections_string = 0;
static char *prefix_alloc_sections_string = 0;

Richard Sandiford's avatar
Richard Sandiford committed
277
278
279
/* True if --extract-symbol was passed on the command line.  */
static bfd_boolean extract_symbol = FALSE;

280
281
282
283
/* If `reverse_bytes' is nonzero, then reverse the order of every chunk
   of <reverse_bytes> bytes within each output section.  */
static int reverse_bytes = 0;

Dave Korn's avatar
Dave Korn committed
284
285
286
/* For Coff objects, we may want to allow or disallow long section names,
   or preserve them where found in the inputs.  Debug info relies on them.  */
enum long_section_name_handling
287
288
289
290
291
{
  DISABLE,
  ENABLE,
  KEEP
};
Dave Korn's avatar
Dave Korn committed
292
293
294
295

/* The default long section handling mode is to preserve them.
   This is also the only behaviour for 'strip'.  */
static enum long_section_name_handling long_section_names = KEEP;
296

Richard Henderson's avatar
Richard Henderson committed
297
/* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
Nick Clifton's avatar
Nick Clifton committed
298
enum command_line_switch
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
{
  OPTION_ADD_SECTION=150,
  OPTION_ADD_GNU_DEBUGLINK,
  OPTION_ADD_SYMBOL,
  OPTION_ALT_MACH_CODE,
  OPTION_CHANGE_ADDRESSES,
  OPTION_CHANGE_LEADING_CHAR,
  OPTION_CHANGE_SECTION_ADDRESS,
  OPTION_CHANGE_SECTION_LMA,
  OPTION_CHANGE_SECTION_VMA,
  OPTION_CHANGE_START,
  OPTION_CHANGE_WARNINGS,
  OPTION_COMPRESS_DEBUG_SECTIONS,
  OPTION_DEBUGGING,
  OPTION_DECOMPRESS_DEBUG_SECTIONS,
  OPTION_DUMP_SECTION,
H.J. Lu's avatar
H.J. Lu committed
315
  OPTION_ELF_STT_COMMON,
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  OPTION_EXTRACT_DWO,
  OPTION_EXTRACT_SYMBOL,
  OPTION_FILE_ALIGNMENT,
  OPTION_FORMATS_INFO,
  OPTION_GAP_FILL,
  OPTION_GLOBALIZE_SYMBOL,
  OPTION_GLOBALIZE_SYMBOLS,
  OPTION_HEAP,
  OPTION_IMAGE_BASE,
  OPTION_IMPURE,
  OPTION_INTERLEAVE_WIDTH,
  OPTION_KEEPGLOBAL_SYMBOLS,
  OPTION_KEEP_FILE_SYMBOLS,
  OPTION_KEEP_SYMBOLS,
  OPTION_LOCALIZE_HIDDEN,
  OPTION_LOCALIZE_SYMBOLS,
  OPTION_LONG_SECTION_NAMES,
333
  OPTION_MERGE_NOTES,
334
  OPTION_NO_MERGE_NOTES,
335
336
337
338
339
340
341
342
343
344
345
  OPTION_NO_CHANGE_WARNINGS,
  OPTION_ONLY_KEEP_DEBUG,
  OPTION_PAD_TO,
  OPTION_PREFIX_ALLOC_SECTIONS,
  OPTION_PREFIX_SECTIONS,
  OPTION_PREFIX_SYMBOLS,
  OPTION_PURE,
  OPTION_READONLY_TEXT,
  OPTION_REDEFINE_SYM,
  OPTION_REDEFINE_SYMS,
  OPTION_REMOVE_LEADING_CHAR,
346
  OPTION_REMOVE_RELOCS,
347
348
  OPTION_RENAME_SECTION,
  OPTION_REVERSE_BYTES,
349
  OPTION_PE_SECTION_ALIGNMENT,
350
  OPTION_SET_SECTION_FLAGS,
351
  OPTION_SET_SECTION_ALIGNMENT,
352
353
354
355
356
357
358
359
360
361
362
  OPTION_SET_START,
  OPTION_SREC_FORCES3,
  OPTION_SREC_LEN,
  OPTION_STACK,
  OPTION_STRIP_DWO,
  OPTION_STRIP_SYMBOLS,
  OPTION_STRIP_UNNEEDED,
  OPTION_STRIP_UNNEEDED_SYMBOL,
  OPTION_STRIP_UNNEEDED_SYMBOLS,
  OPTION_SUBSYSTEM,
  OPTION_UPDATE_SECTION,
363
  OPTION_VERILOG_DATA_WIDTH,
364
365
366
367
  OPTION_WEAKEN,
  OPTION_WEAKEN_SYMBOLS,
  OPTION_WRITABLE_TEXT
};
Richard Henderson's avatar
Richard Henderson committed
368
369
370
371
372

/* Options to handle if running as "strip".  */

static struct option strip_options[] =
{
Roland McGrath's avatar
Roland McGrath committed
373
  {"disable-deterministic-archives", no_argument, 0, 'U'},
Richard Henderson's avatar
Richard Henderson committed
374
375
  {"discard-all", no_argument, 0, 'x'},
  {"discard-locals", no_argument, 0, 'X'},
376
  {"enable-deterministic-archives", no_argument, 0, 'D'},
Richard Henderson's avatar
Richard Henderson committed
377
378
  {"format", required_argument, 0, 'F'}, /* Obsolete */
  {"help", no_argument, 0, 'h'},
Nick Clifton's avatar
Nick Clifton committed
379
  {"info", no_argument, 0, OPTION_FORMATS_INFO},
Richard Henderson's avatar
Richard Henderson committed
380
381
  {"input-format", required_argument, 0, 'I'}, /* Obsolete */
  {"input-target", required_argument, 0, 'I'},
Jan Beulich's avatar
Jan Beulich committed
382
  {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
Richard Henderson's avatar
Richard Henderson committed
383
  {"keep-symbol", required_argument, 0, 'K'},
384
385
  {"merge-notes", no_argument, 0, 'M'},
  {"no-merge-notes", no_argument, 0, OPTION_NO_MERGE_NOTES},
Nick Clifton's avatar
Nick Clifton committed
386
  {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
387
  {"output-file", required_argument, 0, 'o'},
Richard Henderson's avatar
Richard Henderson committed
388
389
390
391
  {"output-format", required_argument, 0, 'O'},	/* Obsolete */
  {"output-target", required_argument, 0, 'O'},
  {"preserve-dates", no_argument, 0, 'p'},
  {"remove-section", required_argument, 0, 'R'},
392
  {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
Richard Henderson's avatar
Richard Henderson committed
393
394
  {"strip-all", no_argument, 0, 's'},
  {"strip-debug", no_argument, 0, 'S'},
Cary Coutant's avatar
Cary Coutant committed
395
  {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
Richard Henderson's avatar
Richard Henderson committed
396
  {"strip-symbol", required_argument, 0, 'N'},
397
  {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
Richard Henderson's avatar
Richard Henderson committed
398
399
400
  {"target", required_argument, 0, 'F'},
  {"verbose", no_argument, 0, 'v'},
  {"version", no_argument, 0, 'V'},
401
  {"wildcard", no_argument, 0, 'w'},
Richard Henderson's avatar
Richard Henderson committed
402
403
404
405
406
407
408
  {0, no_argument, 0, 0}
};

/* Options to handle if running as "objcopy".  */

static struct option copy_options[] =
{
409
  {"add-gnu-debuglink", required_argument, 0, OPTION_ADD_GNU_DEBUGLINK},
Richard Henderson's avatar
Richard Henderson committed
410
  {"add-section", required_argument, 0, OPTION_ADD_SECTION},
411
412
  {"add-symbol", required_argument, 0, OPTION_ADD_SYMBOL},
  {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
Richard Henderson's avatar
Richard Henderson committed
413
414
415
  {"adjust-start", required_argument, 0, OPTION_CHANGE_START},
  {"adjust-vma", required_argument, 0, OPTION_CHANGE_ADDRESSES},
  {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
416
  {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE},
417
  {"binary-architecture", required_argument, 0, 'B'},
Richard Henderson's avatar
Richard Henderson committed
418
419
420
421
422
423
424
425
  {"byte", required_argument, 0, 'b'},
  {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES},
  {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
  {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS},
  {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA},
  {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA},
  {"change-start", required_argument, 0, OPTION_CHANGE_START},
  {"change-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS},
426
  {"compress-debug-sections", optional_argument, 0, OPTION_COMPRESS_DEBUG_SECTIONS},
Richard Henderson's avatar
Richard Henderson committed
427
  {"debugging", no_argument, 0, OPTION_DEBUGGING},
428
  {"decompress-debug-sections", no_argument, 0, OPTION_DECOMPRESS_DEBUG_SECTIONS},
Roland McGrath's avatar
Roland McGrath committed
429
  {"disable-deterministic-archives", no_argument, 0, 'U'},
Richard Henderson's avatar
Richard Henderson committed
430
431
  {"discard-all", no_argument, 0, 'x'},
  {"discard-locals", no_argument, 0, 'X'},
432
  {"dump-section", required_argument, 0, OPTION_DUMP_SECTION},
H.J. Lu's avatar
H.J. Lu committed
433
  {"elf-stt-common", required_argument, 0, OPTION_ELF_STT_COMMON},
434
  {"enable-deterministic-archives", no_argument, 0, 'D'},
Cary Coutant's avatar
Cary Coutant committed
435
  {"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
Richard Sandiford's avatar
Richard Sandiford committed
436
  {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
437
  {"file-alignment", required_argument, 0, OPTION_FILE_ALIGNMENT},
Richard Henderson's avatar
Richard Henderson committed
438
439
  {"format", required_argument, 0, 'F'}, /* Obsolete */
  {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
440
441
  {"globalize-symbol", required_argument, 0, OPTION_GLOBALIZE_SYMBOL},
  {"globalize-symbols", required_argument, 0, OPTION_GLOBALIZE_SYMBOLS},
442
  {"heap", required_argument, 0, OPTION_HEAP},
Richard Henderson's avatar
Richard Henderson committed
443
  {"help", no_argument, 0, 'h'},
444
  {"image-base", required_argument, 0 , OPTION_IMAGE_BASE},
445
  {"impure", no_argument, 0, OPTION_IMPURE},
Nick Clifton's avatar
Nick Clifton committed
446
  {"info", no_argument, 0, OPTION_FORMATS_INFO},
Richard Henderson's avatar
Richard Henderson committed
447
448
  {"input-format", required_argument, 0, 'I'}, /* Obsolete */
  {"input-target", required_argument, 0, 'I'},
449
450
  {"interleave", optional_argument, 0, 'i'},
  {"interleave-width", required_argument, 0, OPTION_INTERLEAVE_WIDTH},
Jan Beulich's avatar
Jan Beulich committed
451
  {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
452
453
  {"keep-global-symbol", required_argument, 0, 'G'},
  {"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
Richard Henderson's avatar
Richard Henderson committed
454
  {"keep-symbol", required_argument, 0, 'K'},
455
  {"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
Richard Sandiford's avatar
Richard Sandiford committed
456
  {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
457
458
  {"localize-symbol", required_argument, 0, 'L'},
  {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
Dave Korn's avatar
Dave Korn committed
459
  {"long-section-names", required_argument, 0, OPTION_LONG_SECTION_NAMES},
460
  {"merge-notes", no_argument, 0, 'M'},
461
  {"no-merge-notes", no_argument, 0, OPTION_NO_MERGE_NOTES},
Richard Henderson's avatar
Richard Henderson committed
462
463
  {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
  {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
Nick Clifton's avatar
Nick Clifton committed
464
  {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
465
  {"only-section", required_argument, 0, 'j'},
Richard Henderson's avatar
Richard Henderson committed
466
467
468
  {"output-format", required_argument, 0, 'O'},	/* Obsolete */
  {"output-target", required_argument, 0, 'O'},
  {"pad-to", required_argument, 0, OPTION_PAD_TO},
469
  {"prefix-alloc-sections", required_argument, 0, OPTION_PREFIX_ALLOC_SECTIONS},
470
471
  {"prefix-sections", required_argument, 0, OPTION_PREFIX_SECTIONS},
  {"prefix-symbols", required_argument, 0, OPTION_PREFIX_SYMBOLS},
Richard Henderson's avatar
Richard Henderson committed
472
  {"preserve-dates", no_argument, 0, 'p'},
473
474
  {"pure", no_argument, 0, OPTION_PURE},
  {"readonly-text", no_argument, 0, OPTION_READONLY_TEXT},
475
  {"redefine-sym", required_argument, 0, OPTION_REDEFINE_SYM},
476
  {"redefine-syms", required_argument, 0, OPTION_REDEFINE_SYMS},
Richard Henderson's avatar
Richard Henderson committed
477
478
  {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
  {"remove-section", required_argument, 0, 'R'},
479
  {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
480
  {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
481
  {"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
482
  {"section-alignment", required_argument, 0, OPTION_PE_SECTION_ALIGNMENT},
Richard Henderson's avatar
Richard Henderson committed
483
  {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
484
  {"set-section-alignment", required_argument, 0, OPTION_SET_SECTION_ALIGNMENT},
Richard Henderson's avatar
Richard Henderson committed
485
  {"set-start", required_argument, 0, OPTION_SET_START},
486
  {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
487
488
  {"srec-len", required_argument, 0, OPTION_SREC_LEN},
  {"stack", required_argument, 0, OPTION_STACK},
Richard Henderson's avatar
Richard Henderson committed
489
490
  {"strip-all", no_argument, 0, 'S'},
  {"strip-debug", no_argument, 0, 'g'},
Cary Coutant's avatar
Cary Coutant committed
491
  {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
492
493
  {"strip-symbol", required_argument, 0, 'N'},
  {"strip-symbols", required_argument, 0, OPTION_STRIP_SYMBOLS},
Richard Henderson's avatar
Richard Henderson committed
494
  {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
Jan Beulich's avatar
Jan Beulich committed
495
496
  {"strip-unneeded-symbol", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOL},
  {"strip-unneeded-symbols", required_argument, 0, OPTION_STRIP_UNNEEDED_SYMBOLS},
497
  {"subsystem", required_argument, 0, OPTION_SUBSYSTEM},
Richard Henderson's avatar
Richard Henderson committed
498
  {"target", required_argument, 0, 'F'},
499
  {"update-section", required_argument, 0, OPTION_UPDATE_SECTION},
Richard Henderson's avatar
Richard Henderson committed
500
  {"verbose", no_argument, 0, 'v'},
501
  {"verilog-data-width", required_argument, 0, OPTION_VERILOG_DATA_WIDTH},
Richard Henderson's avatar
Richard Henderson committed
502
503
504
  {"version", no_argument, 0, 'V'},
  {"weaken", no_argument, 0, OPTION_WEAKEN},
  {"weaken-symbol", required_argument, 0, 'W'},
505
  {"weaken-symbols", required_argument, 0, OPTION_WEAKEN_SYMBOLS},
506
  {"wildcard", no_argument, 0, 'w'},
507
  {"writable-text", no_argument, 0, OPTION_WRITABLE_TEXT},
Richard Henderson's avatar
Richard Henderson committed
508
509
510
511
512
513
514
515
  {0, no_argument, 0, 0}
};

/* IMPORTS */
extern char *program_name;

/* This flag distinguishes between strip and objcopy:
   1 means this is 'strip'; 0 means this is 'objcopy'.
Kazu Hirata's avatar
Kazu Hirata committed
516
   -1 means if we should use argv[0] to decide.  */
Richard Henderson's avatar
Richard Henderson committed
517
518
extern int is_strip;

Pedro Alves's avatar
Pedro Alves committed
519
/* The maximum length of an S record.  This variable is defined in srec.c
520
   and can be modified by the --srec-len parameter.  */
Pedro Alves's avatar
Pedro Alves committed
521
extern unsigned int _bfd_srec_len;
522
523

/* Restrict the generation of Srecords to type S3 only.
Pedro Alves's avatar
Pedro Alves committed
524
   This variable is defined in bfd/srec.c and can be toggled
525
   on by the --srec-forceS3 command line switch.  */
Pedro Alves's avatar
Pedro Alves committed
526
extern bfd_boolean _bfd_srec_forceS3;
Richard Henderson's avatar
Richard Henderson committed
527

528
529
530
531
532
/* Width of data in bytes for verilog output.
   This variable is declared in bfd/verilog.c and can be modified by
   the --verilog-data-width parameter.  */
extern unsigned int VerilogDataWidth;

533
534
/* Forward declarations.  */
static void setup_section (bfd *, asection *, void *);
Bob Wilson's avatar
Bob Wilson committed
535
static void setup_bfd_headers (bfd *, bfd *);
H.J. Lu's avatar
H.J. Lu committed
536
static void copy_relocations_in_section (bfd *, asection *, void *);
537
538
539
540
541
542
static void copy_section (bfd *, asection *, void *);
static void get_sections (bfd *, asection *, void *);
static int compare_section_lma (const void *, const void *);
static void mark_symbols_used_in_relocations (bfd *, asection *, void *);
static bfd_boolean write_debugging_info (bfd *, void *, long *, asymbol ***);
static const char *lookup_sym_redefinition (const char *);
Alan Modra's avatar
Alan Modra committed
543
static const char *find_section_rename (const char *, flagword *);
544

545
ATTRIBUTE_NORETURN static void
Nick Clifton's avatar
Nick Clifton committed
546
copy_usage (FILE *stream, int exit_status)
Richard Henderson's avatar
Richard Henderson committed
547
{
548
549
  fprintf (stream, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name);
  fprintf (stream, _(" Copies a binary file, possibly transforming it in the process\n"));
550
  fprintf (stream, _(" The options are:\n"));
Richard Henderson's avatar
Richard Henderson committed
551
  fprintf (stream, _("\
Nick Clifton's avatar
Nick Clifton committed
552
553
  -I --input-target <bfdname>      Assume input file is in format <bfdname>\n\
  -O --output-target <bfdname>     Create an output file in format <bfdname>\n\
554
  -B --binary-architecture <arch>  Set output arch, when input is arch-less\n\
Nick Clifton's avatar
Nick Clifton committed
555
556
  -F --target <bfdname>            Set both input and output format to <bfdname>\n\
     --debugging                   Convert debugging information, if possible\n\
Roland McGrath's avatar
Roland McGrath committed
557
558
559
560
561
562
563
564
565
  -p --preserve-dates              Copy modified/access timestamps to the output\n"));
  if (DEFAULT_AR_DETERMINISTIC)
    fprintf (stream, _("\
  -D --enable-deterministic-archives\n\
                                   Produce deterministic output when stripping archives (default)\n\
  -U --disable-deterministic-archives\n\
                                   Disable -D behavior\n"));
  else
    fprintf (stream, _("\
566
567
  -D --enable-deterministic-archives\n\
                                   Produce deterministic output when stripping archives\n\
Roland McGrath's avatar
Roland McGrath committed
568
569
570
  -U --disable-deterministic-archives\n\
                                   Disable -D behavior (default)\n"));
  fprintf (stream, _("\
Nick Clifton's avatar
Nick Clifton committed
571
  -j --only-section <name>         Only copy section <name> into the output\n\
572
     --add-gnu-debuglink=<file>    Add section .gnu_debuglink linking to <file>\n\
Nick Clifton's avatar
Nick Clifton committed
573
  -R --remove-section <name>       Remove section <name> from the output\n\
574
     --remove-relocations <name>   Remove relocations from section <name>\n\
Nick Clifton's avatar
Nick Clifton committed
575
  -S --strip-all                   Remove all symbol and relocation information\n\
576
  -g --strip-debug                 Remove all debugging symbols & sections\n\
Cary Coutant's avatar
Cary Coutant committed
577
     --strip-dwo                   Remove all DWO sections\n\
Nick Clifton's avatar
Nick Clifton committed
578
579
     --strip-unneeded              Remove all symbols not needed by relocations\n\
  -N --strip-symbol <name>         Do not copy symbol <name>\n\
Jan Beulich's avatar
Jan Beulich committed
580
581
582
     --strip-unneeded-symbol <name>\n\
                                   Do not copy symbol <name> unless needed by\n\
                                     relocations\n\
583
     --only-keep-debug             Strip everything but the debug information\n\
Cary Coutant's avatar
Cary Coutant committed
584
     --extract-dwo                 Copy only DWO sections\n\
Richard Sandiford's avatar
Richard Sandiford committed
585
     --extract-symbol              Remove section contents but keep symbols\n\
586
  -K --keep-symbol <name>          Do not strip symbol <name>\n\
Jan Beulich's avatar
Jan Beulich committed
587
     --keep-file-symbols           Do not strip file symbol(s)\n\
Richard Sandiford's avatar
Richard Sandiford committed
588
     --localize-hidden             Turn all ELF hidden symbols into locals\n\
Nick Clifton's avatar
Nick Clifton committed
589
  -L --localize-symbol <name>      Force symbol <name> to be marked as a local\n\
590
     --globalize-symbol <name>     Force symbol <name> to be marked as a global\n\
591
  -G --keep-global-symbol <name>   Localize all symbols except <name>\n\
Nick Clifton's avatar
Nick Clifton committed
592
593
  -W --weaken-symbol <name>        Force symbol <name> to be marked as a weak\n\
     --weaken                      Force all global symbols to be marked as weak\n\
594
  -w --wildcard                    Permit wildcard in symbol comparison\n\
Nick Clifton's avatar
Nick Clifton committed
595
596
  -x --discard-all                 Remove all non-global symbols\n\
  -X --discard-locals              Remove any compiler-generated symbols\n\
H.J. Lu's avatar
H.J. Lu committed
597
  -i --interleave[=<number>]       Only copy N out of every <number> bytes\n\
598
     --interleave-width <number>   Set N for --interleave\n\
Nick Clifton's avatar
Nick Clifton committed
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  -b --byte <num>                  Select byte <num> in every interleaved block\n\
     --gap-fill <val>              Fill gaps between sections with <val>\n\
     --pad-to <addr>               Pad the last section up to address <addr>\n\
     --set-start <addr>            Set the start address to <addr>\n\
    {--change-start|--adjust-start} <incr>\n\
                                   Add <incr> to the start address\n\
    {--change-addresses|--adjust-vma} <incr>\n\
                                   Add <incr> to LMA, VMA and start addresses\n\
    {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>\n\
                                   Change LMA and VMA of section <name> by <val>\n\
     --change-section-lma <name>{=|+|-}<val>\n\
                                   Change the LMA of section <name> by <val>\n\
     --change-section-vma <name>{=|+|-}<val>\n\
                                   Change the VMA of section <name> by <val>\n\
    {--[no-]change-warnings|--[no-]adjust-warnings}\n\
                                   Warn if a named section does not exist\n\
     --set-section-flags <name>=<flags>\n\
                                   Set section <name>'s properties to <flags>\n\
617
618
     --set-section-alignment <name>=<align>\n\
                                   Set section <name>'s alignment to 2^<align> bytes\n\
Nick Clifton's avatar
Nick Clifton committed
619
     --add-section <name>=<file>   Add section <name> found in <file> to output\n\
620
621
622
     --update-section <name>=<file>\n\
                                   Update contents of section <name> with\n\
                                   contents found in <file>\n\
623
     --dump-section <name>=<file>  Dump the contents of section <name> into <file>\n\
624
     --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
Dave Korn's avatar
Dave Korn committed
625
626
     --long-section-names {enable|disable|keep}\n\
                                   Handle long section names in Coff objects.\n\
Nick Clifton's avatar
Nick Clifton committed
627
628
     --change-leading-char         Force output format's leading character style\n\
     --remove-leading-char         Remove leading character from global symbols\n\
629
     --reverse-bytes=<num>         Reverse <num> bytes at a time, in output sections with content\n\
Alan Modra's avatar
Alan Modra committed
630
     --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
631
632
     --redefine-syms <file>        --redefine-sym for all symbol pairs \n\
                                     listed in <file>\n\
633
634
     --srec-len <number>           Restrict the length of generated Srecords\n\
     --srec-forceS3                Restrict the type of generated Srecords to S3\n\
635
     --strip-symbols <file>        -N for all symbols listed in <file>\n\
Jan Beulich's avatar
Jan Beulich committed
636
637
638
     --strip-unneeded-symbols <file>\n\
                                   --strip-unneeded-symbol for all symbols listed\n\
                                     in <file>\n\
639
640
     --keep-symbols <file>         -K for all symbols listed in <file>\n\
     --localize-symbols <file>     -L for all symbols listed in <file>\n\
641
     --globalize-symbols <file>    --globalize-symbol for all in <file>\n\
642
643
     --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
     --weaken-symbols <file>       -W for all symbols listed in <file>\n\
644
     --add-symbol <name>=[<section>:]<value>[,<flags>]  Add a symbol\n\
645
     --alt-machine-code <index>    Use the target's <index>'th alternative machine\n\
646
647
648
649
     --writable-text               Mark the output text as writable\n\
     --readonly-text               Make the output text write protected\n\
     --pure                        Mark the output file as demand paged\n\
     --impure                      Mark the output file as impure\n\
650
651
652
653
654
     --prefix-symbols <prefix>     Add <prefix> to start of every symbol name\n\
     --prefix-sections <prefix>    Add <prefix> to start of every section name\n\
     --prefix-alloc-sections <prefix>\n\
                                   Add <prefix> to start of every allocatable\n\
                                     section name\n\
H.J. Lu's avatar
bfd/    
H.J. Lu committed
655
656
657
658
659
660
661
662
     --file-alignment <num>        Set PE file alignment to <num>\n\
     --heap <reserve>[,<commit>]   Set PE reserve/commit heap to <reserve>/\n\
                                   <commit>\n\
     --image-base <address>        Set PE image base to <address>\n\
     --section-alignment <num>     Set PE section alignment to <num>\n\
     --stack <reserve>[,<commit>]  Set PE reserve/commit stack to <reserve>/\n\
                                   <commit>\n\
     --subsystem <name>[:<version>]\n\
663
                                   Set PE subsystem to <name> [& <version>]\n\
664
665
     --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
                                   Compress DWARF debug sections using zlib\n\
666
     --decompress-debug-sections   Decompress DWARF debug sections using zlib\n\
H.J. Lu's avatar
H.J. Lu committed
667
668
     --elf-stt-common=[yes|no]     Generate ELF common symbols with STT_COMMON\n\
                                     type\n\
669
     --verilog-data-width <number> Specifies data width, in bytes, for verilog output\n\
670
  -M  --merge-notes                Remove redundant entries in note sections\n\
671
      --no-merge-notes             Do not attempt to remove redundant notes (default)\n\
Nick Clifton's avatar
Nick Clifton committed
672
  -v --verbose                     List all object files modified\n\
673
  @<file>                          Read options from <file>\n\
Nick Clifton's avatar
Nick Clifton committed
674
675
  -V --version                     Display this program's version number\n\
  -h --help                        Display this output\n\
Nick Clifton's avatar
Nick Clifton committed
676
     --info                        List object formats & architectures supported\n\
Nick Clifton's avatar
Nick Clifton committed
677
"));
Richard Henderson's avatar
Richard Henderson committed
678
  list_supported_targets (program_name, stream);
Joseph Myers's avatar
Joseph Myers committed
679
  if (REPORT_BUGS_TO[0] && exit_status == 0)
680
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
Richard Henderson's avatar
Richard Henderson committed
681
682
683
  exit (exit_status);
}

684
ATTRIBUTE_NORETURN static void
Nick Clifton's avatar
Nick Clifton committed
685
strip_usage (FILE *stream, int exit_status)
Richard Henderson's avatar
Richard Henderson committed
686
{
687
688
  fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
  fprintf (stream, _(" Removes symbols and sections from files\n"));
689
  fprintf (stream, _(" The options are:\n"));
Richard Henderson's avatar
Richard Henderson committed
690
  fprintf (stream, _("\
691
692
693
  -I --input-target=<bfdname>      Assume input file is in format <bfdname>\n\
  -O --output-target=<bfdname>     Create an output file in format <bfdname>\n\
  -F --target=<bfdname>            Set both input and output format to <bfdname>\n\
Nick Clifton's avatar
Nick Clifton committed
694
  -p --preserve-dates              Copy modified/access timestamps to the output\n\
Roland McGrath's avatar
Roland McGrath committed
695
696
697
698
699
700
701
702
703
"));
  if (DEFAULT_AR_DETERMINISTIC)
    fprintf (stream, _("\
  -D --enable-deterministic-archives\n\
                                   Produce deterministic output when stripping archives (default)\n\
  -U --disable-deterministic-archives\n\
                                   Disable -D behavior\n"));
  else
    fprintf (stream, _("\
704
705
  -D --enable-deterministic-archives\n\
                                   Produce deterministic output when stripping archives\n\
Roland McGrath's avatar
Roland McGrath committed
706
707
708
  -U --disable-deterministic-archives\n\
                                   Disable -D behavior (default)\n"));
  fprintf (stream, _("\
Andrew Stubbs's avatar
Andrew Stubbs committed
709
  -R --remove-section=<name>       Also remove section <name> from the output\n\
710
     --remove-relocations <name>   Remove relocations from section <name>\n\
Nick Clifton's avatar
Nick Clifton committed
711
  -s --strip-all                   Remove all symbol and relocation information\n\
712
  -g -S -d --strip-debug           Remove all debugging symbols & sections\n\
Cary Coutant's avatar
Cary Coutant committed
713
     --strip-dwo                   Remove all DWO sections\n\
Nick Clifton's avatar
Nick Clifton committed
714
     --strip-unneeded              Remove all symbols not needed by relocations\n\
715
     --only-keep-debug             Strip everything but the debug information\n\
716
717
  -M  --merge-notes                Remove redundant entries in note sections (default)\n\
      --no-merge-notes             Do not attempt to remove redundant notes\n\
718
  -N --strip-symbol=<name>         Do not copy symbol <name>\n\
719
  -K --keep-symbol=<name>          Do not strip symbol <name>\n\
Jan Beulich's avatar
Jan Beulich committed
720
     --keep-file-symbols           Do not strip file symbol(s)\n\
721
  -w --wildcard                    Permit wildcard in symbol comparison\n\
Nick Clifton's avatar
Nick Clifton committed
722
723
724
725
726
  -x --discard-all                 Remove all non-global symbols\n\
  -X --discard-locals              Remove any compiler-generated symbols\n\
  -v --verbose                     List all object files modified\n\
  -V --version                     Display this program's version number\n\
  -h --help                        Display this output\n\
Nick Clifton's avatar
Nick Clifton committed
727
     --info                        List object formats & architectures supported\n\
Nick Clifton's avatar
Nick Clifton committed
728
729
730
  -o <file>                        Place stripped output into <file>\n\
"));

Richard Henderson's avatar
Richard Henderson committed
731
  list_supported_targets (program_name, stream);
Joseph Myers's avatar
Joseph Myers committed
732
  if (REPORT_BUGS_TO[0] && exit_status == 0)
733
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
Richard Henderson's avatar
Richard Henderson committed
734
735
736
737
738
739
740
  exit (exit_status);
}

/* Parse section flags into a flagword, with a fatal error if the
   string can't be parsed.  */

static flagword
Nick Clifton's avatar
Nick Clifton committed
741
parse_flags (const char *s)
Richard Henderson's avatar
Richard Henderson committed
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
{
  flagword ret;
  const char *snext;
  int len;

  ret = SEC_NO_FLAGS;

  do
    {
      snext = strchr (s, ',');
      if (snext == NULL)
	len = strlen (s);
      else
	{
	  len = snext - s;
	  ++snext;
	}

      if (0) ;
761
762
#define PARSE_FLAG(fname,fval)					\
      else if (strncasecmp (fname, s, len) == 0) ret |= fval
Richard Henderson's avatar
Richard Henderson committed
763
764
      PARSE_FLAG ("alloc", SEC_ALLOC);
      PARSE_FLAG ("load", SEC_LOAD);
765
      PARSE_FLAG ("noload", SEC_NEVER_LOAD);
Richard Henderson's avatar
Richard Henderson committed
766
      PARSE_FLAG ("readonly", SEC_READONLY);
767
      PARSE_FLAG ("debug", SEC_DEBUGGING);
Richard Henderson's avatar
Richard Henderson committed
768
769
770
      PARSE_FLAG ("code", SEC_CODE);
      PARSE_FLAG ("data", SEC_DATA);
      PARSE_FLAG ("rom", SEC_ROM);
H.J. Lu's avatar
bfd/    
H.J. Lu committed
771
      PARSE_FLAG ("share", SEC_COFF_SHARED);
Richard Henderson's avatar
Richard Henderson committed
772
      PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
773
774
      PARSE_FLAG ("merge", SEC_MERGE);
      PARSE_FLAG ("strings", SEC_STRINGS);
Richard Henderson's avatar
Richard Henderson committed
775
776
777
778
779
#undef PARSE_FLAG
      else
	{
	  char *copy;

780
	  copy = (char *) xmalloc (len + 1);
Richard Henderson's avatar
Richard Henderson committed
781
782
783
	  strncpy (copy, s, len);
	  copy[len] = '\0';
	  non_fatal (_("unrecognized section flag `%s'"), copy);
Alan Modra's avatar
Alan Modra committed
784
	  fatal (_("supported flags: %s"),
785
		 "alloc, load, noload, readonly, debug, code, data, rom, share, contents, merge, strings");
Richard Henderson's avatar
Richard Henderson committed
786
787
788
789
790
791
792
793
794
	}

      s = snext;
    }
  while (s != NULL);

  return ret;
}

795
796
797
798
799
800
801
802
/* Parse symbol flags into a flagword, with a fatal error if the
   string can't be parsed.  */

static flagword
parse_symflags (const char *s, char **other)
{
  flagword ret;
  const char *snext;
803
  size_t len;
804
805
806
807
808
809
810

  ret = BSF_NO_FLAGS;

  do
    {
      snext = strchr (s, ',');
      if (snext == NULL)
811
	len = strlen (s);
812
813
814
815
816
817
      else
	{
	  len = snext - s;
	  ++snext;
	}

818
819
820
#define PARSE_FLAG(fname, fval)						\
      else if (len == sizeof fname - 1					\
	       && strncasecmp (fname, s, len) == 0)			\
821
822
	ret |= fval

823
824
825
#define PARSE_OTHER(fname, fval)					\
      else if (len >= sizeof fname					\
	       && strncasecmp (fname, s, sizeof fname - 1) == 0)	\
826
	fval = xstrndup (s + sizeof fname - 1, len - sizeof fname + 1)
827

828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
      if (0) ;
      PARSE_FLAG ("local", BSF_LOCAL);
      PARSE_FLAG ("global", BSF_GLOBAL);
      PARSE_FLAG ("export", BSF_EXPORT);
      PARSE_FLAG ("debug", BSF_DEBUGGING);
      PARSE_FLAG ("function", BSF_FUNCTION);
      PARSE_FLAG ("weak", BSF_WEAK);
      PARSE_FLAG ("section", BSF_SECTION_SYM);
      PARSE_FLAG ("constructor", BSF_CONSTRUCTOR);
      PARSE_FLAG ("warning", BSF_WARNING);
      PARSE_FLAG ("indirect", BSF_INDIRECT);
      PARSE_FLAG ("file", BSF_FILE);
      PARSE_FLAG ("object", BSF_OBJECT);
      PARSE_FLAG ("synthetic", BSF_SYNTHETIC);
      PARSE_FLAG ("indirect-function", BSF_GNU_INDIRECT_FUNCTION | BSF_FUNCTION);
      PARSE_FLAG ("unique-object", BSF_GNU_UNIQUE | BSF_OBJECT);
      PARSE_OTHER ("before=", *other);

#undef PARSE_FLAG
#undef PARSE_OTHER
      else
	{
	  char *copy;

	  copy = (char *) xmalloc (len + 1);
	  strncpy (copy, s, len);
	  copy[len] = '\0';
	  non_fatal (_("unrecognized symbol flag `%s'"), copy);
	  fatal (_("supported flags: %s"),
857
858
859
		 "local, global, export, debug, function, weak, section, "
		 "constructor, warning, indirect, file, object, synthetic, "
		 "indirect-function, unique-object, before=<othersym>");
860
861
862
863
864
865
866
867
868
	}

      s = snext;
    }
  while (s != NULL);

  return ret;
}

Nick Clifton's avatar
Nick Clifton committed
869
870
871
872
873
/* Find and optionally add an entry in the change_sections list.

   We need to be careful in how we match section names because of the support
   for wildcard characters.  For example suppose that the user has invoked
   objcopy like this:
H.J. Lu's avatar
H.J. Lu committed
874

Nick Clifton's avatar
Nick Clifton committed
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
       --set-section-flags .debug_*=debug
       --set-section-flags .debug_str=readonly,debug
       --change-section-address .debug_*ranges=0x1000

   With the idea that all debug sections will receive the DEBUG flag, the
   .debug_str section will also receive the READONLY flag and the
   .debug_ranges and .debug_aranges sections will have their address set to
   0x1000.  (This may not make much sense, but it is just an example).

   When adding the section name patterns to the section list we need to make
   sure that previous entries do not match with the new entry, unless the
   match is exact.  (In which case we assume that the user is overriding
   the previous entry with the new context).

   When matching real section names to the section list we make use of the
   wildcard characters, but we must do so in context.  Eg if we are setting
   section addresses then we match for .debug_ranges but not for .debug_info.

   Finally, if ADD is false and we do find a match, we mark the section list
   entry as used.  */
Richard Henderson's avatar
Richard Henderson committed
895
896

static struct section_list *
Nick Clifton's avatar
Nick Clifton committed
897
find_section_list (const char *name, bfd_boolean add, unsigned int context)
Richard Henderson's avatar
Richard Henderson committed
898
{
899
  struct section_list *p, *match = NULL;
Richard Henderson's avatar
Richard Henderson committed
900

Nick Clifton's avatar
Nick Clifton committed
901
  /* assert ((context & ((1 << 7) - 1)) != 0); */
H.J. Lu's avatar
H.J. Lu committed
902

Richard Henderson's avatar
Richard Henderson committed
903
  for (p = change_sections; p != NULL; p = p->next)
Nick Clifton's avatar
Nick Clifton committed
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
    {
      if (add)
	{
	  if (strcmp (p->pattern, name) == 0)
	    {
	      /* Check for context conflicts.  */
	      if (((p->context & SECTION_CONTEXT_REMOVE)
		   && (context & SECTION_CONTEXT_COPY))
		  || ((context & SECTION_CONTEXT_REMOVE)
		      && (p->context & SECTION_CONTEXT_COPY)))
		fatal (_("error: %s both copied and removed"), name);

	      if (((p->context & SECTION_CONTEXT_SET_VMA)
		  && (context & SECTION_CONTEXT_ALTER_VMA))
		  || ((context & SECTION_CONTEXT_SET_VMA)
		      && (context & SECTION_CONTEXT_ALTER_VMA)))
		fatal (_("error: %s both sets and alters VMA"), name);

	      if (((p->context & SECTION_CONTEXT_SET_LMA)
		  && (context & SECTION_CONTEXT_ALTER_LMA))
		  || ((context & SECTION_CONTEXT_SET_LMA)
		      && (context & SECTION_CONTEXT_ALTER_LMA)))
		fatal (_("error: %s both sets and alters LMA"), name);

	      /* Extend the context.  */
	      p->context |= context;
	      return p;
	    }
	}
      /* If we are not adding a new name/pattern then
	 only check for a match if the context applies.  */
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
      else if (p->context & context)
        {
          /* We could check for the presence of wildchar characters
             first and choose between calling strcmp and fnmatch,
             but is that really worth it ?  */
          if (p->pattern [0] == '!')
            {
              if (fnmatch (p->pattern + 1, name, 0) == 0)
                {
                  p->used = TRUE;
                  return NULL;
                }
            }
          else
            {
              if (fnmatch (p->pattern, name, 0) == 0)
                {
                  if (match == NULL)
                    match = p;
                }
            }
        }
Nick Clifton's avatar
Nick Clifton committed
957
    }
Richard Henderson's avatar
Richard Henderson committed
958
959

  if (! add)
960
961
962
963
964
    {
      if (match != NULL)
        match->used = TRUE;
      return match;
    }
Richard Henderson's avatar
Richard Henderson committed
965

966
  p = (struct section_list *) xmalloc (sizeof (struct section_list));
Nick Clifton's avatar
Nick Clifton committed
967
  p->pattern = name;
968
  p->used = FALSE;
Nick Clifton's avatar
Nick Clifton committed
969
  p->context = context;
Richard Henderson's avatar
Richard Henderson committed
970
971
972
  p->vma_val = 0;
  p->lma_val = 0;
  p->flags = 0;
973
  p->alignment = 0;
Richard Henderson's avatar
Richard Henderson committed
974
975
976
977
978
979
  p->next = change_sections;
  change_sections = p;

  return p;
}

980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
/* S1 is the entry node already in the table, S2 is the key node.  */

static int
eq_string_redefnode (const void *s1, const void *s2)
{
  struct redefine_node *node1 = (struct redefine_node *) s1;
  struct redefine_node *node2 = (struct redefine_node *) s2;
  return !strcmp ((const char *) node1->source, (const char *) node2->source);
}

/* P is redefine node.  Hash value is generated from its "source" filed.  */

static hashval_t
htab_hash_redefnode (const void *p)
{
  struct redefine_node *redefnode = (struct redefine_node *) p;
  return htab_hash_string (redefnode->source);
}

/* Create hashtab used for redefine node.  */

static htab_t
create_symbol2redef_htab (void)
{
  return htab_create_alloc (16, htab_hash_redefnode, eq_string_redefnode, NULL,
			    xcalloc, free);
}

Nick Clifton's avatar
Nick Clifton committed
1008
1009
1010
1011
1012
/* There is htab_hash_string but no htab_eq_string. Makes sense.  */

static int
eq_string (const void *s1, const void *s2)
{
1013
  return strcmp ((const char *) s1, (const char *) s2) == 0;
Nick Clifton's avatar
Nick Clifton committed
1014
1015
1016
1017
1018
1019
1020
}

static htab_t
create_symbol_htab (void)
{
  return htab_create_alloc (16, htab_hash_string, eq_string, NULL, xcalloc, free);
}
Richard Henderson's avatar
Richard Henderson committed
1021

Alan Modra's avatar
Alan Modra committed
1022
static void
Nick Clifton's avatar
Nick Clifton committed
1023
create_symbol_htabs (void)
Richard Henderson's avatar
Richard Henderson committed
1024
{
Nick Clifton's avatar
Nick Clifton committed
1025
1026
1027
1028
1029
1030
1031
  strip_specific_htab = create_symbol_htab ();
  strip_unneeded_htab = create_symbol_htab ();
  keep_specific_htab = create_symbol_htab ();
  localize_specific_htab = create_symbol_htab ();
  globalize_specific_htab = create_symbol_htab ();
  keepglobal_specific_htab = create_symbol_htab ();
  weaken_specific_htab = create_symbol_htab ();
1032
1033
1034
1035
  redefine_specific_htab = create_symbol2redef_htab ();
  /* As there is no bidirectional hash table in libiberty, need a reverse table
     to check duplicated target string.  */
  redefine_specific_reverse_htab = create_symbol_htab ();
Nick Clifton's avatar
Nick Clifton committed
1036
1037
1038
}

/* Add a symbol to strip_specific_list.  */
Richard Henderson's avatar
Richard Henderson committed
1039

Nick Clifton's avatar
Nick Clifton committed
1040
1041
1042
1043
static void
add_specific_symbol (const char *name, htab_t htab)
{
  *htab_find_slot (htab, name, INSERT) = (char *) name;
Richard Henderson's avatar
Richard Henderson committed
1044
1045
}

1046
1047
1048
1049
1050
1051
1052
1053
/* Like add_specific_symbol, but the element type is void *.  */

static void
add_specific_symbol_node (const void *node, htab_t htab)
{
  *htab_find_slot (htab, node, INSERT) = (void *) node;
}

Kazu Hirata's avatar
Kazu Hirata committed
1054
/* Add symbols listed in `filename' to strip_specific_list.  */
1055
1056
1057
1058
1059

#define IS_WHITESPACE(c)      ((c) == ' ' || (c) == '\t')
#define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')

static void
1060
add_specific_symbols (const char *filename, htab_t htab, char **buffer_p)
1061
{
1062
  off_t  size;
1063
1064
1065
1066
  FILE * f;
  char * line;
  char * buffer;
  unsigned int line_count;
Kazu Hirata's avatar
Kazu Hirata committed
1067

1068
1069
  size = get_file_size (filename);
  if (size == 0)
Nick Clifton's avatar
Nick Clifton committed
1070
1071
1072
1073
    {
      status = 1;
      return;
    }
1074

1075
  buffer = (char *) xmalloc (size + 2);
1076
1077
  f = fopen (filename, FOPEN_RT);
  if (f == NULL)
1078
    fatal (_("cannot open '%s': %s"), filename, strerror (errno));
1079

1080
  if (fread (buffer, 1, size, f) == 0 || ferror (f))
1081
1082
1083
    fatal (_("%s: fread failed"), filename);

  fclose (f);
1084
1085
  buffer [size] = '\n';
  buffer [size + 1] = '\0';
1086
1087

  line_count = 1;
Kazu Hirata's avatar
Kazu Hirata committed
1088

1089
1090
1091
1092
1093
  for (line = buffer; * line != '\0'; line ++)
    {
      char * eol;
      char * name;
      char * name_end;
1094
      int finished = FALSE;
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104

      for (eol = line;; eol ++)
	{
	  switch (* eol)
	    {
	    case '\n':
	      * eol = '\0';
	      /* Cope with \n\r.  */
	      if (eol[1] == '\r')
		++ eol;
1105
	      finished = TRUE;
1106
	      break;
Kazu Hirata's avatar
Kazu Hirata committed
1107

1108
1109
1110
1111
1112
	    case '\r':
	      * eol = '\0';
	      /* Cope with \r\n.  */
	      if (eol[1] == '\n')
		++ eol;
1113
	      finished = TRUE;
1114
	      break;
Kazu Hirata's avatar
Kazu Hirata committed
1115

1116
	    case 0:
1117
	      finished = TRUE;
1118
	      break;
Kazu Hirata's avatar
Kazu Hirata committed
1119

1120
1121
1122
1123
1124
1125
	    case '#':
	      /* Line comment, Terminate the line here, in case a
		 name is present and then allow the rest of the
		 loop to find the real end of the line.  */
	      * eol = '\0';
	      break;
Kazu Hirata's avatar
Kazu Hirata committed
1126

1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
	    default:
	      break;
	    }

	  if (finished)
	    break;
	}

      /* A name may now exist somewhere between 'line' and 'eol'.
	 Strip off leading whitespace and trailing whitespace,
	 then add it to the list.  */
      for (name = line; IS_WHITESPACE (* name); name ++)
	;
      for (name_end = name;
	   (! IS_WHITESPACE (* name_end))
	   && (! IS_LINE_TERMINATOR (* name_end));
Kazu Hirata's avatar
Kazu Hirata committed
1143