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