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