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