objcopy.c 168 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-2020 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
struct addsym_node
{
  struct addsym_node *next;
  char *    symdef;
  long      symval;
  flagword  flags;
  char *    section;
71
  const char *  othersym;
72
73
};

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
static int status = 0;			/* Exit status.  */

static bfd_boolean    merge_notes = FALSE;	/* Merge note sections.  */
100
101
102
103
104
105
106
107

typedef struct merged_note_section
{
  asection *                    sec;	 /* The section that is being merged.  */
  bfd_byte *                    contents;/* New contents of the section.  */
  bfd_size_type                 size;	 /* New size of the section.  */
  struct merged_note_section *  next;  	 /* Link to next merged note section.  */
} merged_note_section;
Richard Henderson's avatar
Richard Henderson committed
108
109

enum strip_action
110
111
112
113
114
115
116
117
118
119
{
  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
120

Kazu Hirata's avatar
Kazu Hirata committed
121
/* Which symbols to remove.  */
122
static enum strip_action strip_symbols = STRIP_UNDEF;
Richard Henderson's avatar
Richard Henderson committed
123
124

enum locals_action
125
126
127
128
129
{
  LOCALS_UNDEF,
  LOCALS_START_L,	/* Discard locals starting with L.  */
  LOCALS_ALL		/* Discard all locals.  */
};
Richard Henderson's avatar
Richard Henderson committed
130
131
132
133
134
135
136

/* 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
{
137
  struct section_list * next;	   /* Next section to change.  */
Nick Clifton's avatar
Nick Clifton committed
138
  const char *		pattern;   /* Section name pattern.  */
139
  bfd_boolean		used;	   /* Whether this entry was used.  */
Nick Clifton's avatar
Nick Clifton committed
140
141
142
143
144
145

  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.  */
146
147
148
149
150
151
152
153
#define SECTION_CONTEXT_KEEP      (1 << 2) /* Keep this section.  */
#define SECTION_CONTEXT_SET_VMA   (1 << 3) /* Set the sections' VMA address.  */
#define SECTION_CONTEXT_ALTER_VMA (1 << 4) /* Increment or decrement the section's VMA address.  */
#define SECTION_CONTEXT_SET_LMA   (1 << 5) /* Set the sections' LMA address.  */
#define SECTION_CONTEXT_ALTER_LMA (1 << 6) /* Increment or decrement the section's LMA address.  */
#define SECTION_CONTEXT_SET_FLAGS (1 << 7) /* Set the section's flags.  */
#define SECTION_CONTEXT_REMOVE_RELOCS (1 << 8) /* Remove relocations for this section.  */
#define SECTION_CONTEXT_SET_ALIGNMENT (1 << 9) /* Set alignment for section.  */
Nick Clifton's avatar
Nick Clifton committed
154

155
156
157
  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.	 */
158
  unsigned int	        alignment; /* Alignment of output section.  */
Richard Henderson's avatar
Richard Henderson committed
159
160
161
};

static struct section_list *change_sections;
162

163
164
/* TRUE if some sections are to be removed.  */
static bfd_boolean sections_removed;
165

166
167
/* TRUE if only some sections are to be copied.  */
static bfd_boolean sections_copied;
Richard Henderson's avatar
Richard Henderson committed
168
169
170

/* Changes to the start address.  */
static bfd_vma change_start = 0;
171
static bfd_boolean set_start_set = FALSE;
Richard Henderson's avatar
Richard Henderson committed
172
173
174
175
176
177
static bfd_vma set_start;

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

/* Filling gaps between sections.  */
178
static bfd_boolean gap_fill_set = FALSE;
Richard Henderson's avatar
Richard Henderson committed
179
180
181
static bfd_byte gap_fill = 0;

/* Pad to a given address.  */
182
static bfd_boolean pad_to_set = FALSE;
Richard Henderson's avatar
Richard Henderson committed
183
184
static bfd_vma pad_to;

185
186
/* Use alternative machine code?  */
static unsigned long use_alt_mach_code = 0;
187

188
189
190
191
/* 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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/* 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;
};

209
/* List of sections to add to the output BFD.  */
Richard Henderson's avatar
Richard Henderson committed
210
211
static struct section_add *add_sections;

212
213
214
/* List of sections to update in the output BFD.  */
static struct section_add *update_sections;

215
216
217
/* List of sections to dump from the output BFD.  */
static struct section_add *dump_sections;

218
219
220
221
/* 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
222
/* Whether to convert debugging information.  */
223
static bfd_boolean convert_debugging = FALSE;
Richard Henderson's avatar
Richard Henderson committed
224

225
226
227
/* Whether to compress/decompress DWARF debug sections.  */
static enum
{
228
229
230
231
232
233
  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
234
235
} do_debug_sections = nothing;

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

Richard Henderson's avatar
Richard Henderson committed
239
/* Whether to change the leading character in symbol names.  */
240
static bfd_boolean change_leading_char = FALSE;
Richard Henderson's avatar
Richard Henderson committed
241
242

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

245
/* Whether to permit wildcard in symbol comparison.  */
246
247
static bfd_boolean wildcard = FALSE;

Richard Sandiford's avatar
Richard Sandiford committed
248
249
250
/* True if --localize-hidden is in effect.  */
static bfd_boolean localize_hidden = FALSE;

251
252
/* List of symbols to strip, keep, localize, keep-global, weaken,
   or redefine.  */
Nick Clifton's avatar
Nick Clifton committed
253
254
255
256
257
258
259
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;
260
261
static htab_t redefine_specific_htab = NULL;
static htab_t redefine_specific_reverse_htab = NULL;
262
263
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
264

265
266
267
268
269
270
271
272
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;

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

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

279
280
281
282
283
/* 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
284
285
286
/* True if --extract-symbol was passed on the command line.  */
static bfd_boolean extract_symbol = FALSE;

287
288
289
290
/* 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
291
292
293
/* 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
294
295
296
297
298
{
  DISABLE,
  ENABLE,
  KEEP
};
Dave Korn's avatar
Dave Korn committed
299
300
301
302

/* 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;
303

Richard Henderson's avatar
Richard Henderson committed
304
/* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
Nick Clifton's avatar
Nick Clifton committed
305
enum command_line_switch
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
{
  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
322
  OPTION_ELF_STT_COMMON,
323
324
325
326
327
328
329
330
331
332
333
334
335
  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,
336
  OPTION_KEEP_SECTION,
337
338
339
340
  OPTION_KEEP_SYMBOLS,
  OPTION_LOCALIZE_HIDDEN,
  OPTION_LOCALIZE_SYMBOLS,
  OPTION_LONG_SECTION_NAMES,
341
  OPTION_MERGE_NOTES,
342
  OPTION_NO_MERGE_NOTES,
343
344
345
346
347
348
349
350
351
352
353
  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,
354
  OPTION_REMOVE_RELOCS,
355
356
  OPTION_RENAME_SECTION,
  OPTION_REVERSE_BYTES,
357
  OPTION_PE_SECTION_ALIGNMENT,
358
  OPTION_SET_SECTION_FLAGS,
359
  OPTION_SET_SECTION_ALIGNMENT,
360
361
362
363
364
365
366
367
368
369
370
  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,
371
  OPTION_VERILOG_DATA_WIDTH,
372
373
374
375
  OPTION_WEAKEN,
  OPTION_WEAKEN_SYMBOLS,
  OPTION_WRITABLE_TEXT
};
Richard Henderson's avatar
Richard Henderson committed
376
377
378
379
380

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

static struct option strip_options[] =
{
Roland McGrath's avatar
Roland McGrath committed
381
  {"disable-deterministic-archives", no_argument, 0, 'U'},
Richard Henderson's avatar
Richard Henderson committed
382
383
  {"discard-all", no_argument, 0, 'x'},
  {"discard-locals", no_argument, 0, 'X'},
384
  {"enable-deterministic-archives", no_argument, 0, 'D'},
Richard Henderson's avatar
Richard Henderson committed
385
386
  {"format", required_argument, 0, 'F'}, /* Obsolete */
  {"help", no_argument, 0, 'h'},
Nick Clifton's avatar
Nick Clifton committed
387
  {"info", no_argument, 0, OPTION_FORMATS_INFO},
Richard Henderson's avatar
Richard Henderson committed
388
389
  {"input-format", required_argument, 0, 'I'}, /* Obsolete */
  {"input-target", required_argument, 0, 'I'},
Jan Beulich's avatar
Jan Beulich committed
390
  {"keep-file-symbols", no_argument, 0, OPTION_KEEP_FILE_SYMBOLS},
391
  {"keep-section", required_argument, 0, OPTION_KEEP_SECTION},
Richard Henderson's avatar
Richard Henderson committed
392
  {"keep-symbol", required_argument, 0, 'K'},
393
394
  {"merge-notes", no_argument, 0, 'M'},
  {"no-merge-notes", no_argument, 0, OPTION_NO_MERGE_NOTES},
Nick Clifton's avatar
Nick Clifton committed
395
  {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
396
  {"output-file", required_argument, 0, 'o'},
Richard Henderson's avatar
Richard Henderson committed
397
398
399
400
  {"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'},
401
  {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
Richard Henderson's avatar
Richard Henderson committed
402
403
  {"strip-all", no_argument, 0, 's'},
  {"strip-debug", no_argument, 0, 'S'},
Cary Coutant's avatar
Cary Coutant committed
404
  {"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
Richard Henderson's avatar
Richard Henderson committed
405
  {"strip-symbol", required_argument, 0, 'N'},
406
  {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
Richard Henderson's avatar
Richard Henderson committed
407
408
409
  {"target", required_argument, 0, 'F'},
  {"verbose", no_argument, 0, 'v'},
  {"version", no_argument, 0, 'V'},
410
  {"wildcard", no_argument, 0, 'w'},
Richard Henderson's avatar
Richard Henderson committed
411
412
413
414
415
416
417
  {0, no_argument, 0, 0}
};

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

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

Pedro Alves's avatar
Pedro Alves committed
529
/* The maximum length of an S record.  This variable is defined in srec.c
530
   and can be modified by the --srec-len parameter.  */
Pedro Alves's avatar
Pedro Alves committed
531
extern unsigned int _bfd_srec_len;
532
533

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

538
539
540
541
542
/* 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;

543
544
/* Forward declarations.  */
static void setup_section (bfd *, asection *, void *);
Bob Wilson's avatar
Bob Wilson committed
545
static void setup_bfd_headers (bfd *, bfd *);
H.J. Lu's avatar
H.J. Lu committed
546
static void copy_relocations_in_section (bfd *, asection *, void *);
547
548
549
550
551
552
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
553
static const char *find_section_rename (const char *, flagword *);
554

555
ATTRIBUTE_NORETURN static void
Nick Clifton's avatar
Nick Clifton committed
556
copy_usage (FILE *stream, int exit_status)
Richard Henderson's avatar
Richard Henderson committed
557
{
558
559
  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"));
560
  fprintf (stream, _(" The options are:\n"));
Richard Henderson's avatar
Richard Henderson committed
561
  fprintf (stream, _("\
Nick Clifton's avatar
Nick Clifton committed
562
563
  -I --input-target <bfdname>      Assume input file is in format <bfdname>\n\
  -O --output-target <bfdname>     Create an output file in format <bfdname>\n\
564
  -B --binary-architecture <arch>  Set output arch, when input is arch-less\n\
Nick Clifton's avatar
Nick Clifton committed
565
566
  -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
567
568
569
570
571
572
573
574
575
  -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, _("\
576
577
  -D --enable-deterministic-archives\n\
                                   Produce deterministic output when stripping archives\n\
Roland McGrath's avatar
Roland McGrath committed
578
579
580
  -U --disable-deterministic-archives\n\
                                   Disable -D behavior (default)\n"));
  fprintf (stream, _("\
Nick Clifton's avatar
Nick Clifton committed
581
  -j --only-section <name>         Only copy section <name> into the output\n\
582
     --add-gnu-debuglink=<file>    Add section .gnu_debuglink linking to <file>\n\
Nick Clifton's avatar
Nick Clifton committed
583
  -R --remove-section <name>       Remove section <name> from the output\n\
584
     --remove-relocations <name>   Remove relocations from section <name>\n\
Nick Clifton's avatar
Nick Clifton committed
585
  -S --strip-all                   Remove all symbol and relocation information\n\
586
  -g --strip-debug                 Remove all debugging symbols & sections\n\
Cary Coutant's avatar
Cary Coutant committed
587
     --strip-dwo                   Remove all DWO sections\n\
Nick Clifton's avatar
Nick Clifton committed
588
589
     --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
590
591
592
     --strip-unneeded-symbol <name>\n\
                                   Do not copy symbol <name> unless needed by\n\
                                     relocations\n\
593
     --only-keep-debug             Strip everything but the debug information\n\
Cary Coutant's avatar
Cary Coutant committed
594
     --extract-dwo                 Copy only DWO sections\n\
Richard Sandiford's avatar
Richard Sandiford committed
595
     --extract-symbol              Remove section contents but keep symbols\n\
596
     --keep-section <name>         Do not strip section <name>\n\
597
  -K --keep-symbol <name>          Do not strip symbol <name>\n\
Jan Beulich's avatar
Jan Beulich committed
598
     --keep-file-symbols           Do not strip file symbol(s)\n\
Richard Sandiford's avatar
Richard Sandiford committed
599
     --localize-hidden             Turn all ELF hidden symbols into locals\n\
Nick Clifton's avatar
Nick Clifton committed
600
  -L --localize-symbol <name>      Force symbol <name> to be marked as a local\n\
601
     --globalize-symbol <name>     Force symbol <name> to be marked as a global\n\
602
  -G --keep-global-symbol <name>   Localize all symbols except <name>\n\
Nick Clifton's avatar
Nick Clifton committed
603
604
  -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\
605
  -w --wildcard                    Permit wildcard in symbol comparison\n\
Nick Clifton's avatar
Nick Clifton committed
606
607
  -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
608
  -i --interleave[=<number>]       Only copy N out of every <number> bytes\n\
609
     --interleave-width <number>   Set N for --interleave\n\
Nick Clifton's avatar
Nick Clifton committed
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
  -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\
628
     --set-section-alignment <name>=<align>\n\
629
                                   Set section <name>'s alignment to <align> bytes\n\
Nick Clifton's avatar
Nick Clifton committed
630
     --add-section <name>=<file>   Add section <name> found in <file> to output\n\
631
632
633
     --update-section <name>=<file>\n\
                                   Update contents of section <name> with\n\
                                   contents found in <file>\n\
634
     --dump-section <name>=<file>  Dump the contents of section <name> into <file>\n\
635
     --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
Dave Korn's avatar
Dave Korn committed
636
637
     --long-section-names {enable|disable|keep}\n\
                                   Handle long section names in Coff objects.\n\
Nick Clifton's avatar
Nick Clifton committed
638
639
     --change-leading-char         Force output format's leading character style\n\
     --remove-leading-char         Remove leading character from global symbols\n\
640
     --reverse-bytes=<num>         Reverse <num> bytes at a time, in output sections with content\n\
Alan Modra's avatar
Alan Modra committed
641
     --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>\n\
642
643
     --redefine-syms <file>        --redefine-sym for all symbol pairs \n\
                                     listed in <file>\n\
644
645
     --srec-len <number>           Restrict the length of generated Srecords\n\
     --srec-forceS3                Restrict the type of generated Srecords to S3\n\
646
     --strip-symbols <file>        -N for all symbols listed in <file>\n\
Jan Beulich's avatar
Jan Beulich committed
647
648
649
     --strip-unneeded-symbols <file>\n\
                                   --strip-unneeded-symbol for all symbols listed\n\
                                     in <file>\n\
650
651
     --keep-symbols <file>         -K for all symbols listed in <file>\n\
     --localize-symbols <file>     -L for all symbols listed in <file>\n\
652
     --globalize-symbols <file>    --globalize-symbol for all in <file>\n\
653
654
     --keep-global-symbols <file>  -G for all symbols listed in <file>\n\
     --weaken-symbols <file>       -W for all symbols listed in <file>\n\
655
     --add-symbol <name>=[<section>:]<value>[,<flags>]  Add a symbol\n\
656
     --alt-machine-code <index>    Use the target's <index>'th alternative machine\n\
657
658
659
660
     --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\
661
662
663
664
665
     --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
666
667
668
669
670
671
672
673
     --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\
674
                                   Set PE subsystem to <name> [& <version>]\n\
675
676
     --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
                                   Compress DWARF debug sections using zlib\n\
677
     --decompress-debug-sections   Decompress DWARF debug sections using zlib\n\
H.J. Lu's avatar
H.J. Lu committed
678
679
     --elf-stt-common=[yes|no]     Generate ELF common symbols with STT_COMMON\n\
                                     type\n\
680
     --verilog-data-width <number> Specifies data width, in bytes, for verilog output\n\
681
  -M  --merge-notes                Remove redundant entries in note sections\n\
682
      --no-merge-notes             Do not attempt to remove redundant notes (default)\n\
Nick Clifton's avatar
Nick Clifton committed
683
  -v --verbose                     List all object files modified\n\
684
  @<file>                          Read options from <file>\n\
Nick Clifton's avatar
Nick Clifton committed
685
686
  -V --version                     Display this program's version number\n\
  -h --help                        Display this output\n\
Nick Clifton's avatar
Nick Clifton committed
687
     --info                        List object formats & architectures supported\n\
Nick Clifton's avatar
Nick Clifton committed
688
"));
Richard Henderson's avatar
Richard Henderson committed
689
  list_supported_targets (program_name, stream);
Joseph Myers's avatar
Joseph Myers committed
690
  if (REPORT_BUGS_TO[0] && exit_status == 0)
691
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
Richard Henderson's avatar
Richard Henderson committed
692
693
694
  exit (exit_status);
}

695
ATTRIBUTE_NORETURN static void
Nick Clifton's avatar
Nick Clifton committed
696
strip_usage (FILE *stream, int exit_status)
Richard Henderson's avatar
Richard Henderson committed
697
{
698
699
  fprintf (stream, _("Usage: %s <option(s)> in-file(s)\n"), program_name);
  fprintf (stream, _(" Removes symbols and sections from files\n"));
700
  fprintf (stream, _(" The options are:\n"));
Richard Henderson's avatar
Richard Henderson committed
701
  fprintf (stream, _("\
702
703
704
  -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
705
  -p --preserve-dates              Copy modified/access timestamps to the output\n\
Roland McGrath's avatar
Roland McGrath committed
706
707
708
709
710
711
712
713
714
"));
  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, _("\
715
716
  -D --enable-deterministic-archives\n\
                                   Produce deterministic output when stripping archives\n\
Roland McGrath's avatar
Roland McGrath committed
717
718
719
  -U --disable-deterministic-archives\n\
                                   Disable -D behavior (default)\n"));
  fprintf (stream, _("\
Andrew Stubbs's avatar
Andrew Stubbs committed
720
  -R --remove-section=<name>       Also remove section <name> from the output\n\
721
     --remove-relocations <name>   Remove relocations from section <name>\n\
Nick Clifton's avatar
Nick Clifton committed
722
  -s --strip-all                   Remove all symbol and relocation information\n\
723
  -g -S -d --strip-debug           Remove all debugging symbols & sections\n\
Cary Coutant's avatar
Cary Coutant committed
724
     --strip-dwo                   Remove all DWO sections\n\
Nick Clifton's avatar
Nick Clifton committed
725
     --strip-unneeded              Remove all symbols not needed by relocations\n\
726
     --only-keep-debug             Strip everything but the debug information\n\
727
728
  -M  --merge-notes                Remove redundant entries in note sections (default)\n\
      --no-merge-notes             Do not attempt to remove redundant notes\n\
729
  -N --strip-symbol=<name>         Do not copy symbol <name>\n\
730
     --keep-section=<name>         Do not strip section <name>\n\
731
  -K --keep-symbol=<name>          Do not strip symbol <name>\n\
Jan Beulich's avatar
Jan Beulich committed
732
     --keep-file-symbols           Do not strip file symbol(s)\n\
733
  -w --wildcard                    Permit wildcard in symbol comparison\n\
Nick Clifton's avatar
Nick Clifton committed
734
735
736
737
738
  -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
739
     --info                        List object formats & architectures supported\n\
Nick Clifton's avatar
Nick Clifton committed
740
741
742
  -o <file>                        Place stripped output into <file>\n\
"));

Richard Henderson's avatar
Richard Henderson committed
743
  list_supported_targets (program_name, stream);
Joseph Myers's avatar
Joseph Myers committed
744
  if (REPORT_BUGS_TO[0] && exit_status == 0)
745
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
Richard Henderson's avatar
Richard Henderson committed
746
747
748
749
750
751
752
  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
753
parse_flags (const char *s)
Richard Henderson's avatar
Richard Henderson committed
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
{
  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) ;
773
774
#define PARSE_FLAG(fname,fval)					\
      else if (strncasecmp (fname, s, len) == 0) ret |= fval
Richard Henderson's avatar
Richard Henderson committed
775
776
      PARSE_FLAG ("alloc", SEC_ALLOC);
      PARSE_FLAG ("load", SEC_LOAD);
777
      PARSE_FLAG ("noload", SEC_NEVER_LOAD);
Richard Henderson's avatar
Richard Henderson committed
778
      PARSE_FLAG ("readonly", SEC_READONLY);
779
      PARSE_FLAG ("debug", SEC_DEBUGGING);
Richard Henderson's avatar
Richard Henderson committed
780
781
782
      PARSE_FLAG ("code", SEC_CODE);
      PARSE_FLAG ("data", SEC_DATA);
      PARSE_FLAG ("rom", SEC_ROM);
783
      PARSE_FLAG ("exclude", SEC_EXCLUDE);
H.J. Lu's avatar
bfd/    
H.J. Lu committed
784
      PARSE_FLAG ("share", SEC_COFF_SHARED);
Richard Henderson's avatar
Richard Henderson committed
785
      PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
786
787
      PARSE_FLAG ("merge", SEC_MERGE);
      PARSE_FLAG ("strings", SEC_STRINGS);
Richard Henderson's avatar
Richard Henderson committed
788
789
790
791
792
#undef PARSE_FLAG
      else
	{
	  char *copy;

793
	  copy = (char *) xmalloc (len + 1);
Richard Henderson's avatar
Richard Henderson committed
794
795
796
	  strncpy (copy, s, len);
	  copy[len] = '\0';
	  non_fatal (_("unrecognized section flag `%s'"), copy);
Alan Modra's avatar
Alan Modra committed
797
	  fatal (_("supported flags: %s"),
798
		 "alloc, load, noload, readonly, debug, code, data, rom, exclude, share, contents, merge, strings");
Richard Henderson's avatar
Richard Henderson committed
799
800
801
802
803
804
805
806
807
	}

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

  return ret;
}

808
809
810
811
/* Parse symbol flags into a flagword, with a fatal error if the
   string can't be parsed.  */

static flagword
812
parse_symflags (const char *s, const char **other)
813
814
815
{
  flagword ret;
  const char *snext;
816
  size_t len;
817
818
819
820
821
822
823

  ret = BSF_NO_FLAGS;

  do
    {
      snext = strchr (s, ',');
      if (snext == NULL)
824
	len = strlen (s);
825
826
827
828
829
830
      else
	{
	  len = snext - s;
	  ++snext;
	}

831
832
833
#define PARSE_FLAG(fname, fval)						\
      else if (len == sizeof fname - 1					\
	       && strncasecmp (fname, s, len) == 0)			\
834
835
	ret |= fval

836
837
838
#define PARSE_OTHER(fname, fval)					\
      else if (len >= sizeof fname					\
	       && strncasecmp (fname, s, sizeof fname - 1) == 0)	\
839
	fval = xstrndup (s + sizeof fname - 1, len - sizeof fname + 1)
840

841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
      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"),
870
871
872
		 "local, global, export, debug, function, weak, section, "
		 "constructor, warning, indirect, file, object, synthetic, "
		 "indirect-function, unique-object, before=<othersym>");
873
874
875
876
877
878
879
880
881
	}

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

  return ret;
}

Nick Clifton's avatar
Nick Clifton committed
882
883
884
885
886
/* 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
887

Nick Clifton's avatar
Nick Clifton committed
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
       --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
908
909

static struct section_list *
Nick Clifton's avatar
Nick Clifton committed
910
find_section_list (const char *name, bfd_boolean add, unsigned int context)
Richard Henderson's avatar
Richard Henderson committed
911
{
912
  struct section_list *p, *match = NULL;
Richard Henderson's avatar
Richard Henderson committed
913

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

Richard Henderson's avatar
Richard Henderson committed
916
  for (p = change_sections; p != NULL; p = p->next)
Nick Clifton's avatar
Nick Clifton committed
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
    {
      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.  */
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
      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
970
    }
Richard Henderson's avatar
Richard Henderson committed
971
972

  if (! add)
973
974
975
976
977
    {
      if (match != NULL)
        match->used = TRUE;
      return match;
    }
Richard Henderson's avatar
Richard Henderson committed
978

979
  p = (struct section_list *) xmalloc (sizeof (struct section_list));
Nick Clifton's avatar
Nick Clifton committed
980
  p->pattern = name;
981
  p->used = FALSE;
Nick Clifton's avatar
Nick Clifton committed
982
  p->context = context;
Richard Henderson's avatar
Richard Henderson committed
983
984
985
  p->vma_val = 0;
  p->lma_val = 0;
  p->flags = 0;
986
  p->alignment = 0;
Richard Henderson's avatar
Richard Henderson committed
987
988
989
990
991
992
  p->next = change_sections;
  change_sections = p;

  return p;
}

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
/* 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
1021
1022
1023
1024
1025
/* There is htab_hash_string but no htab_eq_string. Makes sense.  */

static int
eq_string (const void *s1, const void *s2)
{
1026
  return strcmp ((const char *) s1, (const char *) s2) == 0;
Nick Clifton's avatar
Nick Clifton committed
1027
1028
1029
1030
1031
1032
1033
}

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
1034

Alan Modra's avatar
Alan Modra committed
1035
static void
Nick Clifton's avatar
Nick Clifton committed
1036
create_symbol_htabs (void)
Richard Henderson's avatar
Richard Henderson committed
1037
{
Nick Clifton's avatar
Nick Clifton committed
1038
1039
1040
1041
1042
1043
1044
  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 ();
1045
1046
1047
1048
  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
1049
1050
1051
}

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

Nick Clifton's avatar
Nick Clifton committed
1053
1054
1055
1056
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
1057
1058
}

1059
1060
1061
1062
1063
1064
1065
1066
/* 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
1067
/* Add symbols listed in `filename' to strip_specific_list.  */
1068
1069
1070
1071
1072

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

static void
1073
add_specific_symbols (const char *filename, htab_t htab, char **buffer_p)
1074
{
1075
  off_t  size;
1076
1077
1078
1079
  FILE * f;
  char * line;
  char * buffer;
  unsigned int line_count;
Kazu Hirata's avatar
Kazu Hirata committed
1080

1081
1082
  size = get_file_size (filename);
  if (size == 0)
Nick Clifton's avatar
Nick Clifton committed
1083
1084
1085
1086
    {
      status = 1;
      return;
    }
1087

1088
  buffer = (char *) xmalloc (size + 2);
1089
1090
  f = fopen (filename, FOPEN_RT);
  if (f == NULL)
1091
    fatal (_("cannot open '%s': %s"), filename, strerror (errno));
1092

1093
  if (fread (buffer, 1, size, f) == 0 || ferror (f))
1094
1095
1096
    fatal (_("%s: fread failed"), filename);

  fclose (f);
1097
1098
  buffer [size] = '\n';
  buffer [size + 1] = '\0';
1099
1100

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

1102
1103
1104
1105
1106
  for (line = buffer; * line != '\0'; line ++)
    {
      char * eol;
      char * name;
      char * name_end;
1107
      int finished = FALSE;
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117

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

1121
1122
1123
1124
1125
	    case '\r':
	      * eol = '\0';
	      /* Cope with \r\n.  */
	      if (eol[1] == '\n')
		++ eol;
1126
	      finished = TRUE;