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