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