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