Extended help information provided about command line options.
[deliverable/binutils-gdb.git] / binutils / objcopy.c
CommitLineData
c0367ba5 1/* objcopy.c -- copy object file from input to output, optionally massaging it.
eaa147a6
ILT
2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
3 Free Software Foundation, Inc.
c0367ba5 4
46050fe4
ILT
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
eaa147a6
ILT
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
46050fe4 21\f
c0367ba5 22#include "bfd.h"
5ab41086 23#include "progress.h"
c0367ba5 24#include "bucomm.h"
f5818d79 25#include "getopt.h"
6c7ed084 26#include "libiberty.h"
f5818d79 27#include "budbg.h"
28b5eb12 28#include <sys/stat.h>
c0367ba5 29
8d2e72a1
RH
30#ifdef HAVE_GOOD_UTIME_H
31#include <utime.h>
32#else /* ! HAVE_GOOD_UTIME_H */
33#ifdef HAVE_UTIMES
34#include <sys/time.h>
35#endif /* HAVE_UTIMES */
36#endif /* ! HAVE_GOOD_UTIME_H */
37
25fd0ed4
ILT
38/* A list of symbols to explicitly strip out, or to keep. A linked
39 list is good enough for a small number from the command line, but
40 this will slow things down a lot if many symbols are being
41 deleted. */
42
43struct symlist
44{
45 const char *name;
46 struct symlist *next;
47};
48
8d2e72a1
RH
49static void copy_usage PARAMS ((FILE *, int));
50static void strip_usage PARAMS ((FILE *, int));
5ab41086 51static flagword parse_flags PARAMS ((const char *));
5ab41086 52static struct section_list *find_section_list PARAMS ((const char *, boolean));
6c7ed084
ILT
53static void setup_section PARAMS ((bfd *, asection *, PTR));
54static void copy_section PARAMS ((bfd *, asection *, PTR));
596d99ba 55static void get_sections PARAMS ((bfd *, asection *, PTR));
22947e96 56static int compare_section_lma PARAMS ((const PTR, const PTR));
25fd0ed4
ILT
57static void add_specific_symbol PARAMS ((const char *, struct symlist **));
58static boolean is_specified_symbol PARAMS ((const char *, struct symlist *));
5ab41086 59static boolean is_strip_section PARAMS ((bfd *, asection *));
4af19c61 60static unsigned int filter_symbols
8d2e72a1 61 PARAMS ((bfd *, bfd *, asymbol **, asymbol **, long));
6c7ed084 62static void mark_symbols_used_in_relocations PARAMS ((bfd *, asection *, PTR));
8d2e72a1 63static void filter_bytes PARAMS ((char *, bfd_size_type *));
f5818d79 64static boolean write_debugging_info PARAMS ((bfd *, PTR, long *, asymbol ***));
8d2e72a1
RH
65static void copy_object PARAMS ((bfd *, bfd *));
66static void copy_archive PARAMS ((bfd *, bfd *, const char *));
67static void copy_file
68 PARAMS ((const char *, const char *, const char *, const char *));
69static int simple_copy PARAMS ((const char *, const char *));
70static int smart_rename PARAMS ((const char *, const char *));
71static void set_times PARAMS ((const char *, const struct stat *));
72static int strip_main PARAMS ((int, char **));
73static int copy_main PARAMS ((int, char **));
c0367ba5 74
46050fe4 75#define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
c0367ba5 76
46050fe4
ILT
77static asymbol **isympp = NULL; /* Input symbols */
78static asymbol **osympp = NULL; /* Output symbols that survive stripping */
f7b839f7
DM
79
80/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes. */
81static int copy_byte = -1;
82static int interleave = 4;
83
46050fe4 84static boolean verbose; /* Print file and target names. */
22947e96 85static boolean preserve_dates; /* Preserve input file timestamp. */
f7b839f7 86static int status = 0; /* Exit status. */
c0367ba5
ILT
87
88enum strip_action
46050fe4
ILT
89 {
90 strip_undef,
91 strip_none, /* don't strip */
92 strip_debug, /* strip all debugger symbols */
9135e5f8 93 strip_unneeded, /* strip unnecessary symbols */
46050fe4
ILT
94 strip_all /* strip all symbols */
95 };
c0367ba5
ILT
96
97/* Which symbols to remove. */
46050fe4 98static enum strip_action strip_symbols;
c0367ba5
ILT
99
100enum locals_action
46050fe4
ILT
101 {
102 locals_undef,
103 locals_start_L, /* discard locals starting with L */
104 locals_all /* discard all locals */
105 };
106
107/* Which local symbols to remove. Overrides strip_all. */
108static enum locals_action discard_locals;
109
6c7ed084
ILT
110/* Structure used to hold lists of sections and actions to take. */
111
112struct section_list
113{
114 /* Next section to adjust. */
115 struct section_list *next;
116 /* Section name. */
117 const char *name;
118 /* Whether this entry was used. */
119 boolean used;
5ab41086
ILT
120 /* Whether to remove this section. */
121 boolean remove;
6c7ed084 122 /* Whether to adjust or set VMA. */
5ab41086 123 enum { ignore_vma, adjust_vma, set_vma } adjust;
6c7ed084
ILT
124 /* Amount to adjust by or set to. */
125 bfd_vma val;
5ab41086
ILT
126 /* Whether to set the section flags. */
127 boolean set_flags;
128 /* What to set the section flags to. */
129 flagword flags;
6c7ed084
ILT
130};
131
5ab41086
ILT
132static struct section_list *adjust_sections;
133static boolean sections_removed;
6c7ed084
ILT
134
135/* Adjustments to the start address. */
136static bfd_vma adjust_start = 0;
137static boolean set_start_set = false;
138static bfd_vma set_start;
139
140/* Adjustments to section VMA's. */
141static bfd_vma adjust_section_vma = 0;
6c7ed084 142
596d99ba
ILT
143/* Filling gaps between sections. */
144static boolean gap_fill_set = false;
87a15686
ILT
145static bfd_byte gap_fill = 0;
146
147/* Pad to a given address. */
148static boolean pad_to_set = false;
149static bfd_vma pad_to;
596d99ba 150
5ab41086
ILT
151/* List of sections to add. */
152
153struct section_add
154{
155 /* Next section to add. */
156 struct section_add *next;
157 /* Name of section to add. */
158 const char *name;
159 /* Name of file holding section contents. */
160 const char *filename;
161 /* Size of file. */
162 size_t size;
163 /* Contents of file. */
164 bfd_byte *contents;
165 /* BFD section, after it has been added. */
166 asection *section;
167};
168
169static struct section_add *add_sections;
170
f5818d79
ILT
171/* Whether to convert debugging information. */
172
173static boolean convert_debugging = false;
174
8d2e72a1
RH
175/* Whether to change the leading character in symbol names. */
176
177static boolean change_leading_char = false;
178
179/* Whether to remove the leading character from global symbol names. */
180
181static boolean remove_leading_char = false;
182
25fd0ed4
ILT
183/* List of symbols to strip, keep, localize, and weaken. */
184
185static struct symlist *strip_specific_list = NULL;
186static struct symlist *keep_specific_list = NULL;
187static struct symlist *localize_specific_list = NULL;
188static struct symlist *weaken_specific_list = NULL;
189
190/* If this is true, we weaken global symbols (set BSF_WEAK). */
191
192static boolean weaken = false;
193
9135e5f8
ILT
194/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
195
196#define OPTION_ADD_SECTION 150
197#define OPTION_ADJUST_START (OPTION_ADD_SECTION + 1)
198#define OPTION_ADJUST_VMA (OPTION_ADJUST_START + 1)
199#define OPTION_ADJUST_SECTION_VMA (OPTION_ADJUST_VMA + 1)
200#define OPTION_ADJUST_WARNINGS (OPTION_ADJUST_SECTION_VMA + 1)
8d2e72a1
RH
201#define OPTION_CHANGE_LEADING_CHAR (OPTION_ADJUST_WARNINGS + 1)
202#define OPTION_DEBUGGING (OPTION_CHANGE_LEADING_CHAR + 1)
f5818d79 203#define OPTION_GAP_FILL (OPTION_DEBUGGING + 1)
9135e5f8
ILT
204#define OPTION_NO_ADJUST_WARNINGS (OPTION_GAP_FILL + 1)
205#define OPTION_PAD_TO (OPTION_NO_ADJUST_WARNINGS + 1)
8d2e72a1
RH
206#define OPTION_REMOVE_LEADING_CHAR (OPTION_PAD_TO + 1)
207#define OPTION_SET_SECTION_FLAGS (OPTION_REMOVE_LEADING_CHAR + 1)
9135e5f8
ILT
208#define OPTION_SET_START (OPTION_SET_SECTION_FLAGS + 1)
209#define OPTION_STRIP_UNNEEDED (OPTION_SET_START + 1)
8d2e72a1 210#define OPTION_WEAKEN (OPTION_STRIP_UNNEEDED + 1)
9135e5f8 211
46050fe4
ILT
212/* Options to handle if running as "strip". */
213
214static struct option strip_options[] =
c0367ba5 215{
46050fe4
ILT
216 {"discard-all", no_argument, 0, 'x'},
217 {"discard-locals", no_argument, 0, 'X'},
f7b839f7 218 {"format", required_argument, 0, 'F'}, /* Obsolete */
46050fe4 219 {"help", no_argument, 0, 'h'},
46050fe4 220 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
f7b839f7 221 {"input-target", required_argument, 0, 'I'},
9135e5f8 222 {"keep-symbol", required_argument, 0, 'K'},
46050fe4 223 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
f7b839f7 224 {"output-target", required_argument, 0, 'O'},
8d2e72a1 225 {"preserve-dates", no_argument, 0, 'p'},
6c7ed084 226 {"remove-section", required_argument, 0, 'R'},
f7b839f7
DM
227 {"strip-all", no_argument, 0, 's'},
228 {"strip-debug", no_argument, 0, 'S'},
9135e5f8 229 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
4af19c61 230 {"strip-symbol", required_argument, 0, 'N'},
46050fe4 231 {"target", required_argument, 0, 'F'},
46050fe4 232 {"verbose", no_argument, 0, 'v'},
f7b839f7 233 {"version", no_argument, 0, 'V'},
46050fe4 234 {0, no_argument, 0, 0}
c0367ba5
ILT
235};
236
46050fe4 237/* Options to handle if running as "objcopy". */
c0367ba5 238
46050fe4
ILT
239static struct option copy_options[] =
240{
5ab41086 241 {"add-section", required_argument, 0, OPTION_ADD_SECTION},
6c7ed084
ILT
242 {"adjust-start", required_argument, 0, OPTION_ADJUST_START},
243 {"adjust-vma", required_argument, 0, OPTION_ADJUST_VMA},
244 {"adjust-section-vma", required_argument, 0, OPTION_ADJUST_SECTION_VMA},
245 {"adjust-warnings", no_argument, 0, OPTION_ADJUST_WARNINGS},
f7b839f7 246 {"byte", required_argument, 0, 'b'},
8d2e72a1 247 {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR},
f5818d79 248 {"debugging", no_argument, 0, OPTION_DEBUGGING},
46050fe4
ILT
249 {"discard-all", no_argument, 0, 'x'},
250 {"discard-locals", no_argument, 0, 'X'},
f7b839f7 251 {"format", required_argument, 0, 'F'}, /* Obsolete */
596d99ba 252 {"gap-fill", required_argument, 0, OPTION_GAP_FILL},
46050fe4 253 {"help", no_argument, 0, 'h'},
46050fe4 254 {"input-format", required_argument, 0, 'I'}, /* Obsolete */
f7b839f7
DM
255 {"input-target", required_argument, 0, 'I'},
256 {"interleave", required_argument, 0, 'i'},
9135e5f8 257 {"keep-symbol", required_argument, 0, 'K'},
6c7ed084 258 {"no-adjust-warnings", no_argument, 0, OPTION_NO_ADJUST_WARNINGS},
46050fe4 259 {"output-format", required_argument, 0, 'O'}, /* Obsolete */
f7b839f7 260 {"output-target", required_argument, 0, 'O'},
87a15686 261 {"pad-to", required_argument, 0, OPTION_PAD_TO},
8d2e72a1 262 {"preserve-dates", no_argument, 0, 'p'},
246b7c9b 263 {"localize-symbol", required_argument, 0, 'L'},
8d2e72a1 264 {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
6c7ed084 265 {"remove-section", required_argument, 0, 'R'},
5ab41086 266 {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
6c7ed084 267 {"set-start", required_argument, 0, OPTION_SET_START},
f7b839f7
DM
268 {"strip-all", no_argument, 0, 'S'},
269 {"strip-debug", no_argument, 0, 'g'},
9135e5f8 270 {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
4af19c61 271 {"strip-symbol", required_argument, 0, 'N'},
46050fe4 272 {"target", required_argument, 0, 'F'},
46050fe4 273 {"verbose", no_argument, 0, 'v'},
f7b839f7 274 {"version", no_argument, 0, 'V'},
8d2e72a1
RH
275 {"weaken", no_argument, 0, OPTION_WEAKEN},
276 {"weaken-symbol", required_argument, 0, 'W'},
46050fe4 277 {0, no_argument, 0, 0}
c0367ba5
ILT
278};
279
280/* IMPORTS */
46050fe4 281extern char *program_name;
46050fe4
ILT
282
283/* This flag distinguishes between strip and objcopy:
284 1 means this is 'strip'; 0 means this is 'objcopy'.
285 -1 means if we should use argv[0] to decide. */
286extern int is_strip;
c0367ba5
ILT
287
288
46050fe4 289static void
5ab41086 290copy_usage (stream, exit_status)
c0367ba5 291 FILE *stream;
5ab41086 292 int exit_status;
c0367ba5 293{
9d04d618 294 fprintf (stream, _("\
8d2e72a1 295Usage: %s [-vVSpgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
6c7ed084 296 [-R section] [-i interleave] [--interleave=interleave] [--byte=byte]\n\
46050fe4 297 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
9135e5f8 298 [--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n\
9d04d618 299 [--discard-locals] [--debugging] [--remove-section=section]\n"),
5ab41086 300 program_name);
9d04d618 301 fprintf (stream, _("\
8d2e72a1 302 [--gap-fill=val] [--pad-to=address] [--preserve-dates]\n\
f5818d79 303 [--set-start=val] [--adjust-start=incr]\n\
9135e5f8
ILT
304 [--adjust-vma=incr] [--adjust-section-vma=section{=,+,-}val]\n\
305 [--adjust-warnings] [--no-adjust-warnings]\n\
306 [--set-section-flags=section=flags] [--add-section=sectionname=filename]\n\
307 [--keep-symbol symbol] [-K symbol] [--strip-symbol symbol] [-N symbol]\n\
246b7c9b 308 [--localize-symbol symbol] [-L symbol] [--weaken-symbol symbol]\n\
8d2e72a1 309 [-W symbol] [--change-leading-char] [--remove-leading-char] [--weaken]\n\
9d04d618 310 [--verbose] [--version] [--help] in-file [out-file]\n"));
be1d162b 311 list_supported_targets (program_name, stream);
8d2e72a1 312 if (exit_status == 0)
9d04d618 313 fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
5ab41086 314 exit (exit_status);
c0367ba5
ILT
315}
316
46050fe4 317static void
5ab41086 318strip_usage (stream, exit_status)
c0367ba5 319 FILE *stream;
5ab41086 320 int exit_status;
c0367ba5 321{
9d04d618 322 fprintf (stream, _("\
8d2e72a1 323Usage: %s [-vVsSpgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-R section]\n\
46050fe4 324 [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
9135e5f8
ILT
325 [--strip-all] [--strip-debug] [--strip-unneeded] [--discard-all]\n\
326 [--discard-locals] [--keep-symbol symbol] [-K symbol]\n\
327 [--strip-symbol symbol] [-N symbol] [--remove-section=section]\n\
9d04d618 328 [-o file] [--preserve-dates] [--verbose] [--version] [--help] file...\n"),
46050fe4 329 program_name);
be1d162b 330 list_supported_targets (program_name, stream);
8d2e72a1 331 if (exit_status == 0)
9d04d618 332 fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n"));
5ab41086 333 exit (exit_status);
c0367ba5
ILT
334}
335
5ab41086
ILT
336/* Parse section flags into a flagword, with a fatal error if the
337 string can't be parsed. */
338
339static flagword
340parse_flags (s)
341 const char *s;
342{
343 flagword ret;
344 const char *snext;
345 int len;
346
347 ret = SEC_NO_FLAGS;
348
349 do
350 {
351 snext = strchr (s, ',');
352 if (snext == NULL)
353 len = strlen (s);
354 else
355 {
356 len = snext - s;
357 ++snext;
358 }
359
ee1f0bd1
ILT
360 if (0) ;
361#define PARSE_FLAG(fname,fval) \
362 else if (strncasecmp (fname, s, len) == 0) ret |= fval
5ab41086
ILT
363 PARSE_FLAG ("alloc", SEC_ALLOC);
364 PARSE_FLAG ("load", SEC_LOAD);
365 PARSE_FLAG ("readonly", SEC_READONLY);
366 PARSE_FLAG ("code", SEC_CODE);
367 PARSE_FLAG ("data", SEC_DATA);
368 PARSE_FLAG ("rom", SEC_ROM);
ee1f0bd1 369 PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
5ab41086 370#undef PARSE_FLAG
ee1f0bd1
ILT
371 else
372 {
373 char *copy;
374
375 copy = xmalloc (len + 1);
376 strncpy (copy, s, len);
377 copy[len] = '\0';
9d04d618 378 fprintf (stderr, _("%s: unrecognized section flag `%s'\n"),
ee1f0bd1
ILT
379 program_name, copy);
380 fprintf (stderr,
9d04d618 381 _("%s: supported flags: alloc, load, readonly, code, data, rom, contents\n"),
ee1f0bd1
ILT
382 program_name);
383 exit (1);
384 }
5ab41086
ILT
385
386 s = snext;
387 }
388 while (s != NULL);
389
390 return ret;
391}
392
5ab41086
ILT
393/* Find and optionally add an entry in the adjust_sections list. */
394
395static struct section_list *
396find_section_list (name, add)
397 const char *name;
398 boolean add;
399{
400 register struct section_list *p;
401
402 for (p = adjust_sections; p != NULL; p = p->next)
403 if (strcmp (p->name, name) == 0)
404 return p;
405
406 if (! add)
407 return NULL;
408
409 p = (struct section_list *) xmalloc (sizeof (struct section_list));
410 p->name = name;
411 p->used = false;
412 p->remove = false;
413 p->adjust = ignore_vma;
414 p->val = 0;
415 p->set_flags = false;
416 p->flags = 0;
417
418 p->next = adjust_sections;
419 adjust_sections = p;
420
421 return p;
422}
423
9135e5f8
ILT
424/* Add a symbol to strip_specific_list. */
425
4af19c61 426static void
8d2e72a1 427add_specific_symbol (name, list)
4af19c61 428 const char *name;
8d2e72a1 429 struct symlist **list;
4af19c61
KR
430{
431 struct symlist *tmp_list;
432
433 tmp_list = (struct symlist *) xmalloc (sizeof (struct symlist));
434 tmp_list->name = name;
8d2e72a1
RH
435 tmp_list->next = *list;
436 *list = tmp_list;
4af19c61
KR
437}
438
9135e5f8
ILT
439/* See whether a symbol should be stripped or kept based on
440 strip_specific_list and keep_symbols. */
441
5ab41086 442static boolean
8d2e72a1 443is_specified_symbol (name, list)
4af19c61 444 const char *name;
8d2e72a1 445 struct symlist *list;
4af19c61
KR
446{
447 struct symlist *tmp_list;
448
8d2e72a1 449 for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
4af19c61
KR
450 {
451 if (strcmp (name, tmp_list->name) == 0)
8d2e72a1 452 return true;
4af19c61 453 }
8d2e72a1 454 return false;
5ab41086
ILT
455}
456
457/* See if a section is being removed. */
458
459static boolean
460is_strip_section (abfd, sec)
461 bfd *abfd;
462 asection *sec;
463{
464 struct section_list *p;
465
be1d162b
ILT
466 if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
467 && (strip_symbols == strip_debug
9135e5f8 468 || strip_symbols == strip_unneeded
be1d162b 469 || strip_symbols == strip_all
f5818d79
ILT
470 || discard_locals == locals_all
471 || convert_debugging))
be1d162b
ILT
472 return true;
473
5ab41086
ILT
474 if (! sections_removed)
475 return false;
476 p = find_section_list (bfd_get_section_name (abfd, sec), false);
477 return p != NULL && p->remove ? true : false;
4af19c61
KR
478}
479
46050fe4 480/* Choose which symbol entries to copy; put the result in OSYMS.
c0367ba5 481 We don't copy in place, because that confuses the relocs.
46050fe4
ILT
482 Return the number of symbols to print. */
483
c0367ba5 484static unsigned int
8d2e72a1 485filter_symbols (abfd, obfd, osyms, isyms, symcount)
c0367ba5 486 bfd *abfd;
8d2e72a1 487 bfd *obfd;
c0367ba5 488 asymbol **osyms, **isyms;
ae5d2ff5 489 long symcount;
c0367ba5
ILT
490{
491 register asymbol **from = isyms, **to = osyms;
ae5d2ff5 492 long src_count = 0, dst_count = 0;
c0367ba5 493
46050fe4
ILT
494 for (; src_count < symcount; src_count++)
495 {
496 asymbol *sym = from[src_count];
497 flagword flags = sym->flags;
8d2e72a1 498 const char *name = bfd_asymbol_name (sym);
46050fe4 499 int keep;
c0367ba5 500
8d2e72a1
RH
501 if (change_leading_char
502 && (bfd_get_symbol_leading_char (abfd)
503 != bfd_get_symbol_leading_char (obfd))
504 && (bfd_get_symbol_leading_char (abfd) == '\0'
505 || (name[0] == bfd_get_symbol_leading_char (abfd))))
506 {
507 if (bfd_get_symbol_leading_char (obfd) == '\0')
508 name = bfd_asymbol_name (sym) = name + 1;
509 else
510 {
511 char *n;
512
513 n = xmalloc (strlen (name) + 2);
514 n[0] = bfd_get_symbol_leading_char (obfd);
515 if (bfd_get_symbol_leading_char (abfd) == '\0')
516 strcpy (n + 1, name);
517 else
518 strcpy (n + 1, name + 1);
519 name = bfd_asymbol_name (sym) = n;
520 }
521 }
522
523 if (remove_leading_char
524 && ((flags & BSF_GLOBAL) != 0
525 || (flags & BSF_WEAK) != 0
526 || bfd_is_und_section (bfd_get_section (sym))
527 || bfd_is_com_section (bfd_get_section (sym)))
528 && name[0] == bfd_get_symbol_leading_char (abfd))
529 name = bfd_asymbol_name (sym) = name + 1;
530
9135e5f8 531 if ((flags & BSF_KEEP) != 0) /* Used in relocation. */
46050fe4 532 keep = 1;
9135e5f8 533 else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
8d2e72a1 534 || (flags & BSF_WEAK) != 0
9135e5f8
ILT
535 || bfd_is_und_section (bfd_get_section (sym))
536 || bfd_is_com_section (bfd_get_section (sym)))
537 keep = strip_symbols != strip_unneeded;
46050fe4 538 else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */
9135e5f8 539 keep = (strip_symbols != strip_debug
f5818d79
ILT
540 && strip_symbols != strip_unneeded
541 && ! convert_debugging);
46050fe4 542 else /* Local symbol. */
9135e5f8
ILT
543 keep = (strip_symbols != strip_unneeded
544 && (discard_locals != locals_all
545 && (discard_locals != locals_start_L
546 || ! bfd_is_local_label (abfd, sym))));
4af19c61 547
8d2e72a1 548 if (keep && is_specified_symbol (name, strip_specific_list))
4af19c61 549 keep = 0;
8d2e72a1
RH
550 if (!keep && is_specified_symbol (name, keep_specific_list))
551 keep = 1;
5ab41086
ILT
552 if (keep && is_strip_section (abfd, bfd_get_section (sym)))
553 keep = 0;
4af19c61 554
8d2e72a1
RH
555 if (keep && (flags & BSF_GLOBAL) != 0
556 && (weaken || is_specified_symbol (name, weaken_specific_list)))
557 {
558 sym->flags &=~ BSF_GLOBAL;
559 sym->flags |= BSF_WEAK;
560 }
561 if (keep && (flags & (BSF_GLOBAL | BSF_WEAK))
246b7c9b 562 && is_specified_symbol (name, localize_specific_list))
8d2e72a1
RH
563 {
564 sym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
565 sym->flags |= BSF_LOCAL;
566 }
567
46050fe4
ILT
568 if (keep)
569 to[dst_count++] = sym;
c0367ba5 570 }
c0367ba5 571
8d2e72a1
RH
572 to[dst_count] = NULL;
573
c0367ba5
ILT
574 return dst_count;
575}
576
f7b839f7
DM
577/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
578 Adjust *SIZE. */
579
8d2e72a1 580static void
f7b839f7 581filter_bytes (memhunk, size)
5d2f7e30 582 char *memhunk;
f7b839f7
DM
583 bfd_size_type *size;
584{
585 char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
586
587 for (; from < end; from += interleave)
588 *to++ = *from;
589 *size /= interleave;
590}
591
46050fe4
ILT
592/* Copy object file IBFD onto OBFD. */
593
c0367ba5 594static void
46050fe4
ILT
595copy_object (ibfd, obfd)
596 bfd *ibfd;
597 bfd *obfd;
c0367ba5 598{
6c7ed084 599 bfd_vma start;
ae5d2ff5 600 long symcount;
596d99ba
ILT
601 asection **osections = NULL;
602 bfd_size_type *gaps = NULL;
603 bfd_size_type max_gap = 0;
c0367ba5 604
46050fe4
ILT
605 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
606 {
607 nonfatal (bfd_get_filename (obfd));
608 }
c0367ba5 609
46050fe4 610 if (verbose)
9d04d618 611 printf (_("copy from %s(%s) to %s(%s)\n"),
46050fe4
ILT
612 bfd_get_filename(ibfd), bfd_get_target(ibfd),
613 bfd_get_filename(obfd), bfd_get_target(obfd));
c0367ba5 614
6c7ed084
ILT
615 if (set_start_set)
616 start = set_start;
617 else
a6afc090 618 start = bfd_get_start_address (ibfd);
6c7ed084
ILT
619 start += adjust_start;
620
621 if (!bfd_set_start_address (obfd, start)
46050fe4
ILT
622 || !bfd_set_file_flags (obfd,
623 (bfd_get_file_flags (ibfd)
624 & bfd_applicable_file_flags (obfd))))
625 {
626 nonfatal (bfd_get_filename (ibfd));
627 }
c0367ba5 628
46050fe4
ILT
629 /* Copy architecture of input file to output file */
630 if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
631 bfd_get_mach (ibfd)))
632 {
8d2e72a1 633 fprintf (stderr,
9d04d618 634 _("Warning: Output file cannot represent architecture %s\n"),
46050fe4
ILT
635 bfd_printable_arch_mach (bfd_get_arch (ibfd),
636 bfd_get_mach (ibfd)));
637 }
638 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
639 {
640 nonfatal (bfd_get_filename(ibfd));
641 }
c0367ba5 642
46050fe4
ILT
643 if (isympp)
644 free (isympp);
645 if (osympp != isympp)
646 free (osympp);
c0367ba5 647
77ccab3c
JL
648 /* bfd mandates that all output sections be created and sizes set before
649 any output is done. Thus, we traverse all sections multiple times. */
650 bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
651
5ab41086
ILT
652 if (add_sections != NULL)
653 {
654 struct section_add *padd;
655 struct section_list *pset;
656
657 for (padd = add_sections; padd != NULL; padd = padd->next)
658 {
659 padd->section = bfd_make_section (obfd, padd->name);
660 if (padd->section == NULL)
661 {
9d04d618 662 fprintf (stderr, _("%s: can't create section `%s': %s\n"),
5ab41086
ILT
663 program_name, padd->name,
664 bfd_errmsg (bfd_get_error ()));
665 status = 1;
666 return;
667 }
668 else
669 {
670 flagword flags;
671
672 if (! bfd_set_section_size (obfd, padd->section, padd->size))
673 nonfatal (bfd_get_filename (obfd));
674
675 pset = find_section_list (padd->name, false);
676 if (pset != NULL)
677 pset->used = true;
678
679 if (pset != NULL && pset->set_flags)
680 flags = pset->flags | SEC_HAS_CONTENTS;
681 else
682 flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DATA;
683 if (! bfd_set_section_flags (obfd, padd->section, flags))
684 nonfatal (bfd_get_filename (obfd));
685
686 if (pset != NULL
687 && (pset->adjust == adjust_vma
688 || pset->adjust == set_vma))
689 {
690 if (! bfd_set_section_vma (obfd, padd->section, pset->val))
691 nonfatal (bfd_get_filename (obfd));
692 }
693 }
694 }
695 }
696
87a15686 697 if (gap_fill_set || pad_to_set)
596d99ba
ILT
698 {
699 asection **set;
700 unsigned int c, i;
701
87a15686
ILT
702 /* We must fill in gaps between the sections and/or we must pad
703 the last section to a specified address. We do this by
596d99ba 704 grabbing a list of the sections, sorting them by VMA, and
87a15686
ILT
705 increasing the section sizes as required to fill the gaps.
706 We write out the gap contents below. */
596d99ba
ILT
707
708 c = bfd_count_sections (obfd);
709 osections = (asection **) xmalloc (c * sizeof (asection *));
710 set = osections;
711 bfd_map_over_sections (obfd, get_sections, (void *) &set);
712
22947e96 713 qsort (osections, c, sizeof (asection *), compare_section_lma);
596d99ba
ILT
714
715 gaps = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
87a15686
ILT
716 memset (gaps, 0, c * sizeof (bfd_size_type));
717
718 if (gap_fill_set)
719 {
720 for (i = 0; i < c - 1; i++)
721 {
722 flagword flags;
723 bfd_size_type size;
724 bfd_vma gap_start, gap_stop;
725
726 flags = bfd_get_section_flags (obfd, osections[i]);
727 if ((flags & SEC_HAS_CONTENTS) == 0
728 || (flags & SEC_LOAD) == 0)
729 continue;
730
731 size = bfd_section_size (obfd, osections[i]);
22947e96
ILT
732 gap_start = bfd_section_lma (obfd, osections[i]) + size;
733 gap_stop = bfd_section_lma (obfd, osections[i + 1]);
87a15686
ILT
734 if (gap_start < gap_stop)
735 {
736 if (! bfd_set_section_size (obfd, osections[i],
737 size + (gap_stop - gap_start)))
738 {
9d04d618 739 fprintf (stderr, _("%s: Can't fill gap after %s: %s\n"),
87a15686
ILT
740 program_name,
741 bfd_get_section_name (obfd, osections[i]),
742 bfd_errmsg (bfd_get_error()));
743 status = 1;
744 break;
745 }
746 gaps[i] = gap_stop - gap_start;
747 if (max_gap < gap_stop - gap_start)
748 max_gap = gap_stop - gap_start;
749 }
750 }
751 }
752
753 if (pad_to_set)
596d99ba 754 {
22947e96 755 bfd_vma lma;
596d99ba 756 bfd_size_type size;
87a15686 757
22947e96 758 lma = bfd_section_lma (obfd, osections[c - 1]);
87a15686 759 size = bfd_section_size (obfd, osections[c - 1]);
22947e96 760 if (lma + size < pad_to)
596d99ba 761 {
87a15686 762 if (! bfd_set_section_size (obfd, osections[c - 1],
22947e96 763 pad_to - lma))
596d99ba 764 {
9d04d618 765 fprintf (stderr, _("%s: Can't add padding to %s: %s\n"),
596d99ba 766 program_name,
87a15686
ILT
767 bfd_get_section_name (obfd, osections[c - 1]),
768 bfd_errmsg (bfd_get_error ()));
596d99ba 769 status = 1;
596d99ba 770 }
87a15686
ILT
771 else
772 {
22947e96
ILT
773 gaps[c - 1] = pad_to - (lma + size);
774 if (max_gap < pad_to - (lma + size))
775 max_gap = pad_to - (lma + size);
87a15686 776 }
596d99ba 777 }
22947e96 778 }
596d99ba
ILT
779 }
780
77ccab3c
JL
781 /* Symbol filtering must happen after the output sections have
782 been created, but before their contents are set. */
9135e5f8 783 if (strip_symbols == strip_all)
46050fe4
ILT
784 {
785 osympp = isympp = NULL;
786 symcount = 0;
c0367ba5 787 }
46050fe4
ILT
788 else
789 {
ae5d2ff5 790 long symsize;
f5818d79 791 PTR dhandle = NULL;
ae5d2ff5
ILT
792
793 symsize = bfd_get_symtab_upper_bound (ibfd);
794 if (symsize < 0)
795 {
796 nonfatal (bfd_get_filename (ibfd));
797 }
798
799 osympp = isympp = (asymbol **) xmalloc (symsize);
46050fe4 800 symcount = bfd_canonicalize_symtab (ibfd, isympp);
ae5d2ff5
ILT
801 if (symcount < 0)
802 {
803 nonfatal (bfd_get_filename (ibfd));
804 }
46050fe4 805
f5818d79
ILT
806 if (convert_debugging)
807 dhandle = read_debugging_info (ibfd, isympp, symcount);
808
4af19c61 809 if (strip_symbols == strip_debug
9135e5f8 810 || strip_symbols == strip_unneeded
4af19c61 811 || discard_locals != locals_undef
9135e5f8 812 || strip_specific_list != NULL
8d2e72a1 813 || keep_specific_list != NULL
246b7c9b 814 || localize_specific_list != NULL
8d2e72a1 815 || weaken_specific_list != NULL
f5818d79 816 || sections_removed
8d2e72a1
RH
817 || convert_debugging
818 || change_leading_char
819 || remove_leading_char
820 || weaken)
c0367ba5 821 {
77ccab3c
JL
822 /* Mark symbols used in output relocations so that they
823 are kept, even if they are local labels or static symbols.
824
825 Note we iterate over the input sections examining their
826 relocations since the relocations for the output sections
827 haven't been set yet. mark_symbols_used_in_relocations will
828 ignore input sections which have no corresponding output
829 section. */
830 bfd_map_over_sections (ibfd,
831 mark_symbols_used_in_relocations,
6c7ed084 832 (PTR)isympp);
8d2e72a1
RH
833 osympp = (asymbol **) xmalloc ((symcount + 1) * sizeof (asymbol *));
834 symcount = filter_symbols (ibfd, obfd, osympp, isympp, symcount);
c0367ba5 835 }
f5818d79
ILT
836
837 if (convert_debugging && dhandle != NULL)
838 {
839 if (! write_debugging_info (obfd, dhandle, &symcount, &osympp))
840 {
841 status = 1;
842 return;
843 }
844 }
46050fe4
ILT
845 }
846
847 bfd_set_symtab (obfd, osympp, symcount);
c0367ba5 848
77ccab3c 849 /* This has to happen after the symbol table has been set. */
f7b839f7 850 bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
6f9077cd 851
5ab41086
ILT
852 if (add_sections != NULL)
853 {
854 struct section_add *padd;
855
856 for (padd = add_sections; padd != NULL; padd = padd->next)
857 {
858 if (! bfd_set_section_contents (obfd, padd->section,
859 (PTR) padd->contents,
860 (file_ptr) 0,
861 (bfd_size_type) padd->size))
862 nonfatal (bfd_get_filename (obfd));
863 }
864 }
865
87a15686 866 if (gap_fill_set || pad_to_set)
596d99ba
ILT
867 {
868 bfd_byte *buf;
869 int c, i;
870
871 /* Fill in the gaps. */
872
873 if (max_gap > 8192)
874 max_gap = 8192;
875 buf = (bfd_byte *) xmalloc (max_gap);
a445cee7 876 memset (buf, gap_fill, (size_t) max_gap);
596d99ba
ILT
877
878 c = bfd_count_sections (obfd);
87a15686 879 for (i = 0; i < c; i++)
596d99ba
ILT
880 {
881 if (gaps[i] != 0)
882 {
883 bfd_size_type left;
884 file_ptr off;
885
886 left = gaps[i];
887 off = bfd_section_size (obfd, osections[i]) - left;
888 while (left > 0)
889 {
890 bfd_size_type now;
891
892 if (left > 8192)
893 now = 8192;
894 else
895 now = left;
896 if (! bfd_set_section_contents (obfd, osections[i], buf,
897 off, now))
898 {
899 nonfatal (bfd_get_filename (obfd));
596d99ba
ILT
900 }
901 left -= now;
902 off += now;
903 }
904 }
905 }
906 }
907
6f9077cd
JM
908 /* Allow the BFD backend to copy any private data it understands
909 from the input BFD to the output BFD. This is done last to
910 permit the routine to look at the filtered symbol table, which is
911 important for the ECOFF code at least. */
912 if (!bfd_copy_private_bfd_data (ibfd, obfd))
913 {
9d04d618 914 fprintf (stderr, _("%s: %s: error copying private BFD data: %s\n"),
6f9077cd
JM
915 program_name, bfd_get_filename (obfd),
916 bfd_errmsg (bfd_get_error ()));
917 status = 1;
918 return;
919 }
c0367ba5 920}
46050fe4 921
46050fe4
ILT
922/* Read each archive element in turn from IBFD, copy the
923 contents to temp file, and keep the temp file handle. */
924
925static void
926copy_archive (ibfd, obfd, output_target)
927 bfd *ibfd;
928 bfd *obfd;
8d2e72a1 929 const char *output_target;
c0367ba5 930{
87a15686
ILT
931 struct name_list
932 {
933 struct name_list *next;
934 char *name;
4c8d7e6b 935 bfd *obfd;
87a15686 936 } *list, *l;
46050fe4
ILT
937 bfd **ptr = &obfd->archive_head;
938 bfd *this_element;
90f6517d 939 char *dir = make_tempname (bfd_get_filename (obfd));
46050fe4
ILT
940
941 /* Make a temp directory to hold the contents. */
eaa147a6
ILT
942#if defined (_WIN32) && !defined (__CYGWIN32__)
943 if (mkdir (dir) != 0)
944#else
9135e5f8 945 if (mkdir (dir, 0700) != 0)
eaa147a6 946#endif
9135e5f8 947 {
9d04d618 948 fatal (_("cannot mkdir %s for archive copying (error: %s)"),
9135e5f8
ILT
949 dir, strerror (errno));
950 }
46050fe4
ILT
951 obfd->has_armap = ibfd->has_armap;
952
87a15686
ILT
953 list = NULL;
954
46050fe4 955 this_element = bfd_openr_next_archived_file (ibfd, NULL);
46050fe4
ILT
956 while (this_element != (bfd *) NULL)
957 {
958 /* Create an output file for this member. */
8d2e72a1
RH
959 char *output_name = concat (dir, "/", bfd_get_filename(this_element),
960 (char *) NULL);
46050fe4 961 bfd *output_bfd = bfd_openw (output_name, output_target);
87a15686
ILT
962 bfd *last_element;
963
964 l = (struct name_list *) xmalloc (sizeof (struct name_list));
965 l->name = output_name;
966 l->next = list;
967 list = l;
46050fe4
ILT
968
969 if (output_bfd == (bfd *) NULL)
970 {
971 nonfatal (output_name);
c0367ba5 972 }
46050fe4
ILT
973 if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
974 {
975 nonfatal (bfd_get_filename (obfd));
c0367ba5
ILT
976 }
977
46050fe4
ILT
978 if (bfd_check_format (this_element, bfd_object) == true)
979 {
980 copy_object (this_element, output_bfd);
981 }
c0367ba5 982
46050fe4 983 bfd_close (output_bfd);
87a15686
ILT
984
985 /* Open the newly output file and attach to our list. */
46050fe4 986 output_bfd = bfd_openr (output_name, output_target);
c0367ba5 987
4c8d7e6b
ILT
988 l->obfd = output_bfd;
989
46050fe4
ILT
990 *ptr = output_bfd;
991 ptr = &output_bfd->next;
87a15686
ILT
992
993 last_element = this_element;
994
995 this_element = bfd_openr_next_archived_file (ibfd, last_element);
996
997 bfd_close (last_element);
c0367ba5 998 }
46050fe4 999 *ptr = (bfd *) NULL;
c0367ba5 1000
46050fe4
ILT
1001 if (!bfd_close (obfd))
1002 {
1003 nonfatal (bfd_get_filename (obfd));
c0367ba5 1004 }
c0367ba5 1005
46050fe4
ILT
1006 if (!bfd_close (ibfd))
1007 {
1008 nonfatal (bfd_get_filename (ibfd));
1009 }
4c8d7e6b
ILT
1010
1011 /* Delete all the files that we opened. */
1012 for (l = list; l != NULL; l = l->next)
1013 {
1014 bfd_close (l->obfd);
1015 unlink (l->name);
1016 }
1017 rmdir (dir);
c0367ba5
ILT
1018}
1019
46050fe4
ILT
1020/* The top-level control. */
1021
1022static void
1023copy_file (input_filename, output_filename, input_target, output_target)
8d2e72a1
RH
1024 const char *input_filename;
1025 const char *output_filename;
1026 const char *input_target;
1027 const char *output_target;
c0367ba5 1028{
46050fe4 1029 bfd *ibfd;
cef35d48 1030 char **matching;
c0367ba5
ILT
1031
1032 /* To allow us to do "strip *" without dying on the first
1033 non-object file, failures are nonfatal. */
1034
46050fe4 1035 ibfd = bfd_openr (input_filename, input_target);
c0367ba5
ILT
1036 if (ibfd == NULL)
1037 {
46050fe4 1038 nonfatal (input_filename);
c0367ba5
ILT
1039 }
1040
cef35d48
DM
1041 if (bfd_check_format (ibfd, bfd_archive))
1042 {
6c7ed084
ILT
1043 bfd *obfd;
1044
1045 /* bfd_get_target does not return the correct value until
1046 bfd_check_format succeeds. */
1047 if (output_target == NULL)
1048 output_target = bfd_get_target (ibfd);
1049
1050 obfd = bfd_openw (output_filename, output_target);
cef35d48
DM
1051 if (obfd == NULL)
1052 {
1053 nonfatal (output_filename);
1054 }
1055 copy_archive (ibfd, obfd, output_target);
1056 }
1057 else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
46050fe4 1058 {
6c7ed084
ILT
1059 bfd *obfd;
1060
1061 /* bfd_get_target does not return the correct value until
1062 bfd_check_format succeeds. */
1063 if (output_target == NULL)
1064 output_target = bfd_get_target (ibfd);
1065
1066 obfd = bfd_openw (output_filename, output_target);
46050fe4
ILT
1067 if (obfd == NULL)
1068 {
1069 nonfatal (output_filename);
1070 }
c0367ba5 1071
46050fe4 1072 copy_object (ibfd, obfd);
c0367ba5 1073
46050fe4
ILT
1074 if (!bfd_close (obfd))
1075 {
1076 nonfatal (output_filename);
1077 }
1078
1079 if (!bfd_close (ibfd))
1080 {
1081 nonfatal (input_filename);
1082 }
1083 }
cef35d48 1084 else
46050fe4 1085 {
cef35d48 1086 bfd_nonfatal (input_filename);
c9563567 1087 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
46050fe4 1088 {
cef35d48
DM
1089 list_matching_formats (matching);
1090 free (matching);
46050fe4 1091 }
cef35d48 1092 status = 1;
46050fe4
ILT
1093 }
1094}
1095
1096/* Create a section in OBFD with the same name and attributes
1097 as ISECTION in IBFD. */
c0367ba5 1098
c0367ba5 1099static void
6c7ed084 1100setup_section (ibfd, isection, obfdarg)
46050fe4
ILT
1101 bfd *ibfd;
1102 sec_ptr isection;
6c7ed084 1103 PTR obfdarg;
c0367ba5 1104{
6c7ed084
ILT
1105 bfd *obfd = (bfd *) obfdarg;
1106 struct section_list *p;
46050fe4 1107 sec_ptr osection;
6c7ed084 1108 bfd_vma vma;
f5818d79 1109 bfd_vma lma;
5ab41086 1110 flagword flags;
46050fe4
ILT
1111 char *err;
1112
1113 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1114 && (strip_symbols == strip_debug
9135e5f8 1115 || strip_symbols == strip_unneeded
46050fe4 1116 || strip_symbols == strip_all
f5818d79
ILT
1117 || discard_locals == locals_all
1118 || convert_debugging))
46050fe4
ILT
1119 return;
1120
5ab41086
ILT
1121 p = find_section_list (bfd_section_name (ibfd, isection), false);
1122 if (p != NULL)
1123 p->used = true;
1124
1125 if (p != NULL && p->remove)
1126 return;
6c7ed084 1127
77ccab3c 1128 osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection));
46050fe4
ILT
1129 if (osection == NULL)
1130 {
77ccab3c
JL
1131 err = "making";
1132 goto loser;
c0367ba5
ILT
1133 }
1134
46050fe4
ILT
1135 if (!bfd_set_section_size (obfd,
1136 osection,
1137 bfd_section_size (ibfd, isection)))
1138 {
1139 err = "size";
1140 goto loser;
c0367ba5
ILT
1141 }
1142
6c7ed084 1143 vma = bfd_section_vma (ibfd, isection);
5ab41086
ILT
1144 if (p != NULL && p->adjust == adjust_vma)
1145 vma += p->val;
1146 else if (p != NULL && p->adjust == set_vma)
1147 vma = p->val;
1148 else
6c7ed084 1149 vma += adjust_section_vma;
6c7ed084 1150 if (! bfd_set_section_vma (obfd, osection, vma))
46050fe4
ILT
1151 {
1152 err = "vma";
1153 goto loser;
1154 }
c0367ba5 1155
f5818d79
ILT
1156 lma = isection->lma;
1157 if (p != NULL && p->adjust == adjust_vma)
1158 lma += p->val;
1159 else if (p != NULL && p->adjust == set_vma)
1160 lma = p->val;
1161 else
1162 lma += adjust_section_vma;
1163 osection->lma = lma;
1164
46050fe4
ILT
1165 if (bfd_set_section_alignment (obfd,
1166 osection,
1167 bfd_section_alignment (ibfd, isection))
1168 == false)
1169 {
1170 err = "alignment";
1171 goto loser;
1172 }
c0367ba5 1173
842eba66 1174 flags = bfd_get_section_flags (ibfd, isection);
5ab41086 1175 if (p != NULL && p->set_flags)
842eba66 1176 flags = p->flags | (flags & SEC_HAS_CONTENTS);
5ab41086 1177 if (!bfd_set_section_flags (obfd, osection, flags))
46050fe4
ILT
1178 {
1179 err = "flags";
1180 goto loser;
c0367ba5
ILT
1181 }
1182
c9563567
JL
1183 /* This used to be mangle_section; we do here to avoid using
1184 bfd_get_section_by_name since some formats allow multiple
1185 sections with the same name. */
1186 isection->output_section = osection;
1187 isection->output_offset = 0;
1188
77ccab3c
JL
1189 /* Allow the BFD backend to copy any private data it understands
1190 from the input section to the output section. */
1191 if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
1192 {
1193 err = "private data";
1194 goto loser;
1195 }
1196
46050fe4
ILT
1197 /* All went well */
1198 return;
c0367ba5
ILT
1199
1200loser:
9d04d618 1201 fprintf (stderr, _("%s: %s: section `%s': error in %s: %s\n"),
46050fe4
ILT
1202 program_name,
1203 bfd_get_filename (ibfd), bfd_section_name (ibfd, isection),
c9563567 1204 err, bfd_errmsg (bfd_get_error ()));
46050fe4
ILT
1205 status = 1;
1206}
1207
1208/* Copy the data of input section ISECTION of IBFD
1209 to an output section with the same name in OBFD.
1210 If stripping then don't copy any relocation info. */
1211
c0367ba5 1212static void
6c7ed084 1213copy_section (ibfd, isection, obfdarg)
46050fe4
ILT
1214 bfd *ibfd;
1215 sec_ptr isection;
6c7ed084 1216 PTR obfdarg;
c0367ba5 1217{
6c7ed084
ILT
1218 bfd *obfd = (bfd *) obfdarg;
1219 struct section_list *p;
46050fe4 1220 arelent **relpp;
ae5d2ff5 1221 long relcount;
46050fe4
ILT
1222 sec_ptr osection;
1223 bfd_size_type size;
1224
1225 if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
1226 && (strip_symbols == strip_debug
9135e5f8 1227 || strip_symbols == strip_unneeded
46050fe4 1228 || strip_symbols == strip_all
f5818d79
ILT
1229 || discard_locals == locals_all
1230 || convert_debugging))
46050fe4
ILT
1231 {
1232 return;
1233 }
c0367ba5 1234
5ab41086
ILT
1235 p = find_section_list (bfd_section_name (ibfd, isection), false);
1236
1237 if (p != NULL && p->remove)
1238 return;
6c7ed084 1239
77ccab3c 1240 osection = isection->output_section;
46050fe4 1241 size = bfd_get_section_size_before_reloc (isection);
c0367ba5 1242
77ccab3c 1243 if (size == 0 || osection == 0)
c0367ba5
ILT
1244 return;
1245
ae5d2ff5
ILT
1246 if (strip_symbols == strip_all)
1247 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
46050fe4 1248 else
c0367ba5 1249 {
ae5d2ff5
ILT
1250 long relsize;
1251
1252 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1253 if (relsize < 0)
1254 {
1255 nonfatal (bfd_get_filename (ibfd));
1256 }
1257 if (relsize == 0)
1258 bfd_set_reloc (obfd, osection, (arelent **) NULL, 0);
1259 else
1260 {
1261 relpp = (arelent **) xmalloc (relsize);
1262 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
1263 if (relcount < 0)
1264 {
1265 nonfatal (bfd_get_filename (ibfd));
1266 }
1267 bfd_set_reloc (obfd, osection, relpp, relcount);
1268 }
c0367ba5
ILT
1269 }
1270
1271 isection->_cooked_size = isection->_raw_size;
46050fe4 1272 isection->reloc_done = true;
c0367ba5 1273
46050fe4 1274 if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)
c0367ba5 1275 {
46050fe4 1276 PTR memhunk = (PTR) xmalloc ((unsigned) size);
c0367ba5 1277
46050fe4
ILT
1278 if (!bfd_get_section_contents (ibfd, isection, memhunk, (file_ptr) 0,
1279 size))
1280 {
1281 nonfatal (bfd_get_filename (ibfd));
1282 }
c0367ba5 1283
6f9077cd
JM
1284 if (copy_byte >= 0)
1285 {
1286 filter_bytes (memhunk, &size);
1287 /* The section has gotten smaller. */
1288 if (!bfd_set_section_size (obfd, osection, size))
1289 nonfatal (bfd_get_filename (obfd));
1290 }
f7b839f7 1291
46050fe4
ILT
1292 if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1293 size))
1294 {
1295 nonfatal (bfd_get_filename (obfd));
1296 }
1297 free (memhunk);
ee1f0bd1 1298 }
eaa147a6 1299 else if (p != NULL && p->set_flags && (p->flags & SEC_HAS_CONTENTS) != 0)
ee1f0bd1
ILT
1300 {
1301 PTR memhunk = (PTR) xmalloc ((unsigned) size);
1302
1303 /* We don't permit the user to turn off the SEC_HAS_CONTENTS
1304 flag--they can just remove the section entirely and add it
1305 back again. However, we do permit them to turn on the
1306 SEC_HAS_CONTENTS flag, and take it to mean that the section
1307 contents should be zeroed out. */
1308
1309 memset (memhunk, 0, size);
1310 if (! bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
1311 size))
1312 nonfatal (bfd_get_filename (obfd));
1313 free (memhunk);
c0367ba5 1314 }
46050fe4 1315}
c0367ba5 1316
87a15686
ILT
1317/* Get all the sections. This is used when --gap-fill or --pad-to is
1318 used. */
596d99ba
ILT
1319
1320static void
1321get_sections (obfd, osection, secppparg)
1322 bfd *obfd;
1323 asection *osection;
1324 PTR secppparg;
1325{
1326 asection ***secppp = (asection ***) secppparg;
1327
1328 **secppp = osection;
1329 ++(*secppp);
1330}
1331
1332/* Sort sections by VMA. This is called via qsort, and is used when
87a15686
ILT
1333 --gap-fill or --pad-to is used. We force non loadable or empty
1334 sections to the front, where they are easier to ignore. */
596d99ba
ILT
1335
1336static int
22947e96 1337compare_section_lma (arg1, arg2)
596d99ba
ILT
1338 const PTR arg1;
1339 const PTR arg2;
1340{
1341 const asection **sec1 = (const asection **) arg1;
1342 const asection **sec2 = (const asection **) arg2;
87a15686
ILT
1343 flagword flags1, flags2;
1344
1345 /* Sort non loadable sections to the front. */
1346 flags1 = (*sec1)->flags;
1347 flags2 = (*sec2)->flags;
1348 if ((flags1 & SEC_HAS_CONTENTS) == 0
1349 || (flags1 & SEC_LOAD) == 0)
1350 {
1351 if ((flags2 & SEC_HAS_CONTENTS) != 0
1352 && (flags2 & SEC_LOAD) != 0)
1353 return -1;
1354 }
1355 else
1356 {
1357 if ((flags2 & SEC_HAS_CONTENTS) == 0
1358 || (flags2 & SEC_LOAD) == 0)
1359 return 1;
1360 }
596d99ba 1361
22947e96
ILT
1362 /* Sort sections by LMA. */
1363 if ((*sec1)->lma > (*sec2)->lma)
596d99ba 1364 return 1;
22947e96 1365 else if ((*sec1)->lma < (*sec2)->lma)
596d99ba 1366 return -1;
87a15686 1367
22947e96 1368 /* Sort sections with the same LMA by size. */
87a15686
ILT
1369 if ((*sec1)->_raw_size > (*sec2)->_raw_size)
1370 return 1;
1371 else if ((*sec1)->_raw_size < (*sec2)->_raw_size)
1372 return -1;
1373
1374 return 0;
596d99ba
ILT
1375}
1376
77ccab3c
JL
1377/* Mark all the symbols which will be used in output relocations with
1378 the BSF_KEEP flag so that those symbols will not be stripped.
1379
1380 Ignore relocations which will not appear in the output file. */
1381
1382static void
6c7ed084 1383mark_symbols_used_in_relocations (ibfd, isection, symbolsarg)
77ccab3c
JL
1384 bfd *ibfd;
1385 sec_ptr isection;
6c7ed084 1386 PTR symbolsarg;
77ccab3c 1387{
6c7ed084 1388 asymbol **symbols = (asymbol **) symbolsarg;
ae5d2ff5 1389 long relsize;
77ccab3c 1390 arelent **relpp;
ae5d2ff5 1391 long relcount, i;
77ccab3c
JL
1392
1393 /* Ignore an input section with no corresponding output section. */
1394 if (isection->output_section == NULL)
1395 return;
1396
ae5d2ff5
ILT
1397 relsize = bfd_get_reloc_upper_bound (ibfd, isection);
1398 if (relsize < 0)
1399 bfd_fatal (bfd_get_filename (ibfd));
1400
a445cee7 1401 if (relsize == 0)
28b5eb12 1402 return;
a445cee7 1403
ae5d2ff5 1404 relpp = (arelent **) xmalloc (relsize);
77ccab3c 1405 relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, symbols);
ae5d2ff5
ILT
1406 if (relcount < 0)
1407 bfd_fatal (bfd_get_filename (ibfd));
77ccab3c
JL
1408
1409 /* Examine each symbol used in a relocation. If it's not one of the
1410 special bfd section symbols, then mark it with BSF_KEEP. */
1411 for (i = 0; i < relcount; i++)
1412 {
6c7ed084
ILT
1413 if (*relpp[i]->sym_ptr_ptr != bfd_com_section_ptr->symbol
1414 && *relpp[i]->sym_ptr_ptr != bfd_abs_section_ptr->symbol
1415 && *relpp[i]->sym_ptr_ptr != bfd_und_section_ptr->symbol)
77ccab3c
JL
1416 (*relpp[i]->sym_ptr_ptr)->flags |= BSF_KEEP;
1417 }
1418
1419 if (relpp != NULL)
1420 free (relpp);
1421}
1422
f5818d79
ILT
1423/* Write out debugging information. */
1424
1425static boolean
1426write_debugging_info (obfd, dhandle, symcountp, symppp)
1427 bfd *obfd;
1428 PTR dhandle;
1429 long *symcountp;
1430 asymbol ***symppp;
1431{
1432 if (bfd_get_flavour (obfd) == bfd_target_ieee_flavour)
1433 return write_ieee_debugging_info (obfd, dhandle);
1434
8d2e72a1
RH
1435 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
1436 || bfd_get_flavour (obfd) == bfd_target_elf_flavour)
1437 {
1438 bfd_byte *syms, *strings;
1439 bfd_size_type symsize, stringsize;
1440 asection *stabsec, *stabstrsec;
1441
1442 if (! write_stabs_in_sections_debugging_info (obfd, dhandle, &syms,
1443 &symsize, &strings,
1444 &stringsize))
1445 return false;
1446
1447 stabsec = bfd_make_section (obfd, ".stab");
1448 stabstrsec = bfd_make_section (obfd, ".stabstr");
1449 if (stabsec == NULL
1450 || stabstrsec == NULL
1451 || ! bfd_set_section_size (obfd, stabsec, symsize)
1452 || ! bfd_set_section_size (obfd, stabstrsec, stringsize)
1453 || ! bfd_set_section_alignment (obfd, stabsec, 2)
1454 || ! bfd_set_section_alignment (obfd, stabstrsec, 0)
1455 || ! bfd_set_section_flags (obfd, stabsec,
1456 (SEC_HAS_CONTENTS
1457 | SEC_READONLY
1458 | SEC_DEBUGGING))
1459 || ! bfd_set_section_flags (obfd, stabstrsec,
1460 (SEC_HAS_CONTENTS
1461 | SEC_READONLY
1462 | SEC_DEBUGGING)))
1463 {
9d04d618 1464 fprintf (stderr, _("%s: can't create debugging section: %s\n"),
8d2e72a1
RH
1465 bfd_get_filename (obfd), bfd_errmsg (bfd_get_error ()));
1466 return false;
1467 }
1468
1469 /* We can get away with setting the section contents now because
1470 the next thing the caller is going to do is copy over the
1471 real sections. We may someday have to split the contents
1472 setting out of this function. */
1473 if (! bfd_set_section_contents (obfd, stabsec, syms, (file_ptr) 0,
1474 symsize)
1475 || ! bfd_set_section_contents (obfd, stabstrsec, strings,
1476 (file_ptr) 0, stringsize))
1477 {
9d04d618 1478 fprintf (stderr, _("%s: can't set debugging section contents: %s\n"),
8d2e72a1
RH
1479 bfd_get_filename (obfd), bfd_errmsg (bfd_get_error ()));
1480 return false;
1481 }
1482
1483 return true;
1484 }
1485
f5818d79 1486 fprintf (stderr,
9d04d618 1487 _("%s: don't know how to write debugging information for %s\n"),
f5818d79
ILT
1488 bfd_get_filename (obfd), bfd_get_target (obfd));
1489 return false;
1490}
1491
46050fe4
ILT
1492/* The number of bytes to copy at once. */
1493#define COPY_BUF 8192
1494
1495/* Copy file FROM to file TO, performing no translations.
1496 Return 0 if ok, -1 if error. */
1497
1498static int
1499simple_copy (from, to)
8d2e72a1
RH
1500 const char *from;
1501 const char *to;
c0367ba5 1502{
46050fe4 1503 int fromfd, tofd, nread;
d1a917c5 1504 int saved;
46050fe4
ILT
1505 char buf[COPY_BUF];
1506
1507 fromfd = open (from, O_RDONLY);
1508 if (fromfd < 0)
1509 return -1;
28b5eb12 1510 tofd = creat (to, 0777);
46050fe4
ILT
1511 if (tofd < 0)
1512 {
d1a917c5 1513 saved = errno;
46050fe4 1514 close (fromfd);
d1a917c5 1515 errno = saved;
46050fe4
ILT
1516 return -1;
1517 }
1518 while ((nread = read (fromfd, buf, sizeof buf)) > 0)
1519 {
1520 if (write (tofd, buf, nread) != nread)
1521 {
d1a917c5 1522 saved = errno;
46050fe4
ILT
1523 close (fromfd);
1524 close (tofd);
d1a917c5 1525 errno = saved;
46050fe4
ILT
1526 return -1;
1527 }
1528 }
d1a917c5 1529 saved = errno;
46050fe4
ILT
1530 close (fromfd);
1531 close (tofd);
1532 if (nread < 0)
d1a917c5
ILT
1533 {
1534 errno = saved;
1535 return -1;
1536 }
46050fe4
ILT
1537 return 0;
1538}
c0367ba5 1539
46050fe4
ILT
1540#ifndef S_ISLNK
1541#ifdef S_IFLNK
1542#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
1543#else
1544#define S_ISLNK(m) 0
1545#define lstat stat
1546#endif
1547#endif
1548
1549/* Rename FROM to TO, copying if TO is a link.
1550 Assumes that TO already exists, because FROM is a temp file.
1551 Return 0 if ok, -1 if error. */
1552
1553static int
1554smart_rename (from, to)
8d2e72a1
RH
1555 const char *from;
1556 const char *to;
46050fe4
ILT
1557{
1558 struct stat s;
1559 int ret = 0;
c0367ba5 1560
46050fe4
ILT
1561 if (lstat (to, &s))
1562 return -1;
c0367ba5 1563
eaa147a6
ILT
1564#if defined (_WIN32) && !defined (__CYGWIN32__)
1565 /* Win32, unlike unix, will not erase `to' in `rename(from, to)' but
1566 fail instead. Also, chown is not present. */
1567
1568 if (stat (to, &s) == 0)
1569 remove (to);
1570
1571 ret = rename (from, to);
1572 if (ret != 0)
1573 {
1574 /* We have to clean up here. */
1575 int saved = errno;
1576 fprintf (stderr, "%s: %s: ", program_name, to);
1577 errno = saved;
1578 perror ("rename");
1579 unlink (from);
1580 }
1581#else
46050fe4
ILT
1582 /* Use rename only if TO is not a symbolic link and has
1583 only one hard link. */
1584 if (!S_ISLNK (s.st_mode) && s.st_nlink == 1)
1585 {
1586 ret = rename (from, to);
1587 if (ret == 0)
1588 {
8d2e72a1
RH
1589 /* Try to preserve the permission bits and ownership of TO.
1590 First get the mode right except for the setuid bit. Then
1591 change the ownership. Then fix the setuid bit. We do
1592 the chmod before the chown because if the chown succeeds,
1593 and we are a normal user, we won't be able to do the
1594 chmod afterward. We don't bother to fix the setuid bit
1595 first because that might introduce a fleeting security
1596 problem, and because the chown will clear the setuid bit
1597 anyhow. We only fix the setuid bit if the chown
1598 succeeds, because we don't want to introduce an
1599 unexpected setuid file owned by the user running objcopy. */
1600 chmod (to, s.st_mode & 0777);
1601 if (chown (to, s.st_uid, s.st_gid) >= 0)
1602 chmod (to, s.st_mode & 07777);
46050fe4 1603 }
9135e5f8
ILT
1604 else
1605 {
1606 /* We have to clean up here. */
1607 int saved = errno;
d1a917c5 1608 fprintf (stderr, "%s: %s: ", program_name, to);
9135e5f8
ILT
1609 errno = saved;
1610 perror ("rename");
1611 unlink (from);
1612 }
46050fe4
ILT
1613 }
1614 else
1615 {
1616 ret = simple_copy (from, to);
d1a917c5
ILT
1617 if (ret != 0)
1618 {
1619 int saved = errno;
1620 fprintf (stderr, "%s: %s: ", program_name, to);
1621 errno = saved;
1622 perror ("simple_copy");
1623 }
22947e96
ILT
1624 if (preserve_dates)
1625 set_times (to, &s);
d1a917c5 1626 unlink (from);
46050fe4 1627 }
eaa147a6
ILT
1628#endif /* _WIN32 && !__CYGWIN32__ */
1629
46050fe4
ILT
1630 return ret;
1631}
1632
8d2e72a1
RH
1633/* Set the times of the file DESTINATION to be the same as those in
1634 STATBUF. */
1635
1636static void
1637set_times (destination, statbuf)
1638 const char *destination;
1639 const struct stat *statbuf;
1640{
1641 int result;
1642
1643 {
1644#ifdef HAVE_GOOD_UTIME_H
1645 struct utimbuf tb;
1646
1647 tb.actime = statbuf->st_atime;
1648 tb.modtime = statbuf->st_mtime;
1649 result = utime (destination, &tb);
1650#else /* ! HAVE_GOOD_UTIME_H */
1651#ifndef HAVE_UTIMES
1652 long tb[2];
1653
1654 tb[0] = statbuf->st_atime;
1655 tb[1] = statbuf->st_mtime;
1656 result = utime (destination, tb);
1657#else /* HAVE_UTIMES */
1658 struct timeval tv[2];
1659
1660 tv[0].tv_sec = statbuf->st_atime;
1661 tv[0].tv_usec = 0;
1662 tv[1].tv_sec = statbuf->st_mtime;
1663 tv[1].tv_usec = 0;
1664 result = utimes (destination, tv);
1665#endif /* HAVE_UTIMES */
1666#endif /* ! HAVE_GOOD_UTIME_H */
1667 }
1668
1669 if (result != 0)
1670 {
1671 fprintf (stderr, "%s: ", destination);
9d04d618 1672 perror (_("can not set time"));
8d2e72a1
RH
1673 }
1674}
1675
46050fe4
ILT
1676static int
1677strip_main (argc, argv)
1678 int argc;
1679 char *argv[];
1680{
1681 char *input_target = NULL, *output_target = NULL;
1682 boolean show_version = false;
1683 int c, i;
5ab41086 1684 struct section_list *p;
8d2e72a1 1685 char *output_file = NULL;
46050fe4 1686
8d2e72a1 1687 while ((c = getopt_long (argc, argv, "I:O:F:K:N:R:o:sSpgxXVv",
46050fe4
ILT
1688 strip_options, (int *) 0)) != EOF)
1689 {
1690 switch (c)
1691 {
1692 case 'I':
1693 input_target = optarg;
704bbd0d 1694 break;
46050fe4
ILT
1695 case 'O':
1696 output_target = optarg;
1697 break;
1698 case 'F':
1699 input_target = output_target = optarg;
1700 break;
6c7ed084 1701 case 'R':
5ab41086
ILT
1702 p = find_section_list (optarg, true);
1703 p->remove = true;
1704 sections_removed = true;
6c7ed084 1705 break;
46050fe4 1706 case 's':
c0367ba5 1707 strip_symbols = strip_all;
46050fe4
ILT
1708 break;
1709 case 'S':
1710 case 'g':
1711 strip_symbols = strip_debug;
1712 break;
9135e5f8
ILT
1713 case OPTION_STRIP_UNNEEDED:
1714 strip_symbols = strip_unneeded;
1715 break;
1716 case 'K':
8d2e72a1 1717 add_specific_symbol (optarg, &keep_specific_list);
9135e5f8 1718 break;
4af19c61 1719 case 'N':
8d2e72a1
RH
1720 add_specific_symbol (optarg, &strip_specific_list);
1721 break;
1722 case 'o':
1723 output_file = optarg;
1724 break;
1725 case 'p':
1726 preserve_dates = true;
4af19c61 1727 break;
46050fe4
ILT
1728 case 'x':
1729 discard_locals = locals_all;
1730 break;
1731 case 'X':
1732 discard_locals = locals_start_L;
1733 break;
1734 case 'v':
1735 verbose = true;
1736 break;
1737 case 'V':
1738 show_version = true;
1739 break;
1740 case 0:
1741 break; /* we've been given a long option */
1742 case 'h':
1743 strip_usage (stdout, 0);
1744 default:
1745 strip_usage (stderr, 1);
1746 }
1747 }
1748
1749 if (show_version)
8d2e72a1 1750 print_version ("strip");
c0367ba5 1751
46050fe4 1752 /* Default is to strip all symbols. */
4af19c61
KR
1753 if (strip_symbols == strip_undef
1754 && discard_locals == locals_undef
1755 && strip_specific_list == NULL)
46050fe4
ILT
1756 strip_symbols = strip_all;
1757
1758 if (output_target == (char *) NULL)
1759 output_target = input_target;
1760
1761 i = optind;
8d2e72a1
RH
1762 if (i == argc
1763 || (output_file != NULL && (i + 1) < argc))
46050fe4
ILT
1764 strip_usage (stderr, 1);
1765
1766 for (; i < argc; i++)
1767 {
1768 int hold_status = status;
8d2e72a1
RH
1769 struct stat statbuf;
1770 char *tmpname;
1771
1772 if (preserve_dates)
1773 {
1774 if (stat (argv[i], &statbuf) < 0)
1775 {
1776 fprintf (stderr, "%s: ", argv[i]);
9d04d618 1777 perror (_("cannot stat"));
8d2e72a1
RH
1778 continue;
1779 }
1780 }
c0367ba5 1781
8d2e72a1
RH
1782 if (output_file != NULL)
1783 tmpname = output_file;
1784 else
1785 tmpname = make_tempname (argv[i]);
46050fe4 1786 status = 0;
8d2e72a1 1787
46050fe4
ILT
1788 copy_file (argv[i], tmpname, input_target, output_target);
1789 if (status == 0)
1790 {
8d2e72a1
RH
1791 if (preserve_dates)
1792 set_times (tmpname, &statbuf);
1793 if (output_file == NULL)
1794 smart_rename (tmpname, argv[i]);
46050fe4 1795 status = hold_status;
c0367ba5 1796 }
46050fe4
ILT
1797 else
1798 unlink (tmpname);
8d2e72a1
RH
1799 if (output_file == NULL)
1800 free (tmpname);
46050fe4
ILT
1801 }
1802
1803 return 0;
1804}
1805
1806static int
1807copy_main (argc, argv)
1808 int argc;
1809 char *argv[];
1810{
6c7ed084 1811 char *input_filename = NULL, *output_filename = NULL;
46050fe4
ILT
1812 char *input_target = NULL, *output_target = NULL;
1813 boolean show_version = false;
6c7ed084 1814 boolean adjust_warn = true;
46050fe4 1815 int c;
6c7ed084 1816 struct section_list *p;
8d2e72a1 1817 struct stat statbuf;
46050fe4 1818
246b7c9b 1819 while ((c = getopt_long (argc, argv, "b:i:I:K:N:s:O:d:F:L:R:SpgxXVvW:",
46050fe4
ILT
1820 copy_options, (int *) 0)) != EOF)
1821 {
1822 switch (c)
1823 {
f7b839f7
DM
1824 case 'b':
1825 copy_byte = atoi(optarg);
1826 if (copy_byte < 0)
1827 {
9d04d618 1828 fprintf (stderr, _("%s: byte number must be non-negative\n"),
f7b839f7
DM
1829 program_name);
1830 exit (1);
1831 }
1832 break;
1833 case 'i':
1834 interleave = atoi(optarg);
1835 if (interleave < 1)
1836 {
9d04d618 1837 fprintf(stderr, _("%s: interleave must be positive\n"),
f7b839f7
DM
1838 program_name);
1839 exit (1);
1840 }
1841 break;
c0367ba5 1842 case 'I':
46050fe4 1843 case 's': /* "source" - 'I' is preferred */
c0367ba5 1844 input_target = optarg;
704bbd0d 1845 break;
c0367ba5 1846 case 'O':
46050fe4 1847 case 'd': /* "destination" - 'O' is preferred */
c0367ba5
ILT
1848 output_target = optarg;
1849 break;
1850 case 'F':
c0367ba5
ILT
1851 input_target = output_target = optarg;
1852 break;
6c7ed084 1853 case 'R':
5ab41086
ILT
1854 p = find_section_list (optarg, true);
1855 p->remove = true;
1856 sections_removed = true;
6c7ed084 1857 break;
c0367ba5
ILT
1858 case 'S':
1859 strip_symbols = strip_all;
1860 break;
1861 case 'g':
1862 strip_symbols = strip_debug;
1863 break;
9135e5f8
ILT
1864 case OPTION_STRIP_UNNEEDED:
1865 strip_symbols = strip_unneeded;
1866 break;
1867 case 'K':
8d2e72a1 1868 add_specific_symbol (optarg, &keep_specific_list);
9135e5f8 1869 break;
4af19c61 1870 case 'N':
8d2e72a1
RH
1871 add_specific_symbol (optarg, &strip_specific_list);
1872 break;
246b7c9b
RH
1873 case 'L':
1874 add_specific_symbol (optarg, &localize_specific_list);
8d2e72a1
RH
1875 break;
1876 case 'W':
1877 add_specific_symbol (optarg, &weaken_specific_list);
1878 break;
1879 case 'p':
1880 preserve_dates = true;
4af19c61 1881 break;
c0367ba5
ILT
1882 case 'x':
1883 discard_locals = locals_all;
1884 break;
1885 case 'X':
1886 discard_locals = locals_start_L;
1887 break;
1888 case 'v':
1889 verbose = true;
1890 break;
1891 case 'V':
1892 show_version = true;
1893 break;
8d2e72a1
RH
1894 case OPTION_WEAKEN:
1895 weaken = true;
1896 break;
5ab41086
ILT
1897 case OPTION_ADD_SECTION:
1898 {
1899 const char *s;
1900 struct stat st;
1901 struct section_add *pa;
1902 int len;
1903 char *name;
1904 FILE *f;
1905
1906 s = strchr (optarg, '=');
1907 if (s == NULL)
1908 {
1909 fprintf (stderr,
9d04d618 1910 _("%s: bad format for --add-section NAME=FILENAME\n"),
5ab41086
ILT
1911 program_name);
1912 exit (1);
1913 }
1914
1915 if (stat (s + 1, &st) < 0)
1916 {
1917 fprintf (stderr, "%s: ", program_name);
1918 perror (s + 1);
1919 exit (1);
1920 }
1921
1922 pa = (struct section_add *) xmalloc (sizeof (struct section_add));
1923
1924 len = s - optarg;
1925 name = (char *) xmalloc (len + 1);
1926 strncpy (name, optarg, len);
1927 name[len] = '\0';
1928 pa->name = name;
1929
1930 pa->filename = s + 1;
1931
1932 pa->size = st.st_size;
1933
9135e5f8 1934 pa->contents = (bfd_byte *) xmalloc (pa->size);
5ab41086
ILT
1935 f = fopen (pa->filename, FOPEN_RB);
1936 if (f == NULL)
1937 {
1938 fprintf (stderr, "%s: ", program_name);
1939 perror (pa->filename);
1940 exit (1);
1941 }
1942 if (fread (pa->contents, 1, pa->size, f) == 0
1943 || ferror (f))
1944 {
9d04d618 1945 fprintf (stderr, _("%s: %s: fread failed\n"),
5ab41086
ILT
1946 program_name, pa->filename);
1947 exit (1);
1948 }
1949 fclose (f);
1950
1951 pa->next = add_sections;
1952 add_sections = pa;
1953 }
1954 break;
6c7ed084
ILT
1955 case OPTION_ADJUST_START:
1956 adjust_start = parse_vma (optarg, "--adjust-start");
1957 break;
1958 case OPTION_ADJUST_SECTION_VMA:
1959 {
1960 const char *s;
1961 int len;
1962 char *name;
1963
6c7ed084 1964 s = strchr (optarg, '=');
5ab41086 1965 if (s == NULL)
6c7ed084
ILT
1966 {
1967 s = strchr (optarg, '+');
1968 if (s == NULL)
1969 {
1970 s = strchr (optarg, '-');
1971 if (s == NULL)
1972 {
1973 fprintf (stderr,
9d04d618 1974 _("%s: bad format for --adjust-section-vma\n"),
6c7ed084
ILT
1975 program_name);
1976 exit (1);
1977 }
1978 }
6c7ed084
ILT
1979 }
1980
1981 len = s - optarg;
1982 name = (char *) xmalloc (len + 1);
1983 strncpy (name, optarg, len);
1984 name[len] = '\0';
6c7ed084 1985
5ab41086
ILT
1986 p = find_section_list (name, true);
1987
1988 p->val = parse_vma (s + 1, "--adjust-section-vma");
6c7ed084 1989
5ab41086
ILT
1990 if (*s == '=')
1991 p->adjust = set_vma;
1992 else
1993 {
1994 p->adjust = adjust_vma;
1995 if (*s == '-')
1996 p->val = - p->val;
1997 }
6c7ed084
ILT
1998 }
1999 break;
2000 case OPTION_ADJUST_VMA:
2001 adjust_section_vma = parse_vma (optarg, "--adjust-vma");
2002 adjust_start = adjust_section_vma;
2003 break;
2004 case OPTION_ADJUST_WARNINGS:
2005 adjust_warn = true;
2006 break;
8d2e72a1
RH
2007 case OPTION_CHANGE_LEADING_CHAR:
2008 change_leading_char = true;
2009 break;
f5818d79
ILT
2010 case OPTION_DEBUGGING:
2011 convert_debugging = true;
2012 break;
596d99ba
ILT
2013 case OPTION_GAP_FILL:
2014 {
2015 bfd_vma gap_fill_vma;
2016
2017 gap_fill_vma = parse_vma (optarg, "--gap-fill");
2018 gap_fill = (bfd_byte) gap_fill_vma;
2019 if ((bfd_vma) gap_fill != gap_fill_vma)
2020 {
9d04d618 2021 fprintf (stderr, _("%s: warning: truncating gap-fill from 0x"),
596d99ba
ILT
2022 program_name);
2023 fprintf_vma (stderr, gap_fill_vma);
2024 fprintf (stderr, "to 0x%x\n", (unsigned int) gap_fill);
2025 }
2026 gap_fill_set = true;
2027 }
2028 break;
6c7ed084
ILT
2029 case OPTION_NO_ADJUST_WARNINGS:
2030 adjust_warn = false;
2031 break;
87a15686
ILT
2032 case OPTION_PAD_TO:
2033 pad_to = parse_vma (optarg, "--pad-to");
2034 pad_to_set = true;
2035 break;
8d2e72a1
RH
2036 case OPTION_REMOVE_LEADING_CHAR:
2037 remove_leading_char = true;
2038 break;
5ab41086
ILT
2039 case OPTION_SET_SECTION_FLAGS:
2040 {
2041 const char *s;
2042 int len;
2043 char *name;
2044
2045 s = strchr (optarg, '=');
2046 if (s == NULL)
2047 {
9d04d618 2048 fprintf (stderr, _("%s: bad format for --set-section-flags\n"),
5ab41086
ILT
2049 program_name);
2050 exit (1);
2051 }
2052
2053 len = s - optarg;
2054 name = (char *) xmalloc (len + 1);
2055 strncpy (name, optarg, len);
2056 name[len] = '\0';
2057
2058 p = find_section_list (name, true);
2059
2060 p->set_flags = true;
2061 p->flags = parse_flags (s + 1);
2062 }
2063 break;
6c7ed084
ILT
2064 case OPTION_SET_START:
2065 set_start = parse_vma (optarg, "--set-start");
2066 set_start_set = true;
2067 break;
46050fe4 2068 case 0:
c0367ba5
ILT
2069 break; /* we've been given a long option */
2070 case 'h':
2071 copy_usage (stdout, 0);
2072 default:
2073 copy_usage (stderr, 1);
46050fe4
ILT
2074 }
2075 }
2076
2077 if (show_version)
8d2e72a1 2078 print_version ("objcopy");
c0367ba5 2079
f7b839f7
DM
2080 if (copy_byte >= interleave)
2081 {
9d04d618 2082 fprintf (stderr, _("%s: byte number must be less than interleave\n"),
f7b839f7
DM
2083 program_name);
2084 exit (1);
2085 }
2086
46050fe4
ILT
2087 if (optind == argc || optind + 2 < argc)
2088 copy_usage (stderr, 1);
c0367ba5
ILT
2089
2090 input_filename = argv[optind];
2091 if (optind + 1 < argc)
46050fe4 2092 output_filename = argv[optind + 1];
c0367ba5
ILT
2093
2094 /* Default is to strip no symbols. */
2095 if (strip_symbols == strip_undef && discard_locals == locals_undef)
46050fe4 2096 strip_symbols = strip_none;
c0367ba5
ILT
2097
2098 if (output_target == (char *) NULL)
2099 output_target = input_target;
2100
8d2e72a1
RH
2101 if (preserve_dates)
2102 {
2103 if (stat (input_filename, &statbuf) < 0)
2104 {
2105 fprintf (stderr, "%s: ", input_filename);
9d04d618 2106 perror (_("cannot stat"));
8d2e72a1
RH
2107 exit (1);
2108 }
2109 }
2110
46050fe4
ILT
2111 /* If there is no destination file then create a temp and rename
2112 the result into the input. */
2113
2114 if (output_filename == (char *) NULL)
2115 {
2116 char *tmpname = make_tempname (input_filename);
8d2e72a1 2117
46050fe4
ILT
2118 copy_file (input_filename, tmpname, input_target, output_target);
2119 if (status == 0)
8d2e72a1
RH
2120 {
2121 if (preserve_dates)
2122 set_times (tmpname, &statbuf);
2123 smart_rename (tmpname, input_filename);
2124 }
46050fe4
ILT
2125 else
2126 unlink (tmpname);
2127 }
2128 else
2129 {
2130 copy_file (input_filename, output_filename, input_target, output_target);
8d2e72a1
RH
2131 if (status == 0 && preserve_dates)
2132 set_times (output_filename, &statbuf);
46050fe4
ILT
2133 }
2134
6c7ed084
ILT
2135 if (adjust_warn)
2136 {
2137 for (p = adjust_sections; p != NULL; p = p->next)
2138 {
5ab41086 2139 if (! p->used && p->adjust != ignore_vma)
6c7ed084 2140 {
9d04d618 2141 fprintf (stderr, _("%s: warning: --adjust-section-vma %s%c0x"),
6c7ed084 2142 program_name, p->name,
5ab41086 2143 p->adjust == set_vma ? '=' : '+');
6c7ed084 2144 fprintf_vma (stderr, p->val);
9d04d618 2145 fprintf (stderr, _(" never used\n"));
6c7ed084
ILT
2146 }
2147 }
2148 }
2149
c0367ba5
ILT
2150 return 0;
2151}
46050fe4
ILT
2152
2153int
2154main (argc, argv)
2155 int argc;
2156 char *argv[];
2157{
19ac4b08
TT
2158 setlocale (LC_MESSAGES, "");
2159 bindtextdomain (PACKAGE, LOCALEDIR);
2160 textdomain (PACKAGE);
2161
46050fe4 2162 program_name = argv[0];
704bbd0d 2163 xmalloc_set_program_name (program_name);
5ab41086
ILT
2164
2165 START_PROGRESS (program_name, 0);
2166
46050fe4
ILT
2167 strip_symbols = strip_undef;
2168 discard_locals = locals_undef;
2169
2170 bfd_init ();
8d2e72a1 2171 set_default_bfd_target ();
46050fe4
ILT
2172
2173 if (is_strip < 0)
2174 {
2175 int i = strlen (program_name);
87a15686 2176 is_strip = (i >= 5 && strcmp (program_name + i - 5, "strip") == 0);
46050fe4
ILT
2177 }
2178
2179 if (is_strip)
2180 strip_main (argc, argv);
2181 else
2182 copy_main (argc, argv);
2183
5ab41086
ILT
2184 END_PROGRESS (program_name);
2185
46050fe4
ILT
2186 return status;
2187}
This page took 0.258786 seconds and 4 git commands to generate.